From 1efa2e74255816a138ea9be998d49a6bdfbd082f Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 14:49:20 -0700 Subject: [PATCH 01/22] INIT - setup --- .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 a99811c863d561190f92b8aac455117407674880 Mon Sep 17 00:00:00 2001 From: shmck Date: Thu, 16 Apr 2020 21:06:34 -0700 Subject: [PATCH 02/22] INIT - setup test runner --- coderoad/package.json | 15 ++++++ coderoad/test/utils.js | 116 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 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..fcf63d7 --- /dev/null +++ b/coderoad/test/utils.js @@ -0,0 +1,116 @@ +const fs = require("fs"); +const path = require("path"); +const util = require("util"); +const { join } = require("path"); + +const readFile = util.promisify(fs.readFile); +const readdir = util.promisify(fs.readdir); + +const getPackageJson = async (dir = path.join(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 af2a97be3e4e0fda484913aa14df0d1a34c457a3 Mon Sep 17 00:00:00 2001 From: shmck Date: Thu, 16 Apr 2020 21:07:06 -0700 Subject: [PATCH 03/22] 2.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 46794cae9d036c50b673b47363e9429ae331eaf6 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 14:53:10 -0700 Subject: [PATCH 04/22] 2.1S 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 1d2f58330ee9773ac7f80df5a628675fbead1e60 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:09 -0700 Subject: [PATCH 05/22] 3.1 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 ee7a7af1c92693d239528832f2a69859371a147a Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:15 -0700 Subject: [PATCH 06/22] 3.1S 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 6b8e6ef82ad0cd0dbb0193787c14ed39fe039132 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:00 -0700 Subject: [PATCH 07/22] 4.1 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 b0d6dc4a4dd6b510fcd0b9d803e301049ee574d3 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:07 -0700 Subject: [PATCH 08/22] 4.1S 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 67346726fb199a390aa9f402ec3a0516fcfeff74 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:48 -0700 Subject: [PATCH 09/22] 5.1 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 060c0756282e4efc83435008dff06a5e4ef6943c Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:53 -0700 Subject: [PATCH 10/22] 5.1S 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 dc7f47dbbefb5f18cc5980418912d76096ee4907 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:27:54 -0700 Subject: [PATCH 11/22] 6.1 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 ad2cb8466d937eb7c03f99fc876b7ab08dd13067 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:28:03 -0700 Subject: [PATCH 12/22] 6.1S 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 c3a72a33bb7b207b22b2dff04c0e01c269990754 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:24 -0700 Subject: [PATCH 13/22] 7.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 506f466305b95777a1be518bf91c35831806f21c Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:30 -0700 Subject: [PATCH 14/22] 7.1S 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 d75d588947efe26c5a2fe5bfd809da9211f8f2d3 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:14 -0700 Subject: [PATCH 15/22] 8.1 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 c38b20b9c8c5f9d68efa433fc33b715a70060d74 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:21 -0700 Subject: [PATCH 16/22] 8.1S 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 b4f94faaf7ee23103dbdb935083bae86ccf03799 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:08 -0700 Subject: [PATCH 17/22] 9.1 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 35f54899b037b00fdd85f45b0d5d94089cf599f4 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:13 -0700 Subject: [PATCH 18/22] 9.1S 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 36951e66e83966359d20ece1a362b2bc91e4d722 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:15 -0700 Subject: [PATCH 19/22] 10.1 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 9578b3e8ef7f6c0f03d3e3b9b2b6bdc151e4e186 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:22 -0700 Subject: [PATCH 20/22] 10.1S 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 364e2417076bf8d6604084409404ab9ff7b6533f Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:24 -0700 Subject: [PATCH 21/22] 11.1 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 d3ee6474be0c501136dde32efed480c9f3d8fdbf Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:32 -0700 Subject: [PATCH 22/22] 11.1S 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