├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── heads-logo.png ├── npmi.d.ts ├── npmi.js ├── package-lock.json ├── package.json └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | 17 | .idea/ 18 | **iml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "4" 5 | - "8" 6 | before_install: npm i -g mocha 7 | notifications: 8 | email: 9 | recipients: 10 | - leiko@braindead.fr 11 | on_success: never 12 | on_failure: always 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Maxime Tricoire 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | npmi [![Build Status](https://travis-ci.org/maxleiko/npmi.svg)](https://travis-ci.org/maxleiko/npmi) 2 | ==== 3 | NodeJS package that gives a simplier API to npm install (programatically installs things) 4 | 5 | [![NPM](https://nodei.co/npm/npmi.png?downloads=true&downloadRank=true)](https://nodei.co/npm/npmi/) 6 | 7 | ### npmi versions scheme 8 | - **^1**: uses `npm@^2` 9 | - **^2**: uses `npm@^3` 10 | - **^3**: uses `npm@^5` 11 | - **^4**: uses [`global-npm`](https://github.com/dracupid/global-npm) (meaning `npm` is no longer a dependency of `npmi`) 12 | 13 | > :warning: Be advised that `npm` in its `v5+` will symlink local modules from the destination directory to the actual module directory instead of "installing" them old-school style (which is a breaking change regarding the previous npm versions) 14 | 15 | ### Options 16 | #### options.name 17 | __Type:__ `String` 18 | __Optional:__ `true` 19 | 20 | If you don't specify a `name` in options, but just a `path`, __npmi__ will do the same as if you were at this path in a terminal and executing `npm install` 21 | Otherwise, it will install the module specified by this name like `npm install module-name` does. 22 | 23 | #### options.version 24 | __Type:__ `String` 25 | __Optional:__ `true` 26 | __Default__ `'latest'` 27 | 28 | Desired version for installation 29 | 30 | #### options.path 31 | __Type:__ `String` 32 | __Optional:__ `true` 33 | __Default__ `'.'` 34 | 35 | Desired location for installation (note that if you specified /some/foo/path, __npm__ will automatically create a `node_modules` sub-folder at this location, resulting in `/some/foo/path/node_modules`). So don't specify the `node_modules` part in your path 36 | 37 | #### options.forceInstall 38 | __Type:__ `Boolean` 39 | __Optional:__ `true` 40 | __Default__ `false` 41 | 42 | If true, __npmi__ will install `options.name` module even though it has already been installed. 43 | If false, __npmi__ will check if the module is already installed, if it is, it will also check if the installed version is equal to `options.version`, otherwise, it will install `options.name@options.version` 44 | 45 | #### options.localInstall 46 | __Type:__ `Boolean` 47 | __Optional:__ `true` 48 | __Default__ `false` 49 | 50 | Allows __npmi__ to install local module that are not on __npm registry__. If, you want to install a local module by specifying its full path in `options.name`, you need to set this to `true`. 51 | 52 | #### options.npmLoad 53 | __Type:__ `Object` 54 | __Optional:__ `true` 55 | __Default__ `{loglevel: 'silent'}` 56 | 57 | This object is given to __npm__ and allows you to do some fine-grained npm configurations. 58 | It is processed by __npm__ like command-line arguments but within an Object map ([npm-config](https://www.npmjs.org/doc/misc/npm-config.html)) 59 | 60 | ### Usage example 61 | ```js 62 | var npmi = require('npmi'); 63 | var path = require('path'); 64 | 65 | console.log(npmi.NPM_VERSION); // prints the installed npm version used by npmi 66 | 67 | 68 | var options = { 69 | name: 'your-module', // your module name 70 | version: '0.0.1', // expected version [default: 'latest'] 71 | path: '.', // installation path [default: '.'] 72 | forceInstall: false, // force install if set to true (even if already installed, it will do a reinstall) [default: false] 73 | npmLoad: { // npm.load(options, callback): this is the "options" given to npm.load() 74 | loglevel: 'silent' // [default: {loglevel: 'silent'}] 75 | } 76 | }; 77 | npmi(options, function (err, result) { 78 | if (err) { 79 | if (err.code === npmi.LOAD_ERR) console.log('npm load error'); 80 | else if (err.code === npmi.INSTALL_ERR) console.log('npm install error'); 81 | return console.log(err.message); 82 | } 83 | 84 | // installed 85 | console.log(options.name+'@'+options.version+' installed successfully in '+path.resolve(options.path)); 86 | }); 87 | ``` 88 | 89 | ### Acknowledgements 90 | This work has been done in the context of the [HEADS Project](http://heads-project.eu/) 91 | ![HEADS LOGO](heads-logo.png) 92 | 93 | ### Contributors 94 | - [lukaskollmer](https://github.com/lukaskollmer) 95 | - [karanjthakkar](https://github.com/karanjthakkar) 96 | -------------------------------------------------------------------------------- /heads-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxleiko/npmi/82bd049a02d1a30fe662f75035f92b82bdeac9cd/heads-logo.png -------------------------------------------------------------------------------- /npmi.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created with IntelliJ IDEA. 3 | * User: leiko 4 | * Date: 30/01/14 5 | * Time: 10:28 6 | */ 7 | declare function npmi(options: npmi.IOptions, callback: npmi.ICallback): void; 8 | declare module npmi { 9 | const NPM: INPM; 10 | const LOAD_ERR = 'NPM_LOAD_ERR'; 11 | const INSTALL_ERR = 'NPM_INSTALL_ERR'; 12 | const VIEW_ERR = 'NPM_VIEW_ERR'; 13 | const NPM_VERSION: string; 14 | interface INPM { 15 | load(cb: Function): any; 16 | load(options: IConfigOptions, cb?: Function): any; 17 | GLOBAL_NPM_PATH: string; 18 | GLOBAL_NPM_BIN: string; 19 | } 20 | interface ICallback extends Function { 21 | (err?: any, result?: any): any; 22 | } 23 | interface IOptions { 24 | /** 25 | * If you don't specify a name in options, but just a path, npmi will do the same as if you were at this path in a terminal and executing npm install 26 | Otherwise, it will install the module specified by this name like npm install module-name does. 27 | */ 28 | name?: string; 29 | pkgName?: string; 30 | /** 31 | * Desired version for installation 32 | */ 33 | version?: string; 34 | /** 35 | * Desired location for installation (note that if you specified /some/foo/path, npm will automatically create a node_modules sub-folder at this location, resulting in /some/foo/path/node_modules). So don't specify the node_modules part in your path 36 | */ 37 | path?: string; 38 | /** 39 | * If true, npmi will install options.name module even though it has already been installed. 40 | If false, npmi will check if the module is already installed, if it is, it will also check if the installed version is equal to options.version, otherwise, it will install options.name@options.version 41 | */ 42 | forceInstall?: boolean; 43 | /** 44 | * Allows npmi to install local module that are not on npm registry. If, you want to install a local module by specifying its full path in options.name, you need to set this to true. 45 | */ 46 | localInstall?: boolean; 47 | /** 48 | * This object is given to npm and allows you to do some fine-grained npm configurations. 49 | It is processed by npm like command-line arguments but within an Object map (npm-config) 50 | */ 51 | npmLoad?: IConfigOptions; 52 | savedPrefix?: string; 53 | } 54 | interface IConfigOptions { 55 | loglevel?: 'silent'; 56 | } 57 | } 58 | export = npmi; 59 | -------------------------------------------------------------------------------- /npmi.js: -------------------------------------------------------------------------------- 1 | var npm = require('global-npm'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var semver = require('semver'); 5 | 6 | var LOAD_ERR = 'NPM_LOAD_ERR', 7 | INSTALL_ERR = 'NPM_INSTALL_ERR', 8 | VIEW_ERR = 'NPM_VIEW_ERR'; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * User: leiko 13 | * Date: 30/01/14 14 | * Time: 10:28 15 | */ 16 | var npmi = function (options, callback) { 17 | callback = callback || function () {}; 18 | 19 | var name = options.name, 20 | pkgName = options.pkgName || name, 21 | version = options.version || 'latest', 22 | installPath = options.path || '.', 23 | forceInstall = options.forceInstall || false, 24 | localInstall = options.localInstall || false, 25 | npmLoad = options.npmLoad || { loglevel: 'silent' }, 26 | savedPrefix = null; 27 | 28 | function viewCallback(installedVersion) { 29 | return function (err, view) { 30 | if (err) { 31 | // reset npm.prefix to saved value 32 | npm.prefix = savedPrefix; 33 | err.code = VIEW_ERR; 34 | return callback(err); 35 | } 36 | 37 | // npm view success 38 | var latestVersion = Object.keys(view)[0]; 39 | if ( 40 | typeof latestVersion !== 'undefined' && 41 | latestVersion === installedVersion 42 | ) { 43 | // reset npm.prefix to saved value 44 | npm.prefix = savedPrefix; 45 | return callback(); 46 | } else { 47 | npm.commands.install( 48 | installPath, 49 | [name + '@' + latestVersion], 50 | installCallback 51 | ); 52 | } 53 | }; 54 | } 55 | 56 | function checkInstalled(isTarball) { 57 | var module = name + '@' + version; 58 | 59 | if (isTarball) { 60 | module = name; 61 | if (pkgName === name) { 62 | console.warn( 63 | 'npmi warn: install "' + 64 | name + 65 | '" from tarball/folder without options.pkgName specified => forceInstall: true' 66 | ); 67 | } 68 | } 69 | 70 | // check that version matches 71 | fs.readFile( 72 | path.resolve(installPath, 'node_modules', pkgName, 'package.json'), 73 | function (err, pkgRawData) { 74 | if (err) { 75 | // hmm, something went wrong while reading module's package.json file 76 | // lets try to reinstall it just in case 77 | return npm.commands.install(installPath, [module], installCallback); 78 | } 79 | 80 | var pkg = JSON.parse(pkgRawData); 81 | if (version === 'latest') { 82 | // specified version is "latest" which means nothing for a comparison check 83 | if (isTarball) { 84 | // when a package is already installed and it comes from a tarball, you have to specify 85 | // a real version => warn 86 | console.warn( 87 | 'npmi warn: install from tarball without options.version specified => forceInstall: true' 88 | ); 89 | return npm.commands.install(installPath, [module], installCallback); 90 | } else { 91 | // so we need to ask npm to give us a view of the module from remote registry 92 | // in order to check if it really is the latest one that is currently installed 93 | return npm.commands.view([name], true, viewCallback(pkg.version)); 94 | } 95 | } else if (pkg.version === version) { 96 | // package is installed and version matches 97 | // reset npm.prefix to saved value 98 | npm.prefix = savedPrefix; 99 | return callback(); 100 | } else { 101 | // version does not match: reinstall 102 | return npm.commands.install(installPath, [module], installCallback); 103 | } 104 | } 105 | ); 106 | } 107 | 108 | function installCallback(err, result) { 109 | // reset npm.prefix to saved value 110 | npm.prefix = savedPrefix; 111 | 112 | if (err) { 113 | err.code = INSTALL_ERR; 114 | } 115 | 116 | callback(err, result); 117 | } 118 | 119 | function loadCallback(err) { 120 | if (err) { 121 | err.code = LOAD_ERR; 122 | return callback(err); 123 | } 124 | 125 | // npm loaded successfully 126 | savedPrefix = npm.prefix; // save current npm.prefix 127 | npm.prefix = installPath; // change npm.prefix to given installPath 128 | if (!name) { 129 | // just want to do an "npm install" where a package.json is 130 | npm.commands.install(installPath, [], installCallback); 131 | } else if (localInstall) { 132 | if (forceInstall) { 133 | // local install won't work with version specified 134 | npm.commands.install(installPath, [name], installCallback); 135 | } else { 136 | // check if there is already a local install of this module 137 | fs.readFile( 138 | path.resolve(name, 'package.json'), 139 | 'utf8', 140 | function (err, sourcePkgData) { 141 | if (err) { 142 | // reset npm.prefix to saved value 143 | npm.prefix = savedPrefix; 144 | callback(err); 145 | } else { 146 | try { 147 | var sourcePkg = JSON.parse(sourcePkgData); 148 | } catch (err) { 149 | // reset npm.prefix to saved value 150 | npm.prefix = savedPrefix; 151 | callback(err); 152 | return; 153 | } 154 | 155 | var pkgName = sourcePkg.name || path.basename(name); 156 | fs.readFile( 157 | path.resolve( 158 | installPath, 159 | 'node_modules', 160 | pkgName, 161 | 'package.json' 162 | ), 163 | 'utf8', 164 | function (err, targetPkgData) { 165 | if (err) { 166 | // file probably doesn't exist, or is corrupted: install 167 | // local install won't work with version specified 168 | npm.commands.install(installPath, [name], installCallback); 169 | } else { 170 | // there is a module that looks a lot like the one you want to install: do some checks 171 | try { 172 | var targetPkg = JSON.parse(targetPkgData); 173 | } catch (err) { 174 | // reset npm.prefix to saved value 175 | npm.prefix = savedPrefix; 176 | callback(err); 177 | return; 178 | } 179 | 180 | if (semver.gt(sourcePkg.version, targetPkg.version)) { 181 | // install because current found version seems outdated 182 | // local install won't work with version specified 183 | npm.commands.install( 184 | installPath, 185 | [name], 186 | installCallback 187 | ); 188 | } else { 189 | // reset npm.prefix to saved value 190 | npm.prefix = savedPrefix; 191 | callback(); 192 | } 193 | } 194 | } 195 | ); 196 | } 197 | } 198 | ); 199 | } 200 | } else { 201 | if (forceInstall) { 202 | // reinstall package module 203 | if (name.indexOf('/') === -1) { 204 | // not a tarball 205 | npm.commands.install( 206 | installPath, 207 | [name + '@' + version], 208 | installCallback 209 | ); 210 | } else { 211 | // do not specify version for tarball 212 | npm.commands.install(installPath, [name], installCallback); 213 | } 214 | } else { 215 | // check if package is installed 216 | checkInstalled(name.indexOf('/') !== -1); 217 | } 218 | } 219 | } 220 | 221 | npm.load(npmLoad, loadCallback); 222 | }; 223 | 224 | npmi.LOAD_ERR = LOAD_ERR; 225 | npmi.INSTALL_ERR = INSTALL_ERR; 226 | npmi.VIEW_ERR = VIEW_ERR; 227 | 228 | npmi.NPM_VERSION = npm.version; 229 | 230 | module.exports = npmi; 231 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npmi", 3 | "version": "4.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@ungap/promise-all-settled": { 8 | "version": "1.1.2", 9 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 10 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 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": "4.3.0", 27 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 28 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 29 | "dev": true, 30 | "requires": { 31 | "color-convert": "^2.0.1" 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 | "balanced-match": { 54 | "version": "1.0.0", 55 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 56 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 57 | "dev": true 58 | }, 59 | "binary-extensions": { 60 | "version": "2.1.0", 61 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", 62 | "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", 63 | "dev": true 64 | }, 65 | "brace-expansion": { 66 | "version": "1.1.11", 67 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 68 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 69 | "dev": true, 70 | "requires": { 71 | "balanced-match": "^1.0.0", 72 | "concat-map": "0.0.1" 73 | } 74 | }, 75 | "braces": { 76 | "version": "3.0.2", 77 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 78 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 79 | "dev": true, 80 | "requires": { 81 | "fill-range": "^7.0.1" 82 | } 83 | }, 84 | "browser-stdout": { 85 | "version": "1.3.1", 86 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 87 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 88 | "dev": true 89 | }, 90 | "camelcase": { 91 | "version": "5.3.1", 92 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 93 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 94 | "dev": true 95 | }, 96 | "chalk": { 97 | "version": "4.1.0", 98 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 99 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 100 | "dev": true, 101 | "requires": { 102 | "ansi-styles": "^4.1.0", 103 | "supports-color": "^7.1.0" 104 | } 105 | }, 106 | "chokidar": { 107 | "version": "3.4.3", 108 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", 109 | "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", 110 | "dev": true, 111 | "requires": { 112 | "anymatch": "~3.1.1", 113 | "braces": "~3.0.2", 114 | "fsevents": "~2.1.2", 115 | "glob-parent": "~5.1.0", 116 | "is-binary-path": "~2.1.0", 117 | "is-glob": "~4.0.1", 118 | "normalize-path": "~3.0.0", 119 | "readdirp": "~3.5.0" 120 | } 121 | }, 122 | "cliui": { 123 | "version": "5.0.0", 124 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 125 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 126 | "dev": true, 127 | "requires": { 128 | "string-width": "^3.1.0", 129 | "strip-ansi": "^5.2.0", 130 | "wrap-ansi": "^5.1.0" 131 | }, 132 | "dependencies": { 133 | "ansi-regex": { 134 | "version": "4.1.0", 135 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 136 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 137 | "dev": true 138 | }, 139 | "string-width": { 140 | "version": "3.1.0", 141 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 142 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 143 | "dev": true, 144 | "requires": { 145 | "emoji-regex": "^7.0.1", 146 | "is-fullwidth-code-point": "^2.0.0", 147 | "strip-ansi": "^5.1.0" 148 | } 149 | }, 150 | "strip-ansi": { 151 | "version": "5.2.0", 152 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 153 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 154 | "dev": true, 155 | "requires": { 156 | "ansi-regex": "^4.1.0" 157 | } 158 | } 159 | } 160 | }, 161 | "color-convert": { 162 | "version": "2.0.1", 163 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 164 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 165 | "dev": true, 166 | "requires": { 167 | "color-name": "~1.1.4" 168 | } 169 | }, 170 | "color-name": { 171 | "version": "1.1.4", 172 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 173 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 174 | "dev": true 175 | }, 176 | "concat-map": { 177 | "version": "0.0.1", 178 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 179 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 180 | "dev": true 181 | }, 182 | "debug": { 183 | "version": "4.2.0", 184 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", 185 | "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", 186 | "dev": true, 187 | "requires": { 188 | "ms": "2.1.2" 189 | } 190 | }, 191 | "decamelize": { 192 | "version": "1.2.0", 193 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 194 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 195 | "dev": true 196 | }, 197 | "diff": { 198 | "version": "4.0.2", 199 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 200 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 201 | "dev": true 202 | }, 203 | "emoji-regex": { 204 | "version": "7.0.3", 205 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 206 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 207 | "dev": true 208 | }, 209 | "escape-string-regexp": { 210 | "version": "4.0.0", 211 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 212 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 213 | "dev": true 214 | }, 215 | "esprima": { 216 | "version": "4.0.1", 217 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 218 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 219 | "dev": true 220 | }, 221 | "fill-range": { 222 | "version": "7.0.1", 223 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 224 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 225 | "dev": true, 226 | "requires": { 227 | "to-regex-range": "^5.0.1" 228 | } 229 | }, 230 | "find-up": { 231 | "version": "5.0.0", 232 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 233 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 234 | "dev": true, 235 | "requires": { 236 | "locate-path": "^6.0.0", 237 | "path-exists": "^4.0.0" 238 | } 239 | }, 240 | "flat": { 241 | "version": "5.0.2", 242 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 243 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 244 | "dev": true 245 | }, 246 | "fs.realpath": { 247 | "version": "1.0.0", 248 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 249 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 250 | "dev": true 251 | }, 252 | "fsevents": { 253 | "version": "2.1.3", 254 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 255 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 256 | "dev": true, 257 | "optional": true 258 | }, 259 | "get-caller-file": { 260 | "version": "2.0.5", 261 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 262 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 263 | "dev": true 264 | }, 265 | "glob": { 266 | "version": "7.1.6", 267 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 268 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 269 | "dev": true, 270 | "requires": { 271 | "fs.realpath": "^1.0.0", 272 | "inflight": "^1.0.4", 273 | "inherits": "2", 274 | "minimatch": "^3.0.4", 275 | "once": "^1.3.0", 276 | "path-is-absolute": "^1.0.0" 277 | } 278 | }, 279 | "glob-parent": { 280 | "version": "5.1.1", 281 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 282 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 283 | "dev": true, 284 | "requires": { 285 | "is-glob": "^4.0.1" 286 | } 287 | }, 288 | "global-npm": { 289 | "version": "0.3.0", 290 | "resolved": "https://registry.npmjs.org/global-npm/-/global-npm-0.3.0.tgz", 291 | "integrity": "sha1-fFEVOUpnfRJFxOO6C3i7Z1J5fuA=", 292 | "requires": { 293 | "which": "^1.2.1" 294 | } 295 | }, 296 | "growl": { 297 | "version": "1.10.5", 298 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 299 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 300 | "dev": true 301 | }, 302 | "has-flag": { 303 | "version": "4.0.0", 304 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 305 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 306 | "dev": true 307 | }, 308 | "he": { 309 | "version": "1.2.0", 310 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 311 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 312 | "dev": true 313 | }, 314 | "inflight": { 315 | "version": "1.0.6", 316 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 317 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 318 | "dev": true, 319 | "requires": { 320 | "once": "^1.3.0", 321 | "wrappy": "1" 322 | } 323 | }, 324 | "inherits": { 325 | "version": "2.0.4", 326 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 327 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 328 | "dev": true 329 | }, 330 | "is-binary-path": { 331 | "version": "2.1.0", 332 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 333 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 334 | "dev": true, 335 | "requires": { 336 | "binary-extensions": "^2.0.0" 337 | } 338 | }, 339 | "is-extglob": { 340 | "version": "2.1.1", 341 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 342 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 343 | "dev": true 344 | }, 345 | "is-fullwidth-code-point": { 346 | "version": "2.0.0", 347 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 348 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 349 | "dev": true 350 | }, 351 | "is-glob": { 352 | "version": "4.0.1", 353 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 354 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 355 | "dev": true, 356 | "requires": { 357 | "is-extglob": "^2.1.1" 358 | } 359 | }, 360 | "is-number": { 361 | "version": "7.0.0", 362 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 363 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 364 | "dev": true 365 | }, 366 | "is-plain-obj": { 367 | "version": "2.1.0", 368 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 369 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 370 | "dev": true 371 | }, 372 | "isexe": { 373 | "version": "2.0.0", 374 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 375 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 376 | }, 377 | "js-yaml": { 378 | "version": "3.14.0", 379 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 380 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 381 | "dev": true, 382 | "requires": { 383 | "argparse": "^1.0.7", 384 | "esprima": "^4.0.0" 385 | } 386 | }, 387 | "locate-path": { 388 | "version": "6.0.0", 389 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 390 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 391 | "dev": true, 392 | "requires": { 393 | "p-locate": "^5.0.0" 394 | } 395 | }, 396 | "log-symbols": { 397 | "version": "4.0.0", 398 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", 399 | "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", 400 | "dev": true, 401 | "requires": { 402 | "chalk": "^4.0.0" 403 | } 404 | }, 405 | "minimatch": { 406 | "version": "3.0.4", 407 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 408 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 409 | "dev": true, 410 | "requires": { 411 | "brace-expansion": "^1.1.7" 412 | } 413 | }, 414 | "mocha": { 415 | "version": "8.2.1", 416 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", 417 | "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", 418 | "dev": true, 419 | "requires": { 420 | "@ungap/promise-all-settled": "1.1.2", 421 | "ansi-colors": "4.1.1", 422 | "browser-stdout": "1.3.1", 423 | "chokidar": "3.4.3", 424 | "debug": "4.2.0", 425 | "diff": "4.0.2", 426 | "escape-string-regexp": "4.0.0", 427 | "find-up": "5.0.0", 428 | "glob": "7.1.6", 429 | "growl": "1.10.5", 430 | "he": "1.2.0", 431 | "js-yaml": "3.14.0", 432 | "log-symbols": "4.0.0", 433 | "minimatch": "3.0.4", 434 | "ms": "2.1.2", 435 | "nanoid": "3.1.12", 436 | "serialize-javascript": "5.0.1", 437 | "strip-json-comments": "3.1.1", 438 | "supports-color": "7.2.0", 439 | "which": "2.0.2", 440 | "wide-align": "1.1.3", 441 | "workerpool": "6.0.2", 442 | "yargs": "13.3.2", 443 | "yargs-parser": "13.1.2", 444 | "yargs-unparser": "2.0.0" 445 | }, 446 | "dependencies": { 447 | "which": { 448 | "version": "2.0.2", 449 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 450 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 451 | "dev": true, 452 | "requires": { 453 | "isexe": "^2.0.0" 454 | } 455 | } 456 | } 457 | }, 458 | "ms": { 459 | "version": "2.1.2", 460 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 461 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 462 | "dev": true 463 | }, 464 | "nanoid": { 465 | "version": "3.1.12", 466 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", 467 | "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", 468 | "dev": true 469 | }, 470 | "normalize-path": { 471 | "version": "3.0.0", 472 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 473 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 474 | "dev": true 475 | }, 476 | "once": { 477 | "version": "1.4.0", 478 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 479 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 480 | "dev": true, 481 | "requires": { 482 | "wrappy": "1" 483 | } 484 | }, 485 | "p-limit": { 486 | "version": "3.1.0", 487 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 488 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 489 | "dev": true, 490 | "requires": { 491 | "yocto-queue": "^0.1.0" 492 | } 493 | }, 494 | "p-locate": { 495 | "version": "5.0.0", 496 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 497 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 498 | "dev": true, 499 | "requires": { 500 | "p-limit": "^3.0.2" 501 | } 502 | }, 503 | "p-try": { 504 | "version": "2.2.0", 505 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 506 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 507 | "dev": true 508 | }, 509 | "path-exists": { 510 | "version": "4.0.0", 511 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 512 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 513 | "dev": true 514 | }, 515 | "path-is-absolute": { 516 | "version": "1.0.1", 517 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 518 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 519 | "dev": true 520 | }, 521 | "picomatch": { 522 | "version": "2.2.2", 523 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 524 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 525 | "dev": true 526 | }, 527 | "randombytes": { 528 | "version": "2.1.0", 529 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 530 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 531 | "dev": true, 532 | "requires": { 533 | "safe-buffer": "^5.1.0" 534 | } 535 | }, 536 | "readdirp": { 537 | "version": "3.5.0", 538 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", 539 | "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", 540 | "dev": true, 541 | "requires": { 542 | "picomatch": "^2.2.1" 543 | } 544 | }, 545 | "require-directory": { 546 | "version": "2.1.1", 547 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 548 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 549 | "dev": true 550 | }, 551 | "require-main-filename": { 552 | "version": "2.0.0", 553 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 554 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 555 | "dev": true 556 | }, 557 | "safe-buffer": { 558 | "version": "5.2.1", 559 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 560 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 561 | "dev": true 562 | }, 563 | "semver": { 564 | "version": "5.7.1", 565 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 566 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 567 | }, 568 | "serialize-javascript": { 569 | "version": "5.0.1", 570 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", 571 | "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", 572 | "dev": true, 573 | "requires": { 574 | "randombytes": "^2.1.0" 575 | } 576 | }, 577 | "set-blocking": { 578 | "version": "2.0.0", 579 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 580 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 581 | "dev": true 582 | }, 583 | "sprintf-js": { 584 | "version": "1.0.3", 585 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 586 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 587 | "dev": true 588 | }, 589 | "string-width": { 590 | "version": "2.1.1", 591 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 592 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 593 | "dev": true, 594 | "requires": { 595 | "is-fullwidth-code-point": "^2.0.0", 596 | "strip-ansi": "^4.0.0" 597 | } 598 | }, 599 | "strip-ansi": { 600 | "version": "4.0.0", 601 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 602 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 603 | "dev": true, 604 | "requires": { 605 | "ansi-regex": "^3.0.0" 606 | } 607 | }, 608 | "strip-json-comments": { 609 | "version": "3.1.1", 610 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 611 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 612 | "dev": true 613 | }, 614 | "supports-color": { 615 | "version": "7.2.0", 616 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 617 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 618 | "dev": true, 619 | "requires": { 620 | "has-flag": "^4.0.0" 621 | } 622 | }, 623 | "to-regex-range": { 624 | "version": "5.0.1", 625 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 626 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 627 | "dev": true, 628 | "requires": { 629 | "is-number": "^7.0.0" 630 | } 631 | }, 632 | "which": { 633 | "version": "1.3.0", 634 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", 635 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", 636 | "requires": { 637 | "isexe": "^2.0.0" 638 | } 639 | }, 640 | "which-module": { 641 | "version": "2.0.0", 642 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 643 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 644 | "dev": true 645 | }, 646 | "wide-align": { 647 | "version": "1.1.3", 648 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 649 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 650 | "dev": true, 651 | "requires": { 652 | "string-width": "^1.0.2 || 2" 653 | } 654 | }, 655 | "workerpool": { 656 | "version": "6.0.2", 657 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", 658 | "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", 659 | "dev": true 660 | }, 661 | "wrap-ansi": { 662 | "version": "5.1.0", 663 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 664 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 665 | "dev": true, 666 | "requires": { 667 | "ansi-styles": "^3.2.0", 668 | "string-width": "^3.0.0", 669 | "strip-ansi": "^5.0.0" 670 | }, 671 | "dependencies": { 672 | "ansi-regex": { 673 | "version": "4.1.0", 674 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 675 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 676 | "dev": true 677 | }, 678 | "ansi-styles": { 679 | "version": "3.2.1", 680 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 681 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 682 | "dev": true, 683 | "requires": { 684 | "color-convert": "^1.9.0" 685 | } 686 | }, 687 | "color-convert": { 688 | "version": "1.9.3", 689 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 690 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 691 | "dev": true, 692 | "requires": { 693 | "color-name": "1.1.3" 694 | } 695 | }, 696 | "color-name": { 697 | "version": "1.1.3", 698 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 699 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 700 | "dev": true 701 | }, 702 | "string-width": { 703 | "version": "3.1.0", 704 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 705 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 706 | "dev": true, 707 | "requires": { 708 | "emoji-regex": "^7.0.1", 709 | "is-fullwidth-code-point": "^2.0.0", 710 | "strip-ansi": "^5.1.0" 711 | } 712 | }, 713 | "strip-ansi": { 714 | "version": "5.2.0", 715 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 716 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 717 | "dev": true, 718 | "requires": { 719 | "ansi-regex": "^4.1.0" 720 | } 721 | } 722 | } 723 | }, 724 | "wrappy": { 725 | "version": "1.0.2", 726 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 727 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 728 | "dev": true 729 | }, 730 | "y18n": { 731 | "version": "4.0.1", 732 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", 733 | "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", 734 | "dev": true 735 | }, 736 | "yargs": { 737 | "version": "13.3.2", 738 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", 739 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", 740 | "dev": true, 741 | "requires": { 742 | "cliui": "^5.0.0", 743 | "find-up": "^3.0.0", 744 | "get-caller-file": "^2.0.1", 745 | "require-directory": "^2.1.1", 746 | "require-main-filename": "^2.0.0", 747 | "set-blocking": "^2.0.0", 748 | "string-width": "^3.0.0", 749 | "which-module": "^2.0.0", 750 | "y18n": "^4.0.0", 751 | "yargs-parser": "^13.1.2" 752 | }, 753 | "dependencies": { 754 | "ansi-regex": { 755 | "version": "4.1.0", 756 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 757 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 758 | "dev": true 759 | }, 760 | "find-up": { 761 | "version": "3.0.0", 762 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 763 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 764 | "dev": true, 765 | "requires": { 766 | "locate-path": "^3.0.0" 767 | } 768 | }, 769 | "locate-path": { 770 | "version": "3.0.0", 771 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 772 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 773 | "dev": true, 774 | "requires": { 775 | "p-locate": "^3.0.0", 776 | "path-exists": "^3.0.0" 777 | } 778 | }, 779 | "p-limit": { 780 | "version": "2.3.0", 781 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 782 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 783 | "dev": true, 784 | "requires": { 785 | "p-try": "^2.0.0" 786 | } 787 | }, 788 | "p-locate": { 789 | "version": "3.0.0", 790 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 791 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 792 | "dev": true, 793 | "requires": { 794 | "p-limit": "^2.0.0" 795 | } 796 | }, 797 | "path-exists": { 798 | "version": "3.0.0", 799 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 800 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 801 | "dev": true 802 | }, 803 | "string-width": { 804 | "version": "3.1.0", 805 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 806 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 807 | "dev": true, 808 | "requires": { 809 | "emoji-regex": "^7.0.1", 810 | "is-fullwidth-code-point": "^2.0.0", 811 | "strip-ansi": "^5.1.0" 812 | } 813 | }, 814 | "strip-ansi": { 815 | "version": "5.2.0", 816 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 817 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 818 | "dev": true, 819 | "requires": { 820 | "ansi-regex": "^4.1.0" 821 | } 822 | } 823 | } 824 | }, 825 | "yargs-parser": { 826 | "version": "13.1.2", 827 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", 828 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", 829 | "dev": true, 830 | "requires": { 831 | "camelcase": "^5.0.0", 832 | "decamelize": "^1.2.0" 833 | } 834 | }, 835 | "yargs-unparser": { 836 | "version": "2.0.0", 837 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 838 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 839 | "dev": true, 840 | "requires": { 841 | "camelcase": "^6.0.0", 842 | "decamelize": "^4.0.0", 843 | "flat": "^5.0.2", 844 | "is-plain-obj": "^2.1.0" 845 | }, 846 | "dependencies": { 847 | "camelcase": { 848 | "version": "6.2.0", 849 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", 850 | "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", 851 | "dev": true 852 | }, 853 | "decamelize": { 854 | "version": "4.0.0", 855 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 856 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 857 | "dev": true 858 | } 859 | } 860 | }, 861 | "yocto-queue": { 862 | "version": "0.1.0", 863 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 864 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 865 | "dev": true 866 | } 867 | } 868 | } 869 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npmi", 3 | "version": "4.0.1", 4 | "description": "Gives a simplier API to npm install (programatically installs stuffs)", 5 | "main": "npmi.js", 6 | "typings": "npmi.d.ts", 7 | "scripts": { 8 | "test": "mocha" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/maxleiko/npmi.git" 13 | }, 14 | "keywords": [ 15 | "npm", 16 | "install", 17 | "api", 18 | "programatically" 19 | ], 20 | "author": "Maxime Tricoire ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/maxleiko/npmi/issues" 24 | }, 25 | "homepage": "https://github.com/maxleiko/npmi", 26 | "dependencies": { 27 | "global-npm": "^0.3.0", 28 | "semver": "^5.7.1" 29 | }, 30 | "devDependencies": { 31 | "mocha": "^8.2.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var os = require('os'); 2 | var path = require('path'); 3 | var npmi = require('..'); 4 | 5 | describe('npmi', function () { 6 | this.slow('15s'); 7 | this.timeout('30s'); // increase timeout 8 | it('should install kevoree-node-javascript:latest', function (done) { 9 | npmi( 10 | { 11 | name: 'kevoree-node-javascript', 12 | version: 'latest', 13 | path: os.tmpdir(), 14 | }, 15 | function (err) { 16 | if (err) { 17 | throw err; 18 | } else { 19 | done(); 20 | } 21 | } 22 | ); 23 | }); 24 | 25 | it('should install kevoree-node-javascript:0.6.0', function (done) { 26 | npmi( 27 | { 28 | name: 'kevoree-node-javascript', 29 | version: '0.6.0', 30 | path: os.tmpdir(), 31 | }, 32 | function (err) { 33 | if (err) { 34 | throw err; 35 | } else { 36 | done(); 37 | } 38 | } 39 | ); 40 | }); 41 | 42 | it('should install npmi in os.tmpdir()', function (done) { 43 | npmi( 44 | { 45 | name: path.resolve(process.cwd()), 46 | path: os.tmpdir(), 47 | forceInstall: true, 48 | }, 49 | function (err) { 50 | if (err) { 51 | throw err; 52 | } else { 53 | done(); 54 | } 55 | } 56 | ); 57 | }); 58 | }); 59 | --------------------------------------------------------------------------------