From b520daa6f30703139a87b339e3c97a33202ba564 Mon Sep 17 00:00:00 2001 From: MaxGenash Date: Thu, 13 Aug 2020 12:58:17 +0300 Subject: [PATCH 1/2] fix: strf-8574, bump "hapi" and its modules to fix security issues --- bin/stencil-start | 253 ++- package-lock.json | 1777 ++++++----------- package.json | 12 +- server/config.js | 17 +- server/index.js | 69 +- server/manifest.js | 43 +- server/plugins/renderer/renderer.module.js | 264 ++- .../plugins/renderer/renderer.module.spec.js | 29 +- .../renderer/responses/pencil-response.js | 20 +- .../renderer/responses/raw-response.js | 10 +- .../renderer/responses/raw-response.spec.js | 21 +- .../renderer/responses/redirect-response.js | 34 +- server/plugins/router/router.module.js | 68 +- server/plugins/router/router.module.spec.js | 82 +- .../theme-assets/theme-assets.module.js | 95 +- 15 files changed, 1117 insertions(+), 1677 deletions(-) diff --git a/bin/stencil-start b/bin/stencil-start index c20db332..dc2759c6 100755 --- a/bin/stencil-start +++ b/bin/stencil-start @@ -1,34 +1,26 @@ #!/usr/bin/env node -var Bs = require('browser-sync').create(); -var Cycles = require('../lib/cycles'); -var recursiveRead = require('recursive-readdir'); -var Async = require('async'); -var templateAssembler = require('../lib/template-assembler'); -var Fs = require('fs'); -var JspmAssembler = require('../lib/jspm-assembler'); -var Path = require('path'); -var Pkg = require('../package.json'); -var Program = require('commander'); -var Server = require('../server'); -var ThemeConfig = require('../lib/theme-config'); -var buildConfig = require('../lib/build-config'); -var Url = require('url'); -var Wreck = require('wreck'); -var jsonLint = require('../lib/json-lint'); -var versionCheck = require('../lib/version-check'); -var themePath = process.cwd(); -var browserSyncPort; -var templatePath = Path.join(themePath, 'templates'); -var dotStencilFilePath = Path.join(themePath, '.stencil'); -var themeConfigPath = Path.join(themePath, 'config.json'); -var dotStencilFile; -var stencilServerPort; -var themeConfig; -var configuration; -var staplerUrl; -var headers; -let tunnel; +const Bs = require('browser-sync').create(); +const Cycles = require('../lib/cycles'); +const recursiveRead = require('recursive-readdir'); +const Async = require('async'); +const templateAssembler = require('../lib/template-assembler'); +const Fs = require('fs'); +const JspmAssembler = require('../lib/jspm-assembler'); +const Path = require('path'); +const Pkg = require('../package.json'); +const Program = require('commander'); +const Server = require('../server'); +const ThemeConfig = require('../lib/theme-config'); +const buildConfig = require('../lib/build-config'); +const Url = require('url'); +const Wreck = require('wreck'); +const jsonLint = require('../lib/json-lint'); +const versionCheck = require('../lib/version-check'); +let themePath = process.cwd(); +let templatePath = Path.join(themePath, 'templates'); +let dotStencilFilePath = Path.join(themePath, '.stencil'); +let themeConfigPath = Path.join(themePath, 'config.json'); require('colors'); Program @@ -59,8 +51,7 @@ if (Program.variation === true) { } // Instantiate themeConfig -themeConfig = ThemeConfig.getInstance(themePath); - +let themeConfig = ThemeConfig.getInstance(themePath); if (Program.variation) { try { themeConfig.setVariationByName(Program.variation); @@ -69,19 +60,16 @@ if (Program.variation) { } } -configuration = themeConfig.getConfig(); - -dotStencilFile = Fs.readFileSync(dotStencilFilePath, {encoding: 'utf-8'}); - +let configuration = themeConfig.getConfig(); +let dotStencilFile = Fs.readFileSync(dotStencilFilePath, {encoding: 'utf-8'}); try { dotStencilFile = jsonLint.parse(dotStencilFile, dotStencilFilePath); } catch (e) { return console.error(e.stack); } -browserSyncPort = dotStencilFile.port; -stencilServerPort = ++dotStencilFile.port; - +let browserSyncPort = dotStencilFile.port; +let stencilServerPort = ++dotStencilFile.port; if (!(dotStencilFile.normalStoreUrl) || !(dotStencilFile.customLayouts)) { return console.error( 'Error: Your stencil config is outdated. Please run'.red + @@ -89,10 +77,10 @@ if (!(dotStencilFile.normalStoreUrl) || !(dotStencilFile.customLayouts)) { ); } -headers = { +let staplerUrl; +const headers = { 'stencil-cli': Pkg.version, }; - if (dotStencilFile.staplerUrl) { staplerUrl = dotStencilFile.staplerUrl; headers['stencil-store-url'] = dotStencilFile.normalStoreUrl; @@ -108,7 +96,7 @@ Wreck.get( rejectUnauthorized: false, }, function (err, res, payload) { - var bundleTask; + let bundleTask; if (err || !payload) { console.error( @@ -147,116 +135,111 @@ Wreck.get( /** * Starts up the local Stencil Server as well as starts up BrowserSync and sets some watch options. */ -function startServer() { - var params = { +async function startServer() { + await Server.create({ dotStencilFile: dotStencilFile, variationIndex: themeConfig.variationIndex || 0, useCache: Program.cache, themePath: themePath, - }; - - Server(params, err => { - var watchFiles = [ - '/assets', - '/templates', - '/lang', - '/.config' - ]; - var watchIgnored = [ - '/assets/scss', - '/assets/css', - '/assets/jspm_packages', - ]; - - if (err) { - throw err; - } + }); - // Display Set up information - console.log(startUpInformation()); + let watchFiles = [ + '/assets', + '/templates', + '/lang', + '/.config' + ]; + let watchIgnored = [ + '/assets/scss', + '/assets/css', + '/assets/jspm_packages', + ]; + + // Display Set up information + console.log(getStartUpInfo()); + + // Watch sccs directory and automatically reload all css files if a file changes + Bs.watch(Path.join(themePath, 'assets/scss'), event => { + if (event === 'change') { + Bs.reload('*.css'); + } + }); - // Watch sccs directory and automatically reload all css files if a file changes - Bs.watch(Path.join(themePath, 'assets/scss'), event => { - if (event === 'change') { - Bs.reload('*.css'); + Bs.watch('config.json', (event) => { + if (event === 'change') { + try { + configuration = themeConfig.getConfig(); + } catch (e) { + return console.error(e); } - }); - Bs.watch('config.json', (event) => { - if (event === 'change') { - try { - configuration = themeConfig.getConfig(); - } catch (e) { - return console.error(e); - } + Bs.reload(); + } + }); - Bs.reload(); - } - }); + Bs.watch('.config/storefront.json', (event, file) => { + if (event === 'change') { + console.log("storefront json changed"); + Bs.emitter.emit("storefront_config_file:changed", { + event: event, + path: file, + namespace: "" + }); + Bs.reload(); + } + }); - Bs.watch('.config/storefront.json', (event, file) => { - if (event === 'change') { - console.log("storefront json changed"); - Bs.emitter.emit("storefront_config_file:changed", { - event: event, - path: file, - namespace: "" - }); - Bs.reload(); + Bs.watch(templatePath, {ignoreInitial: true}, () => { + assembleTemplates(templatePath, (err, results) => { + if (err) { + return console.error(err); } - }); - Bs.watch(templatePath, {ignoreInitial: true}, () => { - assembleTemplates(templatePath, (err, results) => { - if (err) { - return console.error(err); - } - - try { - new Cycles(results).detect(); - } catch (e) { - console.error(e); - } - }) - }); + try { + new Cycles(results).detect(); + } catch (e) { + console.error(e); + } + }) + }); - if (buildConfig.watchOptions && buildConfig.watchOptions.files) { - watchFiles = buildConfig.watchOptions.files; - } + if (buildConfig.watchOptions && buildConfig.watchOptions.files) { + watchFiles = buildConfig.watchOptions.files; + } - if (buildConfig.watchOptions && buildConfig.watchOptions.ignored) { - watchIgnored = buildConfig.watchOptions.ignored; - } + if (buildConfig.watchOptions && buildConfig.watchOptions.ignored) { + watchIgnored = buildConfig.watchOptions.ignored; + } - // check for tunnel argument - if (typeof Program.tunnel === 'undefined') { tunnel = false; } - else if (Program.tunnel === true) { tunnel = true; } - else { tunnel = Program.tunnel; } - - Bs.init({ - open: !!Program.open, - port: browserSyncPort, - files: watchFiles.map(val => Path.join(themePath, val)), - watchOptions: { - ignoreInitial: true, - ignored: watchIgnored.map(val => Path.join(themePath, val)), - }, - proxy: "localhost:" + stencilServerPort, - tunnel: tunnel, - }); + const tunnel = typeof Program.tunnel === 'undefined' + ? false + : Program.tunnel === true + ? true + : Program.tunnel; + + Bs.init({ + open: !!Program.open, + port: browserSyncPort, + files: watchFiles.map(val => Path.join(themePath, val)), + watchOptions: { + ignoreInitial: true, + ignored: watchIgnored.map(val => Path.join(themePath, val)), + }, + proxy: "localhost:" + stencilServerPort, + tunnel, + }); - // Handle manual reloading of browsers by typing 'rs'; - // Borrowed from https://github.com/remy/nodemon - process.stdin.resume(); - process.stdin.setEncoding('utf8'); - process.stdin.on('data', data => { - data = (data + '').trim().toLowerCase(); + // Handle manual reloading of browsers by typing 'rs'; + // Borrowed from https://github.com/remy/nodemon + process.stdin.resume(); + process.stdin.setEncoding('utf8'); + process.stdin.on('data', data => { + data = (data + '').trim().toLowerCase(); - // if the keys entered match the restartable value, then restart! - if (data === 'rs') { - Bs.reload(); - } - }); + // if the keys entered match the restartable value, then restart! + if (data === 'rs') { + Bs.reload(); + } }); if (buildConfig.development) { @@ -302,7 +285,7 @@ function fileExist(path) { * Displays information about your environment and configuration. * @return {string} */ -function startUpInformation() { +function getStartUpInfo() { let information = '\n'; information += '-----------------Startup Information-------------\n'.gray; diff --git a/package-lock.json b/package-lock.json index f75a379c..ed6644f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -172,21 +172,6 @@ "dev": true, "requires": { "@babel/types": "^7.10.4" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - } } }, "@babel/helper-member-expression-to-functions": { @@ -208,46 +193,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", + "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.10.4", "@babel/helper-replace-supers": "^7.10.4", "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-split-export-declaration": "^7.10.4", "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", + "@babel/types": "^7.10.5", "lodash": "^4.17.19" - }, - "dependencies": { - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", - "dev": true, - "requires": { - "@babel/types": "^7.11.0" - } - }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - } } }, "@babel/helper-optimise-call-expression": { @@ -1964,6 +1921,14 @@ "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" }, + "@hapi/ammo": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@hapi/ammo/-/ammo-3.1.2.tgz", + "integrity": "sha512-ej9OtFmiZv1qr45g1bxEZNGyaR4jRpyMxU6VhbxjaYThymvOwsyIsUKMZnP5Qw2tfYFuwqCJuIBHGpeIbdX9gQ==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, "@hapi/boom": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-8.0.1.tgz", @@ -2007,6 +1972,25 @@ } } }, + "@hapi/bounce": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-1.3.2.tgz", + "integrity": "sha512-3bnb1AlcEByFZnpDIidxQyw1Gds81z/1rSqlx4bIEE+wUN0ATj0D49B5cE1wGocy90Rp/de4tv7GjsKd5RQeew==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "^8.3.1" + }, + "dependencies": { + "@hapi/boom": { + "version": "7.4.11", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz", + "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==", + "requires": { + "@hapi/hoek": "8.x.x" + } + } + } + }, "@hapi/bourne": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", @@ -2034,14 +2018,498 @@ "@hapi/formula": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-1.2.0.tgz", - "integrity": "sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA==", - "dev": true + "integrity": "sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA==" + }, + "@hapi/glue": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@hapi/glue/-/glue-6.2.0.tgz", + "integrity": "sha512-pRDgmP+TqVRzHWIgrRep/Zigia/tTkaAG28HYCvzmwuEi1dg6+8/n3J3rJw39D4sjb74MsbQnuenYJ4Rq+8yuw==", + "requires": { + "@hapi/hapi": "18.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/good": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/@hapi/good/-/good-8.2.4.tgz", + "integrity": "sha512-Paj7BX4C295I+opJ5eIV0XvLhRPcKDLpP9RsnUWGXH/gLRi1SwVMOCYAqitSBjhYSIeZoq+jMmJn6+hUg4W3ug==", + "requires": { + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x", + "@hapi/oppsy": "2.x.x", + "pumpify": "1.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/good-console": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@hapi/good-console/-/good-console-8.1.2.tgz", + "integrity": "sha512-35Uxe7+EsPsbhjQXrhCGB5Ul0W51CxYBBjN7JC95RZnFiB2DAt52pXLZ6aagUPk8yA/DM2OmIsmWJBr+N28hLw==", + "requires": { + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x", + "json-stringify-safe": "5.x.x", + "moment": "2.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/h2o2": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@hapi/h2o2/-/h2o2-8.3.2.tgz", + "integrity": "sha512-2WkZq+QAkvYHWGqnUuG0stcVeGyv9T7bopBYnCJSUEuvBZlUf2BTX2JCVSKxsnTLOxCYwoC/aI4Rr0ZSRd2oVg==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x", + "@hapi/wreck": "15.x.x" + }, + "dependencies": { + "@hapi/boom": { + "version": "7.4.11", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz", + "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/hapi": { + "version": "18.4.1", + "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-18.4.1.tgz", + "integrity": "sha512-9HjVGa0Z4Qv9jk9AVoUdJMQLA+KuZ+liKWyEEkVBx3e3H1F0JM6aGbPkY9jRfwsITBWGBU2iXazn65SFKSi/tg==", + "requires": { + "@hapi/accept": "^3.2.4", + "@hapi/ammo": "^3.1.2", + "@hapi/boom": "7.x.x", + "@hapi/bounce": "1.x.x", + "@hapi/call": "^5.1.3", + "@hapi/catbox": "10.x.x", + "@hapi/catbox-memory": "4.x.x", + "@hapi/heavy": "6.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/joi": "15.x.x", + "@hapi/mimos": "4.x.x", + "@hapi/podium": "3.x.x", + "@hapi/shot": "4.x.x", + "@hapi/somever": "2.x.x", + "@hapi/statehood": "6.x.x", + "@hapi/subtext": "^6.1.3", + "@hapi/teamwork": "3.x.x", + "@hapi/topo": "3.x.x" + }, + "dependencies": { + "@hapi/accept": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-3.2.4.tgz", + "integrity": "sha512-soThGB+QMgfxlh0Vzhzlf3ZOEOPk5biEwcOXhkF0Eedqx8VnhGiggL9UYHrIsOb1rUg3Be3K8kp0iDL2wbVSOQ==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/ammo": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@hapi/ammo/-/ammo-3.1.2.tgz", + "integrity": "sha512-ej9OtFmiZv1qr45g1bxEZNGyaR4jRpyMxU6VhbxjaYThymvOwsyIsUKMZnP5Qw2tfYFuwqCJuIBHGpeIbdX9gQ==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/b64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-4.2.1.tgz", + "integrity": "sha512-zqHpQuH5CBMw6hADzKfU/IGNrxq1Q+/wTYV+OiZRQN9F3tMyk+9BUMeBvFRMamduuqL8iSp62QAnJ+7ATiYLWA==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/boom": { + "version": "7.4.11", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz", + "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/bounce": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-1.3.2.tgz", + "integrity": "sha512-3bnb1AlcEByFZnpDIidxQyw1Gds81z/1rSqlx4bIEE+wUN0ATj0D49B5cE1wGocy90Rp/de4tv7GjsKd5RQeew==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "^8.3.1" + } + }, + "@hapi/call": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@hapi/call/-/call-5.1.3.tgz", + "integrity": "sha512-5DfWpMk7qZiYhvBhM5oUiT4GQ/O8a2rFR121/PdwA/eZ2C1EsuD547ZggMKAR5bZ+FtxOf0fdM20zzcXzq2mZA==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/catbox": { + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-10.2.3.tgz", + "integrity": "sha512-kN9hXO4NYyOHW09CXiuj5qW1syc/0XeVOBsNNk0Tz89wWNQE5h21WF+VsfAw3uFR8swn/Wj3YEVBnWqo82m/JQ==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x", + "@hapi/podium": "3.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/catbox-memory": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-4.1.1.tgz", + "integrity": "sha512-T6Hdy8DExzG0jY7C8yYWZB4XHfc0v+p1EGkwxl2HoaPYAmW7I3E59M/IvmSVpis8RPcIoBp41ZpO2aZPBpM2Ww==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/content": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@hapi/content/-/content-4.1.1.tgz", + "integrity": "sha512-3TWvmwpVPxFSF3KBjKZ8yDqIKKZZIm7VurDSweYpXYENZrJH3C1hd1+qEQW9wQaUaI76pPBLGrXl6I3B7i3ipA==", + "requires": { + "@hapi/boom": "7.x.x" + } + }, + "@hapi/cryptiles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@hapi/cryptiles/-/cryptiles-4.2.1.tgz", + "integrity": "sha512-XoqgKsHK0l/VpqPs+tr6j6vE+VQ3+2bkF2stvttmc7xAOf1oSAwHcJ0tlp/6MxMysktt1IEY0Csy3khKaP9/uQ==", + "requires": { + "@hapi/boom": "7.x.x" + } + }, + "@hapi/file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@hapi/file/-/file-1.0.0.tgz", + "integrity": "sha512-Bsfp/+1Gyf70eGtnIgmScvrH8sSypO3TcK3Zf0QdHnzn/ACnAkI6KLtGACmNRPEzzIy+W7aJX5E+1fc9GwIABQ==" + }, + "@hapi/formula": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-1.2.0.tgz", + "integrity": "sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA==" + }, + "@hapi/heavy": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-6.2.2.tgz", + "integrity": "sha512-PY1dCCO6dsze7RlafIRhTaGeyTgVe49A/lSkxbhKGjQ7x46o/OFf7hLiRqTCDh3atcEKf6362EaB3+kTUbCsVA==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" + }, + "@hapi/iron": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@hapi/iron/-/iron-5.1.4.tgz", + "integrity": "sha512-+ElC+OCiwWLjlJBmm8ZEWjlfzTMQTdgPnU/TsoU5QsktspIWmWi9IU4kU83nH+X/SSya8TP8h8P11Wr5L7dkQQ==", + "requires": { + "@hapi/b64": "4.x.x", + "@hapi/boom": "7.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/cryptiles": "4.x.x", + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/mimos": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@hapi/mimos/-/mimos-4.1.1.tgz", + "integrity": "sha512-CXoi/zfcTWfKYX756eEea8rXJRIb9sR4d7VwyAH9d3BkDyNgAesZxvqIdm55npQc6S9mU3FExinMAQVlIkz0eA==", + "requires": { + "@hapi/hoek": "8.x.x", + "mime-db": "1.x.x" + } + }, + "@hapi/nigel": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-3.1.1.tgz", + "integrity": "sha512-R9YWx4S8yu0gcCBrMUDCiEFm1SQT895dMlYoeNBp8I6YhF1BFF1iYPueKA2Kkp9BvyHdjmvrxCOns7GMmpl+Fw==", + "requires": { + "@hapi/hoek": "8.x.x", + "@hapi/vise": "3.x.x" + } + }, + "@hapi/pez": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@hapi/pez/-/pez-4.1.2.tgz", + "integrity": "sha512-8zSdJ8cZrJLFldTgwjU9Fb1JebID+aBCrCsycgqKYe0OZtM2r3Yv3aAwW5z97VsZWCROC1Vx6Mdn4rujh5Ktcg==", + "requires": { + "@hapi/b64": "4.x.x", + "@hapi/boom": "7.x.x", + "@hapi/content": "^4.1.1", + "@hapi/hoek": "8.x.x", + "@hapi/nigel": "3.x.x" + } + }, + "@hapi/pinpoint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-1.0.2.tgz", + "integrity": "sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ==" + }, + "@hapi/podium": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-3.4.3.tgz", + "integrity": "sha512-QJlnYLEYZWlKQ9fSOtuUcpANyoVGwT68GA9P0iQQCAetBK0fI+nbRBt58+aMixoifczWZUthuGkNjqKxgPh/CQ==", + "requires": { + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/shot": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-4.1.2.tgz", + "integrity": "sha512-6LeHLjvsq/bQ0R+fhEyr7mqExRGguNTrxFZf5DyKe3CK6pNabiGgYO4JVFaRrLZ3JyuhkS0fo8iiRE2Ql2oA/A==", + "requires": { + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/somever": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@hapi/somever/-/somever-2.1.1.tgz", + "integrity": "sha512-cic5Sto4KGd9B0oQSdKTokju+rYhCbdpzbMb0EBnrH5Oc1z048hY8PaZ1lx2vBD7I/XIfTQVQetBH57fU51XRA==", + "requires": { + "@hapi/bounce": "1.x.x", + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/statehood": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-6.1.2.tgz", + "integrity": "sha512-pYXw1x6npz/UfmtcpUhuMvdK5kuOGTKcJNfLqdNptzietK2UZH5RzNJSlv5bDHeSmordFM3kGItcuQWX2lj2nQ==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/bounce": "1.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/cryptiles": "4.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/iron": "5.x.x", + "@hapi/joi": "16.x.x" + }, + "dependencies": { + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + } + } + }, + "@hapi/subtext": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@hapi/subtext/-/subtext-6.1.3.tgz", + "integrity": "sha512-qWN6NbiHNzohVcJMeAlpku/vzbyH4zIpnnMPMPioQMwIxbPFKeNViDCNI6fVBbMPBiw/xB4FjqiJkRG5P9eWWg==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/content": "^4.1.1", + "@hapi/file": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/pez": "^4.1.2", + "@hapi/wreck": "15.x.x" + } + }, + "@hapi/teamwork": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-3.3.1.tgz", + "integrity": "sha512-61tiqWCYvMKP7fCTXy0M4VE6uNIwA0qvgFoiDubgfj7uqJ0fdHJFQNnVPGrxhLWlwz0uBPWrQlBH7r8y9vFITQ==" + }, + "@hapi/vise": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@hapi/vise/-/vise-3.1.1.tgz", + "integrity": "sha512-OXarbiCSadvtg+bSdVPqu31Z1JoBL+FwNYz3cYoBKQ5xq1/Cr4A3IkGpAZbAuxU5y4NL5pZFZG3d2a3ZGm/dOQ==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/wreck": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-15.1.0.tgz", + "integrity": "sha512-tQczYRTTeYBmvhsek/D49En/5khcShaBEmzrAaDjMrFXKJRuF8xA8+tlq1ETLBFwGd6Do6g2OC74rt11kzawzg==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x" + } + } + } }, "@hapi/hoek": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" }, + "@hapi/inert": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-5.2.2.tgz", + "integrity": "sha512-8IaGfAEF8SwZtpdaTq0G3aDPG35ZTfWKjnMNniG2N3kE+qioMsBuImIGxna8TNQ+sYMXYK78aqmvzbQHno8qSQ==", + "requires": { + "@hapi/ammo": "3.x.x", + "@hapi/boom": "7.x.x", + "@hapi/bounce": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/joi": "16.x.x", + "lru-cache": "4.1.x" + }, + "dependencies": { + "@hapi/boom": { + "version": "7.4.11", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz", + "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, + "@hapi/joi": { + "version": "16.1.8", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", + "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", + "requires": { + "@hapi/address": "^2.1.2", + "@hapi/formula": "^1.2.0", + "@hapi/hoek": "^8.2.4", + "@hapi/pinpoint": "^1.0.2", + "@hapi/topo": "^3.1.3" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + } + } + }, "@hapi/joi": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", @@ -2127,6 +2595,12 @@ "minimist": "^1.2.5" } }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "dev": true + }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -2168,11 +2642,18 @@ } } }, + "@hapi/oppsy": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@hapi/oppsy/-/oppsy-2.1.2.tgz", + "integrity": "sha512-V/KNuFemyA//sowFFpeMRY4zE6szuy8vh6v2vWDPDhZFowOIwB7kqdFvmnBogk+aHHR+iKgKCU/SuUiv/xZyzg==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, "@hapi/pinpoint": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-1.0.2.tgz", - "integrity": "sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ==", - "dev": true + "integrity": "sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ==" }, "@hapi/rule-capitalize-modules": { "version": "1.2.1", @@ -2219,6 +2700,26 @@ } } }, + "@hapi/wreck": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-15.1.0.tgz", + "integrity": "sha512-tQczYRTTeYBmvhsek/D49En/5khcShaBEmzrAaDjMrFXKJRuF8xA8+tlq1ETLBFwGd6Do6g2OC74rt11kzawzg==", + "requires": { + "@hapi/boom": "7.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x" + }, + "dependencies": { + "@hapi/boom": { + "version": "7.4.11", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz", + "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==", + "requires": { + "@hapi/hoek": "8.x.x" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2585,6 +3086,17 @@ "jest-util": "^26.1.0" } }, + "@jest/globals": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.1.0.tgz", + "integrity": "sha512-MKiHPNaT+ZoG85oMaYUmGHEqu98y3WO2yeIDJrs2sJqHhYOy3Z6F7F/luzFomRQ8SQ1wEkmahFAz2291Iv8EAw==", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/types": "^26.1.0", + "expect": "^26.1.0" + } + }, "@jest/reporters": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.1.0.tgz", @@ -2986,9 +3498,9 @@ } }, "@octokit/core": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.1.1.tgz", - "integrity": "sha512-cQ2HGrtyNJ1IBxpTP1U5m/FkMAJvgw7d2j1q3c9P0XUuYilEgF6e4naTpsgm4iVcQeOnccZlw7XHRIUBy0ymcg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.1.2.tgz", + "integrity": "sha512-AInOFULmwOa7+NFi9F8DlDkm5qtZVmDQayi7TUgChE3yeIGPq0Y+6cAEXPexQ3Ea+uZy66hKEazR7DJyU+4wfw==", "requires": { "@octokit/auth-token": "^2.4.0", "@octokit/graphql": "^4.3.1", @@ -3091,9 +3603,9 @@ } }, "@octokit/types": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.2.0.tgz", - "integrity": "sha512-XjOk9y4m8xTLIKPe1NFxNWBdzA2/z3PFFA/bwf4EoH6oS8hM0Y46mEa4Cb+KCyj/tFDznJFahzQ0Aj3o1FYq4A==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.4.0.tgz", + "integrity": "sha512-D/uotqF69M50OIlwMqgyIg9PuLT2daOiBAYF0P40I2ekFA2ESwwBY5dxZe/UhXdPvIbNKDzuZmQrO7rMpuFbcg==", "requires": { "@types/node": ">= 8" } @@ -5951,14 +6463,6 @@ "dev": true, "requires": { "hoek": "4.x.x" - }, - "dependencies": { - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - } } }, "code-point-at": { @@ -7888,7 +8392,6 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -7961,15 +8464,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.524", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.524.tgz", - "integrity": "sha512-ZUvklIBkfXQyA6IeiEss1nfKRICcdB5afAGZAaPGaExdfrkpUu/WWVO+X7QpNnphaVMllXnAcvKnVPdyM+DCPQ==" - }, - "emittery": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", - "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", - "dev": true + "version": "1.3.526", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.526.tgz", + "integrity": "sha512-HiroW5ZbGwgT8kCnoEO8qnGjoTPzJxduvV/Vv/wH63eo2N6Zj3xT5fmmaSPAPUM05iN9/5fIEkIg3owTtV6QZg==" }, "emoji-regex": { "version": "8.0.0", @@ -10931,89 +11428,6 @@ "sparkles": "^1.0.0" } }, - "glue": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/glue/-/glue-2.4.0.tgz", - "integrity": "sha1-lY7taTIFbQihtPdY6Ufm/dlDhMI=", - "requires": { - "boom": "2.x.x", - "hapi": "8.x.x || 9.x.x || 10.x.x || 11.x.x", - "hoek": "2.x.x", - "items": "1.x.x", - "joi": "5.x.x || 6.x.x" - }, - "dependencies": { - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "requires": { - "hoek": "2.x.x" - } - }, - "joi": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", - "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", - "requires": { - "hoek": "2.x.x", - "isemail": "1.x.x", - "moment": "2.x.x", - "topo": "1.x.x" - } - } - } - }, - "good": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/good/-/good-5.1.2.tgz", - "integrity": "sha1-//bTT0cMBm+oV4FgwbjDAg6i4Tw=", - "requires": { - "good-reporter": "3.x.x", - "hoek": "2.x.x", - "items": "1.x.x", - "joi": "5.x.x" - }, - "dependencies": { - "joi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-5.1.0.tgz", - "integrity": "sha1-FSrQfbjunGQBmX/1/SwSiWBwv1g=", - "requires": { - "hoek": "^2.2.x", - "isemail": "1.x.x", - "moment": "2.x.x", - "topo": "1.x.x" - } - } - } - }, - "good-console": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/good-console/-/good-console-4.1.0.tgz", - "integrity": "sha1-Lcpx3i3uYbSbbhch1urP2dGVRJ4=", - "requires": { - "good-reporter": "3.x.x", - "hoek": "2.x.x", - "json-stringify-safe": "5.0.x", - "moment": "2.8.x" - }, - "dependencies": { - "moment": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.8.4.tgz", - "integrity": "sha1-zBdKq7GSI+//VpmpRngFoniYOL8=" - } - } - }, - "good-reporter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/good-reporter/-/good-reporter-3.1.0.tgz", - "integrity": "sha1-/19xkdzjgc05TcMA57foIQOWERM=", - "requires": { - "hoek": "2.x.x" - } - }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", @@ -12011,331 +12425,6 @@ } } }, - "hapi": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/hapi/-/hapi-8.8.1.tgz", - "integrity": "sha1-xwZv6TIuQbng4IMV/Xny2Zhfouo=", - "requires": { - "accept": "1.x.x", - "ammo": "1.x.x", - "boom": "^2.5.x", - "call": "2.x.x", - "catbox": "^4.2.x", - "catbox-memory": "1.x.x", - "cryptiles": "2.x.x", - "h2o2": "4.x.x", - "heavy": "3.x.x", - "hoek": "^2.14.x", - "inert": "2.x.x", - "iron": "2.x.x", - "items": "1.x.x", - "joi": "6.x.x", - "kilt": "^1.1.x", - "mimos": "2.x.x", - "peekaboo": "1.x.x", - "qs": "4.x.x", - "shot": "1.x.x", - "statehood": "2.x.x", - "subtext": "1.x.x", - "topo": "1.x.x", - "vision": "2.x.x" - }, - "dependencies": { - "accept": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/accept/-/accept-1.0.0.tgz", - "integrity": "sha1-g++IOWi4WkDFARYEKCoiD/AeYq0=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x" - } - }, - "ammo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ammo/-/ammo-1.0.0.tgz", - "integrity": "sha1-4FlIG/aAhzj66G1GT3L6DBLWeoU=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x" - } - }, - "boom": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.7.2.tgz", - "integrity": "sha1-2tYo2Jf3/S4yzIIZfxMweXHPg1Q=", - "requires": { - "hoek": "2.x.x" - } - }, - "call": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/call/-/call-2.0.1.tgz", - "integrity": "sha1-SbQnCZQ96JoyJYqpEbWHUeI3eg4=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x" - } - }, - "catbox": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/catbox/-/catbox-4.3.0.tgz", - "integrity": "sha1-IiN3vWfxKRrA4l0AAC0GWp3385o=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x", - "joi": "6.x.x" - } - }, - "catbox-memory": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/catbox-memory/-/catbox-memory-1.1.1.tgz", - "integrity": "sha1-QqUvgLye+nJmAeltQBYDNhJIGig=", - "requires": { - "hoek": "2.x.x" - } - }, - "cryptiles": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.4.tgz", - "integrity": "sha1-CeoXdbnhx95+YKmdQqtvCM4aEoU=", - "requires": { - "boom": "2.x.x" - } - }, - "h2o2": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/h2o2/-/h2o2-4.0.1.tgz", - "integrity": "sha1-eg4rztHZcXjsVs48ykjgxW3un40=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x", - "joi": "6.x.x", - "wreck": "5.x.x" - } - }, - "heavy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/heavy/-/heavy-3.0.0.tgz", - "integrity": "sha1-/QEIdiExYy+IVIontVQSws9SKwA=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x", - "joi": "5.x.x" - } - }, - "hoek": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.14.0.tgz", - "integrity": "sha1-gSEWkfUqWoNa5J7b8eickANHaqQ=" - }, - "inert": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/inert/-/inert-2.1.6.tgz", - "integrity": "sha1-jx10v+ylmgmL0+4NwXtki37x49o=", - "requires": { - "ammo": "1.x.x", - "boom": "2.x.x", - "hoek": "2.x.x", - "items": "1.x.x", - "joi": "6.x.x", - "lru-cache": "2.6.x" - }, - "dependencies": { - "lru-cache": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz", - "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=" - } - } - }, - "iron": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/iron/-/iron-2.1.2.tgz", - "integrity": "sha1-WR2RiiVAdTxEbY5DfNzwz6gBEU8=", - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x" - } - }, - "items": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/items/-/items-1.1.0.tgz", - "integrity": "sha1-rZ1VhAsimGDLPRYLMidMLUvZ4mI=" - }, - "joi": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.4.1.tgz", - "integrity": "sha1-9Q9CRTVgBo5jg9oVrC0w3Xzra24=", - "requires": { - "hoek": "^2.2.x", - "isemail": "1.x.x", - "moment": "2.x.x", - "topo": "1.x.x" - }, - "dependencies": { - "isemail": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.1.1.tgz", - "integrity": "sha1-4Mj23D9HCX53dzlcaJYnGqJWw7U=" - }, - "moment": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.10.3.tgz", - "integrity": "sha1-CruZ8wf2UhgwjGk17+KcV7Ggon8=" - } - } - }, - "kilt": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/kilt/-/kilt-1.1.1.tgz", - "integrity": "sha1-d7SmFjyn+lshN6iMFzNCFuwj1ds=", - "requires": { - "hoek": "2.x.x" - } - }, - "mimos": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mimos/-/mimos-2.0.2.tgz", - "integrity": "sha1-wyQXF+dblZkr54esfdbbGptTmx4=", - "requires": { - "hoek": "2.x.x", - "mime-db": "1.x.x" - }, - "dependencies": { - "mime-db": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.14.0.tgz", - "integrity": "sha1-1WHxC27mbbUflK5leilRp0IX7YM=" - } - } - }, - "peekaboo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/peekaboo/-/peekaboo-1.0.0.tgz", - "integrity": "sha1-wNspJq1lTSygH3ymUKtFkadk/EI=" - }, - "qs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz", - "integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc=" - }, - "shot": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/shot/-/shot-1.5.3.tgz", - "integrity": "sha1-SGEHREO8VHLCNRthpGtOrsAH9Xo=", - "requires": { - "hoek": "2.x.x" - } - }, - "statehood": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/statehood/-/statehood-2.1.1.tgz", - "integrity": "sha1-AfFwtmxeklqvZ5qdMiulkYb8AAk=", - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "iron": "2.x.x", - "items": "1.x.x", - "joi": "6.x.x" - } - }, - "subtext": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/subtext/-/subtext-1.1.1.tgz", - "integrity": "sha1-DJGCWuZdUXhVWT2DHjPvdaKEFWs=", - "requires": { - "boom": "2.x.x", - "content": "1.x.x", - "hoek": "2.x.x", - "pez": "1.x.x", - "qs": "4.x.x", - "wreck": "6.x.x" - }, - "dependencies": { - "content": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content/-/content-1.0.1.tgz", - "integrity": "sha1-gD60s7eJVGD9jGnGhMd1RmmvG6E=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x" - } - }, - "pez": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pez/-/pez-1.0.0.tgz", - "integrity": "sha1-hEMYpc5wku7d/6KV4YB5rHefoBg=", - "requires": { - "b64": "2.x.x", - "boom": "2.x.x", - "content": "1.x.x", - "hoek": "2.x.x", - "nigel": "1.x.x" - }, - "dependencies": { - "b64": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/b64/-/b64-2.0.0.tgz", - "integrity": "sha1-tZlbJPR+v9nxMQF6bntdZHVvtvM=", - "requires": { - "hoek": "2.x.x" - } - }, - "nigel": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nigel/-/nigel-1.0.1.tgz", - "integrity": "sha1-RjmJr4gSePuqHTzJOCPb0XtDYKE=", - "requires": { - "hoek": "2.x.x", - "vise": "1.x.x" - }, - "dependencies": { - "vise": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vise/-/vise-1.0.0.tgz", - "integrity": "sha1-KDRb5N5aNB4V/SgW/Z6j5zA+jfM=", - "requires": { - "hoek": "2.x.x" - } - } - } - } - } - } - } - }, - "topo": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.0.3.tgz", - "integrity": "sha1-576uXqSQZ9dp5Sjn40ZC7e1/Llo=", - "requires": { - "hoek": "2.x.x" - } - }, - "vision": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/vision/-/vision-2.0.1.tgz", - "integrity": "sha1-0BIlW6buQm0GlqNOHfMy/sVeZzw=", - "requires": { - "boom": "2.x.x", - "hoek": "^2.9.x", - "items": "^1.1.x", - "joi": "6.x.x" - } - }, - "wreck": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/wreck/-/wreck-6.0.0.tgz", - "integrity": "sha1-T0CGaWHl14rOBPMqa38x8/PFFjg=", - "requires": { - "boom": "2.x.x", - "hoek": "2.x.x" - } - } - } - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -12490,9 +12579,10 @@ } }, "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true }, "home-or-tmp": { "version": "2.0.0", @@ -13012,20 +13102,15 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, "rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", + "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", "requires": { "tslib": "^1.9.0" } @@ -13351,11 +13436,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isemail": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", - "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -13463,11 +13543,6 @@ "istanbul-lib-report": "^3.0.0" } }, - "items": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/items/-/items-1.1.1.tgz", - "integrity": "sha1-Q1td0hvKKLPP0lu1xrJ4txUBD9k=" - }, "jest": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/jest/-/jest-26.1.0.tgz", @@ -14833,151 +14908,39 @@ } }, "jest-runtime": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.2.2.tgz", - "integrity": "sha512-a8VXM3DxCDnCIdl9+QucWFfQ28KdqmyVFqeKLigHdErtsx56O2ZIdQkhFSuP1XtVrG9nTNHbKxjh5XL1UaFDVQ==", + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.1.0.tgz", + "integrity": "sha512-1qiYN+EZLmG1QV2wdEBRf+Ci8i3VSfIYLF02U18PiUDrMbhfpN/EAMMkJtT02jgJUoaEOpHAIXG6zS3QRMzRmA==", "dev": true, "requires": { - "@jest/console": "^26.2.0", - "@jest/environment": "^26.2.0", - "@jest/fake-timers": "^26.2.0", - "@jest/globals": "^26.2.0", + "@jest/console": "^26.1.0", + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/globals": "^26.1.0", "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.2.0", - "@jest/transform": "^26.2.2", - "@jest/types": "^26.2.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.2.2", - "jest-haste-map": "^26.2.2", - "jest-message-util": "^26.2.0", - "jest-mock": "^26.2.0", + "jest-config": "^26.1.0", + "jest-haste-map": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-mock": "^26.1.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.2.2", - "jest-snapshot": "^26.2.2", - "jest-util": "^26.2.0", - "jest-validate": "^26.2.0", + "jest-resolve": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^15.3.1" }, "dependencies": { - "@jest/console": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.2.0.tgz", - "integrity": "sha512-mXQfx3nSLwiHm1i7jbu+uvi+vvpVjNGzIQYLCfsat9rapC+MJkS4zBseNrgJE0vU921b3P67bQzhduphjY3Tig==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.2.0", - "jest-util": "^26.2.0", - "slash": "^3.0.0" - } - }, - "@jest/environment": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.2.0.tgz", - "integrity": "sha512-oCgp9NmEiJ5rbq9VI/v/yYLDpladAAVvFxZgNsnJxOETuzPZ0ZcKKHYjKYwCtPOP1WCrM5nmyuOhMStXFGHn+g==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.2.0", - "@jest/types": "^26.2.0", - "@types/node": "*", - "jest-mock": "^26.2.0" - } - }, - "@jest/fake-timers": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.2.0.tgz", - "integrity": "sha512-45Gfe7YzYTKqTayBrEdAF0qYyAsNRBzfkV0IyVUm3cx7AsCWlnjilBM4T40w7IXT5VspOgMPikQlV0M6gHwy/g==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.2.0", - "jest-mock": "^26.2.0", - "jest-util": "^26.2.0" - } - }, - "@jest/globals": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.2.0.tgz", - "integrity": "sha512-Hoc6ScEIPaym7RNytIL2ILSUWIGKlwEv+JNFof9dGYOdvPjb2evEURSslvCMkNuNg1ECEClTE8PH7ULlMJntYA==", - "dev": true, - "requires": { - "@jest/environment": "^26.2.0", - "@jest/types": "^26.2.0", - "expect": "^26.2.0" - } - }, - "@jest/test-result": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.2.0.tgz", - "integrity": "sha512-kgPlmcVafpmfyQEu36HClK+CWI6wIaAWDHNxfQtGuKsgoa2uQAYdlxjMDBEa3CvI40+2U3v36gQF6oZBkoKatw==", - "dev": true, - "requires": { - "@jest/console": "^26.2.0", - "@jest/types": "^26.2.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.2.2.tgz", - "integrity": "sha512-SliZWon5LNqV/lVXkeowSU6L8++FGOu3f43T01L1Gv6wnFDP00ER0utV9jyK9dVNdXqfMNCN66sfcyar/o7BNw==", - "dev": true, - "requires": { - "@jest/test-result": "^26.2.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.2.2", - "jest-runner": "^26.2.2", - "jest-runtime": "^26.2.2" - } - }, - "@jest/transform": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.2.2.tgz", - "integrity": "sha512-c1snhvi5wRVre1XyoO3Eef5SEWpuBCH/cEbntBUd9tI5sNYiBDmO0My/lc5IuuGYKp/HFIHV1eZpSx5yjdkhKw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.2.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.2.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.2.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -14994,67 +14957,10 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "babel-jest": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.2.2.tgz", - "integrity": "sha512-JmLuePHgA+DSOdOL8lPxCgD2LhPPm+rdw1vnxR73PpIrnmKCS2/aBhtkAcxQWuUcW2hBrH8MJ3LKXE7aWpNZyA==", - "dev": true, - "requires": { - "@jest/transform": "^26.2.2", - "@jest/types": "^26.2.0", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", - "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-jest": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.2.0.tgz", - "integrity": "sha512-R1k8kdP3R9phYQugXeNnK/nvCGlBzG4m3EoIIukC80GXb6wCv2XiwPhK6K9MAkQcMszWBYvl2Wm+yigyXFQqXg==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^26.2.0", - "babel-preset-current-node-syntax": "^0.1.2" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "chalk": { @@ -15093,29 +14999,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "expect": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.2.0.tgz", - "integrity": "sha512-8AMBQ9UVcoUXt0B7v+5/U5H6yiUR87L6eKCfjE3spx7Ya5lF+ebUo37MCFBML2OiLfkX1sxmQOZhIDonyVTkcw==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.2.0", - "jest-message-util": "^26.2.0", - "jest-regex-util": "^26.0.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -15126,13 +15009,6 @@ "path-exists": "^4.0.0" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -15171,312 +15047,13 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "jest-config": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.2.2.tgz", - "integrity": "sha512-2lhxH0y4YFOijMJ65usuf78m7+9/8+hAb1PZQtdRdgnQpAb4zP6KcVDDktpHEkspBKnc2lmFu+RQdHukUUbiTg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.2.2", - "@jest/types": "^26.2.0", - "babel-jest": "^26.2.2", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.2.0", - "jest-environment-node": "^26.2.0", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.2.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.2.2", - "jest-util": "^26.2.0", - "jest-validate": "^26.2.0", - "micromatch": "^4.0.2", - "pretty-format": "^26.2.0" - } - }, - "jest-diff": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.2.0.tgz", - "integrity": "sha512-Wu4Aopi2nzCsHWLBlD48TgRy3Z7OsxlwvHNd1YSnHc7q1NJfrmyCPoUXrTIrydQOG5ApaYpsAsdfnMbJqV1/wQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.2.0" - } - }, - "jest-each": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.2.0.tgz", - "integrity": "sha512-gHPCaho1twWHB5bpcfnozlc6mrMi+VAewVPNgmwf81x2Gzr6XO4dl+eOrwPWxbkYlgjgrYjWK2xgKnixbzH3Ew==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.2.0", - "pretty-format": "^26.2.0" - } - }, - "jest-environment-jsdom": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.2.0.tgz", - "integrity": "sha512-sDG24+5M4NuIGzkI3rJW8XUlrpkvIdE9Zz4jhD8OBnVxAw+Y1jUk9X+lAOD48nlfUTlnt3lbAI3k2Ox+WF3S0g==", - "dev": true, - "requires": { - "@jest/environment": "^26.2.0", - "@jest/fake-timers": "^26.2.0", - "@jest/types": "^26.2.0", - "@types/node": "*", - "jest-mock": "^26.2.0", - "jest-util": "^26.2.0", - "jsdom": "^16.2.2" - } - }, - "jest-environment-node": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.2.0.tgz", - "integrity": "sha512-4M5ExTYkJ19efBzkiXtBi74JqKLDciEk4CEsp5tTjWGYMrlKFQFtwIVG3tW1OGE0AlXhZjuHPwubuRYY4j4uOw==", - "dev": true, - "requires": { - "@jest/environment": "^26.2.0", - "@jest/fake-timers": "^26.2.0", - "@jest/types": "^26.2.0", - "@types/node": "*", - "jest-mock": "^26.2.0", - "jest-util": "^26.2.0" - } - }, - "jest-haste-map": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.2.2.tgz", - "integrity": "sha512-3sJlMSt+NHnzCB+0KhJ1Ut4zKJBiJOlbrqEYNdRQGlXTv8kqzZWjUKQRY3pkjmlf+7rYjAV++MQ4D6g4DhAyOg==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.2.0", - "jest-util": "^26.2.0", - "jest-worker": "^26.2.1", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.2.2.tgz", - "integrity": "sha512-Q8AAHpbiZMVMy4Hz9j1j1bg2yUmPa1W9StBvcHqRaKa9PHaDUMwds8LwaDyzP/2fkybcTQE4+pTMDOG9826tEw==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.2.0", - "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.2.0", - "@jest/types": "^26.2.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.2.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.2.0", - "jest-matcher-utils": "^26.2.0", - "jest-message-util": "^26.2.0", - "jest-runtime": "^26.2.2", - "jest-snapshot": "^26.2.2", - "jest-util": "^26.2.0", - "pretty-format": "^26.2.0", - "throat": "^5.0.0" - } - }, - "jest-leak-detector": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.2.0.tgz", - "integrity": "sha512-aQdzTX1YiufkXA1teXZu5xXOJgy7wZQw6OJ0iH5CtQlOETe6gTSocaYKUNui1SzQ91xmqEUZ/WRavg9FD82rtQ==", - "dev": true, - "requires": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.2.0" - } - }, - "jest-matcher-utils": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.2.0.tgz", - "integrity": "sha512-2cf/LW2VFb3ayPHrH36ZDjp9+CAeAe/pWBAwsV8t3dKcrINzXPVxq8qMWOxwt5BaeBCx4ZupVGH7VIgB8v66vQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.2.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.2.0" - } - }, - "jest-message-util": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.2.0.tgz", - "integrity": "sha512-g362RhZaJuqeqG108n1sthz5vNpzTNy926eNDszo4ncRbmmcMRIUAZibnd6s5v2XSBCChAxQtCoN25gnzp7JbQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.2.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-mock": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.2.0.tgz", - "integrity": "sha512-XeC7yWtWmWByoyVOHSsE7NYsbXJLtJNgmhD7z4MKumKm6ET0si81bsSLbQ64L5saK3TgsHo2B/UqG5KNZ1Sp/Q==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "@types/node": "*" - } - }, - "jest-resolve": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.2.2.tgz", - "integrity": "sha512-ye9Tj/ILn/0OgFPE/3dGpQPUqt4dHwIocxt5qSBkyzxQD8PbL0bVxBogX2FHxsd3zJA7V2H/cHXnBnNyyT9YoQ==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.2.0", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" - } - }, - "jest-runner": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.2.2.tgz", - "integrity": "sha512-/qb6ptgX+KQ+aNMohJf1We695kaAfuu3u3ouh66TWfhTpLd9WbqcF6163d/tMoEY8GqPztXPLuyG0rHRVDLxCA==", - "dev": true, - "requires": { - "@jest/console": "^26.2.0", - "@jest/environment": "^26.2.0", - "@jest/test-result": "^26.2.0", - "@jest/types": "^26.2.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.2.2", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.2.2", - "jest-leak-detector": "^26.2.0", - "jest-message-util": "^26.2.0", - "jest-resolve": "^26.2.2", - "jest-runtime": "^26.2.2", - "jest-util": "^26.2.0", - "jest-worker": "^26.2.1", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - } - }, - "jest-serializer": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.2.0.tgz", - "integrity": "sha512-V7snZI9IVmyJEu0Qy0inmuXgnMWDtrsbV2p9CRAcmlmPVwpC2ZM8wXyYpiugDQnwLHx0V4+Pnog9Exb3UO8M6Q==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.2.2.tgz", - "integrity": "sha512-NdjD8aJS7ePu268Wy/n/aR1TUisG0BOY+QOW4f6h46UHEKOgYmmkvJhh2BqdVZQ0BHSxTMt04WpCf9njzx8KtA==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.2.0", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.2.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.2.0", - "jest-get-type": "^26.0.0", - "jest-haste-map": "^26.2.2", - "jest-matcher-utils": "^26.2.0", - "jest-message-util": "^26.2.0", - "jest-resolve": "^26.2.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.2.0", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.2.0.tgz", - "integrity": "sha512-YmDwJxLZ1kFxpxPfhSJ0rIkiZOM0PQbRcfH0TzJOhqCisCAsI1WcmoQqO83My9xeVA2k4n+rzg2UuexVKzPpig==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "jest-validate": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.2.0.tgz", - "integrity": "sha512-8XKn3hM6VIVmLNuyzYLCPsRCT83o8jMZYhbieh4dAyKLc4Ypr36rVKC+c8WMpWkfHHpGnEkvWUjjIAyobEIY/Q==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "leven": "^3.1.0", - "pretty-format": "^26.2.0" - } - }, - "jest-worker": { - "version": "26.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.2.1.tgz", - "integrity": "sha512-+XcGMMJDTeEGncRb5M5Zq9P7K4sQ1sirhjdOxsN1462h6lFo9w59bl2LVQmdGEEeU3m+maZCkS2Tcc9SfCHO4A==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "p-locate": "^4.1.0" } }, "minimatch": { @@ -15488,110 +15065,48 @@ "brace-expansion": "^1.1.7" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } }, - "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "p-limit": "^2.2.0" } }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", - "dev": true, - "requires": { - "@jest/types": "^26.2.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -15627,15 +15142,6 @@ "has-flag": "^4.0.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -15686,14 +15192,6 @@ "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } } } } @@ -16082,9 +15580,9 @@ } }, "js-base64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz", - "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==" + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" }, "js-tokens": { "version": "4.0.0", @@ -18840,7 +18338,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -18850,7 +18347,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, "requires": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -20236,12 +19732,6 @@ } } }, - "seedrandom": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", - "dev": true - }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -21027,8 +20517,7 @@ "stream-shift": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, "stream-throttle": { "version": "0.1.3", @@ -21692,14 +21181,6 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, - "topo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", - "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", - "requires": { - "hoek": "2.x.x" - } - }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", diff --git a/package.json b/package.json index aa5d85df..e881104a 100644 --- a/package.json +++ b/package.json @@ -36,11 +36,17 @@ "@bigcommerce/stencil-paper": "^3.0.0-rc.29", "@bigcommerce/stencil-styles": "1.2.1", "@octokit/rest": "^18.0.3", + "@hapi/boom": "^8.0.1", + "@hapi/glue": "^6.2.0", + "@hapi/good": "^8.2.4", + "@hapi/good-console": "^8.1.2", + "@hapi/h2o2": "^8.3.2", + "@hapi/hapi": "^18.4.1", + "@hapi/inert": "^5.2.2", "accept-language-parser": "^1.0.2", "ajv": "^6.11.0", "archiver": "^5.0.0", "async": "^2.4.0", - "@hapi/boom": "^8.0.1", "browser-sync": "^2.26.12", "cheerio": "^0.22.0", "colors": "^1.4.0", @@ -49,11 +55,7 @@ "eslint": "^6.8.0", "front-matter": "^1.0.0", "glob": "^5.0.14", - "glue": "^2.0.0", - "good": "^5.1.2", - "good-console": "^4.1.0", "graceful-fs": "^4.1.11", - "hapi": "^8.4.0", "image-size": "^0.4.0", "inquirer": "^7.3.3", "jsonlint": "^1.6.2", diff --git a/server/config.js b/server/config.js index e192390a..6312d867 100644 --- a/server/config.js +++ b/server/config.js @@ -1,6 +1,7 @@ 'use strict'; const Confidence = require('confidence'); +const GoodConsole = require('@hapi/good-console'); const config = { $meta: 'Config file', @@ -9,11 +10,15 @@ const config = { port: 3000, }, good: { - opsInterval: 1000, - reporters: [{ - reporter: require('good-console'), - args: [{log: '*', request: '*'}], - }], + ops: { + interval: 1000, + }, + reporters: { + goodConsoleReporter: [{ + module: GoodConsole, + args: [{log: '*', request: '*'}], + }], + }, }, }; @@ -24,11 +29,9 @@ const criteria = { const store = new Confidence.Store(config); exports.get = function(key) { - return store.get(key, criteria); }; exports.meta = function(key) { - return store.meta(key, criteria); }; diff --git a/server/index.js b/server/index.js index e2e85a43..94749863 100644 --- a/server/index.js +++ b/server/index.js @@ -1,39 +1,52 @@ 'use strict'; -const Glue = require('glue'); +const Glue = require('@hapi/glue'); +const _ = require('lodash'); const Url = require('url'); const manifest = require('./manifest'); const logo = require('./lib/show-logo'); require('colors'); -module.exports = (options, callback) => { - const config = manifest.get('/'); +function buildManifest (srcManifest, options) { + const resManifest = _.cloneDeep(srcManifest); + const pluginsByName = resManifest.register.plugins; + const parsedSecureUrl = Url.parse(options.dotStencilFile.storeUrl); //The url to a secure page (prompted as login page) const parsedNormalUrl = Url.parse(options.dotStencilFile.normalStoreUrl); //The host url of the homepage; - config.connections[0].port = options.dotStencilFile.port; - config.plugins['./plugins/router/router.module'].storeUrl = parsedSecureUrl.protocol + '//' + parsedSecureUrl.host; - config.plugins['./plugins/router/router.module'].normalStoreUrl = parsedNormalUrl.protocol + '//' + parsedNormalUrl.host; - config.plugins['./plugins/router/router.module'].apiKey = options.dotStencilFile.apiKey; - config.plugins['./plugins/router/router.module'].port = options.dotStencilFile.port; - config.plugins['./plugins/router/router.module'].staplerUrl = options.dotStencilFile.staplerUrl; - config.plugins['./plugins/renderer/renderer.module'].useCache = options.useCache; - config.plugins['./plugins/renderer/renderer.module'].username = options.dotStencilFile.username; - config.plugins['./plugins/renderer/renderer.module'].token = options.dotStencilFile.token; - config.plugins['./plugins/renderer/renderer.module'].accessToken = options.dotStencilFile.accessToken; - config.plugins['./plugins/renderer/renderer.module'].customLayouts = options.dotStencilFile.customLayouts; - config.plugins['./plugins/renderer/renderer.module'].themePath = options.themePath; - config.plugins['./plugins/theme-assets/theme-assets.module'].themePath = options.themePath; - - Glue.compose(config, {relativeTo: __dirname}, (err, server) => { - if (err) { - return callback(err); - } - - server.start(() => { - console.log(logo); - return callback(null, server); - }); - }); -}; + resManifest.server.port = options.dotStencilFile.port; + pluginsByName['./plugins/router/router.module'].storeUrl = parsedSecureUrl.protocol + '//' + parsedSecureUrl.host; + pluginsByName['./plugins/router/router.module'].normalStoreUrl = parsedNormalUrl.protocol + '//' + parsedNormalUrl.host; + pluginsByName['./plugins/router/router.module'].apiKey = options.dotStencilFile.apiKey; + pluginsByName['./plugins/router/router.module'].port = options.dotStencilFile.port; + pluginsByName['./plugins/router/router.module'].staplerUrl = options.dotStencilFile.staplerUrl; + pluginsByName['./plugins/renderer/renderer.module'].useCache = options.useCache; + pluginsByName['./plugins/renderer/renderer.module'].username = options.dotStencilFile.username; + pluginsByName['./plugins/renderer/renderer.module'].token = options.dotStencilFile.token; + pluginsByName['./plugins/renderer/renderer.module'].accessToken = options.dotStencilFile.accessToken; + pluginsByName['./plugins/renderer/renderer.module'].customLayouts = options.dotStencilFile.customLayouts; + pluginsByName['./plugins/renderer/renderer.module'].themePath = options.themePath; + pluginsByName['./plugins/theme-assets/theme-assets.module'].themePath = options.themePath; + + resManifest.register.plugins = _.reduce( + pluginsByName, + (pluginsArr, options, plugin) => [...pluginsArr, { plugin, options }], + [], + ); + + return resManifest; +} + +async function create (options) { + const serverManifest = buildManifest(manifest.get('/'), options); + + const server = await Glue.compose(serverManifest, {relativeTo: __dirname}); + await server.start(); + + console.log(logo); + + return server; +} + +module.exports = { create }; diff --git a/server/manifest.js b/server/manifest.js index 77858ed7..188f803b 100644 --- a/server/manifest.js +++ b/server/manifest.js @@ -1,37 +1,36 @@ -var Confidence = require('confidence'), - config = require('./config'), - criteria = { - env: process.env.NODE_ENV, - }, - store, - manifest; +const Confidence = require('confidence'); +const config = require('./config'); + +const criteria = { + env: process.env.NODE_ENV, +}; -manifest = { +const manifest = { $meta: 'Stencil', - connections: [{ + server: { host: config.get('/server/host'), port: config.get('/server/port'), - options: config.get('/server/options'), - tls: config.get('/server/tls'), - }], - plugins: { - // Third Party Plugins - 'good': config.get('/good'), - // First Party Plugins - './plugins/renderer/renderer.module': {}, - './plugins/router/router.module': {}, - './plugins/theme-assets/theme-assets.module': {}, + }, + register: { + plugins: { + // Third Party Plugins + '@hapi/good': config.get('/good'), + '@hapi/inert': {}, + '@hapi/h2o2': {}, + // First Party Plugins + './plugins/renderer/renderer.module': {}, + './plugins/router/router.module': {}, + './plugins/theme-assets/theme-assets.module': {}, + }, }, }; -store = new Confidence.Store(manifest); +const store = new Confidence.Store(manifest); exports.get = function (key) { - return store.get(key, criteria); }; exports.meta = function (key) { - return store.meta(key, criteria); }; diff --git a/server/plugins/renderer/renderer.module.js b/server/plugins/renderer/renderer.module.js index adde555f..477a6cf5 100644 --- a/server/plugins/renderer/renderer.module.js +++ b/server/plugins/renderer/renderer.module.js @@ -5,51 +5,49 @@ const Boom = require('@hapi/boom'); const Cache = require('memory-cache'); const Crypto = require('crypto'); const Frontmatter = require('front-matter'); +const Wreck = require('wreck'); const Path = require('path'); +const { promisify } = require('util'); +const Url = require('url'); + const LangAssembler = require('../../../lib/lang-assembler'); const Pkg = require('../../../package.json'); const Responses = require('./responses/responses'); const TemplateAssembler = require('../../../lib/template-assembler'); -const Url = require('url'); const Utils = require('../../lib/utils'); -const Wreck = require('wreck'); + const internals = { options: {}, cacheTTL: 1000 * 15, // 15 seconds validCustomTemplatePageTypes: ['brand', 'category', 'page', 'product'], }; -module.exports.register = function (server, options, next) { +function register (server, options) { internals.options = _.defaultsDeep(options, internals.options); server.expose('implementation', internals.implementation); - - next(); -}; - -module.exports.register.attributes = { - name: 'Renderer', - version: '0.0.1', -}; +} /** * Renderer Route Handler * * @param request - * @param reply + * @param h */ -internals.implementation = function (request, reply) { - internals.getResponse(request, function (err, response) { - if (err) { - return reply(Boom.badImplementation(err)); - } +internals.implementation = async function (request, h) { + let response; - if (response.statusCode === 401) { - return reply(response).code(401); - } + try { + response = await internals.getResponse(request); + } catch (err) { + throw Boom.badImplementation(err); + } - response.respond(request, reply); - }); + if (response.statusCode === 401) { + return h.response(response).code(401); + } + + return response.respond(request, h); }; /** @@ -66,11 +64,11 @@ internals.sha1sum = function (input) { * Fetches data from Stapler * * @param request - * @param callback */ -internals.getResponse = function (request, callback) { - const staplerUrlObject = request.app.staplerUrl ? Url.parse(request.app.staplerUrl) : Url.parse(request.app.storeUrl); - const urlObject = _.clone(request.url, true); +internals.getResponse = async function (request) { + const staplerUrlObject = request.app.staplerUrl + ? Url.parse(request.app.staplerUrl) + : Url.parse(request.app.storeUrl); const httpOpts = { rejectUnauthorized: false, headers: internals.getHeaders(request, { @@ -83,20 +81,11 @@ internals.getResponse = function (request, callback) { // Set host to stapler host httpOpts.headers.host = staplerUrlObject.host; - // Convert QueryParams with array values to php compatible names (brackets []) - urlObject.query = _.mapKeys(urlObject.query, function (value, key) { - if (_.isArray(value)) { - return key + '[]'; - } - - return key; - }); - const url = Url.format({ protocol: staplerUrlObject.protocol, host: staplerUrlObject.host, - pathname: urlObject.pathname, - search: urlObject.search, + pathname: request.url.pathname, + search: request.url.search, }); const responseArgs = { @@ -114,49 +103,45 @@ internals.getResponse = function (request, callback) { // check request signature and use cache, if available if (cachedResponse && 'get' === request.method && internals.options.useCache) { // if GET request, return with cached response - return internals.parseResponse(cachedResponse.bcAppData, request, cachedResponse.response, responseArgs, callback); + return await internals.parseResponse(cachedResponse.bcAppData, request, cachedResponse.response, responseArgs); } else if ('get' !== request.method) { // clear when making a non-get request Cache.clear(); } - Wreck.request(request.method, url, httpOpts, function (err, response) { - if (err) { - return callback(err); - } + const response = await promisify(Wreck.request.bind(Wreck))(request.method, url, httpOpts); - if (response.statusCode === 401) { - return callback(null, response); - } + if (response.statusCode === 401) { + return response; + } - if (response.statusCode === 500) { - return callback(new Error('The BigCommerce server responded with a 500 error')); - } + if (response.statusCode === 500) { + throw new Error('The BigCommerce server responded with a 500 error'); + } - if (response.headers['set-cookie']) { - response.headers['set-cookie'] = Utils.stripDomainFromCookies(response.headers['set-cookie']); - } + if (response.headers['set-cookie']) { + response.headers['set-cookie'] = Utils.stripDomainFromCookies(response.headers['set-cookie']); + } - // Response is a redirect - if (response.statusCode >= 301 && response.statusCode <= 303) { - return internals.redirect(response, request, callback); - } + // Response is a redirect + if (response.statusCode >= 301 && response.statusCode <= 303) { + return await internals.redirect(response, request); + } - // parse response - Wreck.read(response, {json: true}, function (err, bcAppData) { - if (err) { - return callback(err); - } + // parse response + const bcAppData = await promisify(Wreck.read.bind(Wreck))(response, {json: true}); - // cache response - Cache.put(requestSignature, { - bcAppData: bcAppData, - response: response, - }, internals.cacheTTL); + // cache response + Cache.put( + requestSignature, + { + bcAppData: bcAppData, + response: response, + }, + internals.cacheTTL, + ); - internals.parseResponse(bcAppData, request, response, responseArgs, callback); - }); - }); + return await internals.parseResponse(bcAppData, request, response, responseArgs); }; /** @@ -166,34 +151,32 @@ internals.getResponse = function (request, callback) { * @param request * @param response * @param responseArgs - * @param callback * @returns {*} */ -internals.parseResponse = function (bcAppData, request, response, responseArgs, callback) { - var resourcesConfig; - var dataRequestSignature; - var httpOptsSignature; - var configuration = request.app.themeConfig.getConfig(); - var httpOpts = responseArgs.httpOpts; - var staplerUrlObject = responseArgs.staplerUrlObject; - var url = responseArgs.url; +internals.parseResponse = async function (bcAppData, request, response, responseArgs) { + let resourcesConfig; + let dataRequestSignature; + let httpOptsSignature; + const configuration = request.app.themeConfig.getConfig(); + const httpOpts = responseArgs.httpOpts; + const staplerUrlObject = responseArgs.staplerUrlObject; + const url = responseArgs.url; if (!_.has(bcAppData, 'pencil_response')) { - delete response.headers['x-frame-options']; // this is a raw response not emitted by TemplateEngine - return callback(null, new Responses.RawResponse( + return new Responses.RawResponse( bcAppData, response.headers, response.statusCode, - )); + ); } // If a remote call, no need to do a second call to get the data, // it has already come back if (bcAppData.remote) { - return callback(null, internals.getPencilResponse(bcAppData, request, response, configuration)); + return internals.getPencilResponse(bcAppData, request, response, configuration); } else { resourcesConfig = internals.getResourceConfig(bcAppData, request, configuration); @@ -208,49 +191,44 @@ internals.parseResponse = function (bcAppData, request, response, responseArgs, // check request signature and use cache, if available if (internals.options.useCache && Cache.get(dataRequestSignature)) { - var cache = Cache.get(dataRequestSignature); - - return callback(null, internals.getPencilResponse(cache.data, request, cache.response, configuration)); + const cache = Cache.get(dataRequestSignature); + return internals.getPencilResponse(cache.data, request, cache.response, configuration); } else { - Wreck.get(url, httpOpts, function (err, response, data) { - if (err) { - return callback(err); - } + const { res, payload } = await Wreck.get(url, httpOpts); - // Response is a redirect - if (response.statusCode >= 301 && response.statusCode <= 303) { - return internals.redirect(response, request, callback); - } + // Response is a redirect + if (res.statusCode >= 301 && res.statusCode <= 303) { + return internals.redirect(res, request); + } - // Response is bad - if (response.statusCode === 500) { - return callback(new Error('The BigCommerce server responded with a 500 error')); - } + // Response is bad + if (res.statusCode === 500) { + throw new Error('The BigCommerce server responded with a 500 error'); + } - try { - data = JSON.parse(data); - } catch (e) { - return callback(e); - } + let data = JSON.parse(payload); - // Data response is bad - if (data.statusCode && data.statusCode === 500) { - return callback(new Error('The BigCommerce server responded with a 500 error')); - } + // Data response is bad + if (data.statusCode && data.statusCode === 500) { + throw new Error('The BigCommerce server responded with a 500 error'); + } - // Cache data - Cache.put(dataRequestSignature, { + // Cache data + Cache.put( + dataRequestSignature, + { data: data, - response: response, - }, internals.cacheTTL); + response: res, + }, + internals.cacheTTL, + ); - if (response.headers['set-cookie']) { - response.headers['set-cookie'] = Utils.stripDomainFromCookies(response.headers['set-cookie']); - } + if (res.headers['set-cookie']) { + res.headers['set-cookie'] = Utils.stripDomainFromCookies(res.headers['set-cookie']); + } - return callback(null, internals.getPencilResponse(data, request, response, configuration)); - }); + return internals.getPencilResponse(data, request, res, configuration); } } }; @@ -264,27 +242,23 @@ internals.parseResponse = function (bcAppData, request, response, responseArgs, * @return {Object} */ internals.getResourceConfig = function (data, request, configuration) { - var frontmatter, - frontmatterRegex = /---\r?\n(?:.|\s)*?\r?\n---\r?\n/g, - missingThemeSettingsRegex = /{{\\s*?theme_settings\\..+?\\s*?}}/g, - frontmatterMatch, - frontmatterContent, - rawTemplate, - resourcesConfig = {}, - templatePath = data.template_file; + const frontmatterRegex = /---\r?\n(?:.|\s)*?\r?\n---\r?\n/g; + const missingThemeSettingsRegex = /{{\\s*?theme_settings\\..+?\\s*?}}/g; + let resourcesConfig = {}; + const templatePath = data.template_file; // If the requested template is not an array, we parse the Frontmatter // If it is an array, then it's an ajax request using `render_with` with multiple components // which don't have Frontmatter and needs to get it's config from the `stencil-config` header. if (templatePath && !_.isArray(templatePath)) { - rawTemplate = TemplateAssembler.getTemplateContentSync(internals.getThemeTemplatesPath(), templatePath); + let rawTemplate = TemplateAssembler.getTemplateContentSync(internals.getThemeTemplatesPath(), templatePath); - frontmatterMatch = rawTemplate.match(frontmatterRegex); + const frontmatterMatch = rawTemplate.match(frontmatterRegex); if (frontmatterMatch !== null) { - frontmatterContent = frontmatterMatch[0]; + let frontmatterContent = frontmatterMatch[0]; // Interpolate theme settings for frontmatter _.forOwn(configuration.settings, function (val, key) { - var regex = '{{\\s*?theme_settings\\.' + key + '\\s*?}}'; + const regex = '{{\\s*?theme_settings\\.' + key + '\\s*?}}'; frontmatterContent = frontmatterContent.replace(new RegExp(regex, 'g'), val); }); @@ -295,8 +269,7 @@ internals.getResourceConfig = function (data, request, configuration) { rawTemplate = rawTemplate.replace(frontmatterRegex, frontmatterContent); } - frontmatter = Frontmatter(rawTemplate); - // Set the config + const frontmatter = Frontmatter(rawTemplate); // Set the config resourcesConfig = frontmatter.attributes; // Merge the frontmatter config with the global resource config if (_.isObject(configuration.resources)) { @@ -319,22 +292,21 @@ internals.getResourceConfig = function (data, request, configuration) { * * @param response * @param request - * @param callback * @returns {*} */ -internals.redirect = function (response, request, callback) { +internals.redirect = async function (response, request) { if (!response.headers.location) { - return callback(new Error('StatusCode is set to 30x but there is no location header to redirect to.')); + throw new Error('StatusCode is set to 30x but there is no location header to redirect to.'); } response.headers.location = Utils.normalizeRedirectUrl(request, response.headers.location); // return a redirect response - return callback(null, new Responses.RedirectResponse( + return new Responses.RedirectResponse( response.headers.location, response.headers, response.statusCode, - )); + ); }; /** @@ -344,20 +316,20 @@ internals.redirect = function (response, request, callback) { * @returns {string} */ internals.getTemplatePath = function (path, data) { - var customLayouts = internals.options.customLayouts || {}; - var pageType = data.page_type; - var templatePath; + const customLayouts = internals.options.customLayouts || {}; + const pageType = data.page_type; + let templatePath; if (internals.validCustomTemplatePageTypes.indexOf(pageType) >= 0 && _.isPlainObject(customLayouts[pageType])) { templatePath = _.findKey(customLayouts[pageType], function(p) { // normalize input to an array if (typeof p === 'string') { - p = [p]; + p = [p]; } - var matches = p.filter(function(url) { - // remove trailing slashes to compare - return url.replace(/\/$/, '') === path.replace(/\/$/, ''); + const matches = p.filter(function(url) { + // remove trailing slashes to compare + return url.replace(/\/$/, '') === path.replace(/\/$/, ''); }); return matches.length > 0; @@ -417,9 +389,6 @@ internals.getPencilResponse = function (data, request, response, configuration) * @param config */ internals.getHeaders = function (request, options, config) { - var currentOptions = {}, - headers; - options = options || {}; // If stencil-config header already set, we don't want to overwrite it @@ -428,6 +397,7 @@ internals.getHeaders = function (request, options, config) { } // Merge in current stencil-options with passed in options + let currentOptions = {}; if (request.headers['stencil-options']) { try { currentOptions = JSON.parse(request.headers['stencil-options']); @@ -436,7 +406,7 @@ internals.getHeaders = function (request, options, config) { } } - headers = { + const headers = { 'stencil-cli': Pkg.version, 'stencil-version': Pkg.config.stencil_version, 'stencil-options': JSON.stringify(_.defaultsDeep(currentOptions, options)), @@ -494,3 +464,9 @@ internals.themeAssembler = { internals.getThemeTemplatesPath = () => { return Path.join(internals.options.themePath, 'templates'); }; + +module.exports = { + register, + name: 'Renderer', + version: '0.0.1', +}; diff --git a/server/plugins/renderer/renderer.module.spec.js b/server/plugins/renderer/renderer.module.spec.js index 56163ac2..f130cfe5 100644 --- a/server/plugins/renderer/renderer.module.spec.js +++ b/server/plugins/renderer/renderer.module.spec.js @@ -5,9 +5,8 @@ const Lab = require('@hapi/lab'); const sinon = require('sinon'); const Wreck = require('wreck'); const Path = require('path'); -const { promisify } = require('util'); -const createStencilCLIServer = require('../../index'); +const Server = require('../../../server'); const lab = exports.lab = Lab.script(); const expect = Code.expect; @@ -31,14 +30,14 @@ lab.describe('Renderer Plugin', () => { themePath: Path.join(process.cwd(), 'test/_mocks/themes/valid'), }; - server = await promisify(createStencilCLIServer)(options); + server = await Server.create(options); // Don't log errors during the test - server.ext('onPostHandler', (request, reply) => { + server.ext('onPostHandler', (request, h) => { if (request.response.isBoom) { - return reply().code(500); + return h.response().code(500); } - reply.continue(); + return h.continue; }); }); @@ -53,7 +52,7 @@ lab.describe('Renderer Plugin', () => { }); lab.after(async () => { - await promisify(server.stop.bind(server))(); + await server.stop(); }); it('should handle fatal errors in the BCApp request', async () => { @@ -64,9 +63,7 @@ lab.describe('Renderer Plugin', () => { wreckRequestStub.callsArgWith(3, new Error('failure')); - const response = await new Promise(resolve => - server.inject(options, resolve), - ); + const response = await server.inject(options); expect(response.statusCode).to.equal(500); }); @@ -78,9 +75,7 @@ lab.describe('Renderer Plugin', () => { }; wreckRequestStub.callsArgWith(3, null, { statusCode: 500 }); - const response = await new Promise(resolve => - server.inject(options, resolve), - ); + const response = await server.inject(options); expect(response.statusCode).to.equal(500); }); @@ -97,9 +92,7 @@ lab.describe('Renderer Plugin', () => { }, }); - const response = await new Promise(resolve => - server.inject(options, resolve), - ); + const response = await server.inject(options); expect(response.statusCode).to.equal(301); expect(response.headers.location).to.equal('http://www.example.com/'); @@ -117,9 +110,7 @@ lab.describe('Renderer Plugin', () => { }, }); - const response = await new Promise(resolve => - server.inject(options, resolve), - ); + const response = await server.inject(options); expect(response.statusCode).to.equal(401); }); diff --git a/server/plugins/renderer/responses/pencil-response.js b/server/plugins/renderer/responses/pencil-response.js index fd0f3a97..f5dc483e 100644 --- a/server/plugins/renderer/responses/pencil-response.js +++ b/server/plugins/renderer/responses/pencil-response.js @@ -3,7 +3,7 @@ const Paper = require('@bigcommerce/stencil-paper'); const internals = {}; module.exports = function (data, assembler) { - this.respond = function (request, reply) { + this.respond = function (request, h) { const paper = new Paper(data.context.settings, data.context.theme_settings, assembler, "handlebars-v3"); // Set the environment to dev @@ -19,32 +19,34 @@ module.exports = function (data, assembler) { const templatePath = internals.getTemplatePath(request, data); - paper.loadTheme(templatePath, data.acceptLanguage) + return paper.loadTheme(templatePath, data.acceptLanguage) .then(() => { if (request.query.debug === 'context') { - return reply(data.context); + return data.context; } }) .catch(err => console.error(err.message.red)) .then(() => paper.renderTheme(templatePath, data)) .catch(err => console.error(err.message.red)) .then(output => { - const response = reply(output); - response.code(data.statusCode); + const response = h.response(output).code(data.statusCode); + if (data.headers['set-cookie']) { response.header('set-cookie', data.headers['set-cookie']); } + return response; - }).catch(err => console.error(err.message.red)); + }) + .catch(err => console.error(err.message.red)); }; }; internals.getTemplatePath = function (request, data) { - var path = data.template_file; + let path = data.template_file; if (request.headers['stencil-options']) { - var options = JSON.parse(request.headers['stencil-options']); + const options = JSON.parse(request.headers['stencil-options']); if (options['render_with'] && typeof options['render_with'] === 'string') { @@ -72,7 +74,7 @@ internals.getTemplatePath = function (request, data) { */ internals.makeDecorator = function (request, context) { return function(content) { - var regex, + let regex, debugBar; if (context.settings) { diff --git a/server/plugins/renderer/responses/raw-response.js b/server/plugins/renderer/responses/raw-response.js index e6bafc03..5bc28abf 100644 --- a/server/plugins/renderer/responses/raw-response.js +++ b/server/plugins/renderer/responses/raw-response.js @@ -14,16 +14,16 @@ const internals = { */ function RawResponse(data, headers, statusCode) { - this.respond = function (request, reply) { - var payload = data; + this.respond = function (request, h) { + let payload = data; internals.stubActiveConfig = Utils.int2uuid(request.app.themeConfig.variationIndex + 1); - if (request.url.path.startsWith('/checkout.php') || request.url.path.startsWith('/finishorder.php')) { + if (request.path.startsWith('/checkout.php') || request.path.startsWith('/finishorder.php')) { payload = appendCss(payload.toString('utf8')); } // To be removed when we go to Phase 3 - if (request.url.path.startsWith('/checkout')) { + if (request.path.startsWith('/checkout')) { payload = payload.toString('utf8') .replace( /http[s]?:\/\/.*?\/optimized-checkout.css/, @@ -31,7 +31,7 @@ function RawResponse(data, headers, statusCode) { ); } - const response = reply(payload).code(statusCode); + const response = h.response(payload).code(statusCode); _.each(headers, (value, name) => { if (['transfer-encoding', 'content-length'].indexOf(name) === -1) { diff --git a/server/plugins/renderer/responses/raw-response.spec.js b/server/plugins/renderer/responses/raw-response.spec.js index 73903464..335540c2 100644 --- a/server/plugins/renderer/responses/raw-response.spec.js +++ b/server/plugins/renderer/responses/raw-response.spec.js @@ -19,11 +19,12 @@ lab.describe('RawResponse', () => { const statusCode = 200; let request; let response; - let reply; + let h; lab.beforeEach(() => { request = { - url: {path: '/'}, + url: {}, + path: '/', app: {themeConfig: {variationIndex: 1}}, }; @@ -32,31 +33,33 @@ lab.describe('RawResponse', () => { header: sinon.spy(), }; - reply = sinon.stub().returns(response); + h = { + response: sinon.stub().returns(response), + }; }); lab.describe('respond()', () => { it('should respond', () => { const rawResponse = new RawResponse(data, headers, statusCode); - rawResponse.respond(request, reply); + rawResponse.respond(request, h); - expect(reply.called).to.be.true(); + expect(h.response.called).to.be.true(); }); it('should append checkout css if is the checkout page', () => { - request.url.path = '/checkout.php?blah=blah'; + request.path = '/checkout.php?blah=blah'; const rawResponse = new RawResponse(data, headers, statusCode); - rawResponse.respond(request, reply); + rawResponse.respond(request, h); - expect(reply.lastCall.args[0]).to.contain(` { const rawResponse = new RawResponse(data, headers, statusCode); - rawResponse.respond(request, reply); + rawResponse.respond(request, h); expect(response.header.neverCalledWith('transfer-encoding')).to.be.true(); expect(response.header.calledWith('content-type')).to.be.true(); diff --git a/server/plugins/renderer/responses/redirect-response.js b/server/plugins/renderer/responses/redirect-response.js index 94c72c14..3832ad27 100644 --- a/server/plugins/renderer/responses/redirect-response.js +++ b/server/plugins/renderer/responses/redirect-response.js @@ -1,28 +1,24 @@ -var _ = require('lodash'); +const _ = require('lodash'); module.exports = function (location, headers, statusCode) { - this.respond = function (request, reply) { - var response = reply.redirect(location); - - response.statusCode = statusCode; + this.respond = function (request, h) { + const response = h.redirect(location).code(statusCode); _.each(headers, (value, name) => { switch (name) { - case 'transfer-encoding': - break; - - case 'set-cookie': - response.header('set-cookie', value.map(cookie => { - // remove domain & secure attributes - return cookie - .replace(/; Secure$/, '') - .replace(/; domain=(.+)$/, ''); - })); - break; - - default: - response.header(name, value); + case 'transfer-encoding': + break; + case 'set-cookie': + response.header('set-cookie', value.map(cookie => { + // remove domain & secure attributes + return cookie + .replace(/; Secure$/, '') + .replace(/; domain=(.+)$/, ''); + })); + break; + default: + response.header(name, value); } }); diff --git a/server/plugins/router/router.module.js b/server/plugins/router/router.module.js index e2565302..b9e119c6 100644 --- a/server/plugins/router/router.module.js +++ b/server/plugins/router/router.module.js @@ -2,10 +2,10 @@ const _ = require('lodash'); const ThemeConfig = require('../../../lib/theme-config'); const internals = { options: { - storeUrl: '', - apiKey: '', - staplerUrl: '', - port: '', + storeUrl: '', + apiKey: '', + staplerUrl: '', + port: '', }, paths: { renderer: '/{url*}', @@ -19,29 +19,28 @@ const internals = { }, }; -module.exports.register = function(server, options, next) { +function register (server, options) { internals.options = _.defaultsDeep(options, internals.options); - server.ext('onRequest', function(request, reply) { + server.ext('onRequest', (request, h) => { request.app.storeUrl = internals.options.storeUrl; request.app.normalStoreUrl = internals.options.normalStoreUrl; request.app.apiKey = internals.options.apiKey; request.app.staplerUrl = internals.options.staplerUrl; request.app.themeConfig = ThemeConfig.getInstance(); - reply.continue(); + return h.continue; }); - server.dependency(['Renderer', 'ThemeAssets'], internals.registerRoutes); - return next(); -}; + server.dependency(['inert', 'h2o2', 'Renderer', 'ThemeAssets'], internals.registerRoutes); +} -internals.registerRoutes = function(server, next) { +internals.registerRoutes = function(server) { server.route([ { method: 'GET', path: internals.paths.renderer, - config: { + options: { cors: true, state: { failAction: 'log', @@ -52,7 +51,7 @@ internals.registerRoutes = function(server, next) { { method: ['POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], path: internals.paths.renderer, - config: { + options: { cors: true, payload: { output: 'stream', @@ -69,7 +68,7 @@ internals.registerRoutes = function(server, next) { method: 'GET', path: internals.paths.cdnAssets, handler: server.plugins.ThemeAssets.assetHandler, - config: { + options: { state: { failAction: 'log', }, @@ -83,7 +82,7 @@ internals.registerRoutes = function(server, next) { path: './assets', }, }, - config: { + options: { state: { failAction: 'log', }, @@ -102,7 +101,7 @@ internals.registerRoutes = function(server, next) { xforward: true, }, }, - config: { + options: { state: { failAction: 'log', }, @@ -121,7 +120,7 @@ internals.registerRoutes = function(server, next) { xforward: true, }, }, - config: { + options: { state: { failAction: 'log', }, @@ -133,7 +132,7 @@ internals.registerRoutes = function(server, next) { handler: { file: './assets/favicon.ico', }, - config: { + options: { state: { failAction: 'log', }, @@ -143,7 +142,7 @@ internals.registerRoutes = function(server, next) { method: 'GET', path: internals.paths.cssFiles, handler: server.plugins.ThemeAssets.cssHandler, - config: { + options: { state: { failAction: 'log', }, @@ -154,34 +153,31 @@ internals.registerRoutes = function(server, next) { path: internals.paths.graphQL, handler: { proxy: { - mapUri: function (req, cb) { - return cb( - null, - `${internals.options.storeUrl}${req.path}`, - Object.assign( // Add 'origin' and 'host' headers to request before proxying - req.headers, - { - origin: internals.options.storeUrl, - host: internals.options.storeUrl.replace(/http[s]?:\/\//, ''), - }, - ), - ); - }, + mapUri: req => ({ + uri: `${internals.options.storeUrl}${req.path}`, + // Note, that we should modify the original req.headers to make it work + headers: Object.assign( // Add 'origin' and 'host' headers to request before proxying + req.headers, + { + origin: internals.options.storeUrl, + host: internals.options.storeUrl.replace(/http[s]?:\/\//, ''), + }, + ), + }), passThrough: true, }, }, - config: { + options: { state: { failAction: 'log', }, }, }, ]); - - return next(); }; -module.exports.register.attributes = { +module.exports = { + register, name: 'Router', version: '0.0.1', }; diff --git a/server/plugins/router/router.module.spec.js b/server/plugins/router/router.module.spec.js index 79002416..27c8d884 100644 --- a/server/plugins/router/router.module.spec.js +++ b/server/plugins/router/router.module.spec.js @@ -1,7 +1,6 @@ const Code = require('code'); -const Hapi = require('hapi'); +const Hapi = require('@hapi/hapi'); const Lab = require('@hapi/lab'); -const { promisify } = require('util'); const router = require('./router.module'); @@ -11,49 +10,46 @@ const describe = lab.describe; const it = lab.it; describe('Router', () => { - const server = new Hapi.Server(); - const RendererPluginMock = { - register: function(server, options, next) { - server.expose('implementation', (request, reply) => reply('RendererHandlerFired')); - - next(); - }, + const SERVER_OPTIONS = { + port: 3000, }; - const ThemeAssetsMock = { - register: function(server, options, next) { - server.expose('cssHandler', (request, reply) => reply('CssHandlerFired')); - server.expose('assetHandler', (request, reply) => reply('assetHandlerFired')); - - next(); - }, + const ROUTER_OPTIONS = { + storeUrl: 'https://store-abc124.mybigcommerce.com', + normalStoreUrl: 'http://s1234567890.mybigcommerce.com', + port: SERVER_OPTIONS.port, }; - RendererPluginMock.register.attributes = { + const server = new Hapi.Server(SERVER_OPTIONS); + const RendererPluginMock = { + register (server) { + server.expose('implementation', (request, h) => h.response('RendererHandlerFired')); + }, name: 'Renderer', version: '0.0.1', }; - - ThemeAssetsMock.register.attributes = { + const ThemeAssetsMock = { + register (server) { + server.expose('cssHandler', (request, h) => h.response('CssHandlerFired')); + server.expose('assetHandler', (request, h) => h.response('assetHandlerFired')); + }, name: 'ThemeAssets', version: '0.0.1', }; - server.connection({ - port: 3000, - }); - lab.before(async () => { - await promisify(server.register.bind(server))([ + await server.register([ + require('@hapi/inert'), + require('@hapi/h2o2'), RendererPluginMock, ThemeAssetsMock, - router, + { plugin: router, options: ROUTER_OPTIONS }, ]); - await promisify(server.start.bind(server))(); + await server.start(); }); lab.after(async () => { - await promisify(server.stop.bind(server))(); + await server.stop(); }); it('should call the Renderer handler', async () => { @@ -62,9 +58,7 @@ describe('Router', () => { url: '/test', }; - const response = await new Promise(resolve => - server.inject(options, resolve), - ); + const response = await server.inject(options); expect(response.statusCode).to.equal(200); expect(response.payload).to.equal('RendererHandlerFired'); @@ -76,9 +70,7 @@ describe('Router', () => { url: '/stencil/123/css/file.css', }; - const response = await new Promise(resolve => - server.inject(options, resolve), - ); + const response = await server.inject(options); expect(response.statusCode).to.equal(200); expect(response.payload).to.equal('CssHandlerFired'); @@ -90,9 +82,7 @@ describe('Router', () => { url: '/stencil/123/js/file.js', }; - const response = await new Promise(resolve => - server.inject(options, resolve), - ); + const response = await server.inject(options); expect(response.statusCode).to.equal(200); expect(response.payload).to.equal('assetHandlerFired'); @@ -102,19 +92,15 @@ describe('Router', () => { const options = { method: 'POST', url: '/graphql', - headers: { 'authorization': 'abc123' }, + headers: { 'authorization': 'auth123' }, }; - const response = await new Promise(resolve => - server.inject(options, resolve), - ); - - expect(response.request.payload.headers).to.include( - { - authorization: 'abc123', - origin: 'https://store-abc123.mybigcommerce.com', - host: 'store-abc123.mybigcommerce.com', - }, - ); + const response = await server.inject(options); + + expect(response.request.payload.headers).to.include({ + authorization: 'auth123', + origin: 'https://store-abc124.mybigcommerce.com', + host: 'store-abc124.mybigcommerce.com', + }); }); }); diff --git a/server/plugins/theme-assets/theme-assets.module.js b/server/plugins/theme-assets/theme-assets.module.js index 2dceeb73..61e35756 100644 --- a/server/plugins/theme-assets/theme-assets.module.js +++ b/server/plugins/theme-assets/theme-assets.module.js @@ -1,26 +1,22 @@ const _ = require('lodash'); const Boom = require('@hapi/boom'); +const StencilStyles = require('@bigcommerce/stencil-styles'); +const Path = require('path'); +const { promisify } = require("util"); + const CssAssembler = require('../../../lib/css-assembler'); const Utils = require('../../lib/utils'); -const Path = require('path'); -const StencilStyles = require('@bigcommerce/stencil-styles'); + const internals = { options: {}, }; -module.exports.register = function (server, options, next) { +function register (server, options) { internals.options = _.defaultsDeep(options, internals.options); server.expose('cssHandler', internals.cssHandler); server.expose('assetHandler', internals.assetHandler); - - return next(); -}; - -module.exports.register.attributes = { - name: 'ThemeAssets', - version: '0.0.1', -}; +} /** * Get the variation index from the "ConfigId" in the css filename @@ -48,13 +44,13 @@ internals.getOriginalFileName = fileName => { * CSS Compiler Handler. This utilises the CSS Assembler to gather all of the CSS files and then the * StencilStyles plugin to compile them all. * @param request - * @param reply + * @param h */ -internals.cssHandler = function (request, reply) { +internals.cssHandler = async function (request, h) { const variationIndex = internals.getVariationIndex(request.params.fileName); if (!request.app.themeConfig.variationExists(variationIndex)) { - return reply(Boom.notFound('Variation ' + (variationIndex + 1) + ' does not exist.')); + throw Boom.notFound('Variation ' + (variationIndex + 1) + ' does not exist.'); } // Set the variation to get the right theme configuration @@ -66,46 +62,59 @@ internals.cssHandler = function (request, reply) { const pathToFile = Path.join(fileParts.dir, fileParts.name + '.scss'); const basePath = Path.join(internals.getThemeAssetsPath(), 'scss'); - CssAssembler.assemble(pathToFile, basePath, 'scss', (err, files) => { - const configuration = request.app.themeConfig.getConfig(); - - var params = { - data: files[pathToFile], - files: files, - dest: Path.join('/assets/css', fileName), - themeSettings: configuration.settings, - sourceMap: true, - autoprefixerOptions: { - cascade: configuration.autoprefixer_cascade, - browsers: configuration.autoprefixer_browsers, - }, - }; - - let stencilStyles = new StencilStyles(); - stencilStyles.compileCss('scss', params, (err, css) => { - if (err) { - console.error(err); - return reply(Boom.badData(err)); - } - - reply(css).type('text/css'); - }); - }); + let files; + try { + files = await promisify(CssAssembler.assemble)(pathToFile, basePath, 'scss'); + } catch (err) { + console.error(err); + throw Boom.badData(err); + } + + const configuration = request.app.themeConfig.getConfig(); + + const params = { + data: files[pathToFile], + files: files, + dest: Path.join('/assets/css', fileName), + themeSettings: configuration.settings, + sourceMap: true, + autoprefixerOptions: { + cascade: configuration.autoprefixer_cascade, + browsers: configuration.autoprefixer_browsers, + }, + }; + const stencilStyles = new StencilStyles(); + + let css; + try { + css = await promisify(stencilStyles.compileCss.bind(stencilStyles))('scss', params); + } catch (err) { + console.error(err); + throw Boom.badData(err); + } + + return h.response(css).type('text/css'); }; /** * Assets handler * * @param request - * @param reply + * @param h */ -internals.assetHandler = function (request, reply) { - var filePath = Path.join(internals.getThemeAssetsPath(), request.params.fileName); +internals.assetHandler = function (request, h) { + const filePath = Path.join(internals.getThemeAssetsPath(), request.params.fileName); - reply.file(filePath); + return h.file(filePath); }; internals.getThemeAssetsPath = () => { return Path.join(internals.options.themePath, 'assets'); }; + +module.exports = { + register, + name: 'ThemeAssets', + version: '0.0.1', +}; From e8edabba7ab56aa526195aa814e3696fe61682f4 Mon Sep 17 00:00:00 2001 From: MaxGenash Date: Fri, 14 Aug 2020 20:32:02 +0300 Subject: [PATCH 2/2] refactor(/bin/stencil-start): rearrange some variables --- bin/stencil-start | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/bin/stencil-start b/bin/stencil-start index dc2759c6..b34bedbc 100755 --- a/bin/stencil-start +++ b/bin/stencil-start @@ -1,27 +1,29 @@ #!/usr/bin/env node +require('colors'); const Bs = require('browser-sync').create(); -const Cycles = require('../lib/cycles'); const recursiveRead = require('recursive-readdir'); const Async = require('async'); -const templateAssembler = require('../lib/template-assembler'); +const Wreck = require('wreck'); const Fs = require('fs'); -const JspmAssembler = require('../lib/jspm-assembler'); const Path = require('path'); +const Url = require('url'); + +const Cycles = require('../lib/cycles'); +const templateAssembler = require('../lib/template-assembler'); +const JspmAssembler = require('../lib/jspm-assembler'); const Pkg = require('../package.json'); const Program = require('commander'); const Server = require('../server'); const ThemeConfig = require('../lib/theme-config'); const buildConfig = require('../lib/build-config'); -const Url = require('url'); -const Wreck = require('wreck'); const jsonLint = require('../lib/json-lint'); const versionCheck = require('../lib/version-check'); -let themePath = process.cwd(); -let templatePath = Path.join(themePath, 'templates'); -let dotStencilFilePath = Path.join(themePath, '.stencil'); -let themeConfigPath = Path.join(themePath, 'config.json'); -require('colors'); + +const themePath = process.cwd(); +const templatePath = Path.join(themePath, 'templates'); +const dotStencilFilePath = Path.join(themePath, '.stencil'); +const themeConfigPath = Path.join(themePath, 'config.json'); Program .version(Pkg.version) @@ -32,6 +34,11 @@ Program .option('-n, --no-cache', 'Turns off caching for API resource data per storefront page. The cache lasts for 5 minutes before automatically refreshing.') .parse(process.argv); +// tunnel value should be true/false or a string with name +// https://browsersync.io/docs/options#option-tunnel +const tunnel = typeof Program.tunnel === 'string' + ? Program.tunnel + : Boolean(Program.tunnel) // convert undefined/true -> false/true if (!versionCheck()) { return; @@ -211,12 +218,6 @@ async function startServer() { watchIgnored = buildConfig.watchOptions.ignored; } - const tunnel = typeof Program.tunnel === 'undefined' - ? false - : Program.tunnel === true - ? true - : Program.tunnel; - Bs.init({ open: !!Program.open, port: browserSyncPort,