From 967513359228727d557d15f053dd5d185bda37f8 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Tue, 6 Apr 2021 18:35:03 +0300 Subject: [PATCH 01/16] Started working on HW --- .gitignore | 1 + HW9(http)/.gitignore | 1 + HW9(http)/MVC/controller.js | 0 HW9(http)/MVC/model.js | 0 HW9(http)/MVC/view.js | 0 HW9(http)/app.js | 77 ++ HW9(http)/db.json | 1 + HW9(http)/index.html | 12 + HW9(http)/package-lock.json | 1411 +++++++++++++++++++++++++++++++++++ HW9(http)/package.json | 19 + 10 files changed, 1522 insertions(+) create mode 100644 .gitignore create mode 100644 HW9(http)/.gitignore create mode 100644 HW9(http)/MVC/controller.js create mode 100644 HW9(http)/MVC/model.js create mode 100644 HW9(http)/MVC/view.js create mode 100644 HW9(http)/app.js create mode 100644 HW9(http)/db.json create mode 100644 HW9(http)/index.html create mode 100644 HW9(http)/package-lock.json create mode 100644 HW9(http)/package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba698c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/launch.json diff --git a/HW9(http)/.gitignore b/HW9(http)/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/HW9(http)/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/HW9(http)/MVC/controller.js b/HW9(http)/MVC/controller.js new file mode 100644 index 0000000..e69de29 diff --git a/HW9(http)/MVC/model.js b/HW9(http)/MVC/model.js new file mode 100644 index 0000000..e69de29 diff --git a/HW9(http)/MVC/view.js b/HW9(http)/MVC/view.js new file mode 100644 index 0000000..e69de29 diff --git a/HW9(http)/app.js b/HW9(http)/app.js new file mode 100644 index 0000000..c1cd8cc --- /dev/null +++ b/HW9(http)/app.js @@ -0,0 +1,77 @@ +const http = require('http'); +const express = require('express') +const fs = require('fs').promises +const bodyParser = require('body-parser'); + +const app = express(); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(bodyParser.json()); + +const port = 4200; + +app.get('/', async (req, res) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + if (req.query.id === undefined) { + res.send(stock); + } else { + const requestedId = +req.query.id; + const requestedItem = stock.find(item => item.id === requestedId); + res.send(requestedItem); + } +}) + +app.post('/', async (req, _) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + stock.push({ + name: req.query.name ?? 'Default', + id: req.query.id ?? stock.length, + url: req.query.url ?? '', + }); + + await fs.writeFile('./db.json', JSON.stringify({ + stock: stock + })); +}) + +app.put('/', async (req, res) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + const requestedId = +req.query.id; // index of the item in the stock + const itemToUpdate = stock.find(item => item.id === requestedId); + + if (itemToUpdate === undefined) { + throw new Error('No such item in the stock') + return; + } + + const itemIndex = stock.indexOf(itemToUpdate); + stock[itemIndex] = { + name: req.query.name ?? stock[i].name, + id: req.query.id ?? stock[i].id, + url: req.query.url ?? stock[i].url, + } + + await fs.writeFile('./db.json', JSON.stringify({ + stock: stock + })); +}) + +app.delete('/', async (req, res) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + stock.splice(+req.query.id, 1) + + await fs.writeFile('./db.json', JSON.stringify({ + stock: stock + })); +}) + +app.listen(port, () => { + console.info(`Started server at port: ${port}`); +}) \ No newline at end of file diff --git a/HW9(http)/db.json b/HW9(http)/db.json new file mode 100644 index 0000000..ef5923f --- /dev/null +++ b/HW9(http)/db.json @@ -0,0 +1 @@ +{"stock":[{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},null,null,null,null,{"name":"Name1","id":"9","url":"no"},{"name":"Name1","id":"10","url":"no"}]} \ No newline at end of file diff --git a/HW9(http)/index.html b/HW9(http)/index.html new file mode 100644 index 0000000..dac5e4a --- /dev/null +++ b/HW9(http)/index.html @@ -0,0 +1,12 @@ + + + + + + + Document + + +

Flowers world

+ + \ No newline at end of file diff --git a/HW9(http)/package-lock.json b/HW9(http)/package-lock.json new file mode 100644 index 0000000..a15fa92 --- /dev/null +++ b/HW9(http)/package-lock.json @@ -0,0 +1,1411 @@ +{ + "name": "hw9_http", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "requires": { + "jake": "^10.6.1" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, + "requires": { + "ini": "1.3.7" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nodemon": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "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==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + } + } +} diff --git a/HW9(http)/package.json b/HW9(http)/package.json new file mode 100644 index 0000000..5197908 --- /dev/null +++ b/HW9(http)/package.json @@ -0,0 +1,19 @@ +{ + "name": "hw9_http", + "version": "1.0.0", + "description": "https://docs.google.com/presentation/d/1p1oW9rokPn38tUHVwAMKuyBWewh1_AfI9qfZg3-4oUk/edit?usp=sharing", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "nodemon app.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "ejs": "3.1.6", + "express": "4.17.1" + }, + "devDependencies": { + "nodemon": "2.0.7" + } +} From d4385d0ada2a30e8d670ab0cf8d071401227a7af Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 7 Apr 2021 12:18:17 +0300 Subject: [PATCH 02/16] Made some changes --- HW9(http)/MVC/controller.js | 0 HW9(http)/MVC/model.js | 0 HW9(http)/MVC/view.js | 0 HW9(http)/README.md | 13 ----- HW9(http)/app.js | 77 +++---------------------- HW9(http)/index.html | 11 +++- HW9(http)/public/scripts/Controller.js | 7 +++ HW9(http)/public/scripts/Model.js | 78 ++++++++++++++++++++++++++ HW9(http)/public/scripts/View.js | 8 +++ HW9(http)/public/styles/style.css | 15 +++++ 10 files changed, 126 insertions(+), 83 deletions(-) delete mode 100644 HW9(http)/MVC/controller.js delete mode 100644 HW9(http)/MVC/model.js delete mode 100644 HW9(http)/MVC/view.js delete mode 100644 HW9(http)/README.md create mode 100644 HW9(http)/public/scripts/Controller.js create mode 100644 HW9(http)/public/scripts/Model.js create mode 100644 HW9(http)/public/scripts/View.js create mode 100644 HW9(http)/public/styles/style.css diff --git a/HW9(http)/MVC/controller.js b/HW9(http)/MVC/controller.js deleted file mode 100644 index e69de29..0000000 diff --git a/HW9(http)/MVC/model.js b/HW9(http)/MVC/model.js deleted file mode 100644 index e69de29..0000000 diff --git a/HW9(http)/MVC/view.js b/HW9(http)/MVC/view.js deleted file mode 100644 index e69de29..0000000 diff --git a/HW9(http)/README.md b/HW9(http)/README.md deleted file mode 100644 index 480c8a4..0000000 --- a/HW9(http)/README.md +++ /dev/null @@ -1,13 +0,0 @@ -https://docs.google.com/presentation/d/1p1oW9rokPn38tUHVwAMKuyBWewh1_AfI9qfZg3-4oUk/edit?usp=sharing - -- write a simple server that implements CRUD (https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) -- database - imitation from json file -- do not forget about handling possible errors and correct HTTP codes - -improvement 1 -- split common file by MVC model - -improvement 2 -- add basic UI to the answer - -*details in the video lecture \ No newline at end of file diff --git a/HW9(http)/app.js b/HW9(http)/app.js index c1cd8cc..96124b6 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -1,77 +1,18 @@ -const http = require('http'); const express = require('express') const fs = require('fs').promises -const bodyParser = require('body-parser'); +const $V = require('./public/scripts/View.js') -const app = express(); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(bodyParser.json()); +const app = express() +const port = 4200 -const port = 4200; +app.use(express.static('public')) +app.use('/styles', express.static(__dirname + 'public/styles')) +app.use('/scripts', express.static(__dirname + 'public/scripts')) -app.get('/', async (req, res) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; - - if (req.query.id === undefined) { - res.send(stock); - } else { - const requestedId = +req.query.id; - const requestedItem = stock.find(item => item.id === requestedId); - res.send(requestedItem); - } -}) - -app.post('/', async (req, _) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; - - stock.push({ - name: req.query.name ?? 'Default', - id: req.query.id ?? stock.length, - url: req.query.url ?? '', - }); - - await fs.writeFile('./db.json', JSON.stringify({ - stock: stock - })); -}) - -app.put('/', async (req, res) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; - - const requestedId = +req.query.id; // index of the item in the stock - const itemToUpdate = stock.find(item => item.id === requestedId); - - if (itemToUpdate === undefined) { - throw new Error('No such item in the stock') - return; - } - - const itemIndex = stock.indexOf(itemToUpdate); - stock[itemIndex] = { - name: req.query.name ?? stock[i].name, - id: req.query.id ?? stock[i].id, - url: req.query.url ?? stock[i].url, - } - - await fs.writeFile('./db.json', JSON.stringify({ - stock: stock - })); -}) - -app.delete('/', async (req, res) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; - - stock.splice(+req.query.id, 1) - - await fs.writeFile('./db.json', JSON.stringify({ - stock: stock - })); +app.get('', (_, res) => { + res.sendFile(__dirname + '/index.html') }) app.listen(port, () => { - console.info(`Started server at port: ${port}`); + console.info(`Started server at port: ${port}`) }) \ No newline at end of file diff --git a/HW9(http)/index.html b/HW9(http)/index.html index dac5e4a..ec07e9a 100644 --- a/HW9(http)/index.html +++ b/HW9(http)/index.html @@ -4,9 +4,16 @@ - Document + Flowers world | Home + + + -

Flowers world

+
+

Flowers world

+
+ +
\ No newline at end of file diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js new file mode 100644 index 0000000..e061924 --- /dev/null +++ b/HW9(http)/public/scripts/Controller.js @@ -0,0 +1,7 @@ +console.log('+ Controller'); +const $V = require('./View') +const $M = require('./Model') + +class Controller {} + +module.exports.$C = new Controller; \ No newline at end of file diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js new file mode 100644 index 0000000..c84908e --- /dev/null +++ b/HW9(http)/public/scripts/Model.js @@ -0,0 +1,78 @@ +console.log('+ Model'); + +const express = require('express') +const fs = require('fs').promises +const app = express() + +const $C = require('./Controller') + +class Model { + +} + +app.get('/index', async (req, res) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + if (req.query.id === undefined) { + res.send(stock); + } else { + const requestedId = +req.query.id; + const requestedItem = stock.find(item => item.id === requestedId); + res.send(requestedItem); + } +}) + +app.post('/index', async (req, _) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + stock.push({ + name: req.query.name ?? 'Default', + id: req.query.id ?? stock.length, + url: req.query.url ?? '', + }); + + await fs.writeFile('./db.json', JSON.stringify({ + stock: stock + })); +}) + +app.put('/index', async (req, res) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + const requestedId = +req.query.id; // index of the item in the stock + const itemToUpdate = stock.find(item => item.id === requestedId); + + if (itemToUpdate === undefined) { + throw new Error('No such item in the stock') + return; + } + + const itemIndex = stock.indexOf(itemToUpdate); + stock[itemIndex] = { + name: req.query.name ?? stock[itemIndex].name, + id: req.query.id ?? stock[itemIndex].id, + url: req.query.url ?? stock[itemIndex].url, + } + + await fs.writeFile('./db.json', JSON.stringify({ + stock: stock + })); +}) + +app.delete('/index', async (req, res) => { + const flowersDatabase = await fs.readFile('./db.json'); + const stock = JSON.parse(flowersDatabase).stock; + + stock.splice(+req.query.id, 1) + + await fs.writeFile('./db.json', JSON.stringify({ + stock: stock + })); +}) + + + +module.exports.$M = new Model; \ No newline at end of file diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js new file mode 100644 index 0000000..c4eb2f0 --- /dev/null +++ b/HW9(http)/public/scripts/View.js @@ -0,0 +1,8 @@ +console.log('+ View'); +const $C = require('./Controller') + +class View { + +} + +module.exports.$V = new View; \ No newline at end of file diff --git a/HW9(http)/public/styles/style.css b/HW9(http)/public/styles/style.css new file mode 100644 index 0000000..78aaa9a --- /dev/null +++ b/HW9(http)/public/styles/style.css @@ -0,0 +1,15 @@ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + border: 10px solid #1C5713; + min-height: 100vh; + font-family: 'Montserrat', sans-serif; + font-style: normal; + font-weight: normal; + color: #1C5713; + letter-spacing: 0.15em; +} \ No newline at end of file From 2a49327ec18ee66cc65d746ec9cefe470d12e637 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 7 Apr 2021 14:35:12 +0300 Subject: [PATCH 03/16] Keep working on HW --- HW9(http)/app.js | 96 ++++++++++++++++++++++---- HW9(http)/db.json | 1 - HW9(http)/index.html | 19 ----- HW9(http)/package.json | 3 +- HW9(http)/public/db.json | 1 + HW9(http)/public/index.html | 39 +++++++++++ HW9(http)/public/scripts/Controller.js | 26 +++++-- HW9(http)/public/scripts/Model.js | 91 +++++++----------------- HW9(http)/public/scripts/View.js | 6 +- HW9(http)/public/styles/style.css | 34 +++++++++ 10 files changed, 208 insertions(+), 108 deletions(-) delete mode 100644 HW9(http)/db.json delete mode 100644 HW9(http)/index.html create mode 100644 HW9(http)/public/db.json create mode 100644 HW9(http)/public/index.html diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 96124b6..b39aa26 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -1,18 +1,90 @@ -const express = require('express') -const fs = require('fs').promises -const $V = require('./public/scripts/View.js') +const $C = require('./public/scripts/Controller.js'); -const app = express() -const port = 4200 +const express = require('express'); +const path = require('path'); +const fs = require('fs').promises; -app.use(express.static('public')) -app.use('/styles', express.static(__dirname + 'public/styles')) -app.use('/scripts', express.static(__dirname + 'public/scripts')) +const app = express(); +const PORT = process.env.PORT || 4200; -app.get('', (_, res) => { - res.sendFile(__dirname + '/index.html') +app.use(express.static('public')); + +app.get('/api/list', async (req, res) => { + const items = await $C.getItems(req.query.id); + res.send(items); +}) + +app.post('/api/list', async (req, _) => { + console.log('post'); + $C.addItems(req.query); }) -app.listen(port, () => { - console.info(`Started server at port: ${port}`) +// app.use(express.static(path.join(__dirname + 'public'))); + +// app.get('/', async (req, res) => { +// const flowersDatabase = await fs.readFile('./db.json'); +// const stock = JSON.parse(flowersDatabase).stock; + +// res.sendFile(path.join(__dirname + 'public', 'index.html')) +// // if (req.query.id === undefined) { +// // res.send(stock); +// // } else { +// // const requestedId = +req.query.id; +// // const requestedItem = stock.find(item => item.id === requestedId); +// // res.send(requestedItem); +// // } +// }) + +// app.post('/', async (req, _) => { +// const flowersDatabase = await fs.readFile('./db.json'); +// const stock = JSON.parse(flowersDatabase).stock; + +// stock.push({ +// name: req.query.name ?? 'Default', +// id: req.query.id ?? stock.length, +// url: req.query.url ?? '', +// }); + +// await fs.writeFile('./db.json', JSON.stringify({ +// stock: stock +// })); +// }) + +// app.put('/', async (req, res) => { +// const flowersDatabase = await fs.readFile('./db.json'); +// const stock = JSON.parse(flowersDatabase).stock; + +// const requestedId = +req.query.id; // index of the item in the stock +// const itemToUpdate = stock.find(item => item.id === requestedId); + +// if (itemToUpdate === undefined) { +// throw new Error('No such item in the stock'); +// return; +// } + +// const itemIndex = stock.indexOf(itemToUpdate); +// stock[itemIndex] = { +// name: req.query.name ?? stock[itemIndex].name, +// id: req.query.id ?? stock[itemIndex].id, +// url: req.query.url ?? stock[itemIndex].url, +// } + +// await fs.writeFile('./db.json', JSON.stringify({ +// stock: stock +// })); +// }) + +// app.delete('/', async (req, res) => { +// const flowersDatabase = await fs.readFile('./db.json'); +// const stock = JSON.parse(flowersDatabase).stock; + +// stock.splice(+req.query.id, 1) + +// await fs.writeFile('./db.json', JSON.stringify({ +// stock: stock +// })); +// }) + +app.listen(PORT, () => { + console.info(`Started a server on port: ${PORT}`) }) \ No newline at end of file diff --git a/HW9(http)/db.json b/HW9(http)/db.json deleted file mode 100644 index ef5923f..0000000 --- a/HW9(http)/db.json +++ /dev/null @@ -1 +0,0 @@ -{"stock":[{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},null,null,null,null,{"name":"Name1","id":"9","url":"no"},{"name":"Name1","id":"10","url":"no"}]} \ No newline at end of file diff --git a/HW9(http)/index.html b/HW9(http)/index.html deleted file mode 100644 index ec07e9a..0000000 --- a/HW9(http)/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - Flowers world | Home - - - - - -
-

Flowers world

-
- -
- - \ No newline at end of file diff --git a/HW9(http)/package.json b/HW9(http)/package.json index 5197908..acecb56 100644 --- a/HW9(http)/package.json +++ b/HW9(http)/package.json @@ -5,7 +5,8 @@ "main": "app.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "nodemon app.js" + "start": "node app", + "dev": "nodemon app" }, "author": "", "license": "ISC", diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json new file mode 100644 index 0000000..a9d3be6 --- /dev/null +++ b/HW9(http)/public/db.json @@ -0,0 +1 @@ +{"list":[{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},null,null,null,null,{"name":"Name1","id":"9","url":"no"},{"name":"Name1","id":"10","url":"no"},{"name":"Flower 15","id":"15","url":"NO"},{"name":"Flower 15","id":"15","url":"NO"}]} \ No newline at end of file diff --git a/HW9(http)/public/index.html b/HW9(http)/public/index.html new file mode 100644 index 0000000..1b97084 --- /dev/null +++ b/HW9(http)/public/index.html @@ -0,0 +1,39 @@ + + + + + + + Flowers world | API + + + + + +
+

Flowers world API

+ + + + + + + + + + + + + + + + + + + + + +
GETapi/list - to GET all current items list
GETapi/list?id=0 - to GET item with ID = 0
POSTapi/list?name=F&id=0&url=F - to ADD item with NAME, ID, URL
+
+ + \ No newline at end of file diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index e061924..f9e34e7 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -1,7 +1,23 @@ -console.log('+ Controller'); -const $V = require('./View') -const $M = require('./Model') +const $M = require('./Model.js'); +const $V = require('./View.js'); -class Controller {} +class Controller { + async getItems(requestedItemId) { + const list = await $M.getItemsList(); + let result = null; -module.exports.$C = new Controller; \ No newline at end of file + if (requestedItemId === undefined) { + result = list; + } else { + result = list.find(item => +item.id === +requestedItemId); + } + + return result; + } + + addItems({name, id, url}) { + $M.addNewItems(name, id, url); + } +} + +module.exports = new Controller(); \ No newline at end of file diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index c84908e..fd7960c 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -1,78 +1,35 @@ -console.log('+ Model'); - -const express = require('express') -const fs = require('fs').promises -const app = express() - -const $C = require('./Controller') +const $C = require('./Controller.js'); +const fs = require('fs').promises; class Model { - -} - -app.get('/index', async (req, res) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; - - if (req.query.id === undefined) { - res.send(stock); - } else { - const requestedId = +req.query.id; - const requestedItem = stock.find(item => item.id === requestedId); - res.send(requestedItem); + async getItemsList() { + const items = await fs.readFile('./public/db.json'); + return JSON.parse(items).list; } -}) - -app.post('/index', async (req, _) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; - - stock.push({ - name: req.query.name ?? 'Default', - id: req.query.id ?? stock.length, - url: req.query.url ?? '', - }); - await fs.writeFile('./db.json', JSON.stringify({ - stock: stock - })); -}) + async addNewItems(name, id, url) { + const items = await fs.readFile('./public/db.json'); + const list = JSON.parse(items).list; -app.put('/index', async (req, res) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; + if (checkIfItemAlreadyExists(id)) { + throw new Error('Item already exists'); + return; + } - const requestedId = +req.query.id; // index of the item in the stock - const itemToUpdate = stock.find(item => item.id === requestedId); + list.push({ + name: name ?? 'Default', + id: id ?? list.length, + url: url ?? '', + }); - if (itemToUpdate === undefined) { - throw new Error('No such item in the stock') - return; + await fs.writeFile('./public/db.json', JSON.stringify({ + list: list + })); } - const itemIndex = stock.indexOf(itemToUpdate); - stock[itemIndex] = { - name: req.query.name ?? stock[itemIndex].name, - id: req.query.id ?? stock[itemIndex].id, - url: req.query.url ?? stock[itemIndex].url, + checkIfItemAlreadyExists(id) { + } +} - await fs.writeFile('./db.json', JSON.stringify({ - stock: stock - })); -}) - -app.delete('/index', async (req, res) => { - const flowersDatabase = await fs.readFile('./db.json'); - const stock = JSON.parse(flowersDatabase).stock; - - stock.splice(+req.query.id, 1) - - await fs.writeFile('./db.json', JSON.stringify({ - stock: stock - })); -}) - - - -module.exports.$M = new Model; \ No newline at end of file +module.exports = new Model(); \ No newline at end of file diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js index c4eb2f0..47ca35b 100644 --- a/HW9(http)/public/scripts/View.js +++ b/HW9(http)/public/scripts/View.js @@ -1,8 +1,8 @@ -console.log('+ View'); -const $C = require('./Controller') +const $C = require('./Controller.js'); + class View { } -module.exports.$V = new View; \ No newline at end of file +module.exports = new View(); \ No newline at end of file diff --git a/HW9(http)/public/styles/style.css b/HW9(http)/public/styles/style.css index 78aaa9a..ff3732e 100644 --- a/HW9(http)/public/styles/style.css +++ b/HW9(http)/public/styles/style.css @@ -12,4 +12,38 @@ body { font-weight: normal; color: #1C5713; letter-spacing: 0.15em; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; +} + +table { + border-spacing: 5px; + margin-top: 5px; +} + +tbody { + text-align: left; +} + +tr > td:first-child { + text-align: center; +} + +td { + padding: 5px 10px; +} + +.method, .address { + color: rgb(236, 236, 236); +} + +.method { + background-color: rgba(27, 27, 27, 0.8); +} + +.address { + background-color: rgba(27, 27, 27, 0.6); } \ No newline at end of file From 10acee25eaff7c45ddcb18311ee0642a157b9111 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 7 Apr 2021 18:51:28 +0300 Subject: [PATCH 04/16] Still working. --- HW9(http)/app.js | 46 ++++------------------- HW9(http)/public/db.json | 2 +- HW9(http)/public/index.html | 6 +++ HW9(http)/public/scripts/Controller.js | 51 +++++++++++++++++++++----- HW9(http)/public/scripts/Model.js | 15 +++++--- HW9(http)/public/scripts/View.js | 3 +- 6 files changed, 67 insertions(+), 56 deletions(-) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index b39aa26..6dcb6c9 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -10,45 +10,18 @@ const PORT = process.env.PORT || 4200; app.use(express.static('public')); app.get('/api/list', async (req, res) => { - const items = await $C.getItems(req.query.id); - res.send(items); + const request = await $C.getItems(req.query.id); + res.status(request.statusCode).send(request.result); }) -app.post('/api/list', async (req, _) => { - console.log('post'); - $C.addItems(req.query); +app.post('/api/list', async (req, res) => { + const request = await $C.addItems(req.query); + res.status(request.statusCode).send(request.result); }) -// app.use(express.static(path.join(__dirname + 'public'))); - -// app.get('/', async (req, res) => { -// const flowersDatabase = await fs.readFile('./db.json'); -// const stock = JSON.parse(flowersDatabase).stock; - -// res.sendFile(path.join(__dirname + 'public', 'index.html')) -// // if (req.query.id === undefined) { -// // res.send(stock); -// // } else { -// // const requestedId = +req.query.id; -// // const requestedItem = stock.find(item => item.id === requestedId); -// // res.send(requestedItem); -// // } -// }) - -// app.post('/', async (req, _) => { -// const flowersDatabase = await fs.readFile('./db.json'); -// const stock = JSON.parse(flowersDatabase).stock; - -// stock.push({ -// name: req.query.name ?? 'Default', -// id: req.query.id ?? stock.length, -// url: req.query.url ?? '', -// }); - -// await fs.writeFile('./db.json', JSON.stringify({ -// stock: stock -// })); -// }) +app.listen(PORT, () => { + console.info(`Started a server on port: ${PORT}`) +}) // app.put('/', async (req, res) => { // const flowersDatabase = await fs.readFile('./db.json'); @@ -85,6 +58,3 @@ app.post('/api/list', async (req, _) => { // })); // }) -app.listen(PORT, () => { - console.info(`Started a server on port: ${PORT}`) -}) \ No newline at end of file diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index a9d3be6..9af1c67 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -1 +1 @@ -{"list":[{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},null,null,null,null,{"name":"Name1","id":"9","url":"no"},{"name":"Name1","id":"10","url":"no"},{"name":"Flower 15","id":"15","url":"NO"},{"name":"Flower 15","id":"15","url":"NO"}]} \ No newline at end of file +{"list":[{"name":"Polypodiophyta","id":0,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"name":"Flower 5","id":"5","url":"NO"},{"name":"Default","id":6,"url":""},{"name":"Flower 5","id":"5","url":"NO"},{"name":"Flower 5","id":"9","url":"NO"},{"name":"Flower 5","id":"10","url":"NO"},{"name":"Flower 5","id":"15","url":"NO"}]} \ No newline at end of file diff --git a/HW9(http)/public/index.html b/HW9(http)/public/index.html index 1b97084..7a544a3 100644 --- a/HW9(http)/public/index.html +++ b/HW9(http)/public/index.html @@ -27,6 +27,12 @@

Flowers world API

- to GET item with ID = 0 + + POST + api/list + - to ADD item with default values + + POST api/list?name=F&id=0&url=F diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index f9e34e7..f564f4a 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -1,22 +1,55 @@ +const e = require('express'); const $M = require('./Model.js'); const $V = require('./View.js'); class Controller { - async getItems(requestedItemId) { - const list = await $M.getItemsList(); - let result = null; + async getItems(id) { + const itemsList = await $M.getItemsList(); + const response = { + statusCode: 200, + result: [] + }; - if (requestedItemId === undefined) { - result = list; + // Работа с данными и ошибки - для модели. Контроллер только дёргает ниточки. + // Добавить эмуляцию работы с БД - Репозиторий. + if (id === undefined) { + response.result = itemsList; } else { - result = list.find(item => +item.id === +requestedItemId); + const requestedItem = itemsList.find(item => +item.id === +id); + + if (requestedItem === undefined) { + response.statusCode = 404; + response.result = 'Not Found'; + return response; + } + + response.result.push(requestedItem); + } + + if (response.result.length === 0) { + response.statusCode = 204; + response.result = 'No Content'; } - return result; + return response; } - addItems({name, id, url}) { - $M.addNewItems(name, id, url); + async addItems({name, id, url}) { + const response = await $M.addNewItems(name, id, url); + + if (response) { + return { + statusCode: 201, + result: 'Created' + } + } else { + return { + statusCode: 406, + result: 'Not Acceptable' + } + } + + // updateView() } } diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index fd7960c..4883e62 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -10,10 +10,10 @@ class Model { async addNewItems(name, id, url) { const items = await fs.readFile('./public/db.json'); const list = JSON.parse(items).list; - - if (checkIfItemAlreadyExists(id)) { - throw new Error('Item already exists'); - return; + const isNotUnique = await this.checkIfItemIsUnique(id); + + if (isNotUnique) { + return false; } list.push({ @@ -25,10 +25,13 @@ class Model { await fs.writeFile('./public/db.json', JSON.stringify({ list: list })); + + return true; } - checkIfItemAlreadyExists(id) { - + async checkIfItemIsUnique(id) { + const itemsList = await this.getItemsList(); + return itemsList.some(el => el === null ? false : +el.id === +id) } } diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js index 47ca35b..35798aa 100644 --- a/HW9(http)/public/scripts/View.js +++ b/HW9(http)/public/scripts/View.js @@ -1,8 +1,7 @@ const $C = require('./Controller.js'); - class View { - + // add list on page } module.exports = new View(); \ No newline at end of file From d4c3069b45afa529360528a8f255f514f1296781 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Thu, 8 Apr 2021 14:50:42 +0300 Subject: [PATCH 05/16] Implemented repository pattern. --- HW9(http)/app.js | 18 +- HW9(http)/package-lock.json | 300 +++++-------------------- HW9(http)/package.json | 1 - HW9(http)/public/db.json | 2 +- HW9(http)/public/scripts/Controller.js | 52 ++--- HW9(http)/public/scripts/Model.js | 23 +- HW9(http)/public/scripts/Repository.js | 84 +++++++ 7 files changed, 176 insertions(+), 304 deletions(-) create mode 100644 HW9(http)/public/scripts/Repository.js diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 6dcb6c9..34ebbf8 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -1,8 +1,5 @@ const $C = require('./public/scripts/Controller.js'); - const express = require('express'); -const path = require('path'); -const fs = require('fs').promises; const app = express(); const PORT = process.env.PORT || 4200; @@ -15,7 +12,17 @@ app.get('/api/list', async (req, res) => { }) app.post('/api/list', async (req, res) => { - const request = await $C.addItems(req.query); + const request = await $C.addItem(req.query); + res.status(request.statusCode).send(request.result); +}) + +app.put('/api/list', async (req, res) => { + const request = await $C.updateItem(req.query); + res.status(request.statusCode).send(request.result); +}) + +app.delete('/api/list', async (req, res) => { + const request = await $C.deleteItem(req.query.id); res.status(request.statusCode).send(request.result); }) @@ -23,6 +30,9 @@ app.listen(PORT, () => { console.info(`Started a server on port: ${PORT}`) }) +// const path = require('path'); +// const fs = require('fs').promises; + // app.put('/', async (req, res) => { // const flowersDatabase = await fs.readFile('./db.json'); // const stock = JSON.parse(flowersDatabase).stock; diff --git a/HW9(http)/package-lock.json b/HW9(http)/package-lock.json index a15fa92..d9397ad 100644 --- a/HW9(http)/package-lock.json +++ b/HW9(http)/package-lock.json @@ -7,14 +7,12 @@ "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, "requires": { "defer-to-connect": "^1.0.1" } @@ -22,8 +20,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "accepts": { "version": "1.3.7", @@ -38,7 +35,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, "requires": { "string-width": "^3.0.0" }, @@ -47,7 +43,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -59,23 +54,20 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -86,11 +78,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -99,8 +86,7 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "body-parser": { "version": "1.19.0", @@ -123,7 +109,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, "requires": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", @@ -148,7 +133,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -162,7 +146,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -177,7 +160,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -185,22 +167,19 @@ "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" } } }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -209,14 +188,12 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -227,7 +204,6 @@ "version": "3.5.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -242,20 +218,17 @@ "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -264,7 +237,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -272,8 +244,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "concat-map": { "version": "0.0.1", @@ -284,7 +255,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, "requires": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -320,8 +290,7 @@ "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" }, "debug": { "version": "2.6.9", @@ -335,7 +304,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -343,14 +311,12 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, "depd": { "version": "1.1.2", @@ -366,7 +332,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, "requires": { "is-obj": "^2.0.0" } @@ -374,27 +339,17 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, - "ejs": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", - "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", - "requires": { - "jake": "^10.6.1" - } - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "encodeurl": { "version": "1.0.2", @@ -405,7 +360,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -413,19 +367,13 @@ "escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -468,19 +416,10 @@ "vary": "~1.1.2" } }, - "filelist": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", - "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", - "requires": { - "minimatch": "^3.0.4" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -513,14 +452,12 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -529,7 +466,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -538,7 +474,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "dev": true, "requires": { "ini": "1.3.7" } @@ -547,7 +482,6 @@ "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, "requires": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", @@ -565,8 +499,7 @@ "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "has-flag": { "version": "3.0.0", @@ -576,14 +509,12 @@ "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-errors": { "version": "1.7.2", @@ -608,20 +539,17 @@ "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "inherits": { "version": "2.0.3", @@ -631,8 +559,7 @@ "ini": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", - "dev": true + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" }, "ipaddr.js": { "version": "1.9.1", @@ -643,7 +570,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -652,7 +578,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, "requires": { "ci-info": "^2.0.0" } @@ -660,20 +585,17 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -682,7 +604,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, "requires": { "global-dirs": "^2.0.1", "is-path-inside": "^3.0.1" @@ -691,94 +612,42 @@ "is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "jake": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", - "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", - "requires": { - "async": "0.9.x", - "chalk": "^2.4.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - } - } + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, "requires": { "json-buffer": "3.0.0" } @@ -787,7 +656,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, "requires": { "package-json": "^6.3.0" } @@ -795,14 +663,12 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, "requires": { "semver": "^6.0.0" }, @@ -810,8 +676,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -851,8 +716,7 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, "minimatch": { "version": "3.0.4", @@ -865,8 +729,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "ms": { "version": "2.0.0", @@ -882,7 +745,6 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "dev": true, "requires": { "chokidar": "^3.2.2", "debug": "^3.2.6", @@ -900,7 +762,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -908,8 +769,7 @@ "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, @@ -917,7 +777,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, "requires": { "abbrev": "1" } @@ -925,14 +784,12 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" }, "on-finished": { "version": "2.3.0", @@ -946,7 +803,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -954,14 +810,12 @@ "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" }, "package-json": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, "requires": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", @@ -972,8 +826,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -990,14 +843,12 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "proxy-addr": { "version": "2.0.6", @@ -1011,14 +862,12 @@ "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -1028,7 +877,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, "requires": { "escape-goat": "^2.0.0" } @@ -1058,7 +906,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -1070,7 +917,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -1079,7 +925,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, "requires": { "rc": "^1.2.8" } @@ -1088,7 +933,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, "requires": { "rc": "^1.2.8" } @@ -1097,7 +941,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, "requires": { "lowercase-keys": "^1.0.0" } @@ -1115,14 +958,12 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "semver-diff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, "requires": { "semver": "^6.3.0" }, @@ -1130,8 +971,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -1181,8 +1021,7 @@ "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "statuses": { "version": "1.5.0", @@ -1193,7 +1032,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1203,26 +1041,22 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -1233,7 +1067,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -1241,8 +1074,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { "version": "5.5.0", @@ -1255,20 +1087,17 @@ "term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" }, "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -1282,7 +1111,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, "requires": { "nopt": "~1.0.10" } @@ -1290,8 +1118,7 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" }, "type-is": { "version": "1.6.18", @@ -1306,7 +1133,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -1315,7 +1141,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "dev": true, "requires": { "debug": "^2.2.0" } @@ -1324,7 +1149,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, "requires": { "crypto-random-string": "^2.0.0" } @@ -1338,7 +1162,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "dev": true, "requires": { "boxen": "^4.2.0", "chalk": "^3.0.0", @@ -1359,7 +1182,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, "requires": { "prepend-http": "^2.0.0" } @@ -1378,7 +1200,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, "requires": { "string-width": "^4.0.0" } @@ -1386,14 +1207,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -1404,8 +1223,7 @@ "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" } } } diff --git a/HW9(http)/package.json b/HW9(http)/package.json index acecb56..ff8744c 100644 --- a/HW9(http)/package.json +++ b/HW9(http)/package.json @@ -11,7 +11,6 @@ "author": "", "license": "ISC", "dependencies": { - "ejs": "3.1.6", "express": "4.17.1" }, "devDependencies": { diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index 9af1c67..672c23d 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -1 +1 @@ -{"list":[{"name":"Polypodiophyta","id":0,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"name":"Flower 5","id":"5","url":"NO"},{"name":"Default","id":6,"url":""},{"name":"Flower 5","id":"5","url":"NO"},{"name":"Flower 5","id":"9","url":"NO"},{"name":"Flower 5","id":"10","url":"NO"},{"name":"Flower 5","id":"15","url":"NO"}]} \ No newline at end of file +{"list":[{"name":"Polypodiophyta","id":0,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"name":"Flower 5","id":"5","url":"NO"},{"name":"Flower 6","id":"6","url":"NO"},{"name":"Flower 5","id":"7","url":"NO"},{"name":"Flower 8","id":"8","url":"url"},{"name":"Flower 8","id":"10","url":"url"},{"name":"Flower 8","id":"11","url":"url"},{"name":"Flower 8","id":"12","url":"url"},{"name":"Flower 8","id":"13","url":"url"}]} \ No newline at end of file diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index f564f4a..1420b4b 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -1,54 +1,28 @@ const e = require('express'); -const $M = require('./Model.js'); const $V = require('./View.js'); +const $R = require('./Repository.js'); class Controller { async getItems(id) { - const itemsList = await $M.getItemsList(); - const response = { - statusCode: 200, - result: [] - }; - - // Работа с данными и ошибки - для модели. Контроллер только дёргает ниточки. - // Добавить эмуляцию работы с БД - Репозиторий. if (id === undefined) { - response.result = itemsList; + return await $R.findAll(); } else { - const requestedItem = itemsList.find(item => +item.id === +id); - - if (requestedItem === undefined) { - response.statusCode = 404; - response.result = 'Not Found'; - return response; - } - - response.result.push(requestedItem); + return await $R.findOne(id); } - - if (response.result.length === 0) { - response.statusCode = 204; - response.result = 'No Content'; - } - - return response; } - async addItems({name, id, url}) { - const response = await $M.addNewItems(name, id, url); + async addItem(params) { + return await $R.create(params); + // updateView() + } - if (response) { - return { - statusCode: 201, - result: 'Created' - } - } else { - return { - statusCode: 406, - result: 'Not Acceptable' - } - } + async updateItem(params) { + return await $R.update(params); + // updateView() + } + async deleteItem(id) { + return await $R.delete(id); // updateView() } } diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index 4883e62..489238c 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -1,37 +1,24 @@ -const $C = require('./Controller.js'); const fs = require('fs').promises; class Model { - async getItemsList() { + async getItems() { const items = await fs.readFile('./public/db.json'); return JSON.parse(items).list; } - async addNewItems(name, id, url) { + async addNewItem(name, id, url) { const items = await fs.readFile('./public/db.json'); const list = JSON.parse(items).list; - const isNotUnique = await this.checkIfItemIsUnique(id); - - if (isNotUnique) { - return false; - } list.push({ - name: name ?? 'Default', - id: id ?? list.length, - url: url ?? '', + name: name, + id: id, + url: url, }); await fs.writeFile('./public/db.json', JSON.stringify({ list: list })); - - return true; - } - - async checkIfItemIsUnique(id) { - const itemsList = await this.getItemsList(); - return itemsList.some(el => el === null ? false : +el.id === +id) } } diff --git a/HW9(http)/public/scripts/Repository.js b/HW9(http)/public/scripts/Repository.js new file mode 100644 index 0000000..ad6717f --- /dev/null +++ b/HW9(http)/public/scripts/Repository.js @@ -0,0 +1,84 @@ +const $M = require('./Model.js'); + +class Repository { + constructor(Model) { + this.collection = Model; + } + + async findAll() { + const response = { + statusCode: 200, + result: [] + }; + + response.result = await this.collection.getItems(); + + if (response.result.length === 0) { + response.statusCode = 204; + response.result = 'No Content.\nNo content in database.'; + } + + return response; + } + + async findOne(id) { + const response = { + statusCode: 200, + result: [] + }; + + const allItems = await this.findAll(); + + const requestedItem = allItems.result.find( + item => +item.id === +id + ); + + if (requestedItem === undefined) { + response.statusCode = 404; + response.result = 'Not Found.\nItem was not found'; + } else { + response.result.push(requestedItem); + } + + return response; + } + + async create({ name, id, url }) { + const response = { + statusCode: 201, + result: 'Created.\nItem was successfully created.' + }; + + const gotAllParams = + name !== undefined && + id !== undefined && + url !== undefined; + + if (!gotAllParams) { + response.statusCode = 400; + response.result = 'Bad Request.\nSome params are missing. NAME, ID, URL must be present.'; + return response; + } + + const itemAlreadyExists = await this.findOne(id); + + if (itemAlreadyExists.statusCode === 200) { + response.statusCode = 406; + response.result = 'Not Acceptable.\nItem already exists.' + } else { + $M.addNewItem(name, id, url); + } + + return response; + } + + update(id, value) { + throw new Error("Method not implemented."); + } + + delete(id) { + throw new Error("Method not implemented."); + } +} + +module.exports = new Repository($M); \ No newline at end of file From ccaa28fb9e6cf25ef2b4712c5219cb3e8dfd26e4 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Thu, 8 Apr 2021 19:26:12 +0300 Subject: [PATCH 06/16] Almost done. --- HW9(http)/app.js | 14 ++++-- HW9(http)/db.json | 1 + HW9(http)/public/db.json | 2 +- HW9(http)/public/index.html | 22 ++++++--- HW9(http)/public/scripts/Model.js | 32 +++++++++++- HW9(http)/public/scripts/Repository.js | 67 ++++++++++++++++++-------- 6 files changed, 104 insertions(+), 34 deletions(-) create mode 100644 HW9(http)/db.json diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 34ebbf8..2f7c9e2 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -6,22 +6,22 @@ const PORT = process.env.PORT || 4200; app.use(express.static('public')); -app.get('/api/list', async (req, res) => { +app.get('/api/flowers', async (req, res) => { const request = await $C.getItems(req.query.id); res.status(request.statusCode).send(request.result); }) -app.post('/api/list', async (req, res) => { +app.post('/api/flowers', async (req, res) => { const request = await $C.addItem(req.query); res.status(request.statusCode).send(request.result); }) -app.put('/api/list', async (req, res) => { +app.put('/api/flowers', async (req, res) => { const request = await $C.updateItem(req.query); res.status(request.statusCode).send(request.result); }) -app.delete('/api/list', async (req, res) => { +app.delete('/api/flowers', async (req, res) => { const request = await $C.deleteItem(req.query.id); res.status(request.statusCode).send(request.result); }) @@ -30,6 +30,12 @@ app.listen(PORT, () => { console.info(`Started a server on port: ${PORT}`) }) +// checkIfAllParamsPresent(id, name, url) { +// return name !== undefined && +// id !== undefined && +// url !== undefined; +// } + // const path = require('path'); // const fs = require('fs').promises; diff --git a/HW9(http)/db.json b/HW9(http)/db.json new file mode 100644 index 0000000..a2b4f07 --- /dev/null +++ b/HW9(http)/db.json @@ -0,0 +1 @@ +{"list":[{"id":0,"name":"newName","url":"newURL"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"}]} \ No newline at end of file diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index 672c23d..0126bd5 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -1 +1 @@ -{"list":[{"name":"Polypodiophyta","id":0,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"name":"Flower 5","id":"5","url":"NO"},{"name":"Flower 6","id":"6","url":"NO"},{"name":"Flower 5","id":"7","url":"NO"},{"name":"Flower 8","id":"8","url":"url"},{"name":"Flower 8","id":"10","url":"url"},{"name":"Flower 8","id":"11","url":"url"},{"name":"Flower 8","id":"12","url":"url"},{"name":"Flower 8","id":"13","url":"url"}]} \ No newline at end of file +{"list":[{"name":"Polypodiophyta","id":0,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"id":5,"name":"changed"}]} \ No newline at end of file diff --git a/HW9(http)/public/index.html b/HW9(http)/public/index.html index 7a544a3..574ea41 100644 --- a/HW9(http)/public/index.html +++ b/HW9(http)/public/index.html @@ -17,26 +17,32 @@

Flowers world API

GET - api/list + api/flowers - to GET all current items list GET - api/list?id=0 - - to GET item with ID = 0 + api/flowers?id=0 + - to GET item with a specific ID POST - api/list - - to ADD item with default values + api/flowers?name=F&id=0&url=F + - to ADD item with NAME, ID and URL - POST - api/list?name=F&id=0&url=F - - to ADD item with NAME, ID, URL + PUT + api/flowers?name=new&id=0&url=new + - to UPDATE item with a specific ID + + + + DELETE + api/flowers?id=0 + - to DELETE item with a specific ID diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index 489238c..77c66da 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -7,8 +7,7 @@ class Model { } async addNewItem(name, id, url) { - const items = await fs.readFile('./public/db.json'); - const list = JSON.parse(items).list; + const list = await this.getItems(); list.push({ name: name, @@ -16,10 +15,39 @@ class Model { url: url, }); + this.saveList(list); // mb await + } + + async updateItem(id, name, url) { // NOT WORKING + const list = await this.getItems(); + const itemToUpdate = this.findItem(list, id); + + list[list.indexOf(itemToUpdate)] = { + id: id, + name: name, + url: url, + } + + this.saveList(list); + } + + async deleteItem(id) { + const list = await this.getItems(); + const itemToDelete = findItem(list, id); + + list.splice(list.indexOf(itemToDelete), 1); + this.saveList(list); + } + + async saveList(list) { await fs.writeFile('./public/db.json', JSON.stringify({ list: list })); } + + findItem(list, id) { + return list.find(item => +item.id === +id); + } } module.exports = new Model(); \ No newline at end of file diff --git a/HW9(http)/public/scripts/Repository.js b/HW9(http)/public/scripts/Repository.js index ad6717f..226073b 100644 --- a/HW9(http)/public/scripts/Repository.js +++ b/HW9(http)/public/scripts/Repository.js @@ -26,16 +26,13 @@ class Repository { statusCode: 200, result: [] }; - - const allItems = await this.findAll(); - const requestedItem = allItems.result.find( - item => +item.id === +id - ); + const list = await this.findAll(); + const requestedItem = $M.findItem(list.result, id); if (requestedItem === undefined) { response.statusCode = 404; - response.result = 'Not Found.\nItem was not found'; + response.result = 'Not Found.\nItem was not found.'; } else { response.result.push(requestedItem); } @@ -43,41 +40,73 @@ class Repository { return response; } - async create({ name, id, url }) { + async create({ id, name, url }) { // changed order. it was name id url const response = { statusCode: 201, result: 'Created.\nItem was successfully created.' }; - const gotAllParams = - name !== undefined && - id !== undefined && - url !== undefined; - - if (!gotAllParams) { + if ( + name === undefined || + id === undefined || + url === undefined + ) { response.statusCode = 400; - response.result = 'Bad Request.\nSome params are missing. NAME, ID, URL must be present.'; + response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; return response; } const itemAlreadyExists = await this.findOne(id); - + if (itemAlreadyExists.statusCode === 200) { response.statusCode = 406; response.result = 'Not Acceptable.\nItem already exists.' } else { - $M.addNewItem(name, id, url); + $M.addNewItem(name, +id, url); } return response; } - update(id, value) { - throw new Error("Method not implemented."); + async update({ id, name, url }) { + const response = { + statusCode: 200, + result: 'OK.\nItem was successfully updated.' + }; + + if (id === undefined) { + response.statusCode = 400; + response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; + return response; + } + + const findItem = await this.findOne(id); + const item = findItem.result[0]; + + if (findItem.statusCode === 404) { + response.statusCode = 404; + response.result = 'Not Found.\nItem was not found.'; + } else { + $M.updateItem(+id, name ?? item.name, url ?? item.url); + } + + return response; } delete(id) { - throw new Error("Method not implemented."); + const response = { + statusCode: 200, + result: 'OK.\nItem was successfully deleted.' + }; + + $M.deleteItem(id); + const itemStillExists = this.findOne(id); + + if (itemStillExists.statusCode === 200) { + this.delete(id); + } + + return response; } } From 5832aa6c8b716db5457b96285814544aa074c15f Mon Sep 17 00:00:00 2001 From: Dmytro Date: Thu, 8 Apr 2021 20:58:13 +0300 Subject: [PATCH 07/16] HW without dynamic View --- HW9(http)/app.js | 47 +------------------------- HW9(http)/public/db.json | 30 +++++++++++++++- HW9(http)/public/scripts/Controller.js | 20 +++++++---- HW9(http)/public/scripts/Model.js | 18 +++++----- HW9(http)/public/scripts/Repository.js | 14 ++++---- HW9(http)/public/scripts/View.js | 6 +--- 6 files changed, 61 insertions(+), 74 deletions(-) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 2f7c9e2..6a77bac 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -28,49 +28,4 @@ app.delete('/api/flowers', async (req, res) => { app.listen(PORT, () => { console.info(`Started a server on port: ${PORT}`) -}) - -// checkIfAllParamsPresent(id, name, url) { -// return name !== undefined && -// id !== undefined && -// url !== undefined; -// } - -// const path = require('path'); -// const fs = require('fs').promises; - -// app.put('/', async (req, res) => { -// const flowersDatabase = await fs.readFile('./db.json'); -// const stock = JSON.parse(flowersDatabase).stock; - -// const requestedId = +req.query.id; // index of the item in the stock -// const itemToUpdate = stock.find(item => item.id === requestedId); - -// if (itemToUpdate === undefined) { -// throw new Error('No such item in the stock'); -// return; -// } - -// const itemIndex = stock.indexOf(itemToUpdate); -// stock[itemIndex] = { -// name: req.query.name ?? stock[itemIndex].name, -// id: req.query.id ?? stock[itemIndex].id, -// url: req.query.url ?? stock[itemIndex].url, -// } - -// await fs.writeFile('./db.json', JSON.stringify({ -// stock: stock -// })); -// }) - -// app.delete('/', async (req, res) => { -// const flowersDatabase = await fs.readFile('./db.json'); -// const stock = JSON.parse(flowersDatabase).stock; - -// stock.splice(+req.query.id, 1) - -// await fs.writeFile('./db.json', JSON.stringify({ -// stock: stock -// })); -// }) - +}) \ No newline at end of file diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index 0126bd5..29b2d9b 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -1 +1,29 @@ -{"list":[{"name":"Polypodiophyta","id":0,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"id":5,"name":"changed"}]} \ No newline at end of file +{ + "list": [ + { + "name": "Polypodiophyta", + "id": 0, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true" + }, + { + "name": "Abies alba Miller", + "id": 1, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true" + }, + { + "name": "Garcinia Morella", + "id": 2, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true" + }, + { + "name": "Picea excelsa Lk", + "id": 3, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true" + }, + { + "name": "Quassia amara L", + "id": 4, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true" + } + ] +} diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index 1420b4b..68c06ca 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -1,4 +1,3 @@ -const e = require('express'); const $V = require('./View.js'); const $R = require('./Repository.js'); @@ -12,18 +11,25 @@ class Controller { } async addItem(params) { - return await $R.create(params); - // updateView() + // here and below (Arg1, Arg2) returns only last argument + return ( + $V.updatePage(), + await $R.create(params) + ); } async updateItem(params) { - return await $R.update(params); - // updateView() + return ( + $V.updatePage(), + await $R.update(params) + ); } async deleteItem(id) { - return await $R.delete(id); - // updateView() + return ( + $V.updatePage(), + await $R.delete(id) + ); } } diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index 77c66da..5dcfc17 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -15,10 +15,10 @@ class Model { url: url, }); - this.saveList(list); // mb await + this.saveList(list); } - async updateItem(id, name, url) { // NOT WORKING + async updateItem(id, name, url) { const list = await this.getItems(); const itemToUpdate = this.findItem(list, id); @@ -33,21 +33,21 @@ class Model { async deleteItem(id) { const list = await this.getItems(); - const itemToDelete = findItem(list, id); + const itemToDelete = this.findItem(list, id); list.splice(list.indexOf(itemToDelete), 1); this.saveList(list); } - async saveList(list) { - await fs.writeFile('./public/db.json', JSON.stringify({ - list: list - })); - } - findItem(list, id) { return list.find(item => +item.id === +id); } + + saveList(list) { + fs.writeFile('./public/db.json', JSON.stringify({ + list: list + })); + } } module.exports = new Model(); \ No newline at end of file diff --git a/HW9(http)/public/scripts/Repository.js b/HW9(http)/public/scripts/Repository.js index 226073b..7cf9d14 100644 --- a/HW9(http)/public/scripts/Repository.js +++ b/HW9(http)/public/scripts/Repository.js @@ -40,7 +40,7 @@ class Repository { return response; } - async create({ id, name, url }) { // changed order. it was name id url + async create({ id, name, url }) { const response = { statusCode: 201, result: 'Created.\nItem was successfully created.' @@ -93,17 +93,19 @@ class Repository { return response; } - delete(id) { + async delete(id) { const response = { statusCode: 200, result: 'OK.\nItem was successfully deleted.' }; - $M.deleteItem(id); - const itemStillExists = this.findOne(id); + const findItem = await this.findOne(id); - if (itemStillExists.statusCode === 200) { - this.delete(id); + if (findItem.statusCode === 200) { + $M.deleteItem(id); + } else { + response.statusCode = 404; + response.result = 'Not Found.\nItem was not found.'; } return response; diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js index 35798aa..fc20683 100644 --- a/HW9(http)/public/scripts/View.js +++ b/HW9(http)/public/scripts/View.js @@ -1,7 +1,3 @@ -const $C = require('./Controller.js'); - -class View { - // add list on page -} +class View {} module.exports = new View(); \ No newline at end of file From e8e205a325c473170e10b7fd771e32a5e04d6578 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 9 Apr 2021 13:54:44 +0300 Subject: [PATCH 08/16] Stable version without dynamic View. --- HW9(http)/public/scripts/View.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js index fc20683..028e87d 100644 --- a/HW9(http)/public/scripts/View.js +++ b/HW9(http)/public/scripts/View.js @@ -1,3 +1,5 @@ -class View {} +class View { + updatePage() {} +} module.exports = new View(); \ No newline at end of file From 840d9766fa0dad50e1bbb2ede01aa99b58a2361b Mon Sep 17 00:00:00 2001 From: Dmytro Date: Sun, 11 Apr 2021 16:05:03 +0300 Subject: [PATCH 09/16] Changed responsibilities. --- HW9(http)/app.js | 72 +++++++++++++-- HW9(http)/public/scripts/Controller.js | 24 ++--- HW9(http)/public/scripts/Model.js | 25 +++--- HW9(http)/public/scripts/Repository.js | 120 +++++++++---------------- 4 files changed, 124 insertions(+), 117 deletions(-) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 6a77bac..420663a 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -7,23 +7,79 @@ const PORT = process.env.PORT || 4200; app.use(express.static('public')); app.get('/api/flowers', async (req, res) => { - const request = await $C.getItems(req.query.id); - res.status(request.statusCode).send(request.result); + const items = await $C.getItems(req.query.id); + + if (items.length === 0) { + res.status(204).send('No Content.'); + } else { + res.status(200).send(items); + } }) app.post('/api/flowers', async (req, res) => { - const request = await $C.addItem(req.query); - res.status(request.statusCode).send(request.result); + const response = { + code: null, + result: null + }; + + response.code = await $C.addItem(req.query); + switch (response.code) { + case 201: + response.result = 'Created.\nItem was successfully created.'; + break; + case 400: + response.result = 'Bad response.\nSome parameters are missing. ID, NAME, URL must be present.'; + break; + case 406: + response.result = 'Not Acceptable.\nItem already exists.'; + break; + } + + res.status(response.code).send(response.result); }) app.put('/api/flowers', async (req, res) => { - const request = await $C.updateItem(req.query); - res.status(request.statusCode).send(request.result); + const response = { + code: null, + result: null + }; + + response.code = await $C.updateItem(req.query); + switch (response.code) { + case 200: + response.result = 'OK.\nItem was successfully updated.'; + break; + case 400: + response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; + break; + case 404: + response.result = 'Not Found.\nItem was not found.'; + break; + } + + res.status(response.code).send(response.result); }) app.delete('/api/flowers', async (req, res) => { - const request = await $C.deleteItem(req.query.id); - res.status(request.statusCode).send(request.result); + const response = { + code: null, + result: null + }; + + response.code = await $C.deleteItem(req.query.id); + switch (response.code) { + case 200: + response.result = 'OK.\nItem was successfully deleted.'; + break; + case 400: + response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; + break; + case 404: + response.result = 'Not Found.\nItem was not found.'; + break; + } + + res.status(response.code).send(response.result); }) app.listen(PORT, () => { diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index 68c06ca..80994dd 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -1,35 +1,21 @@ -const $V = require('./View.js'); +// const $V = require('./View.js'); const $R = require('./Repository.js'); class Controller { async getItems(id) { - if (id === undefined) { - return await $R.findAll(); - } else { - return await $R.findOne(id); - } + return await $R.find(id); } async addItem(params) { - // here and below (Arg1, Arg2) returns only last argument - return ( - $V.updatePage(), - await $R.create(params) - ); + return await $R.create(params); } async updateItem(params) { - return ( - $V.updatePage(), - await $R.update(params) - ); + return await $R.update(params); } async deleteItem(id) { - return ( - $V.updatePage(), - await $R.delete(id) - ); + return await $R.delete(id); } } diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index 5dcfc17..a605331 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -1,13 +1,13 @@ const fs = require('fs').promises; class Model { - async getItems() { - const items = await fs.readFile('./public/db.json'); - return JSON.parse(items).list; + async getList() { + const database = await fs.readFile('./public/db.json'); + return JSON.parse(database).list; } - async addNewItem(name, id, url) { - const list = await this.getItems(); + async addNewItemToTheList(name, id, url) { + const list = await this.getList(); list.push({ name: name, @@ -19,8 +19,8 @@ class Model { } async updateItem(id, name, url) { - const list = await this.getItems(); - const itemToUpdate = this.findItem(list, id); + const list = await this.getList(); + const itemToUpdate = this.findItem(list, id)[0]; list[list.indexOf(itemToUpdate)] = { id: id, @@ -32,15 +32,20 @@ class Model { } async deleteItem(id) { - const list = await this.getItems(); - const itemToDelete = this.findItem(list, id); + const list = await this.getList(); + const itemToDelete = this.findItem(list, id)[0]; + + console.log(itemToDelete, list); + console.log('id', id); + console.log('index ', list.indexOf(itemToDelete)); list.splice(list.indexOf(itemToDelete), 1); this.saveList(list); } findItem(list, id) { - return list.find(item => +item.id === +id); + const item = list.find(item => +item.id === +id); + return item === undefined ? [] : [item]; } saveList(list) { diff --git a/HW9(http)/public/scripts/Repository.js b/HW9(http)/public/scripts/Repository.js index 7cf9d14..fa4815c 100644 --- a/HW9(http)/public/scripts/Repository.js +++ b/HW9(http)/public/scripts/Repository.js @@ -1,115 +1,75 @@ const $M = require('./Model.js'); class Repository { - constructor(Model) { - this.collection = Model; - } - - async findAll() { - const response = { - statusCode: 200, - result: [] - }; + async find(id) { + const list = await $M.getList(); - response.result = await this.collection.getItems(); - - if (response.result.length === 0) { - response.statusCode = 204; - response.result = 'No Content.\nNo content in database.'; + if (id === undefined) { + return list; } - return response; - } - - async findOne(id) { - const response = { - statusCode: 200, - result: [] - }; - - const list = await this.findAll(); - const requestedItem = $M.findItem(list.result, id); - - if (requestedItem === undefined) { - response.statusCode = 404; - response.result = 'Not Found.\nItem was not found.'; + const item = ($M.findItem(list, id))[0]; + + if (item === undefined) { + return 404; } else { - response.result.push(requestedItem); + return item; } - - return response; } async create({ id, name, url }) { - const response = { - statusCode: 201, - result: 'Created.\nItem was successfully created.' - }; - - if ( + if ( // middleweare name === undefined || id === undefined || url === undefined ) { - response.statusCode = 400; - response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; - return response; + return 400; } - - const itemAlreadyExists = await this.findOne(id); - - if (itemAlreadyExists.statusCode === 200) { - response.statusCode = 406; - response.result = 'Not Acceptable.\nItem already exists.' - } else { - $M.addNewItem(name, +id, url); + // NOT WORKING + if (await this.checkIfItemExists(id)) { + return 406; } - - return response; + + $M.addNewItemToTheList(name, +id, url); + return 201; } async update({ id, name, url }) { - const response = { - statusCode: 200, - result: 'OK.\nItem was successfully updated.' - }; - if (id === undefined) { - response.statusCode = 400; - response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; - return response; + return 400; } - - const findItem = await this.findOne(id); - const item = findItem.result[0]; - if (findItem.statusCode === 404) { - response.statusCode = 404; - response.result = 'Not Found.\nItem was not found.'; - } else { - $M.updateItem(+id, name ?? item.name, url ?? item.url); + if (!this.checkIfItemExists(id)) { + return 404; } - return response; + $M.updateItem(+id, name ?? item.name, url ?? item.url); + return 200; } async delete(id) { - const response = { - statusCode: 200, - result: 'OK.\nItem was successfully deleted.' - }; + if (id === undefined) { + return 400; + } + + if (!this.checkIfItemExists(id)) { + return 404; + } - const findItem = await this.findOne(id); + $M.deleteItem(id); + return 200; + } + + async checkIfItemExists(id) { + const list = await this.find(id); + console.log(list); - if (findItem.statusCode === 200) { - $M.deleteItem(id); + if (list.length === 0) { + return false; } else { - response.statusCode = 404; - response.result = 'Not Found.\nItem was not found.'; + return true; } - - return response; } } -module.exports = new Repository($M); \ No newline at end of file +module.exports = new Repository(); \ No newline at end of file From 67b4808e335825c915adbefc43349a4cbee2360b Mon Sep 17 00:00:00 2001 From: Dmytro Date: Sun, 11 Apr 2021 16:36:25 +0300 Subject: [PATCH 10/16] New stable version. --- HW9(http)/app.js | 3 --- HW9(http)/public/db.json | 30 +------------------------- HW9(http)/public/scripts/Model.js | 11 +++------- HW9(http)/public/scripts/Repository.js | 22 +++++++------------ 4 files changed, 12 insertions(+), 54 deletions(-) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 420663a..418a7ae 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -34,7 +34,6 @@ app.post('/api/flowers', async (req, res) => { response.result = 'Not Acceptable.\nItem already exists.'; break; } - res.status(response.code).send(response.result); }) @@ -56,7 +55,6 @@ app.put('/api/flowers', async (req, res) => { response.result = 'Not Found.\nItem was not found.'; break; } - res.status(response.code).send(response.result); }) @@ -78,7 +76,6 @@ app.delete('/api/flowers', async (req, res) => { response.result = 'Not Found.\nItem was not found.'; break; } - res.status(response.code).send(response.result); }) diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index 29b2d9b..030259d 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -1,29 +1 @@ -{ - "list": [ - { - "name": "Polypodiophyta", - "id": 0, - "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true" - }, - { - "name": "Abies alba Miller", - "id": 1, - "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true" - }, - { - "name": "Garcinia Morella", - "id": 2, - "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true" - }, - { - "name": "Picea excelsa Lk", - "id": 3, - "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true" - }, - { - "name": "Quassia amara L", - "id": 4, - "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true" - } - ] -} +{"list":[{"id":0,"name":"changed1","url":"changed"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"name":"newName","id":5,"url":"newURL"}]} \ No newline at end of file diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index a605331..719ba9c 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -20,7 +20,7 @@ class Model { async updateItem(id, name, url) { const list = await this.getList(); - const itemToUpdate = this.findItem(list, id)[0]; + const itemToUpdate = this.findItem(list, id); list[list.indexOf(itemToUpdate)] = { id: id, @@ -33,19 +33,14 @@ class Model { async deleteItem(id) { const list = await this.getList(); - const itemToDelete = this.findItem(list, id)[0]; - - console.log(itemToDelete, list); - console.log('id', id); - console.log('index ', list.indexOf(itemToDelete)); + const itemToDelete = this.findItem(list, id); list.splice(list.indexOf(itemToDelete), 1); this.saveList(list); } findItem(list, id) { - const item = list.find(item => +item.id === +id); - return item === undefined ? [] : [item]; + return list.find(item => +item.id === +id); } saveList(list) { diff --git a/HW9(http)/public/scripts/Repository.js b/HW9(http)/public/scripts/Repository.js index fa4815c..daaab0e 100644 --- a/HW9(http)/public/scripts/Repository.js +++ b/HW9(http)/public/scripts/Repository.js @@ -8,13 +8,7 @@ class Repository { return list; } - const item = ($M.findItem(list, id))[0]; - - if (item === undefined) { - return 404; - } else { - return item; - } + return $M.findItem(list, id); } async create({ id, name, url }) { @@ -25,8 +19,8 @@ class Repository { ) { return 400; } - // NOT WORKING - if (await this.checkIfItemExists(id)) { + + if (await (this.checkIfItemExists(id))) { return 406; } @@ -39,7 +33,8 @@ class Repository { return 400; } - if (!this.checkIfItemExists(id)) { + const item = await this.find(id); + if (item === undefined) { return 404; } @@ -52,7 +47,7 @@ class Repository { return 400; } - if (!this.checkIfItemExists(id)) { + if (!(await this.checkIfItemExists(id))) { return 404; } @@ -61,10 +56,9 @@ class Repository { } async checkIfItemExists(id) { - const list = await this.find(id); - console.log(list); + const item = await this.find(id); - if (list.length === 0) { + if (item === undefined) { return false; } else { return true; From aa60109eec7db701228ea4cd2d3324458aa1d34f Mon Sep 17 00:00:00 2001 From: Dmytro Date: Mon, 12 Apr 2021 14:35:38 +0300 Subject: [PATCH 11/16] Added dynamic View. Waiting for sync or review. --- HW9(http)/app.js | 24 +- HW9(http)/db.json | 1 - HW9(http)/package-lock.json | 294 ++++++++++++++---- HW9(http)/package.json | 1 + HW9(http)/public/db.json | 2 +- HW9(http)/public/scripts/Controller.js | 11 +- .../scripts/{Repository.js => Middleware.js} | 18 +- HW9(http)/public/scripts/Model.js | 8 +- HW9(http)/public/scripts/View.js | 14 +- HW9(http)/public/styles/style.css | 37 ++- .../public/{index.html => views/view.ejs} | 12 + 11 files changed, 333 insertions(+), 89 deletions(-) delete mode 100644 HW9(http)/db.json rename HW9(http)/public/scripts/{Repository.js => Middleware.js} (73%) rename HW9(http)/public/{index.html => views/view.ejs} (81%) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 418a7ae..2b7d8d3 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -1,15 +1,20 @@ -const $C = require('./public/scripts/Controller.js'); const express = require('express'); +const controller = require('./public/scripts/Controller.js'); const app = express(); const PORT = process.env.PORT || 4200; app.use(express.static('public')); +app.set('views', './public/views'); +app.set('view engine', 'ejs'); + +const viewRouter = require('./public/scripts/View'); +app.use('/', viewRouter); app.get('/api/flowers', async (req, res) => { - const items = await $C.getItems(req.query.id); + const items = await controller.getItems(req.query.id); - if (items.length === 0) { + if (items === undefined) { res.status(204).send('No Content.'); } else { res.status(200).send(items); @@ -22,18 +27,19 @@ app.post('/api/flowers', async (req, res) => { result: null }; - response.code = await $C.addItem(req.query); + response.code = await controller.addItem(req.query); switch (response.code) { case 201: response.result = 'Created.\nItem was successfully created.'; break; case 400: - response.result = 'Bad response.\nSome parameters are missing. ID, NAME, URL must be present.'; + response.result = 'Bad request.\nSome parameters are missing. ID, NAME, URL must be present.'; break; case 406: response.result = 'Not Acceptable.\nItem already exists.'; break; } + res.status(response.code).send(response.result); }) @@ -43,13 +49,13 @@ app.put('/api/flowers', async (req, res) => { result: null }; - response.code = await $C.updateItem(req.query); + response.code = await controller.updateItem(req.query); switch (response.code) { case 200: response.result = 'OK.\nItem was successfully updated.'; break; case 400: - response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; + response.result = 'Bad request.\nSome parameters are missing. ID, NAME, URL must be present.'; break; case 404: response.result = 'Not Found.\nItem was not found.'; @@ -64,13 +70,13 @@ app.delete('/api/flowers', async (req, res) => { result: null }; - response.code = await $C.deleteItem(req.query.id); + response.code = await controller.deleteItem(req.query.id); switch (response.code) { case 200: response.result = 'OK.\nItem was successfully deleted.'; break; case 400: - response.result = 'Bad Request.\nSome parameters are missing. ID, NAME, URL must be present.'; + response.result = 'Bad request.\nSome parameters are missing. ID, NAME, URL must be present.'; break; case 404: response.result = 'Not Found.\nItem was not found.'; diff --git a/HW9(http)/db.json b/HW9(http)/db.json deleted file mode 100644 index a2b4f07..0000000 --- a/HW9(http)/db.json +++ /dev/null @@ -1 +0,0 @@ -{"list":[{"id":0,"name":"newName","url":"newURL"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"}]} \ No newline at end of file diff --git a/HW9(http)/package-lock.json b/HW9(http)/package-lock.json index d9397ad..06bf94f 100644 --- a/HW9(http)/package-lock.json +++ b/HW9(http)/package-lock.json @@ -7,12 +7,14 @@ "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, "requires": { "defer-to-connect": "^1.0.1" } @@ -20,7 +22,8 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "accepts": { "version": "1.3.7", @@ -35,6 +38,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, "requires": { "string-width": "^3.0.0" }, @@ -43,6 +47,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -54,12 +59,14 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -68,6 +75,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -78,6 +86,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -86,7 +99,8 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true }, "body-parser": { "version": "1.19.0", @@ -109,6 +123,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, "requires": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", @@ -133,6 +148,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -146,6 +162,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -160,6 +177,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, "requires": { "pump": "^3.0.0" } @@ -167,19 +185,22 @@ "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true } } }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -188,12 +209,14 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -204,6 +227,7 @@ "version": "3.5.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -218,17 +242,20 @@ "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true }, "cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -237,6 +264,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -244,7 +272,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -255,6 +284,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, "requires": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -290,7 +320,8 @@ "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true }, "debug": { "version": "2.6.9", @@ -304,6 +335,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -311,12 +343,14 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true }, "depd": { "version": "1.1.2", @@ -332,6 +366,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, "requires": { "is-obj": "^2.0.0" } @@ -339,17 +374,27 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "requires": { + "jake": "^10.6.1" + } + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "encodeurl": { "version": "1.0.2", @@ -360,6 +405,7 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "requires": { "once": "^1.4.0" } @@ -367,13 +413,19 @@ "escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -416,10 +468,19 @@ "vary": "~1.1.2" } }, + "filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -452,12 +513,14 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, "requires": { "pump": "^3.0.0" } @@ -466,6 +529,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -474,6 +538,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, "requires": { "ini": "1.3.7" } @@ -482,6 +547,7 @@ "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, "requires": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", @@ -499,7 +565,8 @@ "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true }, "has-flag": { "version": "3.0.0", @@ -509,12 +576,14 @@ "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true }, "http-errors": { "version": "1.7.2", @@ -539,17 +608,20 @@ "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "inherits": { "version": "2.0.3", @@ -559,7 +631,8 @@ "ini": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true }, "ipaddr.js": { "version": "1.9.1", @@ -570,6 +643,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -578,6 +652,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, "requires": { "ci-info": "^2.0.0" } @@ -585,17 +660,20 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -604,6 +682,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, "requires": { "global-dirs": "^2.0.1", "is-path-inside": "^3.0.1" @@ -612,42 +691,94 @@ "is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, "requires": { "json-buffer": "3.0.0" } @@ -656,6 +787,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, "requires": { "package-json": "^6.3.0" } @@ -663,12 +795,14 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, "requires": { "semver": "^6.0.0" }, @@ -676,7 +810,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -716,7 +851,8 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true }, "minimatch": { "version": "3.0.4", @@ -729,7 +865,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "ms": { "version": "2.0.0", @@ -745,6 +882,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "dev": true, "requires": { "chokidar": "^3.2.2", "debug": "^3.2.6", @@ -762,6 +900,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "requires": { "ms": "^2.1.1" } @@ -769,7 +908,8 @@ "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true } } }, @@ -777,6 +917,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, "requires": { "abbrev": "1" } @@ -784,12 +925,14 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "normalize-url": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true }, "on-finished": { "version": "2.3.0", @@ -803,6 +946,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -810,12 +954,14 @@ "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true }, "package-json": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, "requires": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", @@ -826,7 +972,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -843,12 +990,14 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true }, "proxy-addr": { "version": "2.0.6", @@ -862,12 +1011,14 @@ "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -877,6 +1028,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, "requires": { "escape-goat": "^2.0.0" } @@ -906,6 +1058,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -917,6 +1070,7 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -925,6 +1079,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, "requires": { "rc": "^1.2.8" } @@ -933,6 +1088,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, "requires": { "rc": "^1.2.8" } @@ -941,6 +1097,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, "requires": { "lowercase-keys": "^1.0.0" } @@ -958,12 +1115,14 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true }, "semver-diff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, "requires": { "semver": "^6.3.0" }, @@ -971,7 +1130,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -1021,7 +1181,8 @@ "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true }, "statuses": { "version": "1.5.0", @@ -1032,6 +1193,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1041,22 +1203,26 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -1067,6 +1233,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -1074,7 +1241,8 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true }, "supports-color": { "version": "5.5.0", @@ -1087,17 +1255,20 @@ "term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true }, "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -1111,6 +1282,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, "requires": { "nopt": "~1.0.10" } @@ -1118,7 +1290,8 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true }, "type-is": { "version": "1.6.18", @@ -1133,6 +1306,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -1141,6 +1315,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, "requires": { "debug": "^2.2.0" } @@ -1149,6 +1324,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, "requires": { "crypto-random-string": "^2.0.0" } @@ -1162,6 +1338,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, "requires": { "boxen": "^4.2.0", "chalk": "^3.0.0", @@ -1182,6 +1359,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, "requires": { "prepend-http": "^2.0.0" } @@ -1200,6 +1378,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, "requires": { "string-width": "^4.0.0" } @@ -1207,12 +1386,14 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -1223,7 +1404,8 @@ "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true } } } diff --git a/HW9(http)/package.json b/HW9(http)/package.json index ff8744c..acecb56 100644 --- a/HW9(http)/package.json +++ b/HW9(http)/package.json @@ -11,6 +11,7 @@ "author": "", "license": "ISC", "dependencies": { + "ejs": "3.1.6", "express": "4.17.1" }, "devDependencies": { diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index 030259d..5b66d29 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -1 +1 @@ -{"list":[{"id":0,"name":"changed1","url":"changed"},{"name":"Abies alba Miller","id":1,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"name":"Quassia amara L","id":4,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true"},{"name":"newName","id":5,"url":"newURL"}]} \ No newline at end of file +{"list":[{"id":1,"name":"changed1","url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"id":6,"name":"changed1","url":"newURL"}]} \ No newline at end of file diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index 80994dd..18aea9d 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -1,21 +1,20 @@ -// const $V = require('./View.js'); -const $R = require('./Repository.js'); +const middleware = require('./Middleware.js'); class Controller { async getItems(id) { - return await $R.find(id); + return await middleware.find(id); } async addItem(params) { - return await $R.create(params); + return await middleware.create(params) } async updateItem(params) { - return await $R.update(params); + return await middleware.update(params); } async deleteItem(id) { - return await $R.delete(id); + return await middleware.delete(id); } } diff --git a/HW9(http)/public/scripts/Repository.js b/HW9(http)/public/scripts/Middleware.js similarity index 73% rename from HW9(http)/public/scripts/Repository.js rename to HW9(http)/public/scripts/Middleware.js index daaab0e..6d12ace 100644 --- a/HW9(http)/public/scripts/Repository.js +++ b/HW9(http)/public/scripts/Middleware.js @@ -1,18 +1,18 @@ -const $M = require('./Model.js'); +const model = require('./Model.js'); -class Repository { +class Middleware { async find(id) { - const list = await $M.getList(); + const list = await model.getList(); if (id === undefined) { return list; } - return $M.findItem(list, id); + return model.findItem(list, id); } async create({ id, name, url }) { - if ( // middleweare + if ( name === undefined || id === undefined || url === undefined @@ -24,7 +24,7 @@ class Repository { return 406; } - $M.addNewItemToTheList(name, +id, url); + model.addNewItemToTheList(name, +id, url); return 201; } @@ -38,7 +38,7 @@ class Repository { return 404; } - $M.updateItem(+id, name ?? item.name, url ?? item.url); + model.updateItem(+id, name ?? item.name, url ?? item.url); return 200; } @@ -51,7 +51,7 @@ class Repository { return 404; } - $M.deleteItem(id); + model.deleteItem(id); return 200; } @@ -66,4 +66,4 @@ class Repository { } } -module.exports = new Repository(); \ No newline at end of file +module.exports = new Middleware(); \ No newline at end of file diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index 719ba9c..48a71cb 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -3,7 +3,13 @@ const fs = require('fs').promises; class Model { async getList() { const database = await fs.readFile('./public/db.json'); - return JSON.parse(database).list; + + try { + const list = JSON.parse(database).list; + return list; + } catch (err) { + return undefined; + } } async addNewItemToTheList(name, id, url) { diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js index 028e87d..5023163 100644 --- a/HW9(http)/public/scripts/View.js +++ b/HW9(http)/public/scripts/View.js @@ -1,5 +1,11 @@ -class View { - updatePage() {} -} +const express = require('express'); +const controller = require('./Controller'); -module.exports = new View(); \ No newline at end of file +const View = express.Router(); + +View.get('', async(_, res) => { + const flowersList = await controller.getItems(); + res.render('view', {"list": flowersList}); +}) + +module.exports = View; \ No newline at end of file diff --git a/HW9(http)/public/styles/style.css b/HW9(http)/public/styles/style.css index ff3732e..9725116 100644 --- a/HW9(http)/public/styles/style.css +++ b/HW9(http)/public/styles/style.css @@ -12,16 +12,21 @@ body { font-weight: normal; color: #1C5713; letter-spacing: 0.15em; +} + +main, ul li { display: flex; flex-direction: column; justify-content: center; align-items: center; - text-align: center; +} + +h1, h2 { + margin: 25px 0; } table { border-spacing: 5px; - margin-top: 5px; } tbody { @@ -46,4 +51,32 @@ td { .address { background-color: rgba(27, 27, 27, 0.6); +} + +#content { + display: grid; + grid-template-rows: 1fr; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-gap: 2vw; + margin: 0 25px; +} + +ul { + list-style-type: none; + padding-bottom: 25px; +} + +.card { + padding: 5px 0; + border: 2px solid green; + width: 244px; + height: 417px; +} + +.card__name, .card__id { + margin: 10px; +} + +.card__name { + font-weight: bold; } \ No newline at end of file diff --git a/HW9(http)/public/index.html b/HW9(http)/public/views/view.ejs similarity index 81% rename from HW9(http)/public/index.html rename to HW9(http)/public/views/view.ejs index 574ea41..4cc0445 100644 --- a/HW9(http)/public/index.html +++ b/HW9(http)/public/views/view.ejs @@ -46,6 +46,18 @@

Flowers world API

+ +

Current database state:

+ +
    + <% list.forEach(function(el){ %> +
  • + <%= el.name %> + Image of a <%= el.name %> + ID: <%= el.id %> +
  • + <% }); %> +
\ No newline at end of file From 1dc65e690f5b94f71e10e08d4f8d7257aa4f896d Mon Sep 17 00:00:00 2001 From: Dmytro Date: Mon, 12 Apr 2021 14:40:32 +0300 Subject: [PATCH 12/16] Changed default values in database. --- HW9(http)/public/db.json | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index 5b66d29..29b2d9b 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -1 +1,29 @@ -{"list":[{"id":1,"name":"changed1","url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true"},{"name":"Garcinia Morella","id":2,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true"},{"name":"Picea excelsa Lk","id":3,"url":"https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true"},{"id":6,"name":"changed1","url":"newURL"}]} \ No newline at end of file +{ + "list": [ + { + "name": "Polypodiophyta", + "id": 0, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Polypodiophyta.jpg?raw=true" + }, + { + "name": "Abies alba Miller", + "id": 1, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Abies%20alba%20Miller.jpg?raw=true" + }, + { + "name": "Garcinia Morella", + "id": 2, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Garcinia%20Morella.jpg?raw=true" + }, + { + "name": "Picea excelsa Lk", + "id": 3, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Picea%20excelsa%20Lk.jpg?raw=true" + }, + { + "name": "Quassia amara L", + "id": 4, + "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true" + } + ] +} From 46d11703a8358504937fe1003b92786d7423a74e Mon Sep 17 00:00:00 2001 From: Dmytro Date: Mon, 12 Apr 2021 19:45:47 +0300 Subject: [PATCH 13/16] Final version berfore review. --- HW9(http)/app.js | 76 ++++++++++++-------------- HW9(http)/public/db.json | 2 +- HW9(http)/public/scripts/Controller.js | 6 +- HW9(http)/public/scripts/Middleware.js | 52 +++++++++++++++--- HW9(http)/public/scripts/Model.js | 12 ++-- 5 files changed, 93 insertions(+), 55 deletions(-) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 2b7d8d3..8d954e4 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -12,77 +12,71 @@ const viewRouter = require('./public/scripts/View'); app.use('/', viewRouter); app.get('/api/flowers', async (req, res) => { - const items = await controller.getItems(req.query.id); - - if (items === undefined) { - res.status(204).send('No Content.'); - } else { - res.status(200).send(items); - } + const response = await controller.getItems(req.query.id); + switch (response) { + case 204: + res.status(204).send('No Content.'); + break; + case 400: + res.status(400).send('ID must be a number.'); + break; + case 404: + res.status(404).send('Not Found.\nItem was not found.'); + break; + default: + res.status(200).send(response); + } }) app.post('/api/flowers', async (req, res) => { - const response = { - code: null, - result: null - }; - - response.code = await controller.addItem(req.query); - switch (response.code) { + const response = await controller.addItem(req.query); + switch (response) { case 201: - response.result = 'Created.\nItem was successfully created.'; + res.status(201).send('Created.\nItem was successfully created.'); break; case 400: - response.result = 'Bad request.\nSome parameters are missing. ID, NAME, URL must be present.'; + res.status(400).send('Bad request.\nID, NAME, URL must be present.\nID must be a number.'); break; case 406: - response.result = 'Not Acceptable.\nItem already exists.'; + res.status(406).send('Not Acceptable.\nItem already exists.'); break; + default: + res.status(500).send('Internal Server Error.'); } - - res.status(response.code).send(response.result); }) app.put('/api/flowers', async (req, res) => { - const response = { - code: null, - result: null - }; - - response.code = await controller.updateItem(req.query); - switch (response.code) { + const response = await controller.updateItem(req.query); + switch (response) { case 200: - response.result = 'OK.\nItem was successfully updated.'; + res.status(200).send('OK.\nItem was successfully updated.'); break; case 400: - response.result = 'Bad request.\nSome parameters are missing. ID, NAME, URL must be present.'; + res.status(400).send('Bad request.\nID, NAME or URL must be present.\nID must be a number.'); break; case 404: - response.result = 'Not Found.\nItem was not found.'; + res.status(404).send('Not Found.\nItem was not found.'); break; + default: + res.status(500).send('Internal Server Error.'); } - res.status(response.code).send(response.result); }) app.delete('/api/flowers', async (req, res) => { - const response = { - code: null, - result: null - }; - - response.code = await controller.deleteItem(req.query.id); - switch (response.code) { + const response = await controller.deleteItem(req.query.id); + switch (response) { case 200: - response.result = 'OK.\nItem was successfully deleted.'; + res.status(200).send('OK.\nItem was successfully deleted.'); break; case 400: - response.result = 'Bad request.\nSome parameters are missing. ID, NAME, URL must be present.'; + res.status(400).send('Bad request.\nID must be present.\nID must be a number.'); break; case 404: - response.result = 'Not Found.\nItem was not found.'; + res.status(404).send('Not Found.\nItem was not found.'); break; + default: + res.status(500).send('Internal Server Error.'); } - res.status(response.code).send(response.result); }) app.listen(PORT, () => { diff --git a/HW9(http)/public/db.json b/HW9(http)/public/db.json index 29b2d9b..daa6d37 100644 --- a/HW9(http)/public/db.json +++ b/HW9(http)/public/db.json @@ -26,4 +26,4 @@ "url": "https://github.com/FacelessWanderer/flowers/blob/master/images/Quassia%20amara%20L.jpg?raw=true" } ] -} +} \ No newline at end of file diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index 18aea9d..337309c 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -2,7 +2,11 @@ const middleware = require('./Middleware.js'); class Controller { async getItems(id) { - return await middleware.find(id); + if (id === undefined) { + return await middleware.getAll(); + } else { + return await middleware.getOne(id) + } } async addItem(params) { diff --git a/HW9(http)/public/scripts/Middleware.js b/HW9(http)/public/scripts/Middleware.js index 6d12ace..50b066c 100644 --- a/HW9(http)/public/scripts/Middleware.js +++ b/HW9(http)/public/scripts/Middleware.js @@ -1,14 +1,31 @@ +const e = require('express'); const model = require('./Model.js'); class Middleware { - async find(id) { + async getAll() { const list = await model.getList(); - if (id === undefined) { - return list; + if (list.length === 0) { + return 204; } - return model.findItem(list, id); + return list; + } + + async getOne(id) { + id = parseInt(id); + + if (!this.isNumber(id)) { + return 400; + }; + + const item = await model.findItem(id); + + if (item === undefined) { + return 404; + } + + return [item]; } async create({ id, name, url }) { @@ -20,11 +37,16 @@ class Middleware { return 400; } + id = parseInt(id); + if (!this.isNumber(id)) { + return 400; + }; + if (await (this.checkIfItemExists(id))) { return 406; } - model.addNewItemToTheList(name, +id, url); + model.addNewItemToTheList(name, id, url); return 201; } @@ -33,12 +55,17 @@ class Middleware { return 400; } - const item = await this.find(id); + id = parseInt(id); + if (!this.isNumber(id)) { + return 400; + }; + + const item = await model.findItem(id); if (item === undefined) { return 404; } - model.updateItem(+id, name ?? item.name, url ?? item.url); + model.updateItem(id, name ?? item.name, url ?? item.url); return 200; } @@ -47,6 +74,11 @@ class Middleware { return 400; } + id = parseInt(id); + if (!this.isNumber(id)) { + return 400; + }; + if (!(await this.checkIfItemExists(id))) { return 404; } @@ -56,7 +88,7 @@ class Middleware { } async checkIfItemExists(id) { - const item = await this.find(id); + const item = await model.findItem(id); if (item === undefined) { return false; @@ -64,6 +96,10 @@ class Middleware { return true; } } + + isNumber(n) { + return typeof(n) === 'number' && !isNaN(n); + } } module.exports = new Middleware(); \ No newline at end of file diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index 48a71cb..34cab56 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -26,7 +26,7 @@ class Model { async updateItem(id, name, url) { const list = await this.getList(); - const itemToUpdate = this.findItem(list, id); + const itemToUpdate = await this.findItem(id, list); list[list.indexOf(itemToUpdate)] = { id: id, @@ -39,14 +39,18 @@ class Model { async deleteItem(id) { const list = await this.getList(); - const itemToDelete = this.findItem(list, id); + const itemToDelete = await this.findItem(id, list); list.splice(list.indexOf(itemToDelete), 1); this.saveList(list); } - findItem(list, id) { - return list.find(item => +item.id === +id); + async findItem(id, list) { + if (list === undefined) { + list = await this.getList(); + } + + return list.find(item => item.id === id); } saveList(list) { From 4e264bff074c08242325f5686702f6373f78935c Mon Sep 17 00:00:00 2001 From: Dmytro Date: Mon, 12 Apr 2021 19:50:13 +0300 Subject: [PATCH 14/16] Removed unused dependencies. --- HW9(http)/public/scripts/Middleware.js | 1 - 1 file changed, 1 deletion(-) diff --git a/HW9(http)/public/scripts/Middleware.js b/HW9(http)/public/scripts/Middleware.js index 50b066c..df8a33c 100644 --- a/HW9(http)/public/scripts/Middleware.js +++ b/HW9(http)/public/scripts/Middleware.js @@ -1,4 +1,3 @@ -const e = require('express'); const model = require('./Model.js'); class Middleware { From 78706b1522e2b57cfaf296667c7a7fa80e810cb1 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Thu, 15 Apr 2021 18:53:57 +0300 Subject: [PATCH 15/16] Fixed all issues. --- HW9(http)/app.js | 80 +++----------- HW9(http)/public/scripts/Controller.js | 24 ++--- HW9(http)/public/scripts/Middleware.js | 139 +++++++++++++------------ HW9(http)/public/scripts/Model.js | 52 ++++----- HW9(http)/public/scripts/View.js | 2 +- HW9(http)/public/styles/style.css | 6 ++ 6 files changed, 130 insertions(+), 173 deletions(-) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 8d954e4..4ec8d9f 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -1,83 +1,31 @@ const express = require('express'); -const controller = require('./public/scripts/Controller.js'); +const middleware = require('./public/scripts/Middleware.js'); +const viewRouter = require('./public/scripts/View'); const app = express(); const PORT = process.env.PORT || 4200; -app.use(express.static('public')); app.set('views', './public/views'); app.set('view engine', 'ejs'); -const viewRouter = require('./public/scripts/View'); +app.use(express.static('public')); app.use('/', viewRouter); -app.get('/api/flowers', async (req, res) => { - const response = await controller.getItems(req.query.id); - switch (response) { - case 204: - res.status(204).send('No Content.'); - break; - case 400: - res.status(400).send('ID must be a number.'); - break; - case 404: - res.status(404).send('Not Found.\nItem was not found.'); - break; - default: - res.status(200).send(response); - } -}) +app.get('/api/flowers', middleware.get, (req, res) => { + res.status(200).send(req.response); +}); -app.post('/api/flowers', async (req, res) => { - const response = await controller.addItem(req.query); - switch (response) { - case 201: - res.status(201).send('Created.\nItem was successfully created.'); - break; - case 400: - res.status(400).send('Bad request.\nID, NAME, URL must be present.\nID must be a number.'); - break; - case 406: - res.status(406).send('Not Acceptable.\nItem already exists.'); - break; - default: - res.status(500).send('Internal Server Error.'); - } -}) +app.post('/api/flowers', middleware.post, async (_, res) => { + res.status(201).send('Created.\nItem was successfully created.'); +}); -app.put('/api/flowers', async (req, res) => { - const response = await controller.updateItem(req.query); - switch (response) { - case 200: - res.status(200).send('OK.\nItem was successfully updated.'); - break; - case 400: - res.status(400).send('Bad request.\nID, NAME or URL must be present.\nID must be a number.'); - break; - case 404: - res.status(404).send('Not Found.\nItem was not found.'); - break; - default: - res.status(500).send('Internal Server Error.'); - } +app.put('/api/flowers', middleware.put, async (_, res) => { + res.status(200).send('OK.\nItem was successfully updated.'); }) -app.delete('/api/flowers', async (req, res) => { - const response = await controller.deleteItem(req.query.id); - switch (response) { - case 200: - res.status(200).send('OK.\nItem was successfully deleted.'); - break; - case 400: - res.status(400).send('Bad request.\nID must be present.\nID must be a number.'); - break; - case 404: - res.status(404).send('Not Found.\nItem was not found.'); - break; - default: - res.status(500).send('Internal Server Error.'); - } -}) +app.delete('/api/flowers', middleware.delete, async (_, res) => { + res.status(200).send('OK.\nItem was successfully deleted.'); +}); app.listen(PORT, () => { console.info(`Started a server on port: ${PORT}`) diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index 337309c..47bc6a7 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -1,24 +1,24 @@ -const middleware = require('./Middleware.js'); +const model = require('./Model.js'); class Controller { - async getItems(id) { - if (id === undefined) { - return await middleware.getAll(); - } else { - return await middleware.getOne(id) - } + async getAllItems() { + return await model.getAllItems(); } - async addItem(params) { - return await middleware.create(params) + async getOneItem(id) { + return await model.findOneItem(id); } - async updateItem(params) { - return await middleware.update(params); + async addItem(id, name, url) { + return await model.addNewItemToTheList(id, name, url); + } + + async updateItem(id, name, url) { + return await model.updateItem(id, name, url); } async deleteItem(id) { - return await middleware.delete(id); + return await model.deleteItem(id); } } diff --git a/HW9(http)/public/scripts/Middleware.js b/HW9(http)/public/scripts/Middleware.js index df8a33c..9dd9e63 100644 --- a/HW9(http)/public/scripts/Middleware.js +++ b/HW9(http)/public/scripts/Middleware.js @@ -1,103 +1,104 @@ -const model = require('./Model.js'); +const controller = require('./Controller'); class Middleware { - async getAll() { - const list = await model.getList(); + async get(req, res, next) { + let id = req.query.id; - if (list.length === 0) { - return 204; + if (id === undefined) { + req.response = await controller.getAllItems(); + return next(); } - - return list; - } - - async getOne(id) { + id = parseInt(id); - - if (!this.isNumber(id)) { - return 400; - }; - const item = await model.findItem(id); + if (isNaN(id)) { + return res.status(400).send('Type of ID must be a number.'); + } + + req.response = await controller.getOneItem(id); - if (item === undefined) { - return 404; + if (req.response === undefined) { + return res.status(404).send('Not Found.\nItem was not found.'); } - - return [item]; + + if (req.response.length === 0) { + return res.status(204).send('No content.'); + } + + next(); } - - async create({ id, name, url }) { + + async post(req, res, next) { + let { id, name, url } = req.query; + if ( - name === undefined || id === undefined || + name === undefined || url === undefined ) { - return 400; + return res.status(400).send('Bad request.\nID, NAME, URL must be present.\nID must be a number.'); } - + id = parseInt(id); - if (!this.isNumber(id)) { - return 400; - }; - if (await (this.checkIfItemExists(id))) { - return 406; + if (isNaN(id)) { + return res.status(400).send('Type of ID must be a number.'); } - - model.addNewItemToTheList(name, id, url); - return 201; - } + + const itemToCreate = await controller.getOneItem(id); - async update({ id, name, url }) { + if (itemToCreate !== undefined) { + return res.status(406).send('Not Acceptable.\nItem already exists.'); + } + + controller.addItem(id, name, url); + next(); + } + + async put(req, res, next) { + let { id, name, url } = req.query; + if (id === undefined) { - return 400; + return res.status(400).send('Bad request.\nID, NAME or URL must be present.\nID must be a number.'); } - + id = parseInt(id); - if (!this.isNumber(id)) { - return 400; - }; - const item = await model.findItem(id); - if (item === undefined) { - return 404; + if (isNaN(id)) { + return res.status(400).send('Type of ID must be a number.'); } + + const itemToUpdate = await controller.getOneItem(id); - model.updateItem(id, name ?? item.name, url ?? item.url); - return 200; + if (itemToUpdate === undefined) { + return res.status(404).send('Not Found.\nItem was not found.'); + } + + controller.updateItem(id, name ?? itemToUpdate.name, url ?? itemToUpdate.url); + next(); } - - async delete(id) { + + async delete(req, res, next) { + let id = req.query.id; + if (id === undefined) { - return 400; + return res.status(400).send('Bad request.\nID must be present.'); } - + id = parseInt(id); - if (!this.isNumber(id)) { - return 400; - }; - if (!(await this.checkIfItemExists(id))) { - return 404; + if (isNaN(id)) { + return res.status(400).send('Bad request. \nID must be a number.'); } - - model.deleteItem(id); - return 200; - } - - async checkIfItemExists(id) { - const item = await model.findItem(id); - - if (item === undefined) { - return false; - } else { - return true; + + const itemToDelete = await controller.getOneItem(id); + + if (itemToDelete === undefined) { + return res.status(404).send('Not Found.\nItem was not found.'); } - } - - isNumber(n) { - return typeof(n) === 'number' && !isNaN(n); + + controller.deleteItem(id); + next(); } } diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index 34cab56..c88df78 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -1,59 +1,61 @@ const fs = require('fs').promises; class Model { - async getList() { - const database = await fs.readFile('./public/db.json'); - + async getAllItems() { try { - const list = JSON.parse(database).list; - return list; - } catch (err) { - return undefined; + const database = await fs.readFile('./public/db.json'); + return JSON.parse(database).list; + } catch (error) { + console.error(`No items in the database. ${error}`); + return []; } } - async addNewItemToTheList(name, id, url) { - const list = await this.getList(); + async addNewItemToTheList(id, name, url) { + const list = await this.getAllItems(); list.push({ - name: name, id: id, + name: name, url: url, }); - this.saveList(list); + this.saveItems(list); } async updateItem(id, name, url) { - const list = await this.getList(); - const itemToUpdate = await this.findItem(id, list); + const list = await this.getAllItems(); + const index = await this.findIndexOfItem(id); - list[list.indexOf(itemToUpdate)] = { + list[index] = { id: id, name: name, url: url, } - this.saveList(list); + this.saveItems(list); } async deleteItem(id) { - const list = await this.getList(); - const itemToDelete = await this.findItem(id, list); + const list = await this.getAllItems(); + const index = await this.findIndexOfItem(id); - list.splice(list.indexOf(itemToDelete), 1); - this.saveList(list); + list.splice(index, 1); + this.saveItems(list); } - async findItem(id, list) { - if (list === undefined) { - list = await this.getList(); - } - + async findOneItem(id) { + const list = await this.getAllItems(); return list.find(item => item.id === id); } - saveList(list) { + async findIndexOfItem(id) { + const list = await this.getAllItems(); + const item = list.find(item => item.id === id); + return list.indexOf(item); + } + + saveItems(list) { fs.writeFile('./public/db.json', JSON.stringify({ list: list })); diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js index 5023163..ca56c15 100644 --- a/HW9(http)/public/scripts/View.js +++ b/HW9(http)/public/scripts/View.js @@ -4,7 +4,7 @@ const controller = require('./Controller'); const View = express.Router(); View.get('', async(_, res) => { - const flowersList = await controller.getItems(); + const flowersList = await controller.getAllItems(); res.render('view', {"list": flowersList}); }) diff --git a/HW9(http)/public/styles/style.css b/HW9(http)/public/styles/style.css index 9725116..e14b3b7 100644 --- a/HW9(http)/public/styles/style.css +++ b/HW9(http)/public/styles/style.css @@ -79,4 +79,10 @@ ul { .card__name { font-weight: bold; +} + +img { + width: 240px; + height: 417px; + object-fit: contain; } \ No newline at end of file From bb44a51f9c5605974336a225938351829af029a7 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Sat, 17 Apr 2021 15:31:06 +0300 Subject: [PATCH 16/16] Fixed additional issues. --- HW9(http)/app.js | 34 +++++--- HW9(http)/public/scripts/Controller.js | 113 +++++++++++++++++++++++-- HW9(http)/public/scripts/Middleware.js | 110 +++++------------------- HW9(http)/public/scripts/Model.js | 14 +-- HW9(http)/public/scripts/View.js | 2 +- 5 files changed, 160 insertions(+), 113 deletions(-) diff --git a/HW9(http)/app.js b/HW9(http)/app.js index 4ec8d9f..bba062e 100644 --- a/HW9(http)/app.js +++ b/HW9(http)/app.js @@ -1,30 +1,42 @@ const express = require('express'); -const middleware = require('./public/scripts/Middleware.js'); -const viewRouter = require('./public/scripts/View'); - const app = express(); const PORT = process.env.PORT || 4200; +const controller = require('./public/scripts/Controller.js'); +const middleware = require('./public/scripts/Middleware.js'); +const viewRouter = require('./public/scripts/View'); + app.set('views', './public/views'); app.set('view engine', 'ejs'); app.use(express.static('public')); app.use('/', viewRouter); -app.get('/api/flowers', middleware.get, (req, res) => { - res.status(200).send(req.response); +app.get('/api/flowers', middleware.handleRequest, async (req, res) => { + let response = null; + + if (req.query.id !== undefined) { + response = await controller.getOneItem(req.query.id); + } else { + response = await controller.getAllItems(); + } + + res.status(response.statusCode).send(response.result); }); -app.post('/api/flowers', middleware.post, async (_, res) => { - res.status(201).send('Created.\nItem was successfully created.'); +app.post('/api/flowers', middleware.handleRequest, async (req, res) => { + const response = await controller.addItem(req.query); + res.status(response.statusCode).send(response.result); }); -app.put('/api/flowers', middleware.put, async (_, res) => { - res.status(200).send('OK.\nItem was successfully updated.'); +app.put('/api/flowers', middleware.handleRequest, async (req, res) => { + const response = await controller.updateItem(req.query); + res.status(response.statusCode).send(response.result); }) -app.delete('/api/flowers', middleware.delete, async (_, res) => { - res.status(200).send('OK.\nItem was successfully deleted.'); +app.delete('/api/flowers', middleware.handleRequest, async (req, res) => { + const response = await controller.deleteItem(req.query.id); + res.status(response.statusCode).send(response.result); }); app.listen(PORT, () => { diff --git a/HW9(http)/public/scripts/Controller.js b/HW9(http)/public/scripts/Controller.js index 47bc6a7..e2562f5 100644 --- a/HW9(http)/public/scripts/Controller.js +++ b/HW9(http)/public/scripts/Controller.js @@ -2,23 +2,122 @@ const model = require('./Model.js'); class Controller { async getAllItems() { - return await model.getAllItems(); + const result = await model.getAllItems(); + + if (!Array.isArray(result)) { + return { + result: 'Internal Server Error.', + statusCode: 500 + } + } else if (result.length === 0) { + return { + result, + statusCode: 204 + } + } + + return { + result, + statusCode: 200 + } } async getOneItem(id) { - return await model.findOneItem(id); + const item = await model.findOneItem(id); + + if (item === undefined) { + return { + result: 'Not Found.\nItem was not found.', + statusCode: 404 + } + } + + return { + result: item, + statusCode: 200 + } } - async addItem(id, name, url) { - return await model.addNewItemToTheList(id, name, url); + async addItem({ id, name, url }) { + if ( + id === undefined || + name === undefined || + url === undefined + ) { + return { + result: 'Bad request.\nID, NAME, URL must be present.\nID must be a number.', + statusCode: 400 + } + } + + const itemAlreadyExists = await model.findOneItem(id) ?? false; + + if (itemAlreadyExists) { + return { + result: 'Not Acceptable.\nItem already exists.', + statusCode: 406 + } + } + + await model.addNewItemToTheList(id, name, url); + + return { + result: 'Created.\nItem was successfully created.', + statusCode: 201 + } } - async updateItem(id, name, url) { - return await model.updateItem(id, name, url); + async updateItem({ id, name, url }) { + if (id === undefined || (name === undefined && url === undefined)) { + return { + result: 'Bad request.\nID, NAME or URL must be present.\nID must be a number.', + statusCode: 400 + } + } + + const itemToUpdate = await model.findOneItem(id); + + if (itemToUpdate === undefined) { + return { + result: 'Not Found.\nItem was not found.', + statusCode: 404 + } + } + + name = name ?? itemToUpdate.name; + url = url ?? itemToUpdate.url; + + await model.updateItem(id, name, url); + + return { + result: 'OK.\nItem was successfully updated.', + statusCode: 200 + } } async deleteItem(id) { - return await model.deleteItem(id); + if (id === undefined) { + return { + result: 'Bad request.\nID must be present.\nID must be a number.', + statusCode: 400 + } + } + + const itemToDelete = await model.findOneItem(id); + + if (itemToDelete === undefined) { + return { + result: 'Not Found.\nItem was not found.', + statusCode: 404 + } + } + + await model.deleteItem(id); + + return { + result: 'OK.\nItem was successfully deleted.', + statusCode: 200 + } } } diff --git a/HW9(http)/public/scripts/Middleware.js b/HW9(http)/public/scripts/Middleware.js index 9dd9e63..ef559e6 100644 --- a/HW9(http)/public/scripts/Middleware.js +++ b/HW9(http)/public/scripts/Middleware.js @@ -1,104 +1,36 @@ -const controller = require('./Controller'); - class Middleware { - async get(req, res, next) { - let id = req.query.id; - - if (id === undefined) { - req.response = await controller.getAllItems(); - return next(); - } - - id = parseInt(id); - - if (isNaN(id)) { - return res.status(400).send('Type of ID must be a number.'); - } - - req.response = await controller.getOneItem(id); - - if (req.response === undefined) { - return res.status(404).send('Not Found.\nItem was not found.'); - } - - if (req.response.length === 0) { - return res.status(204).send('No content.'); - } - + handleRequest(req, _, next) { + Middleware.validateQueryParams(req.query); next(); } - - async post(req, res, next) { - let { id, name, url } = req.query; - - if ( - id === undefined || - name === undefined || - url === undefined - ) { - return res.status(400).send('Bad request.\nID, NAME, URL must be present.\nID must be a number.'); - } - - id = parseInt(id); - if (isNaN(id)) { - return res.status(400).send('Type of ID must be a number.'); - } - - const itemToCreate = await controller.getOneItem(id); + static validateQueryParams(query) { + let { id, name, url } = query; - if (itemToCreate !== undefined) { - return res.status(406).send('Not Acceptable.\nItem already exists.'); - } - - controller.addItem(id, name, url); - next(); - } - - async put(req, res, next) { - let { id, name, url } = req.query; - - if (id === undefined) { - return res.status(400).send('Bad request.\nID, NAME or URL must be present.\nID must be a number.'); - } - id = parseInt(id); if (isNaN(id)) { - return res.status(400).send('Type of ID must be a number.'); + query.id = undefined; + } else { + query.id = id; } - - const itemToUpdate = await controller.getOneItem(id); - if (itemToUpdate === undefined) { - return res.status(404).send('Not Found.\nItem was not found.'); - } - - controller.updateItem(id, name ?? itemToUpdate.name, url ?? itemToUpdate.url); - next(); - } - - async delete(req, res, next) { - let id = req.query.id; - - if (id === undefined) { - return res.status(400).send('Bad request.\nID must be present.'); - } - - id = parseInt(id); + if (name !== undefined && url !== undefined) { + name = name.trim(); + url = url.trim(); - if (isNaN(id)) { - return res.status(400).send('Bad request. \nID must be a number.'); - } - - const itemToDelete = await controller.getOneItem(id); - - if (itemToDelete === undefined) { - return res.status(404).send('Not Found.\nItem was not found.'); + if (name === '') { + query.name = undefined; + } else { + query.name = name; + } + + if (url === '') { + query.url = undefined; + } else { + query.url = url; + } } - - controller.deleteItem(id); - next(); } } diff --git a/HW9(http)/public/scripts/Model.js b/HW9(http)/public/scripts/Model.js index c88df78..d5fd240 100644 --- a/HW9(http)/public/scripts/Model.js +++ b/HW9(http)/public/scripts/Model.js @@ -6,8 +6,8 @@ class Model { const database = await fs.readFile('./public/db.json'); return JSON.parse(database).list; } catch (error) { - console.error(`No items in the database. ${error}`); - return []; + console.error(`Cannot get items from the database. ${error}`) + return error; } } @@ -56,9 +56,13 @@ class Model { } saveItems(list) { - fs.writeFile('./public/db.json', JSON.stringify({ - list: list - })); + try { + fs.writeFile('./public/db.json', JSON.stringify({ + list: list + })); + } catch (error) { + console.error(`Cannot save items in the database. ${error}`); + } } } diff --git a/HW9(http)/public/scripts/View.js b/HW9(http)/public/scripts/View.js index ca56c15..95781ce 100644 --- a/HW9(http)/public/scripts/View.js +++ b/HW9(http)/public/scripts/View.js @@ -5,7 +5,7 @@ const View = express.Router(); View.get('', async(_, res) => { const flowersList = await controller.getAllItems(); - res.render('view', {"list": flowersList}); + res.render('view', {"list": flowersList.result}); }) module.exports = View; \ No newline at end of file