node-pre-gyp
Advanced tools
Comparing version 0.7.0 to 0.8.0
# node-pre-gyp changelog | ||
## 0.8.0 | ||
- N-API support (@inspiredware) | ||
## 0.7.1 | ||
- Upgraded to tar v4.x | ||
## 0.7.0 | ||
@@ -4,0 +12,0 @@ |
@@ -7,2 +7,3 @@ "use strict"; | ||
var napi = require('./util/napi.js'); | ||
var compile = require('./util/compile.js'); | ||
@@ -20,3 +21,9 @@ var handle_gyp_opts = require('./util/handle_gyp_opts.js'); | ||
} | ||
if (!err && result.opts.napi_build_version) { | ||
napi.swap_build_dir_in(result.opts.napi_build_version); | ||
} | ||
compile.run_gyp(final_args,result.opts,function(err) { | ||
if (!err && result.opts.napi_build_version) { | ||
napi.swap_build_dir_out(result.opts.napi_build_version); | ||
} | ||
return callback(err); | ||
@@ -33,2 +40,3 @@ }); | ||
if (argv.length && (argv.indexOf('rebuild') > -1)) { | ||
argv.shift(); // remove `rebuild` | ||
// here we map `node-pre-gyp rebuild` to `node-gyp rebuild` which internally means | ||
@@ -35,0 +43,0 @@ // "clean + configure + build" and triggers a full recompile |
@@ -11,6 +11,8 @@ "use strict"; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
function clean (gyp, argv, callback) { | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var opts = versioning.evaluate(package_json, gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
var to_delete = opts.module_path; | ||
@@ -17,0 +19,0 @@ exists(to_delete, function(found) { |
@@ -7,2 +7,3 @@ "use strict"; | ||
var napi = require('./util/napi.js'); | ||
var compile = require('./util/compile.js'); | ||
@@ -45,2 +46,5 @@ var handle_gyp_opts = require('./util/handle_gyp_opts.js'); | ||
compile.run_gyp(['configure'].concat(final_args),result.opts,function(err) { | ||
if (!err && result.opts.napi_build_version) { | ||
napi.swap_build_dir_out(result.opts.napi_build_version); | ||
} | ||
return callback(err); | ||
@@ -47,0 +51,0 @@ }); |
@@ -9,6 +9,7 @@ "use strict"; | ||
var path = require('path'); | ||
var zlib = require('zlib'); | ||
var log = require('npmlog'); | ||
var existsAsync = fs.exists || path.exists; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
var mkdirp = require('mkdirp'); | ||
@@ -79,4 +80,3 @@ var npgVersion = 'unknown'; | ||
var extractCount = 0; | ||
var gunzip = zlib.createGunzip(); | ||
var extracter = require('tar').Extract({ path: to, strip: 1}); | ||
var tar = require('tar'); | ||
@@ -94,5 +94,2 @@ function afterTarball(err) { | ||
function filter_func(entry) { | ||
// ensure directories are +x | ||
// https://github.com/mapnik/node-mapnik/issues/262 | ||
entry.props.mode |= (entry.props.mode >>> 2) & parseInt('0111',8); | ||
log.info('install','unpacking ' + entry.path); | ||
@@ -102,7 +99,2 @@ extractCount++; | ||
gunzip.on('error', callback); | ||
extracter.on('entry', filter_func); | ||
extracter.on('error', callback); | ||
extracter.on('end', afterTarball); | ||
req.on('error', function(err) { | ||
@@ -127,3 +119,7 @@ badDownload = true; | ||
// start unzipping and untaring | ||
req.pipe(gunzip).pipe(extracter); | ||
req.pipe(tar.extract({ | ||
cwd: to, | ||
strip: 1, | ||
onentry: filter_func | ||
}).on('close', afterTarball).on('error', callback)); | ||
}); | ||
@@ -134,3 +130,4 @@ }); | ||
function do_build(gyp,argv,callback) { | ||
gyp.todo.push( { name: 'build', args: ['rebuild'] } ); | ||
var args = ['rebuild'].concat(argv); | ||
gyp.todo.push( { name: 'build', args: args } ); | ||
process.nextTick(callback); | ||
@@ -165,2 +162,3 @@ } | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var source_build = gyp.opts['build-from-source'] || gyp.opts.build_from_source; | ||
@@ -186,3 +184,3 @@ var update_binary = gyp.opts['update-binary'] || gyp.opts.update_binary; | ||
try { | ||
opts = versioning.evaluate(package_json, gyp.opts); | ||
opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
} catch (err) { | ||
@@ -198,3 +196,3 @@ return callback(err); | ||
var binary_module = path.join(to,opts.module_name + '.node'); | ||
if (existsAsync(binary_module,function(found) { | ||
existsAsync(binary_module,function(found) { | ||
if (found && !update_binary) { | ||
@@ -206,16 +204,23 @@ console.log('['+package_json.name+'] Success: "' + binary_module + '" already installed'); | ||
if (!update_binary) log.info('check','checked for "' + binary_module + '" (not found)'); | ||
place_binary(from,to,opts,function(err) { | ||
if (err && should_do_fallback_build) { | ||
print_fallback_error(err,opts,package_json); | ||
return do_build(gyp,argv,callback); | ||
} else if (err) { | ||
return callback(err); | ||
mkdirp(to,function(err) { | ||
if (err) { | ||
after_place(err); | ||
} else { | ||
console.log('['+package_json.name+'] Success: "' + binary_module + '" is installed via remote'); | ||
return callback(); | ||
place_binary(from,to,opts,after_place); | ||
} | ||
}); | ||
} | ||
})); | ||
function after_place(err) { | ||
if (err && should_do_fallback_build) { | ||
print_fallback_error(err,opts,package_json); | ||
return do_build(gyp,argv,callback); | ||
} else if (err) { | ||
return callback(err); | ||
} else { | ||
console.log('['+package_json.name+'] Success: "' + binary_module + '" is installed via remote'); | ||
return callback(); | ||
} | ||
} | ||
}); | ||
} | ||
} |
@@ -13,2 +13,3 @@ "use strict"; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
@@ -18,2 +19,3 @@ var nopt = require('nopt'); | ||
log.disableProgress(); | ||
var napi = require('./util/napi.js'); | ||
@@ -133,2 +135,9 @@ var EE = require('events').EventEmitter; | ||
// expand commands entries for multiple napi builds | ||
var dir = this.opts.directory; | ||
if (dir == null) dir = process.cwd(); | ||
var package_json = JSON.parse(fs.readFileSync(path.join(dir,'package.json'))); | ||
this.todo = napi.expand_commands (package_json, commands); | ||
// support for inheriting config env variables from npm | ||
@@ -135,0 +144,0 @@ var npm_config_prefix = 'npm_config_'; |
@@ -11,10 +11,13 @@ "use strict"; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
var write = require('fs').createWriteStream; | ||
var existsAsync = fs.exists || path.exists; | ||
var mkdirp = require('mkdirp'); | ||
var tar = require('tar'); | ||
function _package(gyp, argv, callback) { | ||
var pack = require('tar-pack').pack; | ||
var packlist = require('npm-packlist'); | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var opts = versioning.evaluate(package_json, gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
var from = opts.module_path; | ||
@@ -34,15 +37,19 @@ var binary_module = path.join(from,opts.module_name + '.node'); | ||
mkdirp(path.dirname(tarball),function(err) { | ||
if (err) throw err; | ||
pack(from, { filter: filter_func }) | ||
.pipe(write(tarball)) | ||
.on('error', function(err) { | ||
if (err) console.error('['+package_json.name+'] ' + err.message); | ||
return callback(err); | ||
}) | ||
.on('close', function() { | ||
log.info('package','Binary staged at "' + tarball + '"'); | ||
return callback(); | ||
}); | ||
from = path.dirname(from); | ||
if (err) return callback(err); | ||
packlist({ path: from }).then(function(files) { | ||
tar.create({ | ||
portable: true, | ||
gzip: true, | ||
onentry: filter_func, | ||
file: tarball, | ||
cwd: from | ||
}, files, function(err) { | ||
if (err) console.error('['+package_json.name+'] ' + err.message); | ||
else log.info('package','Binary staged at "' + tarball + '"'); | ||
return callback(err); | ||
}); | ||
}, callback); | ||
}); | ||
}); | ||
} |
"use strict"; | ||
var versioning = require('../lib/util/versioning.js'); | ||
var napi = require('../lib/util/napi.js'); | ||
var existsSync = require('fs').existsSync || require('path').existsSync; | ||
@@ -21,6 +22,10 @@ var path = require('path'); | ||
versioning.validate_config(package_json); | ||
var napi_build_version; | ||
if (napi.get_napi_build_versions (package_json)) { | ||
napi_build_version = napi.get_best_napi_build_version(package_json); | ||
} | ||
opts = opts || {}; | ||
if (!opts.module_root) opts.module_root = path.dirname(package_json_path); | ||
var meta = versioning.evaluate(package_json,opts); | ||
var meta = versioning.evaluate(package_json,opts,napi_build_version); | ||
return meta.module; | ||
}; |
@@ -11,2 +11,3 @@ "use strict"; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
var s3_setup = require('./util/s3_setup.js'); | ||
@@ -20,3 +21,4 @@ var existsAsync = fs.exists || path.exists; | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var opts = versioning.evaluate(package_json, gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
var tarball = opts.staged_tarball; | ||
@@ -23,0 +25,0 @@ existsAsync(tarball,function(found) { |
@@ -7,8 +7,16 @@ "use strict"; | ||
var fs = require('fs'); | ||
var napi = require('./util/napi.js'); | ||
function rebuild (gyp, argv, callback) { | ||
gyp.todo.unshift( | ||
{ name: 'clean', args: [] }, | ||
{ name: 'build', args: ['rebuild'] } | ||
); | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var commands = [ | ||
{ name: 'clean', args: [] }, | ||
{ name: 'build', args: ['rebuild'] } | ||
]; | ||
commands = napi.expand_commands(package_json, commands); | ||
for (var i = commands.length; i !== 0; i--) { | ||
gyp.todo.unshift(commands[i-1]); | ||
} | ||
process.nextTick(callback); | ||
} |
@@ -7,8 +7,15 @@ "use strict"; | ||
var fs = require('fs'); | ||
var napi = require('./util/napi.js'); | ||
function rebuild (gyp, argv, callback) { | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var installArgs = []; | ||
var napi_build_version = napi.get_best_napi_version(package_json); | ||
if (napi_build_version != null) installArgs = [ napi.get_command_arg (napi_build_version) ]; | ||
gyp.todo.unshift( | ||
{ name: 'clean', args: [] }, | ||
{ name: 'install', args: [] } | ||
{ name: 'install', args: installArgs } | ||
); | ||
process.nextTick(callback); | ||
} |
@@ -9,2 +9,3 @@ "use strict"; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
@@ -17,3 +18,4 @@ function unix_paths(key, val) { | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var opts = versioning.evaluate(package_json, gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
var hit = false; | ||
@@ -23,3 +25,3 @@ // if a second arg is passed look to see | ||
//console.log(JSON.stringify(gyp.opts,null,1)) | ||
var remain = gyp.opts.argv.remain.pop(); | ||
var remain = gyp.opts.argv.remain[gyp.opts.argv.remain.length-1]; | ||
if (remain && opts.hasOwnProperty(remain)) { | ||
@@ -26,0 +28,0 @@ console.log(opts[remain].replace(/\\/g, '/')); |
@@ -12,2 +12,3 @@ "use strict"; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
var path = require('path'); | ||
@@ -20,3 +21,4 @@ | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var opts = versioning.evaluate(package_json, gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
// skip validation for runtimes we don't explicitly support (like electron) | ||
@@ -23,0 +25,0 @@ if (opts.runtime && |
@@ -12,9 +12,11 @@ "use strict"; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
var testbinary = require('./testbinary.js'); | ||
var read = require('fs').createReadStream; | ||
var zlib = require('zlib'); | ||
var tar = require('tar'); | ||
var mkdirp = require('mkdirp'); | ||
function testpackage(gyp, argv, callback) { | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var opts = versioning.evaluate(package_json, gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
var tarball = opts.staged_tarball; | ||
@@ -26,15 +28,20 @@ existsAsync(tarball, function(found) { | ||
var to = opts.module_path; | ||
var gunzip = zlib.createGunzip(); | ||
var extracter = require('tar').Extract({ path: to, strip: 1 }); | ||
function filter_func(entry) { | ||
// ensure directories are +x | ||
// https://github.com/mapnik/node-mapnik/issues/262 | ||
entry.props.mode |= (entry.props.mode >>> 2) & parseInt('0111',8); | ||
log.info('install','unpacking ' + entry.path); | ||
log.info('install','unpacking [' + entry.path + ']'); | ||
} | ||
gunzip.on('error', callback); | ||
extracter.on('error', callback); | ||
extracter.on('entry', filter_func); | ||
extracter.on('end', function(err) { | ||
if (err) return callback(err); | ||
mkdirp(to, function(err) { | ||
if (err) { | ||
return callback(err); | ||
} else { | ||
tar.extract({ | ||
file: tarball, | ||
cwd: to, | ||
strip: 1, | ||
onentry: filter_func | ||
}).then(after_extract, callback); | ||
} | ||
}); | ||
function after_extract() { | ||
testbinary(gyp,argv,function(err) { | ||
@@ -48,5 +55,4 @@ if (err) { | ||
}); | ||
}); | ||
read(tarball).pipe(gunzip).pipe(extracter); | ||
} | ||
}); | ||
} |
@@ -10,2 +10,3 @@ "use strict"; | ||
var versioning = require('./util/versioning.js'); | ||
var napi = require('./util/napi.js'); | ||
var s3_setup = require('./util/s3_setup.js'); | ||
@@ -18,3 +19,4 @@ var url = require('url'); | ||
var package_json = JSON.parse(fs.readFileSync('./package.json')); | ||
var opts = versioning.evaluate(package_json, gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(package_json, gyp.opts, napi_build_version); | ||
s3_setup.detect(opts.hosted_path,config); | ||
@@ -21,0 +23,0 @@ AWS.config.update(config); |
@@ -7,2 +7,3 @@ "use strict"; | ||
var versioning = require('./versioning.js'); | ||
var napi = require('./napi.js'); | ||
@@ -48,2 +49,5 @@ /* | ||
'module_path', | ||
'napi_version', | ||
'node_abi_napi', | ||
'napi_build_version' | ||
]; | ||
@@ -56,3 +60,4 @@ | ||
// generate custom node-pre-gyp versioning info | ||
var opts = versioning.evaluate(JSON.parse(fs.readFileSync('./package.json')), gyp.opts); | ||
var napi_build_version = napi.get_napi_build_version_from_command_args(argv); | ||
var opts = versioning.evaluate(JSON.parse(fs.readFileSync('./package.json')), gyp.opts, napi_build_version); | ||
share_with_node_gyp.forEach(function(key) { | ||
@@ -63,3 +68,4 @@ var val = opts[key]; | ||
} else { | ||
return callback(new Error("Option " + key + " required but not found by node-pre-gyp")); | ||
if (key !== 'napi_version' && key !== 'node_abi_napi' && key !== 'napi_build_version') | ||
return callback(new Error("Option " + key + " required but not found by node-pre-gyp")); | ||
} | ||
@@ -66,0 +72,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
var detect_libc = require('detect-libc'); | ||
var napi = require('./napi.js'); | ||
@@ -229,2 +230,3 @@ var abi_crosswalk; | ||
} | ||
napi.validate_package_json(package_json); | ||
} | ||
@@ -277,3 +279,3 @@ | ||
module.exports.evaluate = function(package_json,options) { | ||
module.exports.evaluate = function(package_json,options,napi_build_version) { | ||
options = options || {}; | ||
@@ -297,2 +299,5 @@ validate_config(package_json); | ||
node_abi: get_runtime_abi(runtime,options.target), | ||
node_abi_napi: napi.get_napi_version() ? 'napi' : get_runtime_abi(runtime,options.target), | ||
napi_version: napi.get_napi_version(), // non-zero numeric, undefined if unsupported | ||
napi_build_version: napi_build_version, // undefined if not specified | ||
target: options.target || '', | ||
@@ -299,0 +304,0 @@ platform: options.target_platform || process.platform, |
{ | ||
"name": "node-pre-gyp", | ||
"description": "Node.js native addon binary install tool", | ||
"version": "0.7.0", | ||
"version": "0.8.0", | ||
"keywords": [ | ||
@@ -23,4 +23,6 @@ "native", | ||
"dependencies": { | ||
"detect-libc": "^1.0.2", | ||
"mkdirp": "^0.5.1", | ||
"nopt": "^4.0.1", | ||
"npm-packlist": "^1.1.6", | ||
"npmlog": "^4.0.2", | ||
@@ -31,5 +33,3 @@ "rc": "^1.1.7", | ||
"semver": "^5.3.0", | ||
"detect-libc": "^1.0.2", | ||
"tar": "^2.2.1", | ||
"tar-pack": "^3.4.0" | ||
"tar": "^4" | ||
}, | ||
@@ -40,3 +40,3 @@ "devDependencies": { | ||
"retire": "^1.2.12", | ||
"jshint": "^2.9.4" | ||
"jshint": "^2.9.5" | ||
}, | ||
@@ -43,0 +43,0 @@ "jshintConfig": { |
@@ -288,2 +288,77 @@ # node-pre-gyp | ||
## N-API Considerations | ||
[N-API](https://nodejs.org/api/n-api.html#n_api_n_api) is an ABI-stable alternative to previous technologies such as [nan](https://github.com/nodejs/nan) which are tied to a specific Node runtime engine. N-API is Node runtime engine agnostic and guarantees modules created today will continue to run, without changes, into the future. | ||
Using `node-pre-gyp` with N-API projects requires a handful of additional congiguration values and imposes some additional requirements. | ||
The most significant difference is that an N-API module can be coded to target multiple N-API versions. Therefore, an N-API module must declare in its `package.json` file which N-API versions the module is designed to run against. In addition, since multiple builds may be required for a single module, path and file names must be specified in way that avoids naming conflicts. | ||
### The `napi_versions` array property | ||
An N-API modules must declare in its `package.json` file, the N-API versions the module is intended to support. This is accomplished by including an `napi-versions` array property in the `binary` object. For example: | ||
```js | ||
"binary": { | ||
"module_name": "your_module", | ||
"module_path": "your_module_path", | ||
"host": "https://your_bucket.s3-us-west-1.amazonaws.com", | ||
"napi_versions": [1,3] | ||
} | ||
``` | ||
If the `napi_versions` array property is *not* present, `node-pre-gyp` operates as it always has. Including the `napi_versions` array property instructs `node-pre-gyp` that this is a N-API module build. | ||
When the `napi_versions` array property is present, `node-pre-gyp` fires off multiple operations, one for each of the N-API versions in the array. In the example above, two operations are initiated, one for N-API version 1 and second for N-API version 3. How this version number is communicated is described next. | ||
### The `napi_build_version` value | ||
For each of the N-API module operations `node-pre-gyp` initiates, it insures that the `napi_build_version` is set appropriately. | ||
This value is of importance in two areas: | ||
1. The C/C++ code which needs to know against which N-API version it should compile. | ||
2. `node-pre-gyp` itself which must assign appropriate path and file names to avoid collisions. | ||
### Defining `NAPI_BUILD_VERSION` for the C/C++ code | ||
The `napi_build_version` value is communicated to the C/C++ code by adding this code to the `binding.gyp` file: | ||
``` | ||
"defines": [ | ||
"NAPI_BUILD_VERSION=<(napi_build_version)", | ||
] | ||
``` | ||
This insures that `NAPI_BUILD_VERSION`, an integer value, is declared appropriately to the C/C++ code for each build. | ||
### Path and file naming requirements in `package.json` | ||
Since `node-pre-gyp` fires off multiple operations for each request, it is essential that path and file names be created in such a way as to avoid collisions. This is accomplished by imposing additional path and file naming requirements. | ||
Specifically, when performing N-API builds, the `{napi_build_version}` text substitution string *must* be present in the `module_path` property. In addition, the `{napi_build_version}` text substitution string *must* be present in either the `remote_path` or `package_name` property. (No problem if it's in both.) | ||
Here's an example: | ||
```js | ||
"binary": { | ||
"module_name": "your_module", | ||
"module_path": "./lib/binding/napi-v{napi_build_version}", | ||
"remote_path": "./{module_name}/v{version}/{configuration}/", | ||
"package_name": "{platform}-{arch}-napi-v{napi_build_version}.tar.gz", | ||
"host": "https://your_bucket.s3-us-west-1.amazonaws.com", | ||
"napi_versions": [1,3] | ||
} | ||
``` | ||
### Two additional configuration values | ||
For those who need them in legacy projects, two additional configuration values are available for all builds. | ||
1. `napi_version` If N-API is supported by the currently executing Node instance, this value is the N-API version number supported by Node. If N-API is not supported, this value is an empty string. | ||
2. `node_abi_napi` If the value returned for `napi_version` is non empty, this value is `'napi'`. If the value returned for `napi_version` is empty, this value is the value returned for `node_abi`. | ||
These values are present for use in the `binding.gyp` file and may be used as `{napi_version}` and `{node_abi_napi}` for text substituion in the `package.json` file. | ||
## S3 Hosting | ||
@@ -290,0 +365,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
138924
33
3203
662
36
+ Addednpm-packlist@^1.1.6
+ Addedchownr@1.1.4(transitive)
+ Addedfs-minipass@1.2.7(transitive)
+ Addedignore-walk@3.0.4(transitive)
+ Addedminipass@2.9.0(transitive)
+ Addedminizlib@1.3.3(transitive)
+ Addednpm-bundled@1.1.2(transitive)
+ Addednpm-normalize-package-bin@1.0.1(transitive)
+ Addednpm-packlist@1.4.8(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedtar@4.4.19(transitive)
+ Addedyallist@3.1.1(transitive)
- Removedtar-pack@^3.4.0
- Removedblock-stream@0.0.9(transitive)
- Removeddebug@2.6.9(transitive)
- Removedfstream@1.0.12(transitive)
- Removedfstream-ignore@1.0.5(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removedms@2.0.0(transitive)
- Removedtar@2.2.2(transitive)
- Removedtar-pack@3.4.1(transitive)
- Removeduid-number@0.0.6(transitive)
Updatedtar@^4