From 55a9b6da4eda9e03b91c4629e8ad08e3e4a7fdfd Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 14:49:20 -0700 Subject: [PATCH 01/22] init --- .gitignore | 3 +++ .vscode/extensions.json | 5 +++++ .vscode/launch.json | 14 ++++++++++++++ .vscode/settings.json | 6 ++++++ README.md | 1 + 5 files changed, 29 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..924963d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# NPM +node_modules +package-lock.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c0a2258 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": ["dbaeumer.vscode-eslint"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..cf82cc7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Run Tests", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": ["--reporter=spec", "--colors", "--bail", "--timeout", "9999999"], + "console": "internalConsole", + "internalConsoleOptions": "openOnSessionStart" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d4c0ca5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll": true + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e13b648 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Backend Challenges: package.json From d58d63051edb81c13fd8dce43fefa93265b6ceee Mon Sep 17 00:00:00 2001 From: shmck Date: Thu, 16 Apr 2020 21:06:34 -0700 Subject: [PATCH 02/22] setup test runner --- coderoad/package.json | 15 ++++++ coderoad/test/utils.js | 115 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 coderoad/package.json create mode 100644 coderoad/test/utils.js diff --git a/coderoad/package.json b/coderoad/package.json new file mode 100644 index 0000000..1a71453 --- /dev/null +++ b/coderoad/package.json @@ -0,0 +1,15 @@ +{ + "name": "coderoad-fcc-learn-npm", + "repository": { + "type": "git", + "url": "https://github.com/coderoad/fcc-learn-npm" + }, + "scripts": { + "test": "mocha", + "programmatic-test": "mocha --reporter=mocha-tap-reporter" + }, + "dependencies": { + "mocha": "^7.0.1", + "mocha-tap-reporter": "^0.1.3" + } +} diff --git a/coderoad/test/utils.js b/coderoad/test/utils.js new file mode 100644 index 0000000..b3f3558 --- /dev/null +++ b/coderoad/test/utils.js @@ -0,0 +1,115 @@ +const fs = require("fs"); +const util = require("util"); +const { join } = require("path"); + +const readFile = util.promisify(fs.readFile); +const readdir = util.promisify(fs.readdir); + +const getPackageJson = async (dir = process.cwd()) => { + // load package.json file + const pathToPackageJson = join(dir, "..", "package.json"); + const packageJson = await readFile(pathToPackageJson, "utf8").catch( + console.error + ); + if (!packageJson) { + throw new Error("Missing root package.json"); + } + // parse as JSON + const json = JSON.parse(packageJson); + if (!json) { + throw new Error("The package.json content looks invalid"); + } + return json; +}; + +exports.getPackageJson = getPackageJson; + +const versionMatch = (current, expected) => { + let currentSemver = current; + if (["~", "^"].includes(current[0])) { + currentSemver = current.substring(1); + } + return currentSemver === expected; +}; + +/** + * isModuleInstalled + * @param { name, type } params + * "name" - the name of the dependency + * "type" - "dependency", "devDependency", "peerDependency" + * @returns boolean + */ +const isModuleInstalled = async ({ name, type, version }) => { + // 1. load package.json file + const json = await getPackageJson(); + + // 2. verify package lists dependency by type + let installCommand; + let hasDependency; + let currentVersion; + + switch (type) { + case "dependency": + installCommand = "--save"; + hasDependency = !!json.dependencies && json.dependencies[name]; + currentVersion = json.dependencies[name]; + break; + case "devDependency": + installCommand = "--save-dev"; + hasDependency = !!json.devDependencies && json.devDependencies[name]; + currentVersion = json.devDependencies[name]; + break; + case "peerDependency": + throw new Error("Peer dependencies unsupported"); + default: + throw new Error("Unsupported packaged type"); + } + + if (!hasDependency) { + throw new Error(`Run "npm install ${installCommand} ${name}"`); + } + + // 3. if version, check dependency version + if (version && !versionMatch(currentVersion, version)) { + throw new Error( + `Dependency ${name} version ${currentVersion} does not match expected ${version}` + ); + } + + // 4. verify node_module installed + const pathToNodeModule = join(process.cwd(), "..", "node_modules", name); + const hasNodeModules = await readdir(pathToNodeModule).catch(() => { + throw new Error('Missing node_modules. Run "npm install"'); + }); + if (!hasNodeModules) { + throw new Error('Missing node_modules. Run "npm install"'); + } + + // 5. if version, has installed node_module version + if (version) { + const nodeModulePackageJson = await getPackageJson(pathToNodeModule); + if (!versionMatch(nodeModulePackageJson.version, version)) { + throw new Error( + `Dependency ${name} version ${version} is not yet installed. Run "npm install"` + ); + } + } + + return true; +}; + +exports.isModuleInstalled = isModuleInstalled; + +// created because assert.doesNotThrow not working predictably with async fns +const doesNotThrow = async (fn) => { + let result = true; + try { + await fn(); + } catch (error) { + console.error(error); + result = false; + } + return result; +}; + +exports.doesNotThrow = doesNotThrow; From 5326ec858764a6afffd5a897a8efe26ce5cb7bf5 Mon Sep 17 00:00:00 2001 From: shmck Date: Thu, 16 Apr 2020 21:07:06 -0700 Subject: [PATCH 03/22] 1.1 author key --- coderoad/test/packagejson.test.js | 18 ++++++++++++++++++ package.json | 14 ++++++++++++++ server.js | 9 +++++++++ 3 files changed, 41 insertions(+) create mode 100644 coderoad/test/packagejson.test.js create mode 100644 package.json create mode 100644 server.js diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js new file mode 100644 index 0000000..190d6bb --- /dev/null +++ b/coderoad/test/packagejson.test.js @@ -0,0 +1,18 @@ +const { getPackageJson } = require("./utils"); +const assert = require("assert"); + +describe("package.json", () => { + let json; + before(async () => { + json = await getPackageJson(); + }); + // 1.1 + it('should have a valid "author" key', () => { + assert.ok(json.author, 'no "author" key provided'); + assert.equal( + typeof json.author, + "string", + 'should have an "author" value that is a string' + ); + }); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..e8e0a21 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "fcc-learn-npm", + "repository": { + "type": "git", + "url": "https://github.com/coderoad/fcc-learn-npm" + }, + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "express": "^4.17.0" + } +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..2fb2ef4 --- /dev/null +++ b/server.js @@ -0,0 +1,9 @@ +const express = require("express"); +const app = express(); +const port = 3000; + +app.get("/", (req, res) => res.send("Hello World!")); + +app.listen(port, () => + console.log(`Example app listening at http://localhost:${port} !`) +); From 424cf66eeee739d10fc0eb4db71a35e0cff12d0e Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 14:53:10 -0700 Subject: [PATCH 04/22] 1.1 author solution --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e8e0a21..803522d 100644 --- a/package.json +++ b/package.json @@ -10,5 +10,6 @@ }, "dependencies": { "express": "^4.17.0" - } + }, + "author": "Your Name " } From 68ddb9784442d787f632d3863b72a3e355a1ae9f Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:09 -0700 Subject: [PATCH 05/22] 1.2 description --- coderoad/test/packagejson.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index 190d6bb..c8e0917 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -15,4 +15,13 @@ describe("package.json", () => { 'should have an "author" value that is a string' ); }); + // 1.2 + it('should have a valid "description" key', () => { + assert.ok(json.description, '"description" is missing'); + assert.equal( + typeof json.description, + "string", + 'should have a "description" value that is a string' + ); + }); }); From 138ad0ed30128b08b5105bf907235cfb24419f01 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:15 -0700 Subject: [PATCH 06/22] 1.2 description solution --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 803522d..25f66a0 100644 --- a/package.json +++ b/package.json @@ -11,5 +11,6 @@ "dependencies": { "express": "^4.17.0" }, - "author": "Your Name " + "author": "Your Name ", + "description": "A description of the project" } From 2069439bc347bbdf1a3cca2eda8593f934306e53 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:00 -0700 Subject: [PATCH 07/22] 1.3 keywords --- coderoad/test/packagejson.test.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index c8e0917..91b7bfe 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -24,4 +24,16 @@ describe("package.json", () => { 'should have a "description" value that is a string' ); }); + // 1.3 + it('should have a valid "keywords" key', () => { + assert.ok(json.keywords, '"keywords" is missing'); + assert.ok( + Array.isArray(json.keywords), + 'should have a "keywords" value that is an array' + ); + assert.ok( + json.keywords.includes("freecodecamp"), + 'should include "freecodecamp"' + ); + }); }); From f2ed4601be02e82a929a041d001a6f60bd190fb6 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:07 -0700 Subject: [PATCH 08/22] 1.3 keywords solution --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 25f66a0..483282c 100644 --- a/package.json +++ b/package.json @@ -12,5 +12,8 @@ "express": "^4.17.0" }, "author": "Your Name ", - "description": "A description of the project" + "description": "A description of the project", + "keywords": [ + "freecodecamp" + ] } From f2229d152b93e17b35a70233c108e97242dfc236 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:48 -0700 Subject: [PATCH 09/22] 1.4 license --- coderoad/test/packagejson.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index 91b7bfe..51a7222 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -36,4 +36,13 @@ describe("package.json", () => { 'should include "freecodecamp"' ); }); + // 1.4 + it('should have a valid "license" key', () => { + assert.ok(json.license, '"license" is missing'); + assert.equal( + typeof json.license, + "string", + 'should have a "license" value that is a string, e.g. "MIT"' + ); + }); }); From 937826753e083238aefd05c7326602828e182c59 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:53 -0700 Subject: [PATCH 10/22] 1.4 license solution --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 483282c..0276735 100644 --- a/package.json +++ b/package.json @@ -15,5 +15,6 @@ "description": "A description of the project", "keywords": [ "freecodecamp" - ] + ], + "license": "MIT" } From 60a4e7b833dc7a9b57b231ad70e2b80404f89389 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:27:54 -0700 Subject: [PATCH 11/22] 1.5 version --- coderoad/test/packagejson.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index 51a7222..d43bd5e 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -45,4 +45,13 @@ describe("package.json", () => { 'should have a "license" value that is a string, e.g. "MIT"' ); }); + // 1.5 + it('should have a valid "version" key', () => { + assert.ok(json.version, '"version" is missing'); + assert.equal( + typeof json.version, + "string", + 'should have a "version" value that is a string' + ); + }); }); From f9f7f297f7cb6275ac3e623391286e68831f5fa1 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:28:03 -0700 Subject: [PATCH 12/22] 1.5 version solution --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0276735..0402598 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,6 @@ "keywords": [ "freecodecamp" ], - "license": "MIT" + "license": "MIT", + "version": "0.1.0" } From e97c095119439a78cafa094ab97cf02b4634767a Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:24 -0700 Subject: [PATCH 13/22] 2.1 install moment --- coderoad/test/packagejson.test.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index d43bd5e..9530b09 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -1,4 +1,4 @@ -const { getPackageJson } = require("./utils"); +const { getPackageJson, isModuleInstalled, doesNotThrow } = require("./utils"); const assert = require("assert"); describe("package.json", () => { @@ -54,4 +54,21 @@ describe("package.json", () => { 'should have a "version" value that is a string' ); }); + // 2.1 + it('should have "dependencies"', () => { + assert.ok(json.dependencies, '"dependencies" is missing'); + assert.equal( + typeof json.dependencies, + "object", + 'should have a "dependencies" value that is an object' + ); + }); + it('should have installed "moment"', async () => { + assert.ok( + await doesNotThrow( + () => isModuleInstalled({ name: "moment", type: "dependency" }), + '"moment" not installed' + ) + ); + }); }); From 97af83aa4584ff5c3c05d8ca1e84ae8bd71de900 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:30 -0700 Subject: [PATCH 14/22] 2.1 install moment solution --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0402598..4760fde 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "start": "node server.js" }, "dependencies": { - "express": "^4.17.0" + "express": "^4.17.0", + "moment": "^2.24.0" }, "author": "Your Name ", "description": "A description of the project", From be039335ab3502e50e7cbd2cc779163dbe20adbd Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:14 -0700 Subject: [PATCH 15/22] 2.2 semver --- coderoad/test/packagejson.test.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index 9530b09..498e7b2 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -71,4 +71,25 @@ describe("package.json", () => { ) ); }); + // 2.2 + it('should use specific version of "moment"', () => { + assert.equal( + json.dependencies.moment, + "2.10.2", + '"moment" should use the specific version' + ); + }); + it('should have installed specific version of "moment"', async () => { + assert.ok( + await doesNotThrow( + () => + isModuleInstalled({ + name: "moment", + type: "dependency", + version: "2.10.2" + }), + '"moment" not installed' + ) + ); + }); }); From ba77ae737dabb8bbebfdf170c7159102f0934eab Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:21 -0700 Subject: [PATCH 16/22] 2.2 semver solution --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4760fde..c0a2560 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "express": "^4.17.0", - "moment": "^2.24.0" + "moment": "2.10.2" }, "author": "Your Name ", "description": "A description of the project", From c4ff0f6ac974d74c26470301d4abd0333ec6e4aa Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:08 -0700 Subject: [PATCH 17/22] 2.3 patch release --- coderoad/test/packagejson.test.js | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index 498e7b2..cc880de 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -71,25 +71,11 @@ describe("package.json", () => { ) ); }); - // 2.2 - it('should use specific version of "moment"', () => { - assert.equal( - json.dependencies.moment, - "2.10.2", - '"moment" should use the specific version' - ); - }); - it('should have installed specific version of "moment"', async () => { + // 2.3 + it('should allow npm to update to any patch release of "moment"', () => { assert.ok( - await doesNotThrow( - () => - isModuleInstalled({ - name: "moment", - type: "dependency", - version: "2.10.2" - }), - '"moment" not installed' - ) + json.dependencies.moment.match(/^~/), + '"moment" should specify a patch release with "~"' ); }); }); From cc1f2a5b52d0e30400a5cc81033fe174d5864de2 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:13 -0700 Subject: [PATCH 18/22] 2.3 patch release solution --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c0a2560..b9fdd1b 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "express": "^4.17.0", - "moment": "2.10.2" + "moment": "~2.10.2" }, "author": "Your Name ", "description": "A description of the project", From fb75ecfa426304ee6ee241a8aefa0653b1c9f7e9 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:15 -0700 Subject: [PATCH 19/22] 2.4 minor release --- coderoad/test/packagejson.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index cc880de..8b1700f 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -71,11 +71,11 @@ describe("package.json", () => { ) ); }); - // 2.3 - it('should allow npm to update to any patch release of "moment"', () => { + // 2.4 + it('should allow npm to update to any minor release of "moment"', () => { assert.ok( - json.dependencies.moment.match(/^~/), - '"moment" should specify a patch release with "~"' + json.dependencies.moment.match(/^\^/), + '"moment" should specify a minor release with "^"' ); }); }); From d0e1a22eb6599ab862ee74376c2670228bc3bcc7 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:22 -0700 Subject: [PATCH 20/22] 2.4 minor release solution --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b9fdd1b..e57ca57 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "express": "^4.17.0", - "moment": "~2.10.2" + "moment": "^2.10.2" }, "author": "Your Name ", "description": "A description of the project", From da1e99e4d138ac4c4c59b0bf45064db1680a3cf8 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:24 -0700 Subject: [PATCH 21/22] 2.5 remove moment --- coderoad/test/packagejson.test.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/coderoad/test/packagejson.test.js b/coderoad/test/packagejson.test.js index 8b1700f..7833e88 100644 --- a/coderoad/test/packagejson.test.js +++ b/coderoad/test/packagejson.test.js @@ -63,19 +63,11 @@ describe("package.json", () => { 'should have a "dependencies" value that is an object' ); }); - it('should have installed "moment"', async () => { + // 2.5 + it('should remove the dependency "moment"', () => { assert.ok( - await doesNotThrow( - () => isModuleInstalled({ name: "moment", type: "dependency" }), - '"moment" not installed' - ) - ); - }); - // 2.4 - it('should allow npm to update to any minor release of "moment"', () => { - assert.ok( - json.dependencies.moment.match(/^\^/), - '"moment" should specify a minor release with "^"' + !json.dependencies.moment, + '"moment" should be removed as a dependency' ); }); }); From 796b17654bf634953181a85fad3f9d1b93ac9a31 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:32 -0700 Subject: [PATCH 22/22] 2.5 remove moment solution --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index e57ca57..0402598 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,7 @@ "start": "node server.js" }, "dependencies": { - "express": "^4.17.0", - "moment": "^2.10.2" + "express": "^4.17.0" }, "author": "Your Name ", "description": "A description of the project", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy