From 3ed5438db9b92bf92b7edf96c463464a4f3e127e Mon Sep 17 00:00:00 2001 From: sw-yx Date: Tue, 16 Apr 2019 19:19:19 -0400 Subject: [PATCH 1/2] make tests actually work --- .eslintignore | 1 + .eslintrc | 10 +- package-lock.json | 77 ++- package.json | 8 +- src/commands/dev/exec.js | 4 +- src/commands/dev/index.js | 29 +- src/commands/functions/build.js | 6 +- src/commands/functions/create.js | 38 +- src/commands/functions/index.js | 2 +- src/commands/functions/list.js | 4 +- src/commands/functions/serve.js | 27 - src/commands/functions/update.js | 28 - src/detect-server.js | 19 +- src/detectors/cra.js | 2 +- src/detectors/eleventy.js | 6 +- src/detectors/gatsby.js | 2 +- src/detectors/hexo.js | 2 +- src/detectors/next.js | 2 +- src/detectors/nuxt.js | 4 +- src/detectors/react-static.js | 2 +- src/detectors/utils/jsdetect.js | 2 + src/detectors/vue.js | 2 +- src/detectors/vuepress.js | 4 +- .../apollo-graphql-rest.js | 1 + .../js/auth-fetch/auth-fetch.js | 1 + .../js/fauna-crud/fauna-crud.js | 1 + .../js/node-fetch/node-fetch.js | 1 + src/live-tunnel.js | 7 +- src/utils/addons.js | 506 +++++++++--------- src/utils/dev.js | 19 +- src/utils/finders.js | 2 +- .../{readRepoURL.js => read-repo-url.js} | 10 +- .../{serveFunctions.js => serve-functions.js} | 42 +- test/commands/functions.test.js | 10 + 34 files changed, 451 insertions(+), 430 deletions(-) create mode 100644 .eslintignore delete mode 100644 src/commands/functions/serve.js delete mode 100644 src/commands/functions/update.js rename src/utils/{readRepoURL.js => read-repo-url.js} (89%) rename src/utils/{serveFunctions.js => serve-functions.js} (88%) create mode 100644 test/commands/functions.test.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..b375f6c --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +src/functions-templates \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 55c6bb3..7e65eae 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,14 @@ { "extends": ["oclif", "plugin:prettier/recommended"], "rules": { - "prettier/prettier": "error" + "no-warning-comments": "off", + "prettier/prettier": "error", + "no-process-exit": "off", + "unicorn/no-process-exit": "off", + "camelcase": "off", + "guard-for-in": "off", + "valid-jsdoc": "off", + "no-inner-declarations": "off", + "no-missing-require": "off" } } diff --git a/package-lock.json b/package-lock.json index 4eecf09..e77ce45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -193,6 +193,17 @@ "read-pkg-up": "^4.0.0", "require-package-name": "^2.0.1", "resolve": "^1.10.0" + }, + "dependencies": { + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + } } }, "@nodelib/fs.stat": { @@ -1734,6 +1745,12 @@ "type-detect": "^4.0.0" } }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -5243,6 +5260,17 @@ "read-pkg-up": "^4.0.0", "require-package-name": "^2.0.1", "resolve": "^1.10.0" + }, + "dependencies": { + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + } } } } @@ -5273,6 +5301,23 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "nock": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz", + "integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==", + "dev": true, + "requires": { + "chai": "^4.1.2", + "debug": "^4.1.0", + "deep-equal": "^1.0.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.5", + "mkdirp": "^0.5.0", + "propagate": "^1.0.0", + "qs": "^6.5.1", + "semver": "^5.5.0" + } + }, "node-fetch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", @@ -7000,6 +7045,12 @@ "through2": "~2.0.3" } }, + "propagate": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", + "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", + "dev": true + }, "proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -7132,11 +7183,6 @@ "strict-uri-encode": "^1.0.0" } }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, "ramda": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", @@ -7204,12 +7250,25 @@ } }, "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-5.0.0.tgz", + "integrity": "sha512-XBQjqOBtTzyol2CpsQOw8LHV0XbDZVG7xMMjmXAJomlVY03WOBRmYgDJETlvcg0H63AJvPRwT7GFi5rvOzUOKg==", + "dev": true, "requires": { "find-up": "^3.0.0", - "read-pkg": "^3.0.0" + "read-pkg": "^5.0.0" + }, + "dependencies": { + "read-pkg": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.0.0.tgz", + "integrity": "sha512-OWufaRc67oJjcgrxckW/qO9q22iYzyiONh8h+GMcnOvSHAmhV1Dr3x+gyRjP+Qxc5jKupkSfoCQLS/98rDPh9A==", + "dev": true, + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0" + } + } } }, "readable-stream": { diff --git a/package.json b/package.json index 9b606b5..eb3c679 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,11 @@ "chalk": "^2.4.2", "chokidar": "^2.1.5", "copy-template-dir": "^1.4.0", + "debug": "^4.1.1", + "npm-packlist": "^1.4.1", + "precinct": "^6.1.2", + "read-pkg-up": "^5.0.0", + "require-package-name": "^2.0.1", "execa": "^1.0.0", "express": "^4.16.4", "express-logging": "^1.1.1", @@ -30,7 +35,7 @@ "netlify-cli-logo": "^1.0.0", "node-fetch": "^2.3.0", "ora": "^3.4.0", - "querystring": "^0.2.0", + "resolve": "^1.10.0", "safe-join": "^0.1.2", "static-server": "^2.2.1", "wait-port": "^0.2.2", @@ -50,6 +55,7 @@ "gh-release": "^3.5.0", "globby": "^8", "mocha": "^5", + "nock": "^10.0.6", "npm-run-all": "^4.1.5", "nyc": "^13", "prettier": "^1.16.4" diff --git a/src/commands/dev/exec.js b/src/commands/dev/exec.js index 9c721c0..6b64bc7 100644 --- a/src/commands/dev/exec.js +++ b/src/commands/dev/exec.js @@ -2,9 +2,9 @@ const execa = require("execa"); const Command = require("@netlify/cli-utils"); const { track } = require("@netlify/cli-utils/src/utils/telemetry"); const { - NETLIFYDEV, + // NETLIFYDEV, NETLIFYDEVLOG, - NETLIFYDEVWARN, + // NETLIFYDEVWARN, NETLIFYDEVERR } = require("netlify-cli-logo"); diff --git a/src/commands/dev/index.js b/src/commands/dev/index.js index d5d1b2d..5d93791 100644 --- a/src/commands/dev/index.js +++ b/src/commands/dev/index.js @@ -5,18 +5,17 @@ const httpProxy = require("http-proxy"); const waitPort = require("wait-port"); const getPort = require("get-port"); const chokidar = require("chokidar"); -const { serveFunctions } = require("../../utils/serveFunctions"); +const { serveFunctions } = require("../../utils/serve-functions"); const { serverSettings } = require("../../detect-server"); const { detectFunctionsBuilder } = require("../../detect-functions-builder"); const Command = require("@netlify/cli-utils"); -const { getAddons } = require("netlify/src/addons"); const { track } = require("@netlify/cli-utils/src/utils/telemetry"); const chalk = require("chalk"); const { NETLIFYDEV, NETLIFYDEVLOG, - NETLIFYDEVWARN, - NETLIFYDEVERR + NETLIFYDEVWARN + // NETLIFYDEVERR } = require("netlify-cli-logo"); const boxen = require("boxen"); const { createTunnel, connectTunnel } = require("../../live-tunnel"); @@ -26,7 +25,7 @@ function isFunction(settings, req) { } function addonUrl(addonUrls, req) { - const m = req.url.match(/^\/.netlify\/([^\/]+)(\/.*)/); + const m = req.url.match(/^\/.netlify\/([^\/]+)(\/.*)/); // eslint-disable-line no-useless-escape const addonUrl = m && addonUrls[m[1]]; return addonUrl ? `${addonUrl}${m[2]}` : null; } @@ -67,7 +66,7 @@ function initializeProxy(port) { if ( proxyRes.statusCode === 404 && req.alternativePaths && - req.alternativePaths.length + req.alternativePaths.length > 0 ) { req.url = req.alternativePaths.shift(); return proxy.web(req, res, req.proxyOptions); @@ -137,7 +136,7 @@ async function startProxy(settings, addonUrls) { return `http://localhost:${port}`; } -function startDevServer(settings, log, error) { +function startDevServer(settings, log) { if (settings.noCmd) { const StaticServer = require("static-server"); @@ -195,7 +194,7 @@ class DevCommand extends Command { (config.dev && config.dev.publish) || (config.build && config.build.publish); if (!dist) { - console.log(`${NETLIFYDEVLOG} Using current working directory`); + this.log(`${NETLIFYDEVLOG} Using current working directory`); this.log( `${NETLIFYDEVWARN} Unable to determine public folder to serve files from.` ); @@ -220,7 +219,7 @@ class DevCommand extends Command { let url; - startDevServer(settings, this.log, this.error); + startDevServer(settings, this.log); // serve functions from zip-it-and-ship-it // env variables relies on `url`, careful moving this code @@ -234,7 +233,9 @@ class DevCommand extends Command { functionWatcher.on("unlink", functionBuilder.build); } const functionsPort = await getPort({ port: 34567 }); - const fnSettings = await serveFunctions({ + + // returns a value but we dont use it + await serveFunctions({ ...settings, port: functionsPort, functionsDir @@ -253,13 +254,7 @@ class DevCommand extends Command { url = liveSession.session_url; process.env.BASE_URL = url; - await connectTunnel( - liveSession, - accessToken, - settings.port, - this.log, - this.error - ); + await connectTunnel(liveSession, accessToken, settings.port, this.log); } // Todo hoist this telemetry `command` to CLI hook diff --git a/src/commands/functions/build.js b/src/commands/functions/build.js index 19f31b5..25557c4 100644 --- a/src/commands/functions/build.js +++ b/src/commands/functions/build.js @@ -3,15 +3,15 @@ const { flags } = require("@oclif/command"); const Command = require("@netlify/cli-utils"); const { zipFunctions } = require("@netlify/zip-it-and-ship-it"); const { - NETLIFYDEV, + // NETLIFYDEV, NETLIFYDEVLOG, - NETLIFYDEVWARN, + // NETLIFYDEVWARN, NETLIFYDEVERR } = require("netlify-cli-logo"); class FunctionsBuildCommand extends Command { async run() { - const { flags, args } = this.parse(FunctionsBuildCommand); + const { flags } = this.parse(FunctionsBuildCommand); const { config } = this.netlify; const src = flags.src || config.build.functionsSource; diff --git a/src/commands/functions/create.js b/src/commands/functions/create.js index 47ee74d..6055c16 100644 --- a/src/commands/functions/create.js +++ b/src/commands/functions/create.js @@ -4,18 +4,16 @@ const copy = require("copy-template-dir"); const { flags } = require("@oclif/command"); const Command = require("@netlify/cli-utils"); const inquirer = require("inquirer"); -const { readRepoURL, validateRepoURL } = require("../../utils/readRepoURL"); +const { readRepoURL, validateRepoURL } = require("../../utils/read-repo-url"); const { addEnvVariables } = require("../../utils/dev"); const { createSiteAddon } = require("../../utils/addons"); -const http = require("http"); const fetch = require("node-fetch"); const cp = require("child_process"); -const { createAddon } = require("netlify/src/addons"); const ora = require("ora"); const { track } = require("@netlify/cli-utils/src/utils/telemetry"); const chalk = require("chalk"); const { - NETLIFYDEV, + // NETLIFYDEV, NETLIFYDEVLOG, NETLIFYDEVWARN, NETLIFYDEVERR @@ -242,14 +240,14 @@ async function downloadFromURL(flags, args, functionsDir) { fs.lstatSync(fnFolder + ".js").isFile() ) { this.log( - `${NETLIFYWARN}: A single file version of the function ${name} already exists at ${fnFolder}.js. Terminating without further action.` + `${NETLIFYDEVWARN}: A single file version of the function ${nameToUse} already exists at ${fnFolder}.js. Terminating without further action.` ); process.exit(1); } try { fs.mkdirSync(fnFolder, { recursive: true }); - } catch (e) { + } catch (error) { // Ignore } await Promise.all( @@ -263,8 +261,10 @@ async function downloadFromURL(flags, args, functionsDir) { const dest = fs.createWriteStream(path.join(fnFolder, finalName)); res.body.pipe(dest); }) - .catch(err => { - throw new Error("Error while retrieving " + download_url); + .catch(error => { + throw new Error( + "Error while retrieving " + download_url + ` ${error}` + ); }); }) ); @@ -295,7 +295,7 @@ async function downloadFromURL(flags, args, functionsDir) { } async function installDeps(functionPath) { - return new Promise((resolve, reject) => { + return new Promise(resolve => { cp.exec("npm i", { cwd: path.join(functionPath) }, () => { resolve(); }); @@ -319,15 +319,13 @@ async function scaffoldFromTemplate(flags, args, functionsDir) { flags.url = chosenurl.trim(); try { await downloadFromURL.call(this, flags, args, functionsDir); - } catch (err) { - console.error( - `$${NETLIFYDEVERR} Error downloading from URL: ` + flags.url - ); - console.error(err); + } catch (error) { + this.error(`$${NETLIFYDEVERR} Error downloading from URL: ` + flags.url); + this.error(error); process.exit(1); } } else if (chosentemplate === "report") { - console.log( + this.log( `${NETLIFYDEVLOG} Open in browser: https://github.com/netlify/netlify-dev-plugin/issues/new` ); } else { @@ -401,7 +399,7 @@ async function scaffoldFromTemplate(flags, args, functionsDir) { } async function installAddons(addons = [], fnPath) { - if (addons.length) { + if (addons.length > 0) { const { api, site } = this.netlify; const siteId = site.id; if (!siteId) { @@ -410,12 +408,12 @@ async function installAddons(addons = [], fnPath) { ); return false; } - console.log(`${NETLIFYDEVLOG} checking Netlify APIs...`); + this.log(`${NETLIFYDEVLOG} checking Netlify APIs...`); return api.getSite({ siteId }).then(async siteData => { const accessToken = api.accessToken; const arr = addons.map(({ addonName, addonDidInstall }) => { - console.log( + this.log( `${NETLIFYDEVLOG} installing addon: ` + chalk.yellow.inverse(addonName) ); @@ -445,8 +443,8 @@ async function installAddons(addons = [], fnPath) { } } }) - .catch(err => { - console.error(`${NETLIFYDEVERR} Error installing addon: `, err); + .catch(error => { + this.error(`${NETLIFYDEVERR} Error installing addon: `, error); }); }); return Promise.all(arr); diff --git a/src/commands/functions/index.js b/src/commands/functions/index.js index f4f6bea..f96db0d 100644 --- a/src/commands/functions/index.js +++ b/src/commands/functions/index.js @@ -39,7 +39,7 @@ The ${name} command will help you manage the functions in this site `; FunctionsCommand.examples = [ "netlify functions:create --name function-xyz", - "netlify functions:update --name function-abc --timeout 30s" + "netlify functions:build --name function-abc --timeout 30s" ]; // TODO make visible once implementation complete diff --git a/src/commands/functions/list.js b/src/commands/functions/list.js index 353a19e..1f5c763 100644 --- a/src/commands/functions/list.js +++ b/src/commands/functions/list.js @@ -24,8 +24,8 @@ class FunctionsListCommand extends Command { "scheduled", "weyhfd-hjjk-67533" ); - - console.log(table.toString()); + this.log(`netlify functions:list NOT IMPLEMENTED YET`); + this.log(table.toString()); } } diff --git a/src/commands/functions/serve.js b/src/commands/functions/serve.js deleted file mode 100644 index 7efaaaf..0000000 --- a/src/commands/functions/serve.js +++ /dev/null @@ -1,27 +0,0 @@ -const { Command, flags } = require("@oclif/command"); -const { - NETLIFYDEV, - NETLIFYDEVLOG, - NETLIFYDEVWARN, - NETLIFYDEVERR -} = require("netlify-cli-logo"); - -class FunctionsServeCommand extends Command { - async run() { - this.log(`${NETLIFYDEVERR} NOT IMPLEMENTED YET: netlify functions:serve`); - } -} - -FunctionsServeCommand.description = `serve functions locally for dev -... -Extra documentation goes here -`; -FunctionsServeCommand.aliases = ["function:serve"]; -FunctionsServeCommand.flags = { - name: flags.string({ char: "n", description: "name to print" }) -}; - -// TODO make visible once implementation complete -FunctionsServeCommand.hidden = true; - -module.exports = FunctionsServeCommand; diff --git a/src/commands/functions/update.js b/src/commands/functions/update.js deleted file mode 100644 index b900f51..0000000 --- a/src/commands/functions/update.js +++ /dev/null @@ -1,28 +0,0 @@ -const { Command, flags } = require("@oclif/command"); -const chalk = require("chalk"); -const { - NETLIFYDEV, - NETLIFYDEVLOG, - NETLIFYDEVWARN, - NETLIFYDEVERR -} = require("netlify-cli-logo"); - -class FunctionsUpdateCommand extends Command { - async run() { - this.log(`${NETLIFYDEVERR} NOT IMPLEMENTED YET: update a function`); - } -} - -FunctionsUpdateCommand.description = `update a function -... -Extra documentation goes here -`; -FunctionsUpdateCommand.aliases = ["function:update"]; -FunctionsUpdateCommand.flags = { - name: flags.string({ char: "n", description: "name to print" }) -}; - -// TODO make visible once implementation complete -FunctionsUpdateCommand.hidden = true; - -module.exports = FunctionsUpdateCommand; diff --git a/src/detect-server.js b/src/detect-server.js index 90d3ca9..3c85317 100644 --- a/src/detect-server.js +++ b/src/detect-server.js @@ -1,10 +1,10 @@ const path = require("path"); const chalk = require("chalk"); const { - NETLIFYDEV, - NETLIFYDEVLOG, - NETLIFYDEVWARN, - NETLIFYDEVERR + // NETLIFYDEV, + NETLIFYDEVLOG + // NETLIFYDEVWARN, + // NETLIFYDEVERR } = require("netlify-cli-logo"); const inquirer = require("inquirer"); const fs = require("fs"); @@ -14,8 +14,8 @@ const detectors = fs .map(det => require(path.join(__dirname, `detectors/${det}`))); module.exports.serverSettings = async devConfig => { - let settingsArr = [], - settings = null; + let settingsArr = []; + let settings = null; for (const i in detectors) { const detectorResult = detectors[i](); if (detectorResult) settingsArr.push(detectorResult); @@ -28,10 +28,12 @@ module.exports.serverSettings = async devConfig => { const { scripts } = JSON.parse( fs.readFileSync("package.json", { encoding: "utf8" }) ); + // eslint-disable-next-line no-console console.error( "empty args assigned, this is an internal Netlify Dev bug, please report your settings and scripts so we can improve", { scripts, settings } ); + // eslint-disable-next-line no-process-exit process.exit(1); } } else if (settingsArr.length > 1) { @@ -92,6 +94,7 @@ module.exports.serverSettings = async devConfig => { /** everything below assumes we have settled on one detector */ const tellUser = settingsField => dV => + // eslint-disable-next-line no-console console.log( `${NETLIFYDEVLOG} Overriding ${chalk.yellow( settingsField @@ -137,13 +140,13 @@ module.exports.serverSettings = async devConfig => { function assignLoudly( optionalValue, defaultValue, + // eslint-disable-next-line no-console tellUser = dV => console.log(`No value specified, using fallback of `, dV) ) { if (defaultValue === undefined) throw new Error("must have a defaultValue"); if (defaultValue !== optionalValue && optionalValue === undefined) { tellUser(defaultValue); return defaultValue; - } else { - return optionalValue; } + return optionalValue; } diff --git a/src/detectors/cra.js b/src/detectors/cra.js index c3d8eda..61d4dc5 100644 --- a/src/detectors/cra.js +++ b/src/detectors/cra.js @@ -21,7 +21,7 @@ module.exports = function() { preferredCommand: "react-scripts start" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["react-scripts", "start"]); } diff --git a/src/detectors/eleventy.js b/src/detectors/eleventy.js index a45ccf4..045d709 100644 --- a/src/detectors/eleventy.js +++ b/src/detectors/eleventy.js @@ -1,7 +1,7 @@ const { - hasRequiredDeps, - hasRequiredFiles, - scanScripts + // hasRequiredDeps, + hasRequiredFiles + // scanScripts } = require("./utils/jsdetect"); module.exports = function() { diff --git a/src/detectors/gatsby.js b/src/detectors/gatsby.js index ce29beb..8caff8c 100644 --- a/src/detectors/gatsby.js +++ b/src/detectors/gatsby.js @@ -17,7 +17,7 @@ module.exports = function() { preferredCommand: "gatsby develop" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["gatsby", "develop"]); } diff --git a/src/detectors/hexo.js b/src/detectors/hexo.js index 1fdd5e8..a269a5c 100644 --- a/src/detectors/hexo.js +++ b/src/detectors/hexo.js @@ -17,7 +17,7 @@ module.exports = function() { preferredCommand: "hexo server" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["hexo", "server"]); } diff --git a/src/detectors/next.js b/src/detectors/next.js index e014d04..67fbace 100644 --- a/src/detectors/next.js +++ b/src/detectors/next.js @@ -17,7 +17,7 @@ module.exports = function() { preferredCommand: "next" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["next"]); } diff --git a/src/detectors/nuxt.js b/src/detectors/nuxt.js index 2336e89..f810472 100644 --- a/src/detectors/nuxt.js +++ b/src/detectors/nuxt.js @@ -18,7 +18,7 @@ module.exports = function() { preferredCommand: "nuxt start" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["nuxt", "start"]); } @@ -33,4 +33,4 @@ module.exports = function() { urlRegexp: new RegExp(`(http://)([^:]+:)${3000}(/)?`, "g"), dist: ".nuxt" }; -}; \ No newline at end of file +}; diff --git a/src/detectors/react-static.js b/src/detectors/react-static.js index da2884f..08dfeb6 100644 --- a/src/detectors/react-static.js +++ b/src/detectors/react-static.js @@ -17,7 +17,7 @@ module.exports = function() { preferredCommand: "react-static start" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["react-static", "start"]); } diff --git a/src/detectors/utils/jsdetect.js b/src/detectors/utils/jsdetect.js index 8dd69ac..3cd2f82 100644 --- a/src/detectors/utils/jsdetect.js +++ b/src/detectors/utils/jsdetect.js @@ -58,9 +58,11 @@ function scanScripts({ preferredScriptsArr, preferredCommand }) { const { scripts } = getPkgJSON(); if (!scripts && !warnedAboutEmptyScript) { + // eslint-disable-next-line no-console console.log( `${NETLIFYDEVWARN} You have a package.json without any npm scripts.` ); + // eslint-disable-next-line no-console console.log( `${NETLIFYDEVWARN} Netlify Dev's detector system works best with a script, or you can specify a command to run in the netlify.toml [dev] block ` ); diff --git a/src/detectors/vue.js b/src/detectors/vue.js index 4fa6ac5..c69bdb3 100644 --- a/src/detectors/vue.js +++ b/src/detectors/vue.js @@ -18,7 +18,7 @@ module.exports = function() { preferredCommand: "vue-cli-service serve" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["vue-cli-service", "serve"]); } diff --git a/src/detectors/vuepress.js b/src/detectors/vuepress.js index e2b19cf..ef20cf5 100644 --- a/src/detectors/vuepress.js +++ b/src/detectors/vuepress.js @@ -18,7 +18,7 @@ module.exports = function() { preferredCommand: "vuepress dev" }); - if (!possibleArgsArrs.length) { + if (possibleArgsArrs.length === 0) { // ofer to run it when the user doesnt have any scripts setup! 🤯 possibleArgsArrs.push(["vuepress", "dev"]); } @@ -33,4 +33,4 @@ module.exports = function() { urlRegexp: new RegExp(`(http://)([^:]+:)${8080}(/)?`, "g"), dist: ".vuepress/dist" }; -}; \ No newline at end of file +}; diff --git a/src/functions-templates/js/apollo-graphql-rest/apollo-graphql-rest.js b/src/functions-templates/js/apollo-graphql-rest/apollo-graphql-rest.js index dd0b7c3..7c12b2f 100644 --- a/src/functions-templates/js/apollo-graphql-rest/apollo-graphql-rest.js +++ b/src/functions-templates/js/apollo-graphql-rest/apollo-graphql-rest.js @@ -1,3 +1,4 @@ +/* eslint-disable */ const { ApolloServer, gql } = require("apollo-server-lambda"); const RandomUser = require("./random-user.js"); // example from: https://medium.com/yld-engineering-blog/easier-graphql-wrappers-for-your-rest-apis-1410b0b5446d diff --git a/src/functions-templates/js/auth-fetch/auth-fetch.js b/src/functions-templates/js/auth-fetch/auth-fetch.js index 8f3ab69..77f2061 100644 --- a/src/functions-templates/js/auth-fetch/auth-fetch.js +++ b/src/functions-templates/js/auth-fetch/auth-fetch.js @@ -1,3 +1,4 @@ +/* eslint-disable */ // for a full working demo of Netlify Identity + Functions, see https://netlify-gotrue-in-react.netlify.com/ const fetch = require("node-fetch"); diff --git a/src/functions-templates/js/fauna-crud/fauna-crud.js b/src/functions-templates/js/fauna-crud/fauna-crud.js index 164809c..3d54dbc 100644 --- a/src/functions-templates/js/fauna-crud/fauna-crud.js +++ b/src/functions-templates/js/fauna-crud/fauna-crud.js @@ -1,3 +1,4 @@ +/* eslint-disable */ exports.handler = async (event, context) => { const path = event.path.replace(/\.netlify\/functions\/[^\/]+/, ""); const segments = path.split("/").filter(e => e); diff --git a/src/functions-templates/js/node-fetch/node-fetch.js b/src/functions-templates/js/node-fetch/node-fetch.js index 608e1d3..4693b00 100644 --- a/src/functions-templates/js/node-fetch/node-fetch.js +++ b/src/functions-templates/js/node-fetch/node-fetch.js @@ -1,3 +1,4 @@ +/* eslint-disable */ const fetch = require("node-fetch"); exports.handler = async function(event, context) { try { diff --git a/src/live-tunnel.js b/src/live-tunnel.js index c850d49..842b1eb 100644 --- a/src/live-tunnel.js +++ b/src/live-tunnel.js @@ -7,7 +7,7 @@ const chalk = require("chalk"); const { fetchLatest, updateAvailable } = require("gh-release-fetch"); const { NETLIFYDEVLOG, - NETLIFYDEVWARN, + // NETLIFYDEVWARN, NETLIFYDEVERR } = require("netlify-cli-logo"); @@ -15,6 +15,7 @@ async function createTunnel(siteId, netlifyApiToken, log) { await installTunnelClient(log); if (!siteId) { + // eslint-disable-next-line no-console console.error( `${NETLIFYDEVERR} Error: no siteId defined, did you forget to run ${chalk.yellow( "netlify init" @@ -43,7 +44,7 @@ async function createTunnel(siteId, netlifyApiToken, log) { return data; } -async function connectTunnel(session, netlifyApiToken, localPort, log, error) { +async function connectTunnel(session, netlifyApiToken, localPort, log) { const execPath = path.join( os.homedir(), ".netlify", @@ -84,7 +85,7 @@ async function installTunnelClient(log) { const win = isWindows(); const platform = win ? "windows" : process.platform; const extension = win ? "zip" : "tar.gz"; - release = { + const release = { repository: "netlify/live-tunnel-client", package: `live-tunnel-client-${platform}-amd64.${extension}`, destination: binPath, diff --git a/src/utils/addons.js b/src/utils/addons.js index 09d8de1..0e8199d 100644 --- a/src/utils/addons.js +++ b/src/utils/addons.js @@ -1,12 +1,12 @@ +/* eslint no-console: 0 */ const { getAddons, createAddon } = require("netlify/src/addons"); -const chalk = require("chalk"); -const inquirer = require("inquirer"); - -const fetch = require("node-fetch"); +// const chalk = require("chalk"); +// const fetch = require("node-fetch"); /** main section - shamelessly adapted from CLI. we can extract and dedupe later. */ /** but we can DRY things up later. */ -module.exports.createSiteAddon = async function createSiteAddon( +// eslint-disable-next-line max-params +module.exports.createSiteAddon = async function( accessToken, addonName, siteId, @@ -36,80 +36,80 @@ module.exports.createSiteAddon = async function createSiteAddon( return false; } - const manifest = await getAddonManifest(addonName, accessToken); + // const manifest = await getAddonManifest(addonName, accessToken); let configValues = rawFlags; - if (manifest.config) { - const required = requiredConfigValues(manifest.config); - const missingValues = missingConfigValues(required, rawFlags); - console.log(`Starting the setup for "${addonName} add-on"`); - console.log(); - - // if (Object.keys(rawFlags).length) { - // const newConfig = updateConfigValues(manifest.config, {}, rawFlags) - - // if (missingValues.length) { - // /* Warn user of missing required values */ - // console.log( - // `${chalk.redBright.underline.bold(`Error: Missing required configuration for "${addonName} add-on"`)}` - // ) - // console.log() - // render.missingValues(missingValues, manifest) - // console.log() - // const msg = `netlify addons:create ${addonName}` - // console.log(`Please supply the configuration values as CLI flags`) - // console.log() - // console.log(`Alternatively, you can run ${chalk.cyan(msg)} with no flags to walk through the setup steps`) - // console.log() - // return false - // } - - // await createSiteAddon({ - // addonName, - // settings: { - // siteId: siteId, - // addon: addonName, - // config: newConfig - // }, - // accessToken, - // siteData - // }) - // return false - // } - - const words = `The ${addonName} add-on has the following configurable options:`; - console.log(` ${chalk.yellowBright.bold(words)}`); - render.configValues(addonName, manifest.config); - console.log(); - console.log(` ${chalk.greenBright.bold("Lets configure those!")}`); - - console.log(); - console.log( - ` - Hit ${chalk.white.bold("enter")} to confirm value or set empty value` - ); - console.log( - ` - Hit ${chalk.white.bold("ctrl + C")} to cancel & exit configuration` - ); - console.log(); - - const prompts = generatePrompts({ - config: manifest.config, - configValues: rawFlags - }); - - const userInput = await inquirer.prompt(prompts); - // Merge user input with the flags specified - configValues = updateConfigValues(manifest.config, rawFlags, userInput); - const missingRequiredValues = missingConfigValues(required, configValues); - if (missingRequiredValues && missingRequiredValues.length) { - missingRequiredValues.forEach(val => { - console.log( - `Missing required value "${val}". Please run the command again` - ); - }); - return false; - } - } + // if (manifest.config) { + // const required = requiredConfigValues(manifest.config); + // console.log(`Starting the setup for "${addonName} add-on"`); + // console.log(); + + // // const missingValues = missingConfigValues(required, rawFlags); + // // if (Object.keys(rawFlags).length) { + // // const newConfig = updateConfigValues(manifest.config, {}, rawFlags) + + // // if (missingValues.length) { + // // /* Warn user of missing required values */ + // // console.log( + // // `${chalk.redBright.underline.bold(`Error: Missing required configuration for "${addonName} add-on"`)}` + // // ) + // // console.log() + // // render.missingValues(missingValues, manifest) + // // console.log() + // // const msg = `netlify addons:create ${addonName}` + // // console.log(`Please supply the configuration values as CLI flags`) + // // console.log() + // // console.log(`Alternatively, you can run ${chalk.cyan(msg)} with no flags to walk through the setup steps`) + // // console.log() + // // return false + // // } + + // // await createSiteAddon({ + // // addonName, + // // settings: { + // // siteId: siteId, + // // addon: addonName, + // // config: newConfig + // // }, + // // accessToken, + // // siteData + // // }) + // // return false + // // } + + // const words = `The ${addonName} add-on has the following configurable options:`; + // console.log(` ${chalk.yellowBright.bold(words)}`); + // render.configValues(addonName, manifest.config); + // console.log(); + // console.log(` ${chalk.greenBright.bold("Lets configure those!")}`); + + // console.log(); + // console.log( + // ` - Hit ${chalk.white.bold("enter")} to confirm value or set empty value` + // ); + // console.log( + // ` - Hit ${chalk.white.bold("ctrl + C")} to cancel & exit configuration` + // ); + // console.log(); + + // const prompts = generatePrompts({ + // config: manifest.config, + // configValues: rawFlags + // }); + + // const userInput = await inquirer.prompt(prompts); + // // Merge user input with the flags specified + // configValues = updateConfigValues(manifest.config, rawFlags, userInput); + // const missingRequiredValues = missingConfigValues(required, configValues); + // if (missingRequiredValues && missingRequiredValues.length) { + // missingRequiredValues.forEach(val => { + // console.log( + // `Missing required value "${val}". Please run the command again` + // ); + // }); + // return false; + // } + // } await actuallyCreateSiteAddon({ addonName, @@ -148,188 +148,180 @@ async function actuallyCreateSiteAddon({ /** all the utils used in the main section */ -async function getAddonManifest(addonName, netlifyApiToken) { - const url = `https://api.netlify.com/api/v1/services/${addonName}/manifest`; - const response = await fetch(url, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${netlifyApiToken}` - } - }); - - const data = await response.json(); - - if (response.status === 422) { - throw new Error(`Error ${JSON.stringify(data)}`); - } - - return data; -} - -function requiredConfigValues(config) { - return Object.keys(config).filter(key => { - return config[key].required; - }); -} - -function missingConfigValues(requiredConfig, providedConfig) { - return requiredConfig.filter(key => { - return !providedConfig[key]; - }); -} - -function missingConfigValues(allowedConfig, currentConfig, newConfig) { - return Object.keys(allowedConfig).reduce((acc, key) => { - if (newConfig[key]) { - acc[key] = newConfig[key]; - return acc; - } - acc[key] = currentConfig[key]; - return acc; - }, {}); -} +// async function getAddonManifest(addonName, netlifyApiToken) { +// const url = `https://api.netlify.com/api/v1/services/${addonName}/manifest`; +// const response = await fetch(url, { +// method: "GET", +// headers: { +// "Content-Type": "application/json", +// Authorization: `Bearer ${netlifyApiToken}` +// } +// }); + +// const data = await response.json(); + +// if (response.status === 422) { +// throw new Error(`Error ${JSON.stringify(data)}`); +// } + +// return data; +// } + +// function requiredConfigValues(config) { +// return Object.keys(config).filter(key => { +// return config[key].required; +// }); +// } + +// function missingConfigValues(requiredConfig, providedConfig) { +// return requiredConfig.filter(key => { +// return !providedConfig[key]; +// }); +// } + +// function missingConfigValues(allowedConfig, currentConfig, newConfig) { +// return Object.keys(allowedConfig).reduce((acc, key) => { +// if (newConfig[key]) { +// acc[key] = newConfig[key]; +// return acc; +// } +// acc[key] = currentConfig[key]; +// return acc; +// }, {}); +// } // const chalk = require('chalk') -/* programmatically generate CLI prompts */ -function generatePrompts(settings) { - const { config, configValues } = settings; - const configItems = Object.keys(config); - - const prompts = configItems - .map((key, i) => { - const setting = config[key]; - // const { type, displayName } = setting - let prompt; - // Tell user to use types - if (!setting.type) { - console.log( - `⚠️ ${chalk.yellowBright( - `Warning: no \`type\` is set for config key: ${configItems[i]}` - )}` - ); - console.log( - `It's highly recommended that you type your configuration values. It will help with automatic documentation, sharing of your services, and make your services configurable through a GUI` - ); - console.log(""); - } - - // Handle shorthand config. Probably will be removed. Severly limited + not great UX - if (typeof setting === "string" || typeof setting === "boolean") { - if (typeof setting === "string") { - prompt = { - type: "input", - name: key, - message: `Enter string value for '${key}':` - }; - // if current stage value set show as default - if (configValues[key]) { - prompt.default = configValues[key]; - } - } else if (typeof setting === "boolean") { - prompt = { - type: "confirm", - name: key, - message: `Do you want '${key}':` - }; - } - return prompt; - } - - // For future use. Once UX is decided - // const defaultValidation = (setting.required) ? validateRequired : noValidate - const defaultValidation = noValidate; - const validateFunction = setting.pattern - ? validate(setting.pattern) - : defaultValidation; - const isRequiredText = setting.required - ? ` (${chalk.yellow("required")})` - : ""; - if (setting.type === "string" || setting.type.match(/string/)) { - prompt = { - type: "input", - name: key, - message: - `${chalk.white(key)}${isRequiredText} - ${setting.displayName}` || - `Please enter value for ${key}`, - validate: validateFunction - }; - // if value previously set show it - if (configValues[key]) { - prompt.default = configValues[key]; - // else show default value if provided - } else if (setting.default) { - prompt.default = setting.default; - } - return prompt; - } - }) - .filter(item => { - return typeof item !== "undefined"; - }); - return prompts; -} - -function noValidate() { - return true; -} - -// Will use this soon -function validateRequired(value) { - // eslint-disable-line - if (value) { - return true; - } - return `Please enter a value this field is required`; -} - -function validate(pattern) { - return function(value) { - const regex = new RegExp(pattern); - if (value.match(regex)) { - return true; - } - return `Please enter a value matching regex pattern: /${chalk.yellowBright( - pattern - )}/`; - }; -} +// /* programmatically generate CLI prompts */ +// function generatePrompts(settings) { +// const { config, configValues } = settings; +// const configItems = Object.keys(config); + +// const prompts = configItems +// .map((key, i) => { +// const setting = config[key]; +// // const { type, displayName } = setting +// let prompt; +// // Tell user to use types +// if (!setting.type) { +// console.log( +// `⚠️ ${chalk.yellowBright( +// `Warning: no \`type\` is set for config key: ${configItems[i]}` +// )}` +// ); +// console.log( +// `It's highly recommended that you type your configuration values. It will help with automatic documentation, sharing of your services, and make your services configurable through a GUI` +// ); +// console.log(""); +// } + +// // Handle shorthand config. Probably will be removed. Severly limited + not great UX +// if (typeof setting === "string" || typeof setting === "boolean") { +// if (typeof setting === "string") { +// prompt = { +// type: "input", +// name: key, +// message: `Enter string value for '${key}':` +// }; +// // if current stage value set show as default +// if (configValues[key]) { +// prompt.default = configValues[key]; +// } +// } else if (typeof setting === "boolean") { +// prompt = { +// type: "confirm", +// name: key, +// message: `Do you want '${key}':` +// }; +// } +// return prompt; +// } + +// // For future use. Once UX is decided +// // const defaultValidation = (setting.required) ? validateRequired : noValidate +// const defaultValidation = noValidate; +// const validateFunction = setting.pattern +// ? validate(setting.pattern) +// : defaultValidation; +// const isRequiredText = setting.required +// ? ` (${chalk.yellow("required")})` +// : ""; +// if (setting.type === "string" || setting.type.match(/string/)) { +// prompt = { +// type: "input", +// name: key, +// message: +// `${chalk.white(key)}${isRequiredText} - ${setting.displayName}` || +// `Please enter value for ${key}`, +// validate: validateFunction +// }; +// // if value previously set show it +// if (configValues[key]) { +// prompt.default = configValues[key]; +// // else show default value if provided +// } else if (setting.default) { +// prompt.default = setting.default; +// } +// return prompt; +// } +// return undefined; +// }) +// .filter(item => { +// return typeof item !== "undefined"; +// }); +// return prompts; +// } + +// function noValidate() { +// return true; +// } + +// function validate(pattern) { +// return function(value) { +// const regex = new RegExp(pattern); +// if (value.match(regex)) { +// return true; +// } +// return `Please enter a value matching regex pattern: /${chalk.yellowBright( +// pattern +// )}/`; +// }; +// } // const chalk = require('chalk') -const AsciiTable = require("ascii-table"); - -function missingValues(values, manifest) { - const display = values - .map(item => { - const itemDisplay = chalk.redBright.bold(`${item}`); - const niceNameDisplay = manifest.config[item].displayName; - return ` - ${itemDisplay} ${niceNameDisplay}`; - }) - .join("\n"); - console.log(display); -} - -function configValues(addonName, configValues, currentValue) { - const table = new AsciiTable(`${addonName} add-on settings`); - - const tableHeader = currentValue - ? ["Setting Name", "Current Value", "Description"] - : ["Setting Name", "Description", "Type", "Required"]; - - table.setHeading(...tableHeader); - - Object.keys(configValues).map(key => { - const { type, displayName, required } = configValues[key]; - let requiredText = required ? `true` : `false`; - const typeInfo = type || ""; - const description = displayName || ""; - if (currentValue) { - const value = currentValue[key] || "Not supplied"; - table.addRow(key, value, description); - } else { - table.addRow(key, description, typeInfo, requiredText); - } - }); - console.log(table.toString()); -} +// const AsciiTable = require("ascii-table"); + +// function missingValues(values, manifest) { +// const display = values +// .map(item => { +// const itemDisplay = chalk.redBright.bold(`${item}`); +// const niceNameDisplay = manifest.config[item].displayName; +// return ` - ${itemDisplay} ${niceNameDisplay}`; +// }) +// .join("\n"); +// console.log(display); +// } + +// function configValues(addonName, configValues, currentValue) { +// const table = new AsciiTable(`${addonName} add-on settings`); + +// const tableHeader = currentValue +// ? ["Setting Name", "Current Value", "Description"] +// : ["Setting Name", "Description", "Type", "Required"]; + +// table.setHeading(...tableHeader); + +// Object.keys(configValues).map(key => { +// const { type, displayName, required } = configValues[key]; +// let requiredText = required ? `true` : `false`; +// const typeInfo = type || ""; +// const description = displayName || ""; +// if (currentValue) { +// const value = currentValue[key] || "Not supplied"; +// table.addRow(key, value, description); +// } else { +// table.addRow(key, description, typeInfo, requiredText); +// } +// }); +// console.log(table.toString()); +// } diff --git a/src/utils/dev.js b/src/utils/dev.js index 2657a2c..eee38db 100644 --- a/src/utils/dev.js +++ b/src/utils/dev.js @@ -1,10 +1,12 @@ +/* eslint no-console: 0 */ + // reusable code for netlify dev // bit of a hasty abstraction but recommended by oclif const { getAddons } = require("netlify/src/addons"); const chalk = require("chalk"); const { NETLIFYDEVLOG, - NETLIFYDEVWARN, + // NETLIFYDEVWARN, NETLIFYDEVERR } = require("netlify-cli-logo"); /** @@ -24,9 +26,9 @@ const { async function addEnvVariables(api, site, accessToken) { /** from addons */ const addonUrls = {}; - const addons = await getAddons(site.id, accessToken).catch(err => { - console.error(err); - switch (err.status) { + const addons = await getAddons(site.id, accessToken).catch(error => { + console.error(error); + switch (error.status) { default: console.error( `${NETLIFYDEVERR} Error retrieving addons data for site ${chalk.yellow( @@ -51,9 +53,9 @@ async function addEnvVariables(api, site, accessToken) { } /** from web UI */ - const apiSite = await api.getSite({ site_id: site.id }).catch(err => { - console.error(err); - switch (err.status) { + const apiSite = await api.getSite({ site_id: site.id }).catch(error => { + console.error(error); + switch (error.status) { case 401: console.error( `${NETLIFYDEVERR} Unauthorized error: This Site ID ${chalk.yellow( @@ -111,7 +113,6 @@ function assignLoudly( if (defaultValue !== optionalValue && optionalValue === undefined) { tellUser(defaultValue); return defaultValue; - } else { - return optionalValue; } + return optionalValue; } diff --git a/src/utils/finders.js b/src/utils/finders.js index 8670f80..56d86e9 100644 --- a/src/utils/finders.js +++ b/src/utils/finders.js @@ -156,7 +156,7 @@ Please ensure "${moduleName}" is installed in the project.`); }); debug("Sizes per extension: ", sizes); - return Array.from(filePaths); + return [...filePaths]; } function findModuleDir(dir) { diff --git a/src/utils/readRepoURL.js b/src/utils/read-repo-url.js similarity index 89% rename from src/utils/readRepoURL.js rename to src/utils/read-repo-url.js index 38cf924..09d6f4e 100644 --- a/src/utils/readRepoURL.js +++ b/src/utils/read-repo-url.js @@ -37,12 +37,11 @@ async function getRepoURLContents(repoHost, owner_and_repo, contents_path) { ); return fetch(APIURL) .then(x => x.json()) - .catch(err => - console.error("Error occurred while fetching ", APIURL, err) + .catch( + error => console.error("Error occurred while fetching ", APIURL, error) // eslint-disable-line no-console ); - } else { - throw new Error("unsupported host ", repoHost); } + throw new Error("unsupported host ", repoHost); } function validateRepoURL(_url) { @@ -57,9 +56,8 @@ function parseRepoURL(repoHost, URL) { // https://developer.github.com/v3/repos/contents/#get-contents const [owner_and_repo, contents_path] = URL.path.split("/tree/master"); // what if it's not master? note that our contents retrieval may assume it is master return [owner_and_repo, contents_path]; - } else { - throw new Error("unsupported host ", repoHost); } + throw new Error("unsupported host ", repoHost); } module.exports = { diff --git a/src/utils/serveFunctions.js b/src/utils/serve-functions.js similarity index 88% rename from src/utils/serveFunctions.js rename to src/utils/serve-functions.js index 9f41a4d..775a447 100644 --- a/src/utils/serveFunctions.js +++ b/src/utils/serve-functions.js @@ -6,10 +6,10 @@ const queryString = require("querystring"); const path = require("path"); const getPort = require("get-port"); const chokidar = require("chokidar"); -const chalk = require("chalk"); +// const chalk = require("chalk"); const { NETLIFYDEVLOG, - NETLIFYDEVWARN, + // NETLIFYDEVWARN, NETLIFYDEVERR } = require("netlify-cli-logo"); @@ -23,17 +23,17 @@ function handleErr(err, response) { `${NETLIFYDEVERR} Function invocation failed: ` + err.toString() ); response.end(); - console.log(`${NETLIFYDEVERR} Error during invocation: `, err); - return; + console.log(`${NETLIFYDEVERR} Error during invocation: `, err); // eslint-disable-line no-console } function createCallback(response) { - return function callback(err, lambdaResponse) { + return function(err, lambdaResponse) { if (err) { return handleErr(err, response); } response.statusCode = lambdaResponse.statusCode; + // eslint-disable-line guard-for-in for (const key in lambdaResponse.headers) { response.setHeader(key, lambdaResponse.headers[key]); } @@ -61,15 +61,15 @@ function promiseCallback(promise, callback) { ); } -function getHandlerPath(functionPath) { - if (functionPath.match(/\.js$/)) { - return functionPath; - } +// function getHandlerPath(functionPath) { +// if (functionPath.match(/\.js$/)) { +// return functionPath; +// } - return path.join(functionPath, `${path.basename(functionPath)}.js`); -} +// return path.join(functionPath, `${path.basename(functionPath)}.js`); +// } -function createHandler(dir, options) { +function createHandler(dir) { const functions = {}; fs.readdirSync(dir).forEach(file => { if (dir === "node_modules") { @@ -132,9 +132,9 @@ function createHandler(dir, options) { module.paths = [moduleDir]; handler = require(functionPath); module.paths = before; - } catch (err) { + } catch (error) { module.paths = before; - handleErr(err, response); + handleErr(error, response); return; } @@ -160,8 +160,7 @@ function createHandler(dir, options) { }; } -async function serveFunctions(settings, options) { - options = options || {}; +async function serveFunctions(settings) { const app = express(); const dir = settings.functionsDir; const port = await getPort({ @@ -179,16 +178,16 @@ async function serveFunctions(settings, options) { app.get("/favicon.ico", function(req, res) { res.status(204).end(); }); - app.all("*", createHandler(dir, options)); + app.all("*", createHandler(dir)); app.listen(port, function(err) { if (err) { - console.error(`${NETLIFYDEVERR} Unable to start lambda server: `, err); + console.error(`${NETLIFYDEVERR} Unable to start lambda server: `, err); // eslint-disable-line no-console process.exit(1); } // add newline because this often appears alongside the client devserver's output - console.log(`\n${NETLIFYDEVLOG} Lambda server is listening on ${port}`); + console.log(`\n${NETLIFYDEVLOG} Lambda server is listening on ${port}`); // eslint-disable-line no-console }); return Promise.resolve({ @@ -203,13 +202,12 @@ function assignLoudly( optionalValue, fallbackValue, tellUser = dV => - console.log(`${NETLIFYDEVLOG} No port specified, using defaultPort of `, dV) + console.log(`${NETLIFYDEVLOG} No port specified, using defaultPort of `, dV) // eslint-disable-line no-console ) { if (fallbackValue === undefined) throw new Error("must have a fallbackValue"); if (fallbackValue !== optionalValue && optionalValue === undefined) { tellUser(fallbackValue); return fallbackValue; - } else { - return optionalValue; } + return optionalValue; } diff --git a/test/commands/functions.test.js b/test/commands/functions.test.js new file mode 100644 index 0000000..22b2097 --- /dev/null +++ b/test/commands/functions.test.js @@ -0,0 +1,10 @@ +const { expect, test } = require("@oclif/test"); +// const nock = require("nock"); + +describe("auth:whoami", () => { + test + .command(["functions:list"]) + .it("shows user email when logged in", ctx => { + expect(ctx.stdout).to.equal("jeff@example.com\n"); + }); +}); From dd092bdfd33927714bc082e60dc56680ca739a18 Mon Sep 17 00:00:00 2001 From: sw-yx Date: Tue, 16 Apr 2019 19:50:08 -0400 Subject: [PATCH 2/2] fix phil bug --- package-lock.json | 2 -- src/utils/serve-functions.js | 13 +++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index e77ce45..e45ffbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7253,7 +7253,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-5.0.0.tgz", "integrity": "sha512-XBQjqOBtTzyol2CpsQOw8LHV0XbDZVG7xMMjmXAJomlVY03WOBRmYgDJETlvcg0H63AJvPRwT7GFi5rvOzUOKg==", - "dev": true, "requires": { "find-up": "^3.0.0", "read-pkg": "^5.0.0" @@ -7263,7 +7262,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.0.0.tgz", "integrity": "sha512-OWufaRc67oJjcgrxckW/qO9q22iYzyiONh8h+GMcnOvSHAmhV1Dr3x+gyRjP+Qxc5jKupkSfoCQLS/98rDPh9A==", - "dev": true, "requires": { "normalize-package-data": "^2.3.2", "parse-json": "^4.0.0" diff --git a/src/utils/serve-functions.js b/src/utils/serve-functions.js index 775a447..a196f1b 100644 --- a/src/utils/serve-functions.js +++ b/src/utils/serve-functions.js @@ -101,12 +101,13 @@ function createHandler(dir) { delete require.cache[require.resolve(fn.functionPath)]; module.paths = before; }; - fn.watcher = chokidar.watch( - [fn.functionPath, path.join(fn.moduleDir, "package.json")], - { - ignored: /node_modules/ - } - ); + const pathsToWatch = [fn.functionPath]; + if (fn.moduleDir) { + pathsToWatch.push(path.join(fn.moduleDir, "package.json")); + } + fn.watcher = chokidar.watch(pathsToWatch, { + ignored: /node_modules/ + }); fn.watcher .on("add", clearCache) .on("change", clearCache)