├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── examples └── express-hot-routes │ ├── package.json │ ├── routes.js │ └── server.js ├── index.js ├── package-lock.json ├── package.json └── test ├── fixtures ├── accept-children │ ├── dependency.js │ └── main.js ├── accept-json-children │ ├── dependency.json │ └── main.js └── accept-subchildren-bubble │ ├── dependency-level1.js │ ├── dependency-level2.js │ ├── dependency.js │ └── main.js └── integration ├── accept-children.js ├── accept-json-children.js └── accept-subchildren-bubble.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - "10" 5 | - "12" 6 | - "14" 7 | install: 8 | - npm install 9 | script: 10 | - npm test 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Andrey Sidorov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hot-module-replacement 2 | Hot module replacement for node.js 3 | 4 | This module tries to mimic [webpack HMR](https://webpack.js.org/api/hot-module-replacement/) API 5 | 6 | ## Installation 7 | ```js 8 | npm install --save-dev hot-module-replacement 9 | ``` 10 | 11 | ## Usage 12 | 13 | Put this code somewhere in your code to initialise hot reload 14 | 15 | ```js 16 | require('hot-module-replacement')({ 17 | // options are optional 18 | ignore: /node_modules/ // regexp to decide if module should be ignored; also can be a function accepting string and returning true/false 19 | }) 20 | ``` 21 | 22 | You need to explicitly mark any subtree as 'hot reloadable' by calling `hot.accept()` 23 | 24 | ```js 25 | let foo = require('./util/foo.js'); 26 | 27 | if (module.hot) { 28 | module.hot.accept('./util/foo', () => { 29 | // if foo.js or any files that foo.js depend on are modified this callback is invoked 30 | foo = require('./util/foo.js'); // by this time module cache entry for 'foo' already cleaned and module reloaded, requiring again is the easiest way of geting reference to new module. We need to assign it to local foo variable to make our local code in this file aware of it. 31 | }) 32 | } 33 | ``` 34 | 35 | ## Similar projects: 36 | 37 | - https://github.com/Julien-R44/hot-hook 38 | - https://github.com/braidnetworks/dynohot 39 | - https://github.com/yyrdl/dload ( forces you to use own module api for replaceables modules ) 40 | - https://github.com/rlindskog/solit ( transpiles all files on start ) 41 | - https://github.com/fgnass/node-dev 42 | 43 | ### webpack hmr on the server 44 | - https://github.com/palmerhq/backpack 45 | - https://hackernoon.com/hot-reload-all-the-things-ec0fed8ab0 46 | - https://github.com/jaredpalmer/razzle 47 | - https://github.com/jlongster/backend-with-webpack ( and http://jlongster.com/Backend-Apps-with-Webpack--Part-III ) 48 | -------------------------------------------------------------------------------- /examples/express-hot-routes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-hot-routes", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "express": "^4.15.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/express-hot-routes/routes.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const router = express.Router(); 4 | 5 | router.get('/hello', (req, res) => res.json({ hello: 1000 })); 6 | router.get('/hi', (req, res) => res.json({ hi: 2 })); 7 | 8 | module.exports = router; 9 | -------------------------------------------------------------------------------- /examples/express-hot-routes/server.js: -------------------------------------------------------------------------------- 1 | //if (process.env.NODE_ENV === 'development') { 2 | require('hot-module-replacement')({ 3 | ignore: /node_modules/ 4 | }); 5 | //} 6 | 7 | const express = require('express'); 8 | const app = express(); 9 | 10 | let router = require('./routes'); 11 | app.use('/', function(req, res, next) { 12 | router(req, res, next); 13 | }); 14 | 15 | require('http').createServer(app).listen(3000); 16 | 17 | if (module.hot) { 18 | module.hot.accept('./routes', () => { 19 | router = require('./routes'); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const watch = require('node-watch'); 2 | const Module = require('module'); 3 | const isBuiltinModule = require('is-builtin-module'); 4 | 5 | // https://github.com/webpack/webpack/blob/0257f6c6e41255cf26230c099fb90140f1f0e0bb/lib/HotModuleReplacement.runtime.js#L77 6 | // https://github.com/masotime/require-watch/blob/master/src/index.js 7 | 8 | function enableModuleReplacement(opts) { 9 | // TODO: use proxy here instead of just monkey-patching so all furure extensions are tracked automatically 10 | const savedExtensions = Module._extensions; 11 | const _extensions = {}; 12 | Object.keys(savedExtensions).forEach(extension => { 13 | _extensions[extension] = function(module, filename) { 14 | addHMRHooks(module); 15 | savedExtensions[extension](module, filename); 16 | }; 17 | }); 18 | 19 | Module._extensions = _extensions; 20 | 21 | // module is changed, which dependency needs to be reloaded? 22 | function collectDependencies(module) { 23 | let paths = []; 24 | function pathsToAcceptingModules(path, root) { 25 | const requiredMe = parents[root.filename]; 26 | if (module.hot._selfAccepted) { 27 | paths.push(path.concat(root.filename)); 28 | return; 29 | } 30 | if (module.hot._selfDeclined) { 31 | return; 32 | } 33 | for (let next in requiredMe) { 34 | let parentHotRuntime = requiredMe[next].hot; 35 | if (parentHotRuntime._acceptedDependencies[root.filename]) { 36 | paths.push(path.concat(root.filename)); 37 | continue; 38 | } 39 | if (parentHotRuntime._declinedDependencies[root.filename]) { 40 | continue; 41 | } 42 | pathsToAcceptingModules(path.concat(root.filename), requiredMe[next]); 43 | } 44 | } 45 | pathsToAcceptingModules([], module); 46 | return paths; 47 | } 48 | 49 | opts = opts || {}; 50 | function ignore(path) { 51 | if (isBuiltinModule(path)) { 52 | return true; 53 | } 54 | if (typeof opts.ignore === 'function') { 55 | return opts.ignore(path); 56 | } 57 | if (opts.ignore instanceof RegExp) { 58 | return !!opts.ignore.exec(path); 59 | } 60 | } 61 | 62 | const watching = {}; 63 | function startWatching(path) { 64 | if (ignore(path)) { 65 | return; 66 | } 67 | if (watching[path]) { 68 | return; 69 | } 70 | watching[path] = watch(path, { persistent: false }, function(eventType, filename) { 71 | const oldModule = require.cache[path]; 72 | 73 | const deps = oldModule ? collectDependencies(oldModule) : []; 74 | const reloaded = {}; 75 | 76 | for (let d = 0; d < deps.length; ++d) { 77 | for (let l = 0; l < deps[d].length; ++l) { 78 | const path = deps[d][l]; 79 | if (reloaded[path]) { 80 | continue; 81 | } 82 | reloaded[path] = true; 83 | const oldModule = require.cache[path]; 84 | if (oldModule.hot._disposeHandlers) { 85 | oldModule.hot._disposeHandlers.forEach(h => h()); 86 | } 87 | const newModule = new Module(path, oldModule.parent); 88 | addHMRHooks(newModule); 89 | try { 90 | newModule.load(path); 91 | require.cache[path] = newModule; 92 | const ps = parents[path]; 93 | for (parentPath in ps) { 94 | let parent = require.cache[parentPath]; 95 | if (parent.hot._acceptedDependencies[path]) { 96 | // TODO: try/catch here? 97 | parent.hot._acceptedDependencies[path](path); 98 | } 99 | } 100 | } catch (e) { 101 | console.log(e); 102 | } 103 | } 104 | } 105 | }); 106 | } 107 | 108 | // monkey-patch require 109 | const originalRequire = Module.prototype.require; 110 | const originalLoad = Module._load; 111 | const originalCompile = Module.prototype._compile; 112 | 113 | const parents = {}; 114 | Module._load = function(request, parent, isMain) { 115 | const requirePath = Module._resolveFilename(request, parent); 116 | if (ignore(requirePath)) { 117 | return originalLoad(request, parent, isMain); 118 | } 119 | 120 | startWatching(requirePath); 121 | const parentPath = parent && parent.filename; 122 | const myParents = parents[requirePath]; 123 | if (parentPath) { 124 | if (!myParents) { 125 | var p = {}; 126 | p[parentPath] = parent; 127 | parents[requirePath] = p; 128 | } else { 129 | myParents[parentPath] = parent; 130 | } 131 | } 132 | return originalLoad(request, parent, isMain); 133 | }; 134 | 135 | if (module.parent) { 136 | if (!module.parent.hot) { 137 | addHMRHooks(module.parent); 138 | } 139 | } 140 | 141 | function addHMRHooks(module) { 142 | const resolve = name => { 143 | return Module._resolveFilename(name, module); 144 | }; 145 | // copied directly from webpack HMR 146 | // https://github.com/webpack/webpack/blob/0257f6c6e41255cf26230c099fb90140f1f0e0bb/lib/HotModuleReplacement.runtime.js#L77 147 | var hot = { 148 | // private stuff 149 | _acceptedDependencies: {}, 150 | _declinedDependencies: {}, 151 | _selfAccepted: false, 152 | _selfDeclined: false, 153 | _disposeHandlers: [], 154 | // _main: hotCurrentChildModule !== moduleId, 155 | 156 | // Module API 157 | active: true, 158 | accept: function(dep, callback) { 159 | if (typeof dep === 'undefined') hot._selfAccepted = true; 160 | else if (typeof dep === 'function') hot._selfAccepted = dep; 161 | else if (typeof dep === 'object') 162 | for (var i = 0; i < dep.length; i++) 163 | hot._acceptedDependencies[resolve(dep[i])] = callback || function() {}; 164 | else hot._acceptedDependencies[resolve(dep)] = callback || function() {}; 165 | }, 166 | decline: function(dep) { 167 | if (typeof dep === 'undefined') hot._selfDeclined = true; 168 | else if (typeof dep === 'object') 169 | for (var i = 0; i < dep.length; i++) hot._declinedDependencies[resolve(dep[i])] = true; 170 | else hot._declinedDependencies[resolve(dep)] = true; 171 | }, 172 | dispose: function(callback) { 173 | hot._disposeHandlers.push(callback); 174 | }, 175 | addDisposeHandler: function(callback) { 176 | hot._disposeHandlers.push(callback); 177 | }, 178 | removeDisposeHandler: function(callback) { 179 | var idx = hot._disposeHandlers.indexOf(callback); 180 | if (idx >= 0) hot._disposeHandlers.splice(idx, 1); 181 | } 182 | /* 183 | // TODO: Management API 184 | check: hotCheck, 185 | apply: hotApply, 186 | 187 | status: function(l) { 188 | if (!l) return hotStatus; 189 | hotStatusHandlers.push(l); 190 | }, 191 | addStatusHandler: function(l) { 192 | hotStatusHandlers.push(l); 193 | }, 194 | removeStatusHandler: function(l) { 195 | var idx = hotStatusHandlers.indexOf(l); 196 | if (idx >= 0) hotStatusHandlers.splice(idx, 1); 197 | } 198 | 199 | //inherit from previous dispose call 200 | data: hotCurrentModuleData[moduleId] 201 | */ 202 | }; 203 | module.hot = hot; 204 | } 205 | } 206 | 207 | module.exports = enableModuleReplacement; 208 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hot-module-replacement", 3 | "version": "3.0.4", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", 11 | "dev": true 12 | }, 13 | "ansi-colors": { 14 | "version": "4.1.1", 15 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 16 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 17 | "dev": true 18 | }, 19 | "ansi-regex": { 20 | "version": "3.0.0", 21 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 22 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 23 | "dev": true 24 | }, 25 | "ansi-styles": { 26 | "version": "3.2.1", 27 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 28 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 29 | "dev": true, 30 | "requires": { 31 | "color-convert": "^1.9.0" 32 | } 33 | }, 34 | "anymatch": { 35 | "version": "3.1.1", 36 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 37 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 38 | "dev": true, 39 | "requires": { 40 | "normalize-path": "^3.0.0", 41 | "picomatch": "^2.0.4" 42 | } 43 | }, 44 | "argparse": { 45 | "version": "1.0.10", 46 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 47 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 48 | "dev": true, 49 | "requires": { 50 | "sprintf-js": "~1.0.2" 51 | } 52 | }, 53 | "array.prototype.map": { 54 | "version": "1.0.2", 55 | "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", 56 | "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", 57 | "dev": true, 58 | "requires": { 59 | "define-properties": "^1.1.3", 60 | "es-abstract": "^1.17.0-next.1", 61 | "es-array-method-boxes-properly": "^1.0.0", 62 | "is-string": "^1.0.4" 63 | } 64 | }, 65 | "balanced-match": { 66 | "version": "1.0.0", 67 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 68 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 69 | "dev": true 70 | }, 71 | "binary-extensions": { 72 | "version": "2.1.0", 73 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", 74 | "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", 75 | "dev": true 76 | }, 77 | "brace-expansion": { 78 | "version": "1.1.11", 79 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 80 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 81 | "dev": true, 82 | "requires": { 83 | "balanced-match": "^1.0.0", 84 | "concat-map": "0.0.1" 85 | } 86 | }, 87 | "braces": { 88 | "version": "3.0.2", 89 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 90 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 91 | "dev": true, 92 | "requires": { 93 | "fill-range": "^7.0.1" 94 | } 95 | }, 96 | "browser-stdout": { 97 | "version": "1.3.1", 98 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 99 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 100 | "dev": true 101 | }, 102 | "builtin-modules": { 103 | "version": "1.1.1", 104 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 105 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 106 | }, 107 | "camelcase": { 108 | "version": "5.3.1", 109 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 110 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 111 | "dev": true 112 | }, 113 | "chalk": { 114 | "version": "2.4.2", 115 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 116 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 117 | "dev": true, 118 | "requires": { 119 | "ansi-styles": "^3.2.1", 120 | "escape-string-regexp": "^1.0.5", 121 | "supports-color": "^5.3.0" 122 | }, 123 | "dependencies": { 124 | "supports-color": { 125 | "version": "5.5.0", 126 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 127 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 128 | "dev": true, 129 | "requires": { 130 | "has-flag": "^3.0.0" 131 | } 132 | } 133 | } 134 | }, 135 | "chokidar": { 136 | "version": "3.3.1", 137 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", 138 | "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", 139 | "dev": true, 140 | "requires": { 141 | "anymatch": "~3.1.1", 142 | "braces": "~3.0.2", 143 | "fsevents": "~2.1.2", 144 | "glob-parent": "~5.1.0", 145 | "is-binary-path": "~2.1.0", 146 | "is-glob": "~4.0.1", 147 | "normalize-path": "~3.0.0", 148 | "readdirp": "~3.3.0" 149 | } 150 | }, 151 | "cliui": { 152 | "version": "5.0.0", 153 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 154 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 155 | "dev": true, 156 | "requires": { 157 | "string-width": "^3.1.0", 158 | "strip-ansi": "^5.2.0", 159 | "wrap-ansi": "^5.1.0" 160 | }, 161 | "dependencies": { 162 | "ansi-regex": { 163 | "version": "4.1.0", 164 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 165 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 166 | "dev": true 167 | }, 168 | "string-width": { 169 | "version": "3.1.0", 170 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 171 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 172 | "dev": true, 173 | "requires": { 174 | "emoji-regex": "^7.0.1", 175 | "is-fullwidth-code-point": "^2.0.0", 176 | "strip-ansi": "^5.1.0" 177 | } 178 | }, 179 | "strip-ansi": { 180 | "version": "5.2.0", 181 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 182 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 183 | "dev": true, 184 | "requires": { 185 | "ansi-regex": "^4.1.0" 186 | } 187 | } 188 | } 189 | }, 190 | "color-convert": { 191 | "version": "1.9.3", 192 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 193 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 194 | "dev": true, 195 | "requires": { 196 | "color-name": "1.1.3" 197 | } 198 | }, 199 | "color-name": { 200 | "version": "1.1.3", 201 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 202 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 203 | "dev": true 204 | }, 205 | "concat-map": { 206 | "version": "0.0.1", 207 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 208 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 209 | "dev": true 210 | }, 211 | "debug": { 212 | "version": "3.2.6", 213 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 214 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 215 | "dev": true, 216 | "requires": { 217 | "ms": "^2.1.1" 218 | } 219 | }, 220 | "decamelize": { 221 | "version": "1.2.0", 222 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 223 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 224 | "dev": true 225 | }, 226 | "define-properties": { 227 | "version": "1.1.3", 228 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 229 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 230 | "dev": true, 231 | "requires": { 232 | "object-keys": "^1.0.12" 233 | } 234 | }, 235 | "diff": { 236 | "version": "4.0.2", 237 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 238 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 239 | "dev": true 240 | }, 241 | "emoji-regex": { 242 | "version": "7.0.3", 243 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 244 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 245 | "dev": true 246 | }, 247 | "es-abstract": { 248 | "version": "1.17.6", 249 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", 250 | "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", 251 | "dev": true, 252 | "requires": { 253 | "es-to-primitive": "^1.2.1", 254 | "function-bind": "^1.1.1", 255 | "has": "^1.0.3", 256 | "has-symbols": "^1.0.1", 257 | "is-callable": "^1.2.0", 258 | "is-regex": "^1.1.0", 259 | "object-inspect": "^1.7.0", 260 | "object-keys": "^1.1.1", 261 | "object.assign": "^4.1.0", 262 | "string.prototype.trimend": "^1.0.1", 263 | "string.prototype.trimstart": "^1.0.1" 264 | } 265 | }, 266 | "es-array-method-boxes-properly": { 267 | "version": "1.0.0", 268 | "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", 269 | "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", 270 | "dev": true 271 | }, 272 | "es-get-iterator": { 273 | "version": "1.1.0", 274 | "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", 275 | "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", 276 | "dev": true, 277 | "requires": { 278 | "es-abstract": "^1.17.4", 279 | "has-symbols": "^1.0.1", 280 | "is-arguments": "^1.0.4", 281 | "is-map": "^2.0.1", 282 | "is-set": "^2.0.1", 283 | "is-string": "^1.0.5", 284 | "isarray": "^2.0.5" 285 | } 286 | }, 287 | "es-to-primitive": { 288 | "version": "1.2.1", 289 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 290 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 291 | "dev": true, 292 | "requires": { 293 | "is-callable": "^1.1.4", 294 | "is-date-object": "^1.0.1", 295 | "is-symbol": "^1.0.2" 296 | } 297 | }, 298 | "escape-string-regexp": { 299 | "version": "1.0.5", 300 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 301 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 302 | "dev": true 303 | }, 304 | "esprima": { 305 | "version": "4.0.1", 306 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 307 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 308 | "dev": true 309 | }, 310 | "fill-range": { 311 | "version": "7.0.1", 312 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 313 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 314 | "dev": true, 315 | "requires": { 316 | "to-regex-range": "^5.0.1" 317 | } 318 | }, 319 | "find-up": { 320 | "version": "4.1.0", 321 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 322 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 323 | "dev": true, 324 | "requires": { 325 | "locate-path": "^5.0.0", 326 | "path-exists": "^4.0.0" 327 | } 328 | }, 329 | "flat": { 330 | "version": "4.1.0", 331 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", 332 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", 333 | "dev": true, 334 | "requires": { 335 | "is-buffer": "~2.0.3" 336 | } 337 | }, 338 | "fs.realpath": { 339 | "version": "1.0.0", 340 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 341 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 342 | "dev": true 343 | }, 344 | "fsevents": { 345 | "version": "2.1.3", 346 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 347 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 348 | "dev": true, 349 | "optional": true 350 | }, 351 | "function-bind": { 352 | "version": "1.1.1", 353 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 354 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 355 | "dev": true 356 | }, 357 | "get-caller-file": { 358 | "version": "2.0.5", 359 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 360 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 361 | "dev": true 362 | }, 363 | "glob": { 364 | "version": "7.1.6", 365 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 366 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 367 | "dev": true, 368 | "requires": { 369 | "fs.realpath": "^1.0.0", 370 | "inflight": "^1.0.4", 371 | "inherits": "2", 372 | "minimatch": "^3.0.4", 373 | "once": "^1.3.0", 374 | "path-is-absolute": "^1.0.0" 375 | } 376 | }, 377 | "glob-parent": { 378 | "version": "5.1.1", 379 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 380 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 381 | "dev": true, 382 | "requires": { 383 | "is-glob": "^4.0.1" 384 | } 385 | }, 386 | "growl": { 387 | "version": "1.10.5", 388 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 389 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 390 | "dev": true 391 | }, 392 | "has": { 393 | "version": "1.0.3", 394 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 395 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 396 | "dev": true, 397 | "requires": { 398 | "function-bind": "^1.1.1" 399 | } 400 | }, 401 | "has-flag": { 402 | "version": "3.0.0", 403 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 404 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 405 | "dev": true 406 | }, 407 | "has-symbols": { 408 | "version": "1.0.1", 409 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 410 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 411 | "dev": true 412 | }, 413 | "he": { 414 | "version": "1.2.0", 415 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 416 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 417 | "dev": true 418 | }, 419 | "inflight": { 420 | "version": "1.0.6", 421 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 422 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 423 | "dev": true, 424 | "requires": { 425 | "once": "^1.3.0", 426 | "wrappy": "1" 427 | } 428 | }, 429 | "inherits": { 430 | "version": "2.0.4", 431 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 432 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 433 | "dev": true 434 | }, 435 | "is-arguments": { 436 | "version": "1.0.4", 437 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", 438 | "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", 439 | "dev": true 440 | }, 441 | "is-binary-path": { 442 | "version": "2.1.0", 443 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 444 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 445 | "dev": true, 446 | "requires": { 447 | "binary-extensions": "^2.0.0" 448 | } 449 | }, 450 | "is-buffer": { 451 | "version": "2.0.4", 452 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 453 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", 454 | "dev": true 455 | }, 456 | "is-builtin-module": { 457 | "version": "1.0.0", 458 | "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 459 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 460 | "requires": { 461 | "builtin-modules": "^1.0.0" 462 | } 463 | }, 464 | "is-callable": { 465 | "version": "1.2.0", 466 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", 467 | "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", 468 | "dev": true 469 | }, 470 | "is-date-object": { 471 | "version": "1.0.2", 472 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 473 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 474 | "dev": true 475 | }, 476 | "is-extglob": { 477 | "version": "2.1.1", 478 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 479 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 480 | "dev": true 481 | }, 482 | "is-fullwidth-code-point": { 483 | "version": "2.0.0", 484 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 485 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 486 | "dev": true 487 | }, 488 | "is-glob": { 489 | "version": "4.0.1", 490 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 491 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 492 | "dev": true, 493 | "requires": { 494 | "is-extglob": "^2.1.1" 495 | } 496 | }, 497 | "is-map": { 498 | "version": "2.0.1", 499 | "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", 500 | "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", 501 | "dev": true 502 | }, 503 | "is-number": { 504 | "version": "7.0.0", 505 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 506 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 507 | "dev": true 508 | }, 509 | "is-regex": { 510 | "version": "1.1.0", 511 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", 512 | "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", 513 | "dev": true, 514 | "requires": { 515 | "has-symbols": "^1.0.1" 516 | } 517 | }, 518 | "is-set": { 519 | "version": "2.0.1", 520 | "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", 521 | "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", 522 | "dev": true 523 | }, 524 | "is-string": { 525 | "version": "1.0.5", 526 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", 527 | "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", 528 | "dev": true 529 | }, 530 | "is-symbol": { 531 | "version": "1.0.3", 532 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 533 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 534 | "dev": true, 535 | "requires": { 536 | "has-symbols": "^1.0.1" 537 | } 538 | }, 539 | "isarray": { 540 | "version": "2.0.5", 541 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", 542 | "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", 543 | "dev": true 544 | }, 545 | "isexe": { 546 | "version": "2.0.0", 547 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 548 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 549 | "dev": true 550 | }, 551 | "iterate-iterator": { 552 | "version": "1.0.1", 553 | "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", 554 | "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", 555 | "dev": true 556 | }, 557 | "iterate-value": { 558 | "version": "1.0.2", 559 | "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", 560 | "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", 561 | "dev": true, 562 | "requires": { 563 | "es-get-iterator": "^1.0.2", 564 | "iterate-iterator": "^1.0.1" 565 | } 566 | }, 567 | "js-yaml": { 568 | "version": "3.13.1", 569 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 570 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 571 | "dev": true, 572 | "requires": { 573 | "argparse": "^1.0.7", 574 | "esprima": "^4.0.0" 575 | } 576 | }, 577 | "locate-path": { 578 | "version": "5.0.0", 579 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 580 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 581 | "dev": true, 582 | "requires": { 583 | "p-locate": "^4.1.0" 584 | } 585 | }, 586 | "lodash": { 587 | "version": "4.17.19", 588 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", 589 | "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", 590 | "dev": true 591 | }, 592 | "log-symbols": { 593 | "version": "3.0.0", 594 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", 595 | "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", 596 | "dev": true, 597 | "requires": { 598 | "chalk": "^2.4.2" 599 | } 600 | }, 601 | "minimatch": { 602 | "version": "3.0.4", 603 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 604 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 605 | "dev": true, 606 | "requires": { 607 | "brace-expansion": "^1.1.7" 608 | } 609 | }, 610 | "mocha": { 611 | "version": "8.0.1", 612 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz", 613 | "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==", 614 | "dev": true, 615 | "requires": { 616 | "ansi-colors": "4.1.1", 617 | "browser-stdout": "1.3.1", 618 | "chokidar": "3.3.1", 619 | "debug": "3.2.6", 620 | "diff": "4.0.2", 621 | "escape-string-regexp": "1.0.5", 622 | "find-up": "4.1.0", 623 | "glob": "7.1.6", 624 | "growl": "1.10.5", 625 | "he": "1.2.0", 626 | "js-yaml": "3.13.1", 627 | "log-symbols": "3.0.0", 628 | "minimatch": "3.0.4", 629 | "ms": "2.1.2", 630 | "object.assign": "4.1.0", 631 | "promise.allsettled": "1.0.2", 632 | "serialize-javascript": "3.0.0", 633 | "strip-json-comments": "3.0.1", 634 | "supports-color": "7.1.0", 635 | "which": "2.0.2", 636 | "wide-align": "1.1.3", 637 | "workerpool": "6.0.0", 638 | "yargs": "13.3.2", 639 | "yargs-parser": "13.1.2", 640 | "yargs-unparser": "1.6.0" 641 | } 642 | }, 643 | "ms": { 644 | "version": "2.1.2", 645 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 646 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 647 | "dev": true 648 | }, 649 | "node-watch": { 650 | "version": "0.5.9", 651 | "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.5.9.tgz", 652 | "integrity": "sha512-W0SgGKaB9qSCfFfNj2uQZ/5BlVumaNHjVCAPdEoXrkEJ3ynSf/806LEz1rbDFbJ4+PL9G8IxRkJJTvZndd5D9g==" 653 | }, 654 | "nopt": { 655 | "version": "1.0.10", 656 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", 657 | "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", 658 | "dev": true, 659 | "requires": { 660 | "abbrev": "1" 661 | } 662 | }, 663 | "normalize-path": { 664 | "version": "3.0.0", 665 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 666 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 667 | "dev": true 668 | }, 669 | "object-inspect": { 670 | "version": "1.8.0", 671 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", 672 | "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", 673 | "dev": true 674 | }, 675 | "object-keys": { 676 | "version": "1.1.1", 677 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 678 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 679 | "dev": true 680 | }, 681 | "object.assign": { 682 | "version": "4.1.0", 683 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 684 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 685 | "dev": true, 686 | "requires": { 687 | "define-properties": "^1.1.2", 688 | "function-bind": "^1.1.1", 689 | "has-symbols": "^1.0.0", 690 | "object-keys": "^1.0.11" 691 | } 692 | }, 693 | "once": { 694 | "version": "1.4.0", 695 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 696 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 697 | "dev": true, 698 | "requires": { 699 | "wrappy": "1" 700 | } 701 | }, 702 | "p-limit": { 703 | "version": "2.3.0", 704 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 705 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 706 | "dev": true, 707 | "requires": { 708 | "p-try": "^2.0.0" 709 | } 710 | }, 711 | "p-locate": { 712 | "version": "4.1.0", 713 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 714 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 715 | "dev": true, 716 | "requires": { 717 | "p-limit": "^2.2.0" 718 | } 719 | }, 720 | "p-try": { 721 | "version": "2.2.0", 722 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 723 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 724 | "dev": true 725 | }, 726 | "path-exists": { 727 | "version": "4.0.0", 728 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 729 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 730 | "dev": true 731 | }, 732 | "path-is-absolute": { 733 | "version": "1.0.1", 734 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 735 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 736 | "dev": true 737 | }, 738 | "picomatch": { 739 | "version": "2.2.2", 740 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 741 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 742 | "dev": true 743 | }, 744 | "promise.allsettled": { 745 | "version": "1.0.2", 746 | "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", 747 | "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", 748 | "dev": true, 749 | "requires": { 750 | "array.prototype.map": "^1.0.1", 751 | "define-properties": "^1.1.3", 752 | "es-abstract": "^1.17.0-next.1", 753 | "function-bind": "^1.1.1", 754 | "iterate-value": "^1.0.0" 755 | } 756 | }, 757 | "readdirp": { 758 | "version": "3.3.0", 759 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", 760 | "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", 761 | "dev": true, 762 | "requires": { 763 | "picomatch": "^2.0.7" 764 | } 765 | }, 766 | "require-directory": { 767 | "version": "2.1.1", 768 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 769 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 770 | "dev": true 771 | }, 772 | "require-main-filename": { 773 | "version": "2.0.0", 774 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 775 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 776 | "dev": true 777 | }, 778 | "serialize-javascript": { 779 | "version": "3.0.0", 780 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", 781 | "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==", 782 | "dev": true 783 | }, 784 | "set-blocking": { 785 | "version": "2.0.0", 786 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 787 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 788 | "dev": true 789 | }, 790 | "sprintf-js": { 791 | "version": "1.0.3", 792 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 793 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 794 | "dev": true 795 | }, 796 | "string-width": { 797 | "version": "2.1.1", 798 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 799 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 800 | "dev": true, 801 | "requires": { 802 | "is-fullwidth-code-point": "^2.0.0", 803 | "strip-ansi": "^4.0.0" 804 | } 805 | }, 806 | "string.prototype.trimend": { 807 | "version": "1.0.1", 808 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", 809 | "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", 810 | "dev": true, 811 | "requires": { 812 | "define-properties": "^1.1.3", 813 | "es-abstract": "^1.17.5" 814 | } 815 | }, 816 | "string.prototype.trimstart": { 817 | "version": "1.0.1", 818 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", 819 | "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", 820 | "dev": true, 821 | "requires": { 822 | "define-properties": "^1.1.3", 823 | "es-abstract": "^1.17.5" 824 | } 825 | }, 826 | "strip-ansi": { 827 | "version": "4.0.0", 828 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 829 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 830 | "dev": true, 831 | "requires": { 832 | "ansi-regex": "^3.0.0" 833 | } 834 | }, 835 | "strip-json-comments": { 836 | "version": "3.0.1", 837 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 838 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 839 | "dev": true 840 | }, 841 | "supports-color": { 842 | "version": "7.1.0", 843 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 844 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 845 | "dev": true, 846 | "requires": { 847 | "has-flag": "^4.0.0" 848 | }, 849 | "dependencies": { 850 | "has-flag": { 851 | "version": "4.0.0", 852 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 853 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 854 | "dev": true 855 | } 856 | } 857 | }, 858 | "to-regex-range": { 859 | "version": "5.0.1", 860 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 861 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 862 | "dev": true, 863 | "requires": { 864 | "is-number": "^7.0.0" 865 | } 866 | }, 867 | "touch": { 868 | "version": "1.0.0", 869 | "resolved": "https://registry.npmjs.org/touch/-/touch-1.0.0.tgz", 870 | "integrity": "sha1-RJy+LbrlqMgDjjDXH6D/RklHxN4=", 871 | "dev": true, 872 | "requires": { 873 | "nopt": "~1.0.10" 874 | } 875 | }, 876 | "which": { 877 | "version": "2.0.2", 878 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 879 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 880 | "dev": true, 881 | "requires": { 882 | "isexe": "^2.0.0" 883 | } 884 | }, 885 | "which-module": { 886 | "version": "2.0.0", 887 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 888 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 889 | "dev": true 890 | }, 891 | "wide-align": { 892 | "version": "1.1.3", 893 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 894 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 895 | "dev": true, 896 | "requires": { 897 | "string-width": "^1.0.2 || 2" 898 | } 899 | }, 900 | "workerpool": { 901 | "version": "6.0.0", 902 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", 903 | "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", 904 | "dev": true 905 | }, 906 | "wrap-ansi": { 907 | "version": "5.1.0", 908 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 909 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 910 | "dev": true, 911 | "requires": { 912 | "ansi-styles": "^3.2.0", 913 | "string-width": "^3.0.0", 914 | "strip-ansi": "^5.0.0" 915 | }, 916 | "dependencies": { 917 | "ansi-regex": { 918 | "version": "4.1.0", 919 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 920 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 921 | "dev": true 922 | }, 923 | "string-width": { 924 | "version": "3.1.0", 925 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 926 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 927 | "dev": true, 928 | "requires": { 929 | "emoji-regex": "^7.0.1", 930 | "is-fullwidth-code-point": "^2.0.0", 931 | "strip-ansi": "^5.1.0" 932 | } 933 | }, 934 | "strip-ansi": { 935 | "version": "5.2.0", 936 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 937 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 938 | "dev": true, 939 | "requires": { 940 | "ansi-regex": "^4.1.0" 941 | } 942 | } 943 | } 944 | }, 945 | "wrappy": { 946 | "version": "1.0.2", 947 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 948 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 949 | "dev": true 950 | }, 951 | "y18n": { 952 | "version": "4.0.0", 953 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 954 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", 955 | "dev": true 956 | }, 957 | "yargs": { 958 | "version": "13.3.2", 959 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", 960 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", 961 | "dev": true, 962 | "requires": { 963 | "cliui": "^5.0.0", 964 | "find-up": "^3.0.0", 965 | "get-caller-file": "^2.0.1", 966 | "require-directory": "^2.1.1", 967 | "require-main-filename": "^2.0.0", 968 | "set-blocking": "^2.0.0", 969 | "string-width": "^3.0.0", 970 | "which-module": "^2.0.0", 971 | "y18n": "^4.0.0", 972 | "yargs-parser": "^13.1.2" 973 | }, 974 | "dependencies": { 975 | "ansi-regex": { 976 | "version": "4.1.0", 977 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 978 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 979 | "dev": true 980 | }, 981 | "find-up": { 982 | "version": "3.0.0", 983 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 984 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 985 | "dev": true, 986 | "requires": { 987 | "locate-path": "^3.0.0" 988 | } 989 | }, 990 | "locate-path": { 991 | "version": "3.0.0", 992 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 993 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 994 | "dev": true, 995 | "requires": { 996 | "p-locate": "^3.0.0", 997 | "path-exists": "^3.0.0" 998 | } 999 | }, 1000 | "p-locate": { 1001 | "version": "3.0.0", 1002 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1003 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1004 | "dev": true, 1005 | "requires": { 1006 | "p-limit": "^2.0.0" 1007 | } 1008 | }, 1009 | "path-exists": { 1010 | "version": "3.0.0", 1011 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1012 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1013 | "dev": true 1014 | }, 1015 | "string-width": { 1016 | "version": "3.1.0", 1017 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1018 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1019 | "dev": true, 1020 | "requires": { 1021 | "emoji-regex": "^7.0.1", 1022 | "is-fullwidth-code-point": "^2.0.0", 1023 | "strip-ansi": "^5.1.0" 1024 | } 1025 | }, 1026 | "strip-ansi": { 1027 | "version": "5.2.0", 1028 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1029 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1030 | "dev": true, 1031 | "requires": { 1032 | "ansi-regex": "^4.1.0" 1033 | } 1034 | } 1035 | } 1036 | }, 1037 | "yargs-parser": { 1038 | "version": "13.1.2", 1039 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", 1040 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", 1041 | "dev": true, 1042 | "requires": { 1043 | "camelcase": "^5.0.0", 1044 | "decamelize": "^1.2.0" 1045 | } 1046 | }, 1047 | "yargs-unparser": { 1048 | "version": "1.6.0", 1049 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", 1050 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", 1051 | "dev": true, 1052 | "requires": { 1053 | "flat": "^4.1.0", 1054 | "lodash": "^4.17.15", 1055 | "yargs": "^13.3.0" 1056 | } 1057 | } 1058 | } 1059 | } 1060 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hot-module-replacement", 3 | "version": "3.0.4", 4 | "description": "Hot module replacement for node.js", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha -t 5000 ./test/integration/*.js" 8 | }, 9 | "files": [ 10 | "index.js" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/sidorares/hot-module-replacement.git" 15 | }, 16 | "keywords": [], 17 | "author": "", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/sidorares/hot-module-replacement/issues" 21 | }, 22 | "homepage": "https://github.com/sidorares/hot-module-replacement#readme", 23 | "devDependencies": { 24 | "mocha": "^8.0.1", 25 | "touch": "^1.0.0" 26 | }, 27 | "dependencies": { 28 | "is-builtin-module": "^1.0.0", 29 | "node-watch": "^0.5.8" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/fixtures/accept-children/dependency.js: -------------------------------------------------------------------------------- 1 | const loadTimeTs = process.hrtime(); 2 | const ns = loadTimeTs[0] * 1e9 + loadTimeTs[1]; 3 | 4 | module.exports = function() { 5 | process.send && 6 | process.send({ message: 'call from dependency', param: loadTimeTs }); 7 | return ''; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/accept-children/main.js: -------------------------------------------------------------------------------- 1 | require('../../../index.js')(); 2 | 3 | let dep = require('./dependency.js'); 4 | 5 | const main = () => { 6 | dep(); 7 | }; 8 | 9 | process.send && process.send({ message: 'start' }); 10 | main(); 11 | 12 | const interval = setInterval(() => { 13 | // nothing, just to have something in the event loop 14 | }, 1000); 15 | 16 | process.on('message', function(msg) { 17 | process.exit(0); 18 | }); 19 | 20 | if (module.hot) { 21 | module.hot.accept('./dependency', function(updatedDep) { 22 | process.send && 23 | process.send({ 24 | message: 'call from accept handler' 25 | }); 26 | dep = require('./dependency'); 27 | main(); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /test/fixtures/accept-json-children/dependency.json: -------------------------------------------------------------------------------- 1 | { "value": 42 } 2 | -------------------------------------------------------------------------------- /test/fixtures/accept-json-children/main.js: -------------------------------------------------------------------------------- 1 | require('../../../index.js')(); 2 | 3 | let dep = require('./dependency.json'); 4 | 5 | const main = () => { 6 | process.send && process.send({ message: 'call from main', value: dep.value }); 7 | }; 8 | 9 | process.send && process.send({ message: 'start' }); 10 | main(); 11 | 12 | const interval = setInterval(() => { 13 | // nothing, just to have something in the event loop 14 | }, 1000); 15 | 16 | process.on('message', function(msg) { 17 | process.exit(0); 18 | }); 19 | 20 | if (module.hot) { 21 | module.hot.accept('./dependency', function(updatedDep) { 22 | dep = require('./dependency'); 23 | process.send && 24 | process.send({ 25 | message: 'call from accept handler', 26 | value: dep.value 27 | }); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /test/fixtures/accept-subchildren-bubble/dependency-level1.js: -------------------------------------------------------------------------------- 1 | const loadTimeTs = process.hrtime(); 2 | const ns = loadTimeTs[0] * 1e9 + loadTimeTs[1]; 3 | 4 | const dep2 = require('./dependency-level2'); 5 | 6 | module.exports = function() { 7 | process.send && 8 | process.send({ message: 'call from dependency 1', param: loadTimeTs }); 9 | return '1-' + dep2(); 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/accept-subchildren-bubble/dependency-level2.js: -------------------------------------------------------------------------------- 1 | const loadTimeTs = process.hrtime(); 2 | const ns = loadTimeTs[0] * 1e9 + loadTimeTs[1]; 3 | 4 | module.exports = function() { 5 | process.send && 6 | process.send({ message: 'call from dependency 2', param: loadTimeTs }); 7 | return '=2'; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/accept-subchildren-bubble/dependency.js: -------------------------------------------------------------------------------- 1 | const loadTimeTs = process.hrtime(); 2 | const ns = loadTimeTs[0] * 1e9 + loadTimeTs[1]; 3 | 4 | const dep = require('./dependency-level1'); 5 | 6 | module.exports = function() { 7 | process.send && 8 | process.send({ message: 'call from dependency', param: loadTimeTs }); 9 | return '0' + dep(); 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/accept-subchildren-bubble/main.js: -------------------------------------------------------------------------------- 1 | require('../../../index.js')(); 2 | 3 | let dep = require('./dependency.js'); 4 | let dep2 = require('./dependency-level2'); 5 | 6 | const main = () => { 7 | console.log('Dep:', dep()); 8 | }; 9 | 10 | process.send && process.send({ message: 'start' }); 11 | main(); 12 | 13 | const interval = setInterval(() => { 14 | // nothing, just to have something in the event loop 15 | }, 1000); 16 | 17 | process.on('message', function(msg) { 18 | process.exit(0); 19 | }); 20 | 21 | if (module.hot) { 22 | module.hot.accept(['./dependency'], function(updatedDep) { 23 | console.log('Accept handler!', updatedDep); 24 | process.send && 25 | process.send({ 26 | message: 'call from accept handler' 27 | }); 28 | dep = require('./dependency'); 29 | main(); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /test/integration/accept-children.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const touch = require('touch'); 3 | const path = require('path'); 4 | const fork = require('child_process').fork; 5 | 6 | describe('when one level dependency is updated', () => { 7 | describe('and parent accepts it', () => { 8 | it('should call accept handler', done => { 9 | const child = fork('../fixtures/accept-children/main.js', { 10 | cwd: __dirname 11 | }); 12 | 13 | let touched = false; 14 | let accepted = false; 15 | const depMessages = []; 16 | 17 | child.on('message', message => { 18 | switch (message.message) { 19 | case 'start': 20 | touched = true; 21 | touch.sync( 22 | path.join(__dirname, '../fixtures/accept-children/dependency.js') 23 | ); 24 | break; 25 | case 'call from accept handler': 26 | if (!touched) { 27 | done(new Error('accepted before dependency is changed')); 28 | } 29 | accepted = true; 30 | child.on('exit', e => { 31 | assert.equal(e, 0); 32 | done(); 33 | }); 34 | child.send('exit'); 35 | break; 36 | case 'call from dependency': 37 | depMessages.push(message.param); 38 | if (accepted) { 39 | // this is second call 40 | assert.equal(depMessages.length, 2); 41 | // and it should be from updated dependency. 42 | // Check time in milliseconds between calls 43 | // if module was NOT reloaded it should be zero 44 | // we expect second call to come from reloaded verion 45 | assert( 46 | (depMessages[1][0] - depMessages[0][0]) * 1e9 + 47 | (depMessages[1][1] - depMessages[0][1]) > 48 | 0 49 | ); 50 | } 51 | break; 52 | } 53 | }); 54 | }); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /test/integration/accept-json-children.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const path = require('path'); 3 | const fs = require('fs'); 4 | const fork = require('child_process').fork; 5 | 6 | describe('when one level JSON dependency is updated', () => { 7 | describe('and parent accepts it', () => { 8 | it('should call accept handler', done => { 9 | const child = fork('../fixtures/accept-json-children/main.js', { 10 | cwd: __dirname 11 | }); 12 | 13 | let touched = false; 14 | let accepted = false; 15 | const depMessages = []; 16 | const updatedValue = +new Date(); 17 | 18 | child.on('message', message => { 19 | switch (message.message) { 20 | case 'start': 21 | break; 22 | case 'call from main': 23 | assert.equal(message.value, 42); 24 | touched = true; 25 | fs.writeFileSync( 26 | path.join(__dirname, '../fixtures/accept-json-children/dependency.json'), 27 | JSON.stringify({ value: updatedValue }) 28 | ); 29 | break; 30 | 31 | case 'call from accept handler': 32 | if (!touched) { 33 | done(new Error('accepted before dependency is changed')); 34 | } 35 | accepted = true; 36 | child.on('exit', e => { 37 | assert.equal(e, 0); 38 | assert.equal(message.value, updatedValue); 39 | done(); 40 | }); 41 | child.send('exit'); 42 | break; 43 | } 44 | }); 45 | }); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /test/integration/accept-subchildren-bubble.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const touch = require('touch'); 3 | const path = require('path'); 4 | const fork = require('child_process').fork; 5 | 6 | describe('when nested dependency is updated', () => { 7 | describe('and parent accepts dependency that depend on it', () => { 8 | it('should call accept handler and reload all dependencies on path', done => { 9 | const child = fork('../fixtures/accept-subchildren-bubble/main.js', { 10 | cwd: __dirname 11 | }); 12 | 13 | let touched = false; 14 | let accepted = false; 15 | const depMessages = []; 16 | const depMessages1 = []; 17 | const depMessages2 = []; 18 | 19 | child.on('message', message => { 20 | switch (message.message) { 21 | case 'start': 22 | touched = true; 23 | touch.sync( 24 | path.join( 25 | __dirname, 26 | '../fixtures/accept-subchildren-bubble/dependency-level2.js' 27 | ) 28 | ); 29 | break; 30 | case 'call from accept handler': 31 | if (!touched) { 32 | done(new Error('accepted before dependency is changed')); 33 | } 34 | accepted = true; 35 | child.on('exit', e => { 36 | assert.equal(e, 0); 37 | assert.equal(depMessages.length, 2); 38 | assert.equal(depMessages1.length, 2); 39 | assert.equal(depMessages2.length, 2); 40 | done(); 41 | }); 42 | child.send('exit'); 43 | break; 44 | case 'call from dependency 1': 45 | depMessages1.push(message.param); 46 | if (accepted) { 47 | // this is second call 48 | assert.equal(depMessages1.length, 2); 49 | // and it should be from updated dependency. 50 | // Check time in milliseconds between calls 51 | // if module was NOT reloaded it should be zero 52 | // we expect second call to come from reloaded verion 53 | assert( 54 | (depMessages1[1][0] - depMessages1[0][0]) * 1e9 + 55 | (depMessages1[1][1] - depMessages1[0][1]) > 56 | 0 57 | ); 58 | } 59 | break; 60 | case 'call from dependency 2': 61 | depMessages2.push(message.param); 62 | if (accepted) { 63 | // this is second call 64 | assert.equal(depMessages2.length, 2); 65 | // and it should be from updated dependency. 66 | // Check time in milliseconds between calls 67 | // if module was NOT reloaded it should be zero 68 | // we expect second call to come from reloaded verion 69 | assert( 70 | (depMessages2[1][0] - depMessages2[0][0]) * 1e9 + 71 | (depMessages2[1][1] - depMessages2[0][1]) > 72 | 0 73 | ); 74 | } 75 | break; 76 | case 'call from dependency': 77 | depMessages.push(message.param); 78 | if (accepted) { 79 | // this is second call 80 | assert.equal(depMessages.length, 2); 81 | // and it should be from updated dependency. 82 | // Check time in milliseconds between calls 83 | // if module was NOT reloaded it should be zero 84 | // we expect second call to come from reloaded verion 85 | assert( 86 | (depMessages[1][0] - depMessages[0][0]) * 1e9 + 87 | (depMessages[1][1] - depMessages[0][1]) > 88 | 0 89 | ); 90 | } 91 | break; 92 | } 93 | }); 94 | }); 95 | }); 96 | }); 97 | --------------------------------------------------------------------------------