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 79f4f12935518405cad1c1ca1726c631ca6201fa Mon Sep 17 00:00:00 2001 From: shmck Date: Thu, 16 Apr 2020 21:07:06 -0700 Subject: [PATCH 03/22] L2S1Q 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 490dc3177e1b050c4ec651905dad0c476c0318ea Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 14:53:10 -0700 Subject: [PATCH 04/22] L2S1A 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 60ca8b62e36f359ec53511892ec58df7335ef716 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:09 -0700 Subject: [PATCH 05/22] L3S1Q 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 56d2ba948c96c4529765111c29e6d0b49f52bc7b Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:15 -0700 Subject: [PATCH 06/22] L3S1A 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 b7ec6abfe4575f06071d22ec441d4bb569d74685 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:00 -0700 Subject: [PATCH 07/22] L4S1Q 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 97868eb960439c68907e59c96879cb7cba8b3a05 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:07 -0700 Subject: [PATCH 08/22] L4S1A 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 b5fff886da2482b28250577806f011d2330dce75 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:48 -0700 Subject: [PATCH 09/22] L5S1Q 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 e4f474a975df4321f7211eb5d9177d627e91405b Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:53 -0700 Subject: [PATCH 10/22] L5S1A 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 62e21ad0d23e6c966e8c80b4d1d7af1951a56600 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:27:54 -0700 Subject: [PATCH 11/22] L6S1Q 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 37ee4feeeaa8e8095f51451a1389dd7d889eda33 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:28:03 -0700 Subject: [PATCH 12/22] L6S1A 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 9834b96ec3c6d3b75d9ddbd2c7fd43154980a1a7 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:24 -0700 Subject: [PATCH 13/22] L7S1Q 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 05ef5739993996627b3b4e9c832b34e00fd48a87 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:30 -0700 Subject: [PATCH 14/22] L7S1A 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 c7871dcfbd2399fabb7110a7bbb9c43669b03f65 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:14 -0700 Subject: [PATCH 15/22] L8S1Q 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 c3a572eae6cd7845cfab51ec2e26d8564a9f3283 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:21 -0700 Subject: [PATCH 16/22] L8S1A 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 0386333535d6ceb2c077adb819bf5ff45f226192 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:08 -0700 Subject: [PATCH 17/22] L9S1Q 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 71eaab1efcb460f1043b58d9b160970cf883bac3 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:13 -0700 Subject: [PATCH 18/22] L9S1A 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 b743d61f0aacf975eb2c84a3b9cf527eda5526c2 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:15 -0700 Subject: [PATCH 19/22] L10S1Q 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 d98a104cb9ca5436b1c8cde723a73b848e25c9c5 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:22 -0700 Subject: [PATCH 20/22] L10S1A 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 f92d9cedae1029edaab049ad967a3c96f2ae0181 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:24 -0700 Subject: [PATCH 21/22] L11S1Q 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 de659f9693615472b0594caf723d57272c3e3adc Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:32 -0700 Subject: [PATCH 22/22] L11S1A 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