diff --git a/index.js b/index.js index 0625acc84c511972831e8b6a435cd46253c3a9ca..7fb0e93a29e98f9c72b79ec9bd11983d5fb37ed8 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,12 @@ -//toimivat 3.1-3.6 +//toimivat 3.1-3.12 + const http = require('http') const express = require('express') const app = express() +const Contact = require('./models/contact') + const bodyParser = require('body-parser') app.use(bodyParser.json()) @@ -21,6 +24,14 @@ app.use(express.static('build')) app.use(logger) +const formatContact = (contact) => { + return { + name: contact.name, + number: contact.number, + id: contact._id + } +} + let persons = [ { name: "Murto Karhunen", @@ -44,65 +55,76 @@ let persons = [ } ] app.get('/', (req, res) => { - res.send('<h1>Hello World!</h1>') + res.send('<h1>please move to /api/persons</h1>') }) -app.get('/api/persons', (req, res) => { - res.json(persons) +app.get('/api/persons', (request, response) => { + Contact + .find({}) + .then(persons => { + response.json(persons.map(formatContact)) + }) }) app.get('/api/persons/:id', (request, response) => { - const id = Number(request.params.id) - const person = persons.find(person => person.id === id ) - - if (person){ - response.json(person) -}else{ - response.status(404).end() -} -}) - -app.delete('/api/persons/:id' , (request, response) =>{ - - const id = Number(request.params.id) - persons = persons.filter(person => person.id !== id) - - response.status(204).end() + Contact + .findById(request.params.id) + .then(contact => { + if (contact){ + response.json(formatContact(contact)) + } else{ + response.status(404).end() + } + }) + .catch(error => { + console.log(error) + response.status(404).send({error: 'Malformatted id'}) + }) }) -const generateId = () => { - const minId = Math.ceil(persons.length > 0 ? persons.map(n => n.id).sort((a,b) => a - b).reverse()[0] : 1) - const maxId = Math.floor(1000) - return Math.floor(Math.random() * (maxId - minId)); -} - app.post('/api/persons', (request, response) => { const body = request.body const person_list = () => persons.map(part => part.name) - if ((body.name === undefined) || (body.number === undefined)) { - return response.status(400).json({error: 'Please check the input, there is some content missing.'}) } - //setTimeout('', 1000); if ((person_list().includes(body.name))){ return response.status(400).json({error: 'Sorry, but the name must be unique.'}) console.log("name must be unique!"); } - const person = { + const contact = new Contact ({ name: body.name, - number: body.number, - id: generateId() - } - - persons = persons.concat(person) + number: body.number + }) + + contact + .save() + .then(formatContact) + .then(savedAndFormattedContact => { + response.json(savedAndFormattedContact) + }) +}) - response.json(person) +app.delete('/api/persons/:id' , (request, response) =>{ + Contact + .findByIdAndRemove(request.params.id) + .then(result => { + response.status(204).end() + }) + .catch(error => { + response.status(400).send({ error: 'malformatted id' }) + }) }) +const generateId = () => { + const minId = Math.ceil(persons.length > 0 ? persons.map(n => n.id).sort((a,b) => a - b).reverse()[0] : 1) + const maxId = Math.floor(1000) + return Math.floor(Math.random() * (maxId - minId)); +} + const error = (request, response) => { response.status(404).send({error: 'unknown endpoint'}) } diff --git a/models/contact.js b/models/contact.js new file mode 100644 index 0000000000000000000000000000000000000000..6e853760b1dc8d4212a577eccb62a47a0be20780 --- /dev/null +++ b/models/contact.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose') + +const url = 'mongodb+srv://fullstack:xxx@clusterphonebook-duq8b.mongodb.net/fullstack-contacts' + +mongoose.connect(url, { useNewUrlParser: true }) + +const Contact = mongoose.model('Contact', { + name: String, + number: String +}) + + +module.exports = Contact diff --git a/mongo.js b/mongo.js new file mode 100644 index 0000000000000000000000000000000000000000..e37945d3c480faf609a023f19514f77e32a44570 --- /dev/null +++ b/mongo.js @@ -0,0 +1,45 @@ +const mongoose = require('mongoose') + +// Replace with the URL of your own database. Do not store the password on GitHub! +const url = 'mongodb+srv://fullstack:Koodaanko247@clusterphonebook-duq8b.mongodb.net/fullstack-contacts' + +mongoose.connect(url, { useNewUrlParser: true }) + + +process.argv.forEach((name, number) => { + var name = process.argv[2] + var number = process.argv[3] + console.log(`Adding person ${name} with the number ${number} to the directory`); +}); + + + +const contactSchema = new mongoose.Schema({ + name: String, + number: String +}) + +const Contact = mongoose.model('Contact', contactSchema); + +const contact = new Contact({ + name: 'Terho Tammi', + number: '666-555' +}) + + +contact + .save() + .then(response => { + console.log('contact saved!') + mongoose.connection.close() +}) + + +Contact + .find({}) + .then(result => { + result.forEach(contact => { + console.log(contact) + }) + mongoose.connection.close() + }) diff --git a/package-lock.json b/package-lock.json index 43f644285b6c524e4b847e897f10a0da9899a041..3ded73cef87c1d61922d5f9eee622b31bcbe5213 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,6 +99,14 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } + }, "async-each": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz", @@ -178,6 +186,11 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, "body-parser": { "version": "1.18.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", @@ -249,6 +262,11 @@ } } }, + "bson": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -1713,6 +1731,11 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "kareem": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", + "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" + }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -1728,6 +1751,11 @@ "package-json": "^4.0.0" } }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1773,6 +1801,12 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -1858,6 +1892,84 @@ } } }, + "mongodb": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.13.tgz", + "integrity": "sha512-sz2dhvBZQWf3LRNDhbd30KHVzdjZx9IKC0L+kSZ/gzYquCF5zPOgGqRz6sSCqYZtKP2ekB4nfLxhGtzGHnIKxA==", + "requires": { + "mongodb-core": "3.1.11", + "safe-buffer": "^5.1.2" + } + }, + "mongodb-core": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.11.tgz", + "integrity": "sha512-rD2US2s5qk/ckbiiGFHeu+yKYDXdJ1G87F6CG3YdaZpzdOm5zpoAZd/EKbPmFO6cQZ+XVXBXBJ660sSI0gc6qg==", + "requires": { + "bson": "^1.1.0", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "mongoose": { + "version": "5.4.20", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.4.20.tgz", + "integrity": "sha512-CyybxMQbCaq6jvbroamS5mPfFbxTOLLpdpkQrk1cj7Az1TX+mBbcCVhz+7XElfTMIOb58ah9O+EXmZJsLPD3Lg==", + "requires": { + "async": "2.6.1", + "bson": "~1.1.0", + "kareem": "2.3.0", + "mongodb": "3.1.13", + "mongodb-core": "3.1.11", + "mongoose-legacy-pluralize": "1.0.2", + "mpath": "0.5.1", + "mquery": "3.2.0", + "ms": "2.1.1", + "regexp-clone": "0.0.1", + "safe-buffer": "5.1.2", + "sliced": "1.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "mongoose-legacy-pluralize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", + "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" + }, + "mpath": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.5.1.tgz", + "integrity": "sha512-H8OVQ+QEz82sch4wbODFOz+3YQ61FYz/z3eJ5pIdbMEaUzDqA268Wd+Vt4Paw9TJfvDgVKaayC0gBzMIw2jhsg==" + }, + "mquery": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz", + "integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==", + "requires": { + "bluebird": "3.5.1", + "debug": "3.1.0", + "regexp-clone": "0.0.1", + "safe-buffer": "5.1.2", + "sliced": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2187,6 +2299,11 @@ "safe-regex": "^1.1.0" } }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, "registry-auth-token": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", @@ -2224,6 +2341,20 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -2255,11 +2386,19 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "saslprep": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz", + "integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, "semver-diff": { "version": "2.1.0", @@ -2350,6 +2489,11 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -2482,6 +2626,15 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", diff --git a/package.json b/package.json index 68cd791da1c5591b1086b73849a4da7d4d95b33d..b55cdccbc61564b014175d495a2ec030f02e6b80 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "license": "ISC", "dependencies": { "cors": "^2.8.5", - "express": "^4.16.4" + "express": "^4.16.4", + "mongoose": "^5.4.20" }, "devDependencies": { "nodemon": "^1.18.10"