From 6bfa2e3f1d8e9e3dcb07ab7c6b8bc863f56e11b0 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 14:49:20 -0700 Subject: [PATCH 01/21] INIT - setup --- .gitignore | 3 ++ .vscode/extensions.json | 5 ++ .vscode/launch.json | 14 +++++ .vscode/settings.json | 6 +++ README.md | 1 + coderoad/package.json | 15 ++++++ coderoad/test/utils.js | 116 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 160 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 create mode 100644 coderoad/package.json create mode 100644 coderoad/test/utils.js 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 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 ae28b98a44066947fa2a3ecab26e62e0743ff016 Mon Sep 17 00:00:00 2001 From: shmck Date: Thu, 16 Apr 2020 21:07:06 -0700 Subject: [PATCH 02/21] 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 e2778eaea801474be3569e31941651b11da08601 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 14:53:10 -0700 Subject: [PATCH 03/21] 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 c2f35a0e0c1d88435e7cb87d61d2a23b011d231b Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:09 -0700 Subject: [PATCH 04/21] 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 dbbdf52595dcfe9d39343f0b8a2ebb6cc7254c1e Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:01:15 -0700 Subject: [PATCH 05/21] 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 9cfe1fec533df98eb9c6ed927eac8e0103ecdd50 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:00 -0700 Subject: [PATCH 06/21] 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 7212e9079d67470e0ea6f21906b308ee82ba483d Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:08:07 -0700 Subject: [PATCH 07/21] 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 9652bd6438d1f403fdef12580616ed99771b3a3b Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:48 -0700 Subject: [PATCH 08/21] 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 effa4b7d6e65428affaff4423832b39a4314b161 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:12:53 -0700 Subject: [PATCH 09/21] 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 dfbce6652999bf559aed44434cec24c80e494452 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:27:54 -0700 Subject: [PATCH 10/21] 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 784e624939e8e47283ae9e687d2fc4fb5fcfcd61 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 15:28:03 -0700 Subject: [PATCH 11/21] 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 327be97be42414034279727046ced58130ebbeee Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:24 -0700 Subject: [PATCH 12/21] 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 0eefcdbb090e62515c19b41d51998fe18bfcb7ac Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 18:41:30 -0700 Subject: [PATCH 13/21] 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 e25b5f37da2f052080f29bc0f1e6fb6b3ba43d93 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:14 -0700 Subject: [PATCH 14/21] 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 ec1e905af4139e524369974dadcbec6a08343fcd Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 19:11:21 -0700 Subject: [PATCH 15/21] 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 c7fecf0bce6abe2885b6d968486ad22417a6eded Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:08 -0700 Subject: [PATCH 16/21] 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 70b29effbc6a65e1cab618edd92879949160a1a0 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:02:13 -0700 Subject: [PATCH 17/21] 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 dc2689e47dcb0db5933ce8d599bbd292b08b9bda Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:15 -0700 Subject: [PATCH 18/21] 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 72b8fa6680bf55da451b92ccdda89974b6742617 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:03:22 -0700 Subject: [PATCH 19/21] 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 6b0d618d312d7db46a5c30062a7ea1730ee2992c Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:24 -0700 Subject: [PATCH 20/21] 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 41e46747dfb3977c21321d473b5f230e91240d4f Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 14 Mar 2020 20:21:32 -0700 Subject: [PATCH 21/21] 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