diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..00022d9c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+test/fixtures/files/** text eol=lf
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..f0bc5b36
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,45 @@
+name: CI
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ node-version: [10.x, 12.x, 14.x]
+ platform:
+ - os: ubuntu-latest
+ shell: bash
+ - os: macos-latest
+ shell: bash
+ - os: windows-latest
+ shell: powershell
+
+ fail-fast: false
+
+ runs-on: ${{ matrix.platform.os }}
+ defaults:
+ run:
+ shell: ${{ matrix.platform.shell }}
+
+ steps:
+ # there are files here that make windows unhappy by default
+ - name: Support longpaths
+ run: git config --global core.longpaths true
+
+ - name: Checkout Repository
+ uses: actions/checkout@v1.1.0
+
+ - name: Use Nodejs ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: use latest npm
+ run: npm i -g npm@latest
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Run Tap Tests
+ run: npm test -- -c -t0
diff --git a/.travis.yml b/.travis.yml
index 18681b43..09263d7a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,9 +2,13 @@ language: node_js
sudo: false
node_js:
+ - node
+ - 12
- 10
- 8
- - 6
+
+os:
+ - linux
cache:
directories:
diff --git a/benchmarks/node_modules/balanced-match/index.js b/benchmarks/node_modules/balanced-match/index.js
index e8d85870..1685a762 100644
--- a/benchmarks/node_modules/balanced-match/index.js
+++ b/benchmarks/node_modules/balanced-match/index.js
@@ -1,3 +1,4 @@
+'use strict';
module.exports = balanced;
function balanced(a, b, str) {
if (a instanceof RegExp) a = maybeMatch(a, str);
diff --git a/benchmarks/node_modules/balanced-match/package.json b/benchmarks/node_modules/balanced-match/package.json
index 8ec4c8c5..dc208685 100644
--- a/benchmarks/node_modules/balanced-match/package.json
+++ b/benchmarks/node_modules/balanced-match/package.json
@@ -1,33 +1,32 @@
{
- "_from": "balanced-match@^0.4.1",
- "_id": "balanced-match@0.4.2",
- "_integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "_from": "balanced-match@^1.0.0",
+ "_id": "balanced-match@1.0.0",
+ "_inBundle": false,
+ "_integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"_location": "/balanced-match",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
- "raw": "balanced-match@^0.4.1",
+ "raw": "balanced-match@^1.0.0",
"name": "balanced-match",
"escapedName": "balanced-match",
- "rawSpec": "^0.4.1",
+ "rawSpec": "^1.0.0",
"saveSpec": null,
- "fetchSpec": "^0.4.1"
+ "fetchSpec": "^1.0.0"
},
"_requiredBy": [
"/brace-expansion"
],
- "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
- "_shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838",
- "_shrinkwrap": null,
- "_spec": "balanced-match@^0.4.1",
+ "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767",
+ "_spec": "balanced-match@^1.0.0",
"_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/brace-expansion",
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
- "bin": null,
"bugs": {
"url": "https://github.com/juliangruber/balanced-match/issues"
},
@@ -36,6 +35,7 @@
"deprecated": false,
"description": "Match balanced character pairs, like \"{\" and \"}\"",
"devDependencies": {
+ "matcha": "^0.7.0",
"tape": "^4.6.0"
},
"homepage": "https://github.com/juliangruber/balanced-match",
@@ -49,13 +49,12 @@
"license": "MIT",
"main": "index.js",
"name": "balanced-match",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/balanced-match.git"
},
"scripts": {
+ "bench": "make bench",
"test": "make test"
},
"testling": {
@@ -74,5 +73,5 @@
"android-browser/4.2..latest"
]
},
- "version": "0.4.2"
+ "version": "1.0.0"
}
diff --git a/benchmarks/node_modules/brace-expansion/README.md b/benchmarks/node_modules/brace-expansion/README.md
index ed2ec1fd..6b4e0e16 100644
--- a/benchmarks/node_modules/brace-expansion/README.md
+++ b/benchmarks/node_modules/brace-expansion/README.md
@@ -63,7 +63,7 @@ Valid expansions are:
// {a,b,...}
```
-A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
+A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
```js
/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
@@ -98,6 +98,12 @@ npm install brace-expansion
- [Julian Gruber](https://github.com/juliangruber)
- [Isaac Z. Schlueter](https://github.com/isaacs)
+## Sponsors
+
+This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)!
+
+Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)!
+
## License
(MIT)
diff --git a/benchmarks/node_modules/brace-expansion/package.json b/benchmarks/node_modules/brace-expansion/package.json
index 52b2baef..26587e47 100644
--- a/benchmarks/node_modules/brace-expansion/package.json
+++ b/benchmarks/node_modules/brace-expansion/package.json
@@ -1,39 +1,38 @@
{
- "_from": "brace-expansion@^1.0.0",
- "_id": "brace-expansion@1.1.7",
- "_integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=",
+ "_from": "brace-expansion@^1.1.7",
+ "_id": "brace-expansion@1.1.11",
+ "_inBundle": false,
+ "_integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"_location": "/brace-expansion",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
- "raw": "brace-expansion@^1.0.0",
+ "raw": "brace-expansion@^1.1.7",
"name": "brace-expansion",
"escapedName": "brace-expansion",
- "rawSpec": "^1.0.0",
+ "rawSpec": "^1.1.7",
"saveSpec": null,
- "fetchSpec": "^1.0.0"
+ "fetchSpec": "^1.1.7"
},
"_requiredBy": [
"/minimatch"
],
- "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
- "_shasum": "3effc3c50e000531fb720eaff80f0ae8ef23cf59",
- "_shrinkwrap": null,
- "_spec": "brace-expansion@^1.0.0",
+ "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "_shasum": "3c7fcbf529d87226f3d2f52b966ff5271eb441dd",
+ "_spec": "brace-expansion@^1.1.7",
"_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/minimatch",
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
- "bin": null,
"bugs": {
"url": "https://github.com/juliangruber/brace-expansion/issues"
},
"bundleDependencies": false,
"dependencies": {
- "balanced-match": "^0.4.1",
+ "balanced-match": "^1.0.0",
"concat-map": "0.0.1"
},
"deprecated": false,
@@ -47,8 +46,6 @@
"license": "MIT",
"main": "index.js",
"name": "brace-expansion",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/brace-expansion.git"
@@ -74,5 +71,5 @@
"android-browser/4.2..latest"
]
},
- "version": "1.1.7"
+ "version": "1.1.11"
}
diff --git a/benchmarks/node_modules/fstream/.npmignore b/benchmarks/node_modules/fstream/.npmignore
deleted file mode 100644
index 494272a8..00000000
--- a/benchmarks/node_modules/fstream/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.*.swp
-node_modules/
-examples/deep-copy/
-examples/path/
-examples/filter-copy/
diff --git a/benchmarks/node_modules/fstream/lib/writer.js b/benchmarks/node_modules/fstream/lib/writer.js
index 140e449e..3f105478 100644
--- a/benchmarks/node_modules/fstream/lib/writer.js
+++ b/benchmarks/node_modules/fstream/lib/writer.js
@@ -147,7 +147,7 @@ Writer.prototype._stat = function (current) {
// if it's a type change, then we need to clobber or error.
// if it's not a type change, then let the impl take care of it.
- if (currentType !== self.type) {
+ if (currentType !== self.type || self.type === 'File' && current.nlink > 1) {
return rimraf(self._path, function (er) {
if (er) return self.error(er)
self._old = null
diff --git a/benchmarks/node_modules/fstream/package.json b/benchmarks/node_modules/fstream/package.json
index 63fc2fff..fb48fdc2 100644
--- a/benchmarks/node_modules/fstream/package.json
+++ b/benchmarks/node_modules/fstream/package.json
@@ -1,33 +1,32 @@
{
- "_from": "fstream@^1.0.2",
- "_id": "fstream@1.0.11",
- "_integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+ "_from": "fstream@^1.0.12",
+ "_id": "fstream@1.0.12",
+ "_inBundle": false,
+ "_integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"_location": "/fstream",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
- "raw": "fstream@^1.0.2",
+ "raw": "fstream@^1.0.12",
"name": "fstream",
"escapedName": "fstream",
- "rawSpec": "^1.0.2",
+ "rawSpec": "^1.0.12",
"saveSpec": null,
- "fetchSpec": "^1.0.2"
+ "fetchSpec": "^1.0.12"
},
"_requiredBy": [
"/tar"
],
- "_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
- "_shasum": "5c1fb1f117477114f0632a0eb4b71b3cb0fd3171",
- "_shrinkwrap": null,
- "_spec": "fstream@^1.0.2",
+ "_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+ "_shasum": "4e8ba8ee2d48be4f7d0de505455548eae5932045",
+ "_spec": "fstream@^1.0.12",
"_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/tar",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
- "bin": null,
"bugs": {
"url": "https://github.com/npm/fstream/issues"
},
@@ -51,8 +50,6 @@
"license": "ISC",
"main": "fstream.js",
"name": "fstream",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git+https://github.com/npm/fstream.git"
@@ -60,5 +57,5 @@
"scripts": {
"test": "standard && tap examples/*.js"
},
- "version": "1.0.11"
+ "version": "1.0.12"
}
diff --git a/benchmarks/node_modules/glob/LICENSE b/benchmarks/node_modules/glob/LICENSE
index 19129e31..42ca266d 100644
--- a/benchmarks/node_modules/glob/LICENSE
+++ b/benchmarks/node_modules/glob/LICENSE
@@ -13,3 +13,9 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+## Glob Logo
+
+Glob's logo created by Tanya Brassie , licensed
+under a Creative Commons Attribution-ShareAlike 4.0 International License
+https://creativecommons.org/licenses/by-sa/4.0/
diff --git a/benchmarks/node_modules/glob/README.md b/benchmarks/node_modules/glob/README.md
index baa1d1ba..e71b967e 100644
--- a/benchmarks/node_modules/glob/README.md
+++ b/benchmarks/node_modules/glob/README.md
@@ -7,7 +7,7 @@ Match files using the patterns the shell uses, like stars and stuff.
This is a glob implementation in JavaScript. It uses the `minimatch`
library to do its matching.
-
+
## Usage
@@ -347,6 +347,11 @@ Users are thus advised not to use a glob result as a guarantee of
filesystem state in the face of rapid changes. For the vast majority
of operations, this is never a problem.
+## Glob Logo
+Glob's logo was created by [Tanya Brassie](http://tanyabrassie.com/). Logo files can be found [here](https://github.com/isaacs/node-glob/tree/master/logo).
+
+The logo is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/).
+
## Contributing
Any change to behavior (including bugfixes) must come with a test.
diff --git a/benchmarks/node_modules/glob/glob.js b/benchmarks/node_modules/glob/glob.js
index bfdd7a11..58dec0f6 100644
--- a/benchmarks/node_modules/glob/glob.js
+++ b/benchmarks/node_modules/glob/glob.js
@@ -153,9 +153,7 @@ function Glob (pattern, options, cb) {
}
var self = this
- var n = this.minimatch.set.length
this._processing = 0
- this.matches = new Array(n)
this._emitQueue = []
this._processQueue = []
diff --git a/benchmarks/node_modules/glob/package.json b/benchmarks/node_modules/glob/package.json
index e1dc4e02..1df6c1c2 100644
--- a/benchmarks/node_modules/glob/package.json
+++ b/benchmarks/node_modules/glob/package.json
@@ -1,33 +1,32 @@
{
- "_from": "glob@^7.0.5",
- "_id": "glob@7.1.1",
- "_integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+ "_from": "glob@^7.1.3",
+ "_id": "glob@7.1.4",
+ "_inBundle": false,
+ "_integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"_location": "/glob",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
- "raw": "glob@^7.0.5",
+ "raw": "glob@^7.1.3",
"name": "glob",
"escapedName": "glob",
- "rawSpec": "^7.0.5",
+ "rawSpec": "^7.1.3",
"saveSpec": null,
- "fetchSpec": "^7.0.5"
+ "fetchSpec": "^7.1.3"
},
"_requiredBy": [
"/rimraf"
],
- "_resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
- "_shasum": "805211df04faaf1c63a3600306cdf5ade50b2ec8",
- "_shrinkwrap": null,
- "_spec": "glob@^7.0.5",
+ "_resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "_shasum": "aa608a2f6c577ad357e1ae5a5c26d9a8d1969255",
+ "_spec": "glob@^7.1.3",
"_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/rimraf",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
- "bin": null,
"bugs": {
"url": "https://github.com/isaacs/node-glob/issues"
},
@@ -36,7 +35,7 @@
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.2",
+ "minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
@@ -45,7 +44,7 @@
"devDependencies": {
"mkdirp": "0",
"rimraf": "^2.2.8",
- "tap": "^7.1.2",
+ "tap": "^12.0.1",
"tick": "0.0.6"
},
"engines": {
@@ -60,8 +59,6 @@
"license": "ISC",
"main": "glob.js",
"name": "glob",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-glob.git"
@@ -75,5 +72,5 @@
"test": "tap test/*.js --cov",
"test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js"
},
- "version": "7.1.1"
+ "version": "7.1.4"
}
diff --git a/benchmarks/node_modules/graceful-fs/fs.js b/benchmarks/node_modules/graceful-fs/fs.js
deleted file mode 100644
index 8ad4a383..00000000
--- a/benchmarks/node_modules/graceful-fs/fs.js
+++ /dev/null
@@ -1,21 +0,0 @@
-'use strict'
-
-var fs = require('fs')
-
-module.exports = clone(fs)
-
-function clone (obj) {
- if (obj === null || typeof obj !== 'object')
- return obj
-
- if (obj instanceof Object)
- var copy = { __proto__: obj.__proto__ }
- else
- var copy = Object.create(null)
-
- Object.getOwnPropertyNames(obj).forEach(function (key) {
- Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key))
- })
-
- return copy
-}
diff --git a/benchmarks/node_modules/graceful-fs/graceful-fs.js b/benchmarks/node_modules/graceful-fs/graceful-fs.js
index 33b30d2e..ac206757 100644
--- a/benchmarks/node_modules/graceful-fs/graceful-fs.js
+++ b/benchmarks/node_modules/graceful-fs/graceful-fs.js
@@ -1,6 +1,8 @@
var fs = require('fs')
var polyfills = require('./polyfills.js')
var legacy = require('./legacy-streams.js')
+var clone = require('./clone.js')
+
var queue = []
var util = require('util')
@@ -24,17 +26,17 @@ if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
})
}
-module.exports = patch(require('./fs.js'))
-if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) {
- module.exports = patch(fs)
+module.exports = patch(clone(fs))
+if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) {
+ module.exports = patch(fs)
+ fs.__patched = true;
}
// Always patch fs.close/closeSync, because we want to
// retry() whenever a close happens *anywhere* in the program.
// This is essential when multiple graceful-fs instances are
// in play at the same time.
-module.exports.close =
-fs.close = (function (fs$close) { return function (fd, cb) {
+module.exports.close = (function (fs$close) { return function (fd, cb) {
return fs$close.call(fs, fd, function (err) {
if (!err)
retry()
@@ -44,8 +46,7 @@ fs.close = (function (fs$close) { return function (fd, cb) {
})
}})(fs.close)
-module.exports.closeSync =
-fs.closeSync = (function (fs$closeSync) { return function (fd) {
+module.exports.closeSync = (function (fs$closeSync) { return function (fd) {
// Note that graceful-fs also retries when fs.closeSync() fails.
// Looks like a bug to me, although it's probably a harmless one.
var rval = fs$closeSync.apply(fs, arguments)
@@ -53,6 +54,17 @@ fs.closeSync = (function (fs$closeSync) { return function (fd) {
return rval
}})(fs.closeSync)
+// Only patch fs once, otherwise we'll run into a memory leak if
+// graceful-fs is loaded multiple times, such as in test environments that
+// reset the loaded modules between tests.
+// We look for the string `graceful-fs` from the comment above. This
+// way we are not adding any extra properties and it will detect if older
+// versions of graceful-fs are installed.
+if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) {
+ fs.closeSync = module.exports.closeSync;
+ fs.close = module.exports.close;
+}
+
function patch (fs) {
// Everything that references the open() function needs to be in here
polyfills(fs)
@@ -144,6 +156,7 @@ function patch (fs) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$readdir, [args]])
+
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
@@ -163,12 +176,16 @@ function patch (fs) {
}
var fs$ReadStream = fs.ReadStream
- ReadStream.prototype = Object.create(fs$ReadStream.prototype)
- ReadStream.prototype.open = ReadStream$open
+ if (fs$ReadStream) {
+ ReadStream.prototype = Object.create(fs$ReadStream.prototype)
+ ReadStream.prototype.open = ReadStream$open
+ }
var fs$WriteStream = fs.WriteStream
- WriteStream.prototype = Object.create(fs$WriteStream.prototype)
- WriteStream.prototype.open = WriteStream$open
+ if (fs$WriteStream) {
+ WriteStream.prototype = Object.create(fs$WriteStream.prototype)
+ WriteStream.prototype.open = WriteStream$open
+ }
fs.ReadStream = ReadStream
fs.WriteStream = WriteStream
diff --git a/benchmarks/node_modules/graceful-fs/package.json b/benchmarks/node_modules/graceful-fs/package.json
index b81becf6..abe85bec 100644
--- a/benchmarks/node_modules/graceful-fs/package.json
+++ b/benchmarks/node_modules/graceful-fs/package.json
@@ -1,7 +1,8 @@
{
"_from": "graceful-fs@^4.1.2",
- "_id": "graceful-fs@4.1.11",
- "_integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "_id": "graceful-fs@4.1.15",
+ "_inBundle": false,
+ "_integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
"_location": "/graceful-fs",
"_phantomChildren": {},
"_requested": {
@@ -17,35 +18,31 @@
"_requiredBy": [
"/fstream"
],
- "_resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "_shasum": "0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658",
- "_shrinkwrap": null,
+ "_resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "_shasum": "ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00",
"_spec": "graceful-fs@^4.1.2",
"_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/fstream",
- "bin": null,
"bugs": {
"url": "https://github.com/isaacs/node-graceful-fs/issues"
},
"bundleDependencies": false,
- "dependencies": {},
"deprecated": false,
"description": "A drop-in replacement for fs, making various improvements.",
"devDependencies": {
+ "import-fresh": "^2.0.0",
"mkdirp": "^0.5.0",
"rimraf": "^2.2.8",
- "tap": "^5.4.2"
+ "tap": "^12.0.1"
},
"directories": {
"test": "test"
},
- "engines": {
- "node": ">=0.4.0"
- },
"files": [
"fs.js",
"graceful-fs.js",
"legacy-streams.js",
- "polyfills.js"
+ "polyfills.js",
+ "clone.js"
],
"homepage": "https://github.com/isaacs/node-graceful-fs#readme",
"keywords": [
@@ -67,14 +64,15 @@
"license": "ISC",
"main": "graceful-fs.js",
"name": "graceful-fs",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git+https://github.com/isaacs/node-graceful-fs.git"
},
"scripts": {
+ "postpublish": "git push origin --all; git push origin --tags",
+ "postversion": "npm publish",
+ "preversion": "npm test",
"test": "node test.js | tap -"
},
- "version": "4.1.11"
+ "version": "4.1.15"
}
diff --git a/benchmarks/node_modules/graceful-fs/polyfills.js b/benchmarks/node_modules/graceful-fs/polyfills.js
index 4c6aca78..b964ed08 100644
--- a/benchmarks/node_modules/graceful-fs/polyfills.js
+++ b/benchmarks/node_modules/graceful-fs/polyfills.js
@@ -1,4 +1,3 @@
-var fs = require('./fs.js')
var constants = require('constants')
var origCwd = process.cwd
@@ -145,73 +144,36 @@ function patch (fs) {
}
}
}})(fs.readSync)
-}
-
-function patchLchmod (fs) {
- fs.lchmod = function (path, mode, callback) {
- fs.open( path
- , constants.O_WRONLY | constants.O_SYMLINK
- , mode
- , function (err, fd) {
- if (err) {
- if (callback) callback(err)
- return
- }
- // prefer to return the chmod error, if one occurs,
- // but still try to close, and report closing errors if they occur.
- fs.fchmod(fd, mode, function (err) {
- fs.close(fd, function(err2) {
- if (callback) callback(err || err2)
- })
- })
- })
- }
-
- fs.lchmodSync = function (path, mode) {
- var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
-
- // prefer to return the chmod error, if one occurs,
- // but still try to close, and report closing errors if they occur.
- var threw = true
- var ret
- try {
- ret = fs.fchmodSync(fd, mode)
- threw = false
- } finally {
- if (threw) {
- try {
- fs.closeSync(fd)
- } catch (er) {}
- } else {
- fs.closeSync(fd)
- }
- }
- return ret
- }
-}
-function patchLutimes (fs) {
- if (constants.hasOwnProperty("O_SYMLINK")) {
- fs.lutimes = function (path, at, mt, cb) {
- fs.open(path, constants.O_SYMLINK, function (er, fd) {
- if (er) {
- if (cb) cb(er)
+ function patchLchmod (fs) {
+ fs.lchmod = function (path, mode, callback) {
+ fs.open( path
+ , constants.O_WRONLY | constants.O_SYMLINK
+ , mode
+ , function (err, fd) {
+ if (err) {
+ if (callback) callback(err)
return
}
- fs.futimes(fd, at, mt, function (er) {
- fs.close(fd, function (er2) {
- if (cb) cb(er || er2)
+ // prefer to return the chmod error, if one occurs,
+ // but still try to close, and report closing errors if they occur.
+ fs.fchmod(fd, mode, function (err) {
+ fs.close(fd, function(err2) {
+ if (callback) callback(err || err2)
})
})
})
}
- fs.lutimesSync = function (path, at, mt) {
- var fd = fs.openSync(path, constants.O_SYMLINK)
- var ret
+ fs.lchmodSync = function (path, mode) {
+ var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
+
+ // prefer to return the chmod error, if one occurs,
+ // but still try to close, and report closing errors if they occur.
var threw = true
+ var ret
try {
- ret = fs.futimesSync(fd, at, mt)
+ ret = fs.fchmodSync(fd, mode)
threw = false
} finally {
if (threw) {
@@ -224,107 +186,144 @@ function patchLutimes (fs) {
}
return ret
}
+ }
+
+ function patchLutimes (fs) {
+ if (constants.hasOwnProperty("O_SYMLINK")) {
+ fs.lutimes = function (path, at, mt, cb) {
+ fs.open(path, constants.O_SYMLINK, function (er, fd) {
+ if (er) {
+ if (cb) cb(er)
+ return
+ }
+ fs.futimes(fd, at, mt, function (er) {
+ fs.close(fd, function (er2) {
+ if (cb) cb(er || er2)
+ })
+ })
+ })
+ }
+
+ fs.lutimesSync = function (path, at, mt) {
+ var fd = fs.openSync(path, constants.O_SYMLINK)
+ var ret
+ var threw = true
+ try {
+ ret = fs.futimesSync(fd, at, mt)
+ threw = false
+ } finally {
+ if (threw) {
+ try {
+ fs.closeSync(fd)
+ } catch (er) {}
+ } else {
+ fs.closeSync(fd)
+ }
+ }
+ return ret
+ }
- } else {
- fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) }
- fs.lutimesSync = function () {}
+ } else {
+ fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) }
+ fs.lutimesSync = function () {}
+ }
}
-}
-function chmodFix (orig) {
- if (!orig) return orig
- return function (target, mode, cb) {
- return orig.call(fs, target, mode, function (er) {
- if (chownErOk(er)) er = null
- if (cb) cb.apply(this, arguments)
- })
+ function chmodFix (orig) {
+ if (!orig) return orig
+ return function (target, mode, cb) {
+ return orig.call(fs, target, mode, function (er) {
+ if (chownErOk(er)) er = null
+ if (cb) cb.apply(this, arguments)
+ })
+ }
}
-}
-function chmodFixSync (orig) {
- if (!orig) return orig
- return function (target, mode) {
- try {
- return orig.call(fs, target, mode)
- } catch (er) {
- if (!chownErOk(er)) throw er
+ function chmodFixSync (orig) {
+ if (!orig) return orig
+ return function (target, mode) {
+ try {
+ return orig.call(fs, target, mode)
+ } catch (er) {
+ if (!chownErOk(er)) throw er
+ }
}
}
-}
-function chownFix (orig) {
- if (!orig) return orig
- return function (target, uid, gid, cb) {
- return orig.call(fs, target, uid, gid, function (er) {
- if (chownErOk(er)) er = null
- if (cb) cb.apply(this, arguments)
- })
+ function chownFix (orig) {
+ if (!orig) return orig
+ return function (target, uid, gid, cb) {
+ return orig.call(fs, target, uid, gid, function (er) {
+ if (chownErOk(er)) er = null
+ if (cb) cb.apply(this, arguments)
+ })
+ }
}
-}
-function chownFixSync (orig) {
- if (!orig) return orig
- return function (target, uid, gid) {
- try {
- return orig.call(fs, target, uid, gid)
- } catch (er) {
- if (!chownErOk(er)) throw er
+ function chownFixSync (orig) {
+ if (!orig) return orig
+ return function (target, uid, gid) {
+ try {
+ return orig.call(fs, target, uid, gid)
+ } catch (er) {
+ if (!chownErOk(er)) throw er
+ }
}
}
-}
-function statFix (orig) {
- if (!orig) return orig
- // Older versions of Node erroneously returned signed integers for
- // uid + gid.
- return function (target, cb) {
- return orig.call(fs, target, function (er, stats) {
- if (!stats) return cb.apply(this, arguments)
+ function statFix (orig) {
+ if (!orig) return orig
+ // Older versions of Node erroneously returned signed integers for
+ // uid + gid.
+ return function (target, cb) {
+ return orig.call(fs, target, function (er, stats) {
+ if (!stats) return cb.apply(this, arguments)
+ if (stats.uid < 0) stats.uid += 0x100000000
+ if (stats.gid < 0) stats.gid += 0x100000000
+ if (cb) cb.apply(this, arguments)
+ })
+ }
+ }
+
+ function statFixSync (orig) {
+ if (!orig) return orig
+ // Older versions of Node erroneously returned signed integers for
+ // uid + gid.
+ return function (target) {
+ var stats = orig.call(fs, target)
if (stats.uid < 0) stats.uid += 0x100000000
if (stats.gid < 0) stats.gid += 0x100000000
- if (cb) cb.apply(this, arguments)
- })
+ return stats;
+ }
}
-}
-function statFixSync (orig) {
- if (!orig) return orig
- // Older versions of Node erroneously returned signed integers for
- // uid + gid.
- return function (target) {
- var stats = orig.call(fs, target)
- if (stats.uid < 0) stats.uid += 0x100000000
- if (stats.gid < 0) stats.gid += 0x100000000
- return stats;
- }
-}
+ // ENOSYS means that the fs doesn't support the op. Just ignore
+ // that, because it doesn't matter.
+ //
+ // if there's no getuid, or if getuid() is something other
+ // than 0, and the error is EINVAL or EPERM, then just ignore
+ // it.
+ //
+ // This specific case is a silent failure in cp, install, tar,
+ // and most other unix tools that manage permissions.
+ //
+ // When running as root, or if other types of errors are
+ // encountered, then it's strict.
+ function chownErOk (er) {
+ if (!er)
+ return true
-// ENOSYS means that the fs doesn't support the op. Just ignore
-// that, because it doesn't matter.
-//
-// if there's no getuid, or if getuid() is something other
-// than 0, and the error is EINVAL or EPERM, then just ignore
-// it.
-//
-// This specific case is a silent failure in cp, install, tar,
-// and most other unix tools that manage permissions.
-//
-// When running as root, or if other types of errors are
-// encountered, then it's strict.
-function chownErOk (er) {
- if (!er)
- return true
-
- if (er.code === "ENOSYS")
- return true
-
- var nonroot = !process.getuid || process.getuid() !== 0
- if (nonroot) {
- if (er.code === "EINVAL" || er.code === "EPERM")
+ if (er.code === "ENOSYS")
return true
- }
- return false
+ var nonroot = !process.getuid || process.getuid() !== 0
+ if (nonroot) {
+ if (er.code === "EINVAL" || er.code === "EPERM")
+ return true
+ }
+
+ return false
+ }
}
diff --git a/benchmarks/node_modules/minimatch/package.json b/benchmarks/node_modules/minimatch/package.json
index f8a4ef30..4f29eb4d 100644
--- a/benchmarks/node_modules/minimatch/package.json
+++ b/benchmarks/node_modules/minimatch/package.json
@@ -1,45 +1,43 @@
{
- "_from": "minimatch@^3.0.2",
- "_id": "minimatch@3.0.3",
- "_integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+ "_from": "minimatch@^3.0.4",
+ "_id": "minimatch@3.0.4",
+ "_inBundle": false,
+ "_integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"_location": "/minimatch",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
- "raw": "minimatch@^3.0.2",
+ "raw": "minimatch@^3.0.4",
"name": "minimatch",
"escapedName": "minimatch",
- "rawSpec": "^3.0.2",
+ "rawSpec": "^3.0.4",
"saveSpec": null,
- "fetchSpec": "^3.0.2"
+ "fetchSpec": "^3.0.4"
},
"_requiredBy": [
"/glob"
],
- "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
- "_shasum": "2a4e4090b96b2db06a9d7df01055a62a77c9b774",
- "_shrinkwrap": null,
- "_spec": "minimatch@^3.0.2",
+ "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "_shasum": "5166e286457f03306064be5497e8dbb0c3d32083",
+ "_spec": "minimatch@^3.0.4",
"_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/glob",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me"
},
- "bin": null,
"bugs": {
"url": "https://github.com/isaacs/minimatch/issues"
},
"bundleDependencies": false,
"dependencies": {
- "brace-expansion": "^1.0.0"
+ "brace-expansion": "^1.1.7"
},
"deprecated": false,
"description": "a glob matcher in javascript",
"devDependencies": {
- "standard": "^3.7.2",
- "tap": "^5.6.0"
+ "tap": "^10.3.2"
},
"engines": {
"node": "*"
@@ -51,15 +49,15 @@
"license": "ISC",
"main": "minimatch.js",
"name": "minimatch",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/isaacs/minimatch.git"
},
"scripts": {
- "posttest": "standard minimatch.js test/*.js",
- "test": "tap test/*.js"
+ "postpublish": "git push origin --all; git push origin --tags",
+ "postversion": "npm publish",
+ "preversion": "npm test",
+ "test": "tap test/*.js --cov"
},
- "version": "3.0.3"
+ "version": "3.0.4"
}
diff --git a/benchmarks/node_modules/rimraf/package.json b/benchmarks/node_modules/rimraf/package.json
index 551aa27b..1eef864a 100644
--- a/benchmarks/node_modules/rimraf/package.json
+++ b/benchmarks/node_modules/rimraf/package.json
@@ -1,7 +1,8 @@
{
"_from": "rimraf@2",
- "_id": "rimraf@2.6.1",
- "_integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
+ "_id": "rimraf@2.6.3",
+ "_inBundle": false,
+ "_integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"_location": "/rimraf",
"_phantomChildren": {},
"_requested": {
@@ -17,9 +18,8 @@
"_requiredBy": [
"/fstream"
],
- "_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
- "_shasum": "c2338ec643df7a1b7fe5c54fa86f57428a55f33d",
- "_shrinkwrap": null,
+ "_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "_shasum": "b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab",
"_spec": "rimraf@2",
"_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/fstream",
"author": {
@@ -35,13 +35,13 @@
},
"bundleDependencies": false,
"dependencies": {
- "glob": "^7.0.5"
+ "glob": "^7.1.3"
},
"deprecated": false,
"description": "A deep deletion module for node (like `rm -rf`)",
"devDependencies": {
"mkdirp": "^0.5.1",
- "tap": "^10.1.2"
+ "tap": "^12.1.1"
},
"files": [
"LICENSE",
@@ -53,14 +53,15 @@
"license": "ISC",
"main": "rimraf.js",
"name": "rimraf",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/isaacs/rimraf.git"
},
"scripts": {
+ "postpublish": "git push origin --all; git push origin --tags",
+ "postversion": "npm publish",
+ "preversion": "npm test",
"test": "tap test/*.js"
},
- "version": "2.6.1"
+ "version": "2.6.3"
}
diff --git a/benchmarks/node_modules/rimraf/rimraf.js b/benchmarks/node_modules/rimraf/rimraf.js
index c2633126..e80dd106 100644
--- a/benchmarks/node_modules/rimraf/rimraf.js
+++ b/benchmarks/node_modules/rimraf/rimraf.js
@@ -5,6 +5,7 @@ var assert = require("assert")
var path = require("path")
var fs = require("fs")
var glob = require("glob")
+var _0666 = parseInt('666', 8)
var defaultGlobOpts = {
nosort: true,
@@ -165,7 +166,7 @@ function fixWinEPERM (p, options, er, cb) {
if (er)
assert(er instanceof Error)
- options.chmod(p, 666, function (er2) {
+ options.chmod(p, _0666, function (er2) {
if (er2)
cb(er2.code === "ENOENT" ? null : er)
else
@@ -187,7 +188,7 @@ function fixWinEPERMSync (p, options, er) {
assert(er instanceof Error)
try {
- options.chmodSync(p, 666)
+ options.chmodSync(p, _0666)
} catch (er2) {
if (er2.code === "ENOENT")
return
diff --git a/benchmarks/node_modules/tar/.npmignore b/benchmarks/node_modules/tar/.npmignore
deleted file mode 100644
index c167ad5b..00000000
--- a/benchmarks/node_modules/tar/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.*.swp
-node_modules
-examples/extract/
-test/tmp/
-test/fixtures/
diff --git a/benchmarks/node_modules/tar/lib/parse.js b/benchmarks/node_modules/tar/lib/parse.js
index 600ad782..1c66ebda 100644
--- a/benchmarks/node_modules/tar/lib/parse.js
+++ b/benchmarks/node_modules/tar/lib/parse.js
@@ -38,6 +38,7 @@ function Parse () {
me._stream = new BlockStream(512)
me.position = 0
me._ended = false
+ me._hardLinks = {}
me._stream.on("error", function (e) {
me.emit("error", e)
@@ -251,6 +252,11 @@ Parse.prototype._startEntry = function (c) {
if (onend) entry.on("end", onend)
this._entry = entry
+
+ if (entry.type === "Link") {
+ this._hardLinks[entry.path] = entry
+ }
+
var me = this
entry.on("pause", function () {
diff --git a/benchmarks/node_modules/tar/package.json b/benchmarks/node_modules/tar/package.json
index 0d8d0982..c9c694c0 100644
--- a/benchmarks/node_modules/tar/package.json
+++ b/benchmarks/node_modules/tar/package.json
@@ -1,41 +1,40 @@
{
- "_from": "tar@latest",
- "_id": "tar@2.2.1",
- "_integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+ "_from": "tar@2.2.2",
+ "_id": "tar@2.2.2",
+ "_inBundle": false,
+ "_integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
"_location": "/tar",
"_phantomChildren": {},
"_requested": {
- "type": "tag",
+ "type": "version",
"registry": true,
- "raw": "tar@latest",
+ "raw": "tar@2.2.2",
"name": "tar",
"escapedName": "tar",
- "rawSpec": "latest",
+ "rawSpec": "2.2.2",
"saveSpec": null,
- "fetchSpec": "latest"
+ "fetchSpec": "2.2.2"
},
"_requiredBy": [
"#USER",
"/"
],
- "_resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
- "_shasum": "8e4d2a256c0e2185c6b18ad694aec968b83cb1d1",
- "_shrinkwrap": null,
- "_spec": "tar@latest",
+ "_resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
+ "_shasum": "0ca8848562c7299b8b446ff6a4d60cdbb23edc40",
+ "_spec": "tar@2.2.2",
"_where": "/Users/isaacs/dev/js/tar/benchmarks",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
- "bin": null,
"bugs": {
"url": "https://github.com/isaacs/node-tar/issues"
},
"bundleDependencies": false,
"dependencies": {
"block-stream": "*",
- "fstream": "^1.0.2",
+ "fstream": "^1.0.12",
"inherits": "2"
},
"deprecated": false,
@@ -50,8 +49,6 @@
"license": "ISC",
"main": "tar.js",
"name": "tar",
- "optionalDependencies": {},
- "peerDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-tar.git"
@@ -59,5 +56,5 @@
"scripts": {
"test": "tap test/*.js"
},
- "version": "2.2.1"
+ "version": "2.2.2"
}
diff --git a/benchmarks/package-lock.json b/benchmarks/package-lock.json
index b1f88c0f..f24ac944 100644
--- a/benchmarks/package-lock.json
+++ b/benchmarks/package-lock.json
@@ -1,19 +1,30 @@
{
+ "name": "benchmarks",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
"dependencies": {
"balanced-match": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
- "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"block-stream": {
"version": "0.0.9",
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
- "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo="
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+ "requires": {
+ "inherits": "~2.0.0"
+ }
},
"brace-expansion": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
- "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k="
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
},
"concat-map": {
"version": "0.0.1",
@@ -26,24 +37,42 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fstream": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
- "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE="
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
+ }
},
"glob": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
- "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg="
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
},
"graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk="
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
},
"inherits": {
"version": "2.0.3",
@@ -51,9 +80,12 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"minimatch": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
- "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q="
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
},
"minimist": {
"version": "0.0.8",
@@ -63,12 +95,18 @@
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM="
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
},
"path-is-absolute": {
"version": "1.0.1",
@@ -76,14 +114,22 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"rimraf": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
- "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0="
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "requires": {
+ "glob": "^7.1.3"
+ }
},
"tar": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
- "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE="
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
+ "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
+ "requires": {
+ "block-stream": "*",
+ "fstream": "^1.0.12",
+ "inherits": "2"
+ }
},
"wrappy": {
"version": "1.0.2",
diff --git a/benchmarks/package.json b/benchmarks/package.json
new file mode 100644
index 00000000..78dfdbc8
--- /dev/null
+++ b/benchmarks/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "benchmarks",
+ "version": "1.0.0",
+ "dependencies": {
+ "tar": "^2.2.2"
+ }
+}
diff --git a/lib/extract.js b/lib/extract.js
index cbb458a0..6d032016 100644
--- a/lib/extract.js
+++ b/lib/extract.js
@@ -6,6 +6,7 @@ const Unpack = require('./unpack.js')
const fs = require('fs')
const fsm = require('fs-minipass')
const path = require('path')
+const stripSlash = require('./strip-trailing-slashes.js')
const x = module.exports = (opt_, files, cb) => {
if (typeof opt_ === 'function')
@@ -41,7 +42,7 @@ const x = module.exports = (opt_, files, cb) => {
// construct a filter that limits the file entries listed
// include child entries if a dir is included
const filesFilter = (opt, files) => {
- const map = new Map(files.map(f => [f.replace(/\/+$/, ''), true]))
+ const map = new Map(files.map(f => [stripSlash(f), true]))
const filter = opt.filter
const mapHas = (file, r) => {
@@ -55,8 +56,8 @@ const filesFilter = (opt, files) => {
}
opt.filter = filter
- ? (file, entry) => filter(file, entry) && mapHas(file.replace(/\/+$/, ''))
- : file => mapHas(file.replace(/\/+$/, ''))
+ ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file))
+ : file => mapHas(stripSlash(file))
}
const extractFileSync = opt => {
diff --git a/lib/large-numbers.js b/lib/large-numbers.js
index ff499926..3e5c9925 100644
--- a/lib/large-numbers.js
+++ b/lib/large-numbers.js
@@ -1,12 +1,13 @@
'use strict'
// Tar can encode large and negative numbers using a leading byte of
-// 0xff for negative, and 0x80 for positive. The trailing byte in the
-// section will always be 0x20, or in some implementations 0x00.
-// this module encodes and decodes these things.
+// 0xff for negative, and 0x80 for positive.
const encode = exports.encode = (num, buf) => {
- buf[buf.length - 1] = 0x20
- if (num < 0)
+ if (!Number.isSafeInteger(num))
+ // The number is so large that javascript cannot represent it with integer
+ // precision.
+ throw TypeError('cannot encode number outside of javascript safe integer range')
+ else if (num < 0)
encodeNegative(num, buf)
else
encodePositive(num, buf)
@@ -15,13 +16,10 @@ const encode = exports.encode = (num, buf) => {
const encodePositive = (num, buf) => {
buf[0] = 0x80
- for (var i = buf.length - 2; i > 0; i--) {
- if (num === 0)
- buf[i] = 0
- else {
- buf[i] = num % 0x100
- num = Math.floor(num / 0x100)
- }
+
+ for (var i = buf.length; i > 1; i--) {
+ buf[i-1] = num & 0xff
+ num = Math.floor(num / 0x100)
}
}
@@ -29,21 +27,16 @@ const encodeNegative = (num, buf) => {
buf[0] = 0xff
var flipped = false
num = num * -1
- for (var i = buf.length - 2; i > 0; i--) {
- var byte
- if (num === 0)
- byte = 0
- else {
- byte = num % 0x100
- num = Math.floor(num / 0x100)
- }
+ for (var i = buf.length; i > 1; i--) {
+ var byte = num & 0xff
+ num = Math.floor(num / 0x100)
if (flipped)
- buf[i] = onesComp(byte)
+ buf[i-1] = onesComp(byte)
else if (byte === 0)
- buf[i] = 0
+ buf[i-1] = 0
else {
flipped = true
- buf[i] = twosComp(byte)
+ buf[i-1] = twosComp(byte)
}
}
}
@@ -51,8 +44,20 @@ const encodeNegative = (num, buf) => {
const parse = exports.parse = (buf) => {
var post = buf[buf.length - 1]
var pre = buf[0]
- return pre === 0x80 ? pos(buf.slice(1, buf.length - 1))
- : twos(buf.slice(1, buf.length - 1))
+ var value;
+ if (pre === 0x80)
+ value = pos(buf.slice(1, buf.length))
+ else if (pre === 0xff)
+ value = twos(buf)
+ else
+ throw TypeError('invalid base256 encoding')
+
+ if (!Number.isSafeInteger(value))
+ // The number is so large that javascript cannot represent it with integer
+ // precision.
+ throw TypeError('parsed number outside of javascript safe integer range')
+
+ return value
}
const twos = (buf) => {
@@ -71,9 +76,9 @@ const twos = (buf) => {
f = twosComp(byte)
}
if (f !== 0)
- sum += f * Math.pow(256, len - i - 1)
+ sum -= f * Math.pow(256, len - i - 1)
}
- return sum * -1
+ return sum
}
const pos = (buf) => {
diff --git a/lib/list.js b/lib/list.js
index 250ebe00..5a5023bb 100644
--- a/lib/list.js
+++ b/lib/list.js
@@ -11,6 +11,7 @@ const Parser = require('./parse.js')
const fs = require('fs')
const fsm = require('fs-minipass')
const path = require('path')
+const stripSlash = require('./strip-trailing-slashes.js')
const t = module.exports = (opt_, files, cb) => {
if (typeof opt_ === 'function')
@@ -56,7 +57,7 @@ const onentryFunction = opt => {
// construct a filter that limits the file entries listed
// include child entries if a dir is included
const filesFilter = (opt, files) => {
- const map = new Map(files.map(f => [f.replace(/\/+$/, ''), true]))
+ const map = new Map(files.map(f => [stripSlash(f), true]))
const filter = opt.filter
const mapHas = (file, r) => {
@@ -70,8 +71,8 @@ const filesFilter = (opt, files) => {
}
opt.filter = filter
- ? (file, entry) => filter(file, entry) && mapHas(file.replace(/\/+$/, ''))
- : file => mapHas(file.replace(/\/+$/, ''))
+ ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file))
+ : file => mapHas(stripSlash(file))
}
const listFileSync = opt => {
diff --git a/lib/mkdir.js b/lib/mkdir.js
index 382329ef..69e8c083 100644
--- a/lib/mkdir.js
+++ b/lib/mkdir.js
@@ -8,6 +8,7 @@ const mkdirp = require('mkdirp')
const fs = require('fs')
const path = require('path')
const chownr = require('chownr')
+const normPath = require('./normalize-windows-path.js')
class SymlinkError extends Error {
constructor (symlink, path) {
@@ -33,7 +34,20 @@ class CwdError extends Error {
}
}
-const mkdir = module.exports = (dir, opt, cb) => {
+const cGet = (cache, key) => cache.get(normPath(key))
+const cSet = (cache, key, val) => cache.set(normPath(key), val)
+
+const checkCwd = (dir, cb) => {
+ fs.stat(dir, (er, st) => {
+ if (er || !st.isDirectory())
+ er = new CwdError(dir, er && er.code || 'ENOTDIR')
+ cb(er)
+ })
+}
+
+module.exports = (dir, opt, cb) => {
+ dir = normPath(dir)
+
// if there's any overlap between mask and mode,
// then we'll need an explicit chmod
const umask = opt.umask
@@ -49,13 +63,13 @@ const mkdir = module.exports = (dir, opt, cb) => {
const preserve = opt.preserve
const unlink = opt.unlink
const cache = opt.cache
- const cwd = opt.cwd
+ const cwd = normPath(opt.cwd)
const done = (er, created) => {
if (er)
cb(er)
else {
- cache.set(dir, true)
+ cSet(cache, dir, true)
if (created && doChown)
chownr(created, uid, gid, er => done(er))
else if (needChmod)
@@ -65,21 +79,17 @@ const mkdir = module.exports = (dir, opt, cb) => {
}
}
- if (cache && cache.get(dir) === true)
+ if (cache && cGet(cache, dir) === true)
return done()
if (dir === cwd)
- return fs.lstat(dir, (er, st) => {
- if (er || !st.isDirectory())
- er = new CwdError(dir, er && er.code || 'ENOTDIR')
- done(er)
- })
+ return checkCwd(dir, done)
if (preserve)
return mkdirp(dir, mode, done)
- const sub = path.relative(cwd, dir)
- const parts = sub.split(/\/|\\/)
+ const sub = normPath(path.relative(cwd, dir))
+ const parts = sub.split('/')
mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done)
}
@@ -87,22 +97,19 @@ const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => {
if (!parts.length)
return cb(null, created)
const p = parts.shift()
- const part = base + '/' + p
- if (cache.get(part))
+ const part = normPath(path.resolve(base + '/' + p))
+ if (cGet(cache, part))
return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb)
fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb))
}
const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => {
if (er) {
- if (er.path && path.dirname(er.path) === cwd &&
- (er.code === 'ENOTDIR' || er.code === 'ENOENT'))
- return cb(new CwdError(cwd, er.code))
-
fs.lstat(part, (statEr, st) => {
- if (statEr)
+ if (statEr) {
+ statEr.path = statEr.path && normPath(statEr.path)
cb(statEr)
- else if (st.isDirectory())
+ } else if (st.isDirectory())
mkdir_(part, parts, mode, cache, unlink, cwd, created, cb)
else if (unlink)
fs.unlink(part, er => {
@@ -121,7 +128,21 @@ const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => {
}
}
-const mkdirSync = module.exports.sync = (dir, opt) => {
+const checkCwdSync = dir => {
+ let ok = false
+ let code = 'ENOTDIR'
+ try {
+ ok = fs.statSync(dir).isDirectory()
+ } catch (er) {
+ code = er.code
+ } finally {
+ if (!ok)
+ throw new CwdError(dir, code)
+ }
+}
+
+module.exports.sync = (dir, opt) => {
+ dir = normPath(dir)
// if there's any overlap between mask and mode,
// then we'll need an explicit chmod
const umask = opt.umask
@@ -137,65 +158,51 @@ const mkdirSync = module.exports.sync = (dir, opt) => {
const preserve = opt.preserve
const unlink = opt.unlink
const cache = opt.cache
- const cwd = opt.cwd
+ const cwd = normPath(opt.cwd)
const done = (created) => {
- cache.set(dir, true)
+ cSet(cache, dir, true)
if (created && doChown)
chownr.sync(created, uid, gid)
if (needChmod)
fs.chmodSync(dir, mode)
}
- if (cache && cache.get(dir) === true)
+ if (cache && cGet(cache, dir) === true)
return done()
if (dir === cwd) {
- let ok = false
- let code = 'ENOTDIR'
- try {
- ok = fs.lstatSync(dir).isDirectory()
- } catch (er) {
- code = er.code
- } finally {
- if (!ok)
- throw new CwdError(dir, code)
- }
- done()
- return
+ checkCwdSync(cwd)
+ return done()
}
if (preserve)
return done(mkdirp.sync(dir, mode))
- const sub = path.relative(cwd, dir)
- const parts = sub.split(/\/|\\/)
+ const sub = normPath(path.relative(cwd, dir))
+ const parts = sub.split('/')
let created = null
for (let p = parts.shift(), part = cwd;
- p && (part += '/' + p);
- p = parts.shift()) {
-
- if (cache.get(part))
+ p && (part += '/' + p);
+ p = parts.shift()) {
+ part = normPath(path.resolve(part))
+ if (cGet(cache, part))
continue
try {
fs.mkdirSync(part, mode)
created = created || part
- cache.set(part, true)
+ cSet(cache, part, true)
} catch (er) {
- if (er.path && path.dirname(er.path) === cwd &&
- (er.code === 'ENOTDIR' || er.code === 'ENOENT'))
- return new CwdError(cwd, er.code)
-
const st = fs.lstatSync(part)
if (st.isDirectory()) {
- cache.set(part, true)
+ cSet(cache, part, true)
continue
} else if (unlink) {
fs.unlinkSync(part)
fs.mkdirSync(part, mode)
created = created || part
- cache.set(part, true)
+ cSet(cache, part, true)
continue
} else if (st.isSymbolicLink())
return new SymlinkError(part, part + '/' + parts.join('/'))
diff --git a/lib/normalize-windows-path.js b/lib/normalize-windows-path.js
new file mode 100644
index 00000000..eb13ba01
--- /dev/null
+++ b/lib/normalize-windows-path.js
@@ -0,0 +1,8 @@
+// on windows, either \ or / are valid directory separators.
+// on unix, \ is a valid character in filenames.
+// so, on windows, and only on windows, we replace all \ chars with /,
+// so that we can use / as our one and only directory separator char.
+
+const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform
+module.exports = platform !== 'win32' ? p => p
+ : p => p && p.replace(/\\/g, '/')
diff --git a/lib/pack.js b/lib/pack.js
index 857cea91..102a3d51 100644
--- a/lib/pack.js
+++ b/lib/pack.js
@@ -56,6 +56,7 @@ const ONDRAIN = Symbol('ondrain')
const fs = require('fs')
const path = require('path')
const warner = require('./warn-mixin.js')
+const normPath = require('./normalize-windows-path.js')
const Pack = warner(class Pack extends MiniPass {
constructor (opt) {
@@ -67,7 +68,7 @@ const Pack = warner(class Pack extends MiniPass {
this.preservePaths = !!opt.preservePaths
this.strict = !!opt.strict
this.noPax = !!opt.noPax
- this.prefix = (opt.prefix || '').replace(/(\\|\/)+$/, '')
+ this.prefix = normPath(opt.prefix || '')
this.linkCache = opt.linkCache || new Map()
this.statCache = opt.statCache || new Map()
this.readdirCache = opt.readdirCache || new Map()
@@ -132,10 +133,7 @@ const Pack = warner(class Pack extends MiniPass {
}
[ADDTARENTRY] (p) {
- const absolute = path.resolve(this.cwd, p.path)
- if (this.prefix)
- p.path = this.prefix + '/' + p.path.replace(/^\.(\/+|$)/, '')
-
+ const absolute = normPath(path.resolve(this.cwd, p.path))
// in this case, we don't have to wait for the stat
if (!this.filter(p.path, p))
p.resume()
@@ -151,10 +149,7 @@ const Pack = warner(class Pack extends MiniPass {
}
[ADDFSENTRY] (p) {
- const absolute = path.resolve(this.cwd, p)
- if (this.prefix)
- p = this.prefix + '/' + p.replace(/^\.(\/+|$)/, '')
-
+ const absolute = normPath(path.resolve(this.cwd, p))
this[QUEUE].push(new PackJob(p, absolute))
this[PROCESS]()
}
@@ -298,7 +293,8 @@ const Pack = warner(class Pack extends MiniPass {
linkCache: this.linkCache,
statCache: this.statCache,
noMtime: this.noMtime,
- mtime: this.mtime
+ mtime: this.mtime,
+ prefix: this.prefix,
}
}
@@ -324,10 +320,7 @@ const Pack = warner(class Pack extends MiniPass {
if (job.readdir)
job.readdir.forEach(entry => {
- const p = this.prefix ?
- job.path.slice(this.prefix.length + 1) || './'
- : job.path
-
+ const p = job.path
const base = p === './' ? '' : p.replace(/\/*$/, '/')
this[ADDFSENTRY](base + entry)
})
@@ -380,10 +373,7 @@ class PackSync extends Pack {
if (job.readdir)
job.readdir.forEach(entry => {
- const p = this.prefix ?
- job.path.slice(this.prefix.length + 1) || './'
- : job.path
-
+ const p = job.path
const base = p === './' ? '' : p.replace(/\/*$/, '/')
this[ADDFSENTRY](base + entry)
})
diff --git a/lib/parse.js b/lib/parse.js
index 34e3cd70..43d4383d 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -102,7 +102,12 @@ module.exports = warner(class Parser extends EE {
}
[CONSUMEHEADER] (chunk, position) {
- const header = new Header(chunk, position, this[EX], this[GEX])
+ let header
+ try {
+ header = new Header(chunk, position, this[EX], this[GEX])
+ } catch (er) {
+ return this.warn('invalid entry', er)
+ }
if (header.nullBlock)
this[EMIT]('nullBlock')
diff --git a/lib/path-reservations.js b/lib/path-reservations.js
new file mode 100644
index 00000000..b7f6c916
--- /dev/null
+++ b/lib/path-reservations.js
@@ -0,0 +1,149 @@
+// A path exclusive reservation system
+// reserve([list, of, paths], fn)
+// When the fn is first in line for all its paths, it
+// is called with a cb that clears the reservation.
+//
+// Used by async unpack to avoid clobbering paths in use,
+// while still allowing maximal safe parallelization.
+
+const assert = require('assert')
+const normPath = require('./normalize-windows-path.js')
+const stripSlashes = require('./strip-trailing-slashes.js')
+const { join } = require('path')
+
+const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform
+const isWindows = platform === 'win32'
+
+module.exports = () => {
+ // path => [function or Set]
+ // A Set object means a directory reservation
+ // A fn is a direct reservation on that path
+ const queues = new Map()
+
+ // fn => {paths:[path,...], dirs:[path, ...]}
+ const reservations = new Map()
+
+ // return a set of parent dirs for a given path
+ // '/a/b/c/d' -> ['/', '/a', '/a/b', '/a/b/c', '/a/b/c/d']
+ const getDirs = path => {
+ const dirs = path.split('/').slice(0, -1).reduce((set, path) => {
+ if (set.length)
+ path = normPath(join(set[set.length - 1], path))
+ set.push(path || '/')
+ return set
+ }, [])
+ return dirs
+ }
+
+ // functions currently running
+ const running = new Set()
+
+ // return the queues for each path the function cares about
+ // fn => {paths, dirs}
+ const getQueues = fn => {
+ const res = reservations.get(fn)
+ /* istanbul ignore if - unpossible */
+ if (!res)
+ throw new Error('function does not have any path reservations')
+ return {
+ paths: res.paths.map(path => queues.get(path)),
+ dirs: [...res.dirs].map(path => queues.get(path)),
+ }
+ }
+
+ // check if fn is first in line for all its paths, and is
+ // included in the first set for all its dir queues
+ const check = fn => {
+ const {paths, dirs} = getQueues(fn)
+ return paths.every(q => q[0] === fn) &&
+ dirs.every(q => q[0] instanceof Set && q[0].has(fn))
+ }
+
+ // run the function if it's first in line and not already running
+ const run = fn => {
+ if (running.has(fn) || !check(fn))
+ return false
+ running.add(fn)
+ fn(() => clear(fn))
+ return true
+ }
+
+ const clear = fn => {
+ if (!running.has(fn))
+ return false
+
+ const { paths, dirs } = reservations.get(fn)
+ const next = new Set()
+
+ paths.forEach(path => {
+ const q = queues.get(path)
+ assert.equal(q[0], fn)
+ if (q.length === 1)
+ queues.delete(path)
+ else {
+ q.shift()
+ if (typeof q[0] === 'function')
+ next.add(q[0])
+ else
+ q[0].forEach(fn => next.add(fn))
+ }
+ })
+
+ dirs.forEach(dir => {
+ const q = queues.get(dir)
+ assert(q[0] instanceof Set)
+ if (q[0].size === 1 && q.length === 1) {
+ queues.delete(dir)
+ } else if (q[0].size === 1) {
+ q.shift()
+
+ // must be a function or else the Set would've been reused
+ next.add(q[0])
+ } else
+ q[0].delete(fn)
+ })
+ running.delete(fn)
+
+ next.forEach(fn => run(fn))
+ return true
+ }
+
+ const reserve = (paths, fn) => {
+ // collide on matches across case and unicode normalization
+ // On windows, thanks to the magic of 8.3 shortnames, it is fundamentally
+ // impossible to determine whether two paths refer to the same thing on
+ // disk, without asking the kernel for a shortname.
+ // So, we just pretend that every path matches every other path here,
+ // effectively removing all parallelization on windows.
+ paths = isWindows ? ['win32 parallelization disabled'] : paths.map(p => {
+ return stripSlashes(normPath(join(p)))
+ .normalize('NFKD')
+ .toLowerCase()
+ })
+
+ const dirs = new Set(
+ paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b))
+ )
+ reservations.set(fn, {dirs, paths})
+ paths.forEach(path => {
+ const q = queues.get(path)
+ if (!q)
+ queues.set(path, [fn])
+ else
+ q.push(fn)
+ })
+ dirs.forEach(dir => {
+ const q = queues.get(dir)
+ if (!q)
+ queues.set(dir, [new Set([fn])])
+ else if (q[q.length-1] instanceof Set)
+ q[q.length-1].add(fn)
+ else
+ q.push(new Set([fn]))
+ })
+
+ return run(fn)
+ }
+
+ return { check, reserve }
+}
diff --git a/lib/read-entry.js b/lib/read-entry.js
index aa369c74..6ea3135c 100644
--- a/lib/read-entry.js
+++ b/lib/read-entry.js
@@ -1,11 +1,16 @@
'use strict'
const types = require('./types.js')
const MiniPass = require('minipass')
+const normPath = require('./normalize-windows-path.js')
const SLURP = Symbol('slurp')
module.exports = class ReadEntry extends MiniPass {
constructor (header, ex, gex) {
super()
+ // read entries always start life paused. this is to avoid the
+ // situation where Minipass's auto-ending empty streams results
+ // in an entry ending before we're ready for it.
+ this.pause()
this.extended = ex
this.globalExtended = gex
this.header = header
@@ -43,7 +48,7 @@ module.exports = class ReadEntry extends MiniPass {
this.ignore = true
}
- this.path = header.path
+ this.path = normPath(header.path)
this.mode = header.mode
if (this.mode)
this.mode = this.mode & 0o7777
@@ -55,7 +60,7 @@ module.exports = class ReadEntry extends MiniPass {
this.mtime = header.mtime
this.atime = header.atime
this.ctime = header.ctime
- this.linkpath = header.linkpath
+ this.linkpath = normPath(header.linkpath)
this.uname = header.uname
this.gname = header.gname
@@ -88,7 +93,7 @@ module.exports = class ReadEntry extends MiniPass {
// a global extended header, because that's weird.
if (ex[k] !== null && ex[k] !== undefined &&
!(global && k === 'path'))
- this[k] = ex[k]
+ this[k] = k === 'path' || k === 'linkpath' ? normPath(ex[k]) : ex[k]
}
}
}
diff --git a/lib/replace.js b/lib/replace.js
index 571cee94..68d83a47 100644
--- a/lib/replace.js
+++ b/lib/replace.js
@@ -168,7 +168,8 @@ const replace = (opt, files, cb) => {
fs.fstat(fd, (er, st) => {
if (er)
- return reject(er)
+ return fs.close(fd, () => reject(er))
+
getPos(fd, st.size, (er, position) => {
if (er)
return reject(er)
diff --git a/lib/strip-absolute-path.js b/lib/strip-absolute-path.js
new file mode 100644
index 00000000..1aa2d2ae
--- /dev/null
+++ b/lib/strip-absolute-path.js
@@ -0,0 +1,24 @@
+// unix absolute paths are also absolute on win32, so we use this for both
+const { isAbsolute, parse } = require('path').win32
+
+// returns [root, stripped]
+// Note that windows will think that //x/y/z/a has a "root" of //x/y, and in
+// those cases, we want to sanitize it to x/y/z/a, not z/a, so we strip /
+// explicitly if it's the first character.
+// drive-specific relative paths on Windows get their root stripped off even
+// though they are not absolute, so `c:../foo` becomes ['c:', '../foo']
+module.exports = path => {
+ let r = ''
+
+ let parsed = parse(path)
+ while (isAbsolute(path) || parsed.root) {
+ // windows will think that //x/y/z has a "root" of //x/y/
+ // but strip the //?/C:/ off of //?/C:/path
+ const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? '/'
+ : parsed.root
+ path = path.substr(root.length)
+ r += root
+ parsed = parse(path)
+ }
+ return [r, path]
+}
diff --git a/lib/strip-trailing-slashes.js b/lib/strip-trailing-slashes.js
new file mode 100644
index 00000000..f702ed5a
--- /dev/null
+++ b/lib/strip-trailing-slashes.js
@@ -0,0 +1,24 @@
+// this is the only approach that was significantly faster than using
+// str.replace(/\/+$/, '') for strings ending with a lot of / chars and
+// containing multiple / chars.
+const batchStrings = [
+ '/'.repeat(1024),
+ '/'.repeat(512),
+ '/'.repeat(256),
+ '/'.repeat(128),
+ '/'.repeat(64),
+ '/'.repeat(32),
+ '/'.repeat(16),
+ '/'.repeat(8),
+ '/'.repeat(4),
+ '/'.repeat(2),
+ '/',
+]
+
+module.exports = str => {
+ for (const s of batchStrings) {
+ while (str.length >= s.length && str.slice(-1 * s.length) === s)
+ str = str.slice(0, -1 * s.length)
+ }
+ return str
+}
diff --git a/lib/unpack.js b/lib/unpack.js
index fc765096..726c4576 100644
--- a/lib/unpack.js
+++ b/lib/unpack.js
@@ -1,5 +1,11 @@
'use strict'
+// the PEND/UNPEND stuff tracks whether we're ready to emit end/close yet.
+// but the path reservations are required to avoid race conditions where
+// parallelized unpack ops may mess with one another, due to dependencies
+// (like a Link depending on its target) or destructive operations (like
+// clobbering an fs object to create one of a different type.)
+
const assert = require('assert')
const EE = require('events').EventEmitter
const Parser = require('./parse.js')
@@ -9,9 +15,15 @@ const path = require('path')
const mkdir = require('./mkdir.js')
const mkdirSync = mkdir.sync
const wc = require('./winchars.js')
+const stripAbsolutePath = require('./strip-absolute-path.js')
+const pathReservations = require('./path-reservations.js')
+const normPath = require('./normalize-windows-path.js')
+const stripSlash = require('./strip-trailing-slashes.js')
const ONENTRY = Symbol('onEntry')
const CHECKFS = Symbol('checkFs')
+const CHECKFS2 = Symbol('checkFs2')
+const PRUNECACHE = Symbol('pruneCache')
const ISREUSABLE = Symbol('isReusable')
const MAKEFS = Symbol('makeFs')
const FILE = Symbol('file')
@@ -33,7 +45,10 @@ const SKIP = Symbol('skip')
const DOCHOWN = Symbol('doChown')
const UID = Symbol('uid')
const GID = Symbol('gid')
+const CHECKED_CWD = Symbol('checkedCwd')
const crypto = require('crypto')
+const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform
+const isWindows = platform === 'win32'
// Unlinks on Windows are not atomic.
//
@@ -52,7 +67,7 @@ const crypto = require('crypto')
// See: https://github.com/npm/node-tar/issues/183
/* istanbul ignore next */
const unlinkFile = (path, cb) => {
- if (process.platform !== 'win32')
+ if (!isWindows)
return fs.unlink(path, cb)
const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex')
@@ -65,7 +80,7 @@ const unlinkFile = (path, cb) => {
/* istanbul ignore next */
const unlinkFileSync = path => {
- if (process.platform !== 'win32')
+ if (!isWindows)
return fs.unlinkSync(path)
const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex')
@@ -79,6 +94,33 @@ const uint32 = (a, b, c) =>
: b === b >>> 0 ? b
: c
+// clear the cache if it's a case-insensitive unicode-squashing match.
+// we can't know if the current file system is case-sensitive or supports
+// unicode fully, so we check for similarity on the maximally compatible
+// representation. Err on the side of pruning, since all it's doing is
+// preventing lstats, and it's not the end of the world if we get a false
+// positive.
+// Note that on windows, we always drop the entire cache whenever a
+// symbolic link is encountered, because 8.3 filenames are impossible
+// to reason about, and collisions are hazards rather than just failures.
+const cacheKeyNormalize = path => stripSlash(normPath(path))
+ .normalize('NFKD')
+ .toLowerCase()
+
+const pruneCache = (cache, abs) => {
+ abs = cacheKeyNormalize(abs)
+ for (const path of cache.keys()) {
+ const pnorm = cacheKeyNormalize(path)
+ if (pnorm === abs || pnorm.indexOf(abs + '/') === 0)
+ cache.delete(path)
+ }
+}
+
+const dropCache = cache => {
+ for (const key of cache.keys())
+ cache.delete(key)
+}
+
class Unpack extends Parser {
constructor (opt) {
if (!opt)
@@ -91,6 +133,10 @@ class Unpack extends Parser {
super(opt)
+ this[CHECKED_CWD] = false
+
+ this.reservations = pathReservations()
+
this.transform = typeof opt.transform === 'function' ? opt.transform : null
this.writable = true
@@ -133,7 +179,7 @@ class Unpack extends Parser {
this.forceChown = opt.forceChown === true
// turn >| in filenames into 0xf000-higher encoded forms
- this.win32 = !!opt.win32 || process.platform === 'win32'
+ this.win32 = !!opt.win32 || isWindows
// do not unpack over files that are newer than what's in the archive
this.newer = !!opt.newer
@@ -153,7 +199,7 @@ class Unpack extends Parser {
// links, and removes symlink directories rather than erroring
this.unlink = !!opt.unlink
- this.cwd = path.resolve(opt.cwd || process.cwd())
+ this.cwd = normPath(path.resolve(opt.cwd || process.cwd()))
this.strip = +opt.strip || 0
this.processUmask = process.umask()
this.umask = typeof opt.umask === 'number' ? opt.umask : this.processUmask
@@ -174,46 +220,72 @@ class Unpack extends Parser {
[CHECKPATH] (entry) {
if (this.strip) {
- const parts = entry.path.split(/\/|\\/)
+ const parts = normPath(entry.path).split('/')
if (parts.length < this.strip)
return false
entry.path = parts.slice(this.strip).join('/')
if (entry.type === 'Link') {
- const linkparts = entry.linkpath.split(/\/|\\/)
+ const linkparts = normPath(entry.linkpath).split('/')
if (linkparts.length >= this.strip)
entry.linkpath = linkparts.slice(this.strip).join('/')
+ else
+ return false
}
}
if (!this.preservePaths) {
- const p = entry.path
- if (p.match(/(^|\/|\\)\.\.(\\|\/|$)/)) {
- this.warn('path contains \'..\'', p)
+ const p = normPath(entry.path)
+ const parts = p.split('/')
+ if (parts.includes('..') || isWindows && /^[a-z]:\.\.$/i.test(parts[0])) {
+ this.warn(`path contains '..'`, p)
return false
}
- // absolutes on posix are also absolutes on win32
- // so we only need to test this one to get both
- if (path.win32.isAbsolute(p)) {
- const parsed = path.win32.parse(p)
- this.warn('stripping ' + parsed.root + ' from absolute path', p)
- entry.path = p.substr(parsed.root.length)
+ // strip off the root
+ const s = stripAbsolutePath(p)
+ if (s[0]) {
+ entry.path = s[1]
+ this.warn(`stripping ${s[0]} from absolute path`, p)
}
}
+ if (path.isAbsolute(entry.path))
+ entry.absolute = normPath(path.resolve(entry.path))
+ else
+ entry.absolute = normPath(path.resolve(this.cwd, entry.path))
+
+ // if we somehow ended up with a path that escapes the cwd, and we are
+ // not in preservePaths mode, then something is fishy! This should have
+ // been prevented above, so ignore this for coverage.
+ /* istanbul ignore if - defense in depth */
+ if (!this.preservePaths &&
+ entry.absolute.indexOf(this.cwd + '/') !== 0 &&
+ entry.absolute !== this.cwd) {
+ this.warn('TAR_ENTRY_ERROR', 'path escaped extraction target', {
+ entry,
+ path: normPath(entry.path),
+ resolvedPath: entry.absolute,
+ cwd: this.cwd,
+ })
+ return false
+ }
+
+ // an archive can set properties on the extraction directory, but it
+ // may not replace the cwd with a different kind of thing entirely.
+ if (entry.absolute === this.cwd &&
+ entry.type !== 'Directory' &&
+ entry.type !== 'GNUDumpDir')
+ return false
+
// only encode : chars that aren't drive letter indicators
if (this.win32) {
- const parsed = path.win32.parse(entry.path)
- entry.path = parsed.root === '' ? wc.encode(entry.path)
- : parsed.root + wc.encode(entry.path.substr(parsed.root.length))
+ const { root: aRoot } = path.win32.parse(entry.absolute)
+ entry.absolute = aRoot + wc.encode(entry.absolute.substr(aRoot.length))
+ const { root: pRoot } = path.win32.parse(entry.path)
+ entry.path = pRoot + wc.encode(entry.path.substr(pRoot.length))
}
- if (path.isAbsolute(entry.path))
- entry.absolute = entry.path
- else
- entry.absolute = path.resolve(this.cwd, entry.path)
-
return true
}
@@ -257,7 +329,7 @@ class Unpack extends Parser {
}
[MKDIR] (dir, mode, cb) {
- mkdir(dir, {
+ mkdir(normPath(dir), {
uid: this.uid,
gid: this.gid,
processUid: this.processUid,
@@ -291,21 +363,44 @@ class Unpack extends Parser {
return uint32(this.gid, entry.gid, this.processGid)
}
- [FILE] (entry) {
+ [FILE] (entry, fullyDone) {
const mode = entry.mode & 0o7777 || this.fmode
const stream = new fsm.WriteStream(entry.absolute, {
mode: mode,
autoClose: false
})
- stream.on('error', er => this[ONERROR](er, entry))
+ stream.on('error', er => {
+ if (stream.fd)
+ fs.close(stream.fd, () => {})
+
+ // flush all the data out so that we aren't left hanging
+ // if the error wasn't actually fatal. otherwise the parse
+ // is blocked, and we never proceed.
+ /* istanbul ignore next */
+ stream.write = () => true
+ this[ONERROR](er, entry)
+ fullyDone()
+ })
let actions = 1
const done = er => {
- if (er)
- return this[ONERROR](er, entry)
+ if (er) {
+ /* istanbul ignore else - we should always have a fd by now */
+ if (stream.fd)
+ fs.close(stream.fd, () => {})
- if (--actions === 0)
- fs.close(stream.fd, _ => this[UNPEND]())
+ this[ONERROR](er, entry)
+ fullyDone()
+ return
+ }
+
+ if (--actions === 0) {
+ fs.close(stream.fd, er => {
+ fullyDone()
+ /* istanbul ignore next */
+ er ? this[ONERROR](er, entry) : this[UNPEND]()
+ })
+ }
}
stream.on('finish', _ => {
@@ -344,15 +439,18 @@ class Unpack extends Parser {
tx.pipe(stream)
}
- [DIRECTORY] (entry) {
+ [DIRECTORY] (entry, fullyDone) {
const mode = entry.mode & 0o7777 || this.dmode
this[MKDIR](entry.absolute, mode, er => {
- if (er)
+ if (er) {
+ fullyDone()
return this[ONERROR](er, entry)
+ }
let actions = 1
const done = _ => {
if (--actions === 0) {
+ fullyDone()
this[UNPEND]()
entry.resume()
}
@@ -377,12 +475,13 @@ class Unpack extends Parser {
entry.resume()
}
- [SYMLINK] (entry) {
- this[LINK](entry, entry.linkpath, 'symlink')
+ [SYMLINK] (entry, done) {
+ this[LINK](entry, entry.linkpath, 'symlink', done)
}
- [HARDLINK] (entry) {
- this[LINK](entry, path.resolve(this.cwd, entry.linkpath), 'link')
+ [HARDLINK] (entry, done) {
+ const linkpath = normPath(path.resolve(this.cwd, entry.linkpath))
+ this[LINK](entry, linkpath, 'link', done)
}
[PEND] () {
@@ -407,35 +506,122 @@ class Unpack extends Parser {
!this.unlink &&
st.isFile() &&
st.nlink <= 1 &&
- process.platform !== 'win32'
+ !isWindows
}
// check if a thing is there, and if so, try to clobber it
[CHECKFS] (entry) {
this[PEND]()
- this[MKDIR](path.dirname(entry.absolute), this.dmode, er => {
- if (er)
- return this[ONERROR](er, entry)
- fs.lstat(entry.absolute, (er, st) => {
- if (st && (this.keep || this.newer && st.mtime > entry.mtime))
+ const paths = [entry.path]
+ if (entry.linkpath)
+ paths.push(entry.linkpath)
+ this.reservations.reserve(paths, done => this[CHECKFS2](entry, done))
+ }
+
+ [PRUNECACHE] (entry) {
+ // if we are not creating a directory, and the path is in the dirCache,
+ // then that means we are about to delete the directory we created
+ // previously, and it is no longer going to be a directory, and neither
+ // is any of its children.
+ // If a symbolic link is encountered, all bets are off. There is no
+ // reasonable way to sanitize the cache in such a way we will be able to
+ // avoid having filesystem collisions. If this happens with a non-symlink
+ // entry, it'll just fail to unpack, but a symlink to a directory, using an
+ // 8.3 shortname or certain unicode attacks, can evade detection and lead
+ // to arbitrary writes to anywhere on the system.
+ if (entry.type === 'SymbolicLink')
+ dropCache(this.dirCache)
+ else if (entry.type !== 'Directory')
+ pruneCache(this.dirCache, entry.absolute)
+ }
+
+ [CHECKFS2] (entry, fullyDone) {
+ this[PRUNECACHE](entry)
+
+ const done = er => {
+ this[PRUNECACHE](entry)
+ fullyDone(er)
+ }
+
+ const checkCwd = () => {
+ this[MKDIR](this.cwd, this.dmode, er => {
+ if (er) {
+ this[ONERROR](er, entry)
+ done()
+ return
+ }
+ this[CHECKED_CWD] = true
+ start()
+ })
+ }
+
+ const start = () => {
+ if (entry.absolute !== this.cwd) {
+ const parent = normPath(path.dirname(entry.absolute))
+ if (parent !== this.cwd) {
+ return this[MKDIR](parent, this.dmode, er => {
+ if (er) {
+ this[ONERROR](er, entry)
+ done()
+ return
+ }
+ afterMakeParent()
+ })
+ }
+ }
+ afterMakeParent()
+ }
+
+ const afterMakeParent = () => {
+ fs.lstat(entry.absolute, (lstatEr, st) => {
+ if (st && (this.keep || this.newer && st.mtime > entry.mtime)) {
this[SKIP](entry)
- else if (er || this[ISREUSABLE](entry, st))
- this[MAKEFS](null, entry)
- else if (st.isDirectory()) {
+ done()
+ return
+ }
+ if (lstatEr || this[ISREUSABLE](entry, st))
+ return this[MAKEFS](null, entry, done)
+
+ if (st.isDirectory()) {
if (entry.type === 'Directory') {
- if (!entry.mode || (st.mode & 0o7777) === entry.mode)
- this[MAKEFS](null, entry)
- else
- fs.chmod(entry.absolute, entry.mode, er => this[MAKEFS](er, entry))
- } else
- fs.rmdir(entry.absolute, er => this[MAKEFS](er, entry))
- } else
- unlinkFile(entry.absolute, er => this[MAKEFS](er, entry))
+ const needChmod = !this.noChmod &&
+ entry.mode &&
+ (st.mode & 0o7777) !== entry.mode
+ const afterChmod = er => this[MAKEFS](er, entry, done)
+ if (!needChmod)
+ return afterChmod()
+ return fs.chmod(entry.absolute, entry.mode, afterChmod)
+ }
+ // Not a dir entry, have to remove it.
+ // NB: the only way to end up with an entry that is the cwd
+ // itself, in such a way that == does not detect, is a
+ // tricky windows absolute path with UNC or 8.3 parts (and
+ // preservePaths:true, or else it will have been stripped).
+ // In that case, the user has opted out of path protections
+ // explicitly, so if they blow away the cwd, c'est la vie.
+ if (entry.absolute !== this.cwd) {
+ return fs.rmdir(entry.absolute, er =>
+ this[MAKEFS](er, entry, done))
+ }
+ }
+
+ // not a dir, and not reusable
+ // don't remove if the cwd, we want that error
+ if (entry.absolute === this.cwd)
+ return this[MAKEFS](null, entry, done)
+
+ unlinkFile(entry.absolute, er =>
+ this[MAKEFS](er, entry, done))
})
- })
+ }
+
+ if (this[CHECKED_CWD])
+ start()
+ else
+ checkCwd()
}
- [MAKEFS] (er, entry) {
+ [MAKEFS] (er, entry, done) {
if (er)
return this[ONERROR](er, entry)
@@ -443,73 +629,107 @@ class Unpack extends Parser {
case 'File':
case 'OldFile':
case 'ContiguousFile':
- return this[FILE](entry)
+ return this[FILE](entry, done)
case 'Link':
- return this[HARDLINK](entry)
+ return this[HARDLINK](entry, done)
case 'SymbolicLink':
- return this[SYMLINK](entry)
+ return this[SYMLINK](entry, done)
case 'Directory':
case 'GNUDumpDir':
- return this[DIRECTORY](entry)
+ return this[DIRECTORY](entry, done)
}
}
- [LINK] (entry, linkpath, link) {
- // XXX: get the type ('file' or 'dir') for windows
+ [LINK] (entry, linkpath, link, done) {
+ // XXX: get the type ('symlink' or 'junction') for windows
fs[link](linkpath, entry.absolute, er => {
if (er)
return this[ONERROR](er, entry)
+ done()
this[UNPEND]()
entry.resume()
})
}
}
+const callSync = fn => {
+ try {
+ return [null, fn()]
+ } catch (er) {
+ return [er, null]
+ }
+}
class UnpackSync extends Unpack {
- constructor (opt) {
- super(opt)
+ [MAKEFS] (er, entry) {
+ return super[MAKEFS](er, entry, /* istanbul ignore next */ () => {})
}
[CHECKFS] (entry) {
- const er = this[MKDIR](path.dirname(entry.absolute), this.dmode)
- if (er)
- return this[ONERROR](er, entry)
- try {
- const st = fs.lstatSync(entry.absolute)
- if (this.keep || this.newer && st.mtime > entry.mtime)
- return this[SKIP](entry)
- else if (this[ISREUSABLE](entry, st))
- return this[MAKEFS](null, entry)
- else {
- try {
- if (st.isDirectory()) {
- if (entry.type === 'Directory') {
- if (entry.mode && (st.mode & 0o7777) !== entry.mode)
- fs.chmodSync(entry.absolute, entry.mode)
- } else
- fs.rmdirSync(entry.absolute)
- } else
- unlinkFileSync(entry.absolute)
- return this[MAKEFS](null, entry)
- } catch (er) {
- return this[ONERROR](er, entry)
- }
+ this[PRUNECACHE](entry)
+
+ if (!this[CHECKED_CWD]) {
+ const er = this[MKDIR](this.cwd, this.dmode)
+ if (er)
+ return this[ONERROR](er, entry)
+ this[CHECKED_CWD] = true
+ }
+
+ // don't bother to make the parent if the current entry is the cwd,
+ // we've already checked it.
+ if (entry.absolute !== this.cwd) {
+ const parent = normPath(path.dirname(entry.absolute))
+ if (parent !== this.cwd) {
+ const mkParent = this[MKDIR](parent, this.dmode)
+ if (mkParent)
+ return this[ONERROR](mkParent, entry)
}
- } catch (er) {
+ }
+
+ const [lstatEr, st] = callSync(() => fs.lstatSync(entry.absolute))
+ if (st && (this.keep || this.newer && st.mtime > entry.mtime))
+ return this[SKIP](entry)
+
+ if (lstatEr || this[ISREUSABLE](entry, st))
return this[MAKEFS](null, entry)
+
+ if (st.isDirectory()) {
+ if (entry.type === 'Directory') {
+ const needChmod = !this.noChmod &&
+ entry.mode &&
+ (st.mode & 0o7777) !== entry.mode
+ const [er] = needChmod ? callSync(() => {
+ fs.chmodSync(entry.absolute, entry.mode)
+ }) : []
+ return this[MAKEFS](er, entry)
+ }
+ // not a dir entry, have to remove it
+ const [er] = callSync(() => fs.rmdirSync(entry.absolute))
+ this[MAKEFS](er, entry)
}
+
+ // not a dir, and not reusable.
+ // don't remove if it's the cwd, since we want that error.
+ const [er] = entry.absolute === this.cwd ? []
+ : callSync(() => unlinkFileSync(entry.absolute))
+ this[MAKEFS](er, entry)
}
- [FILE] (entry) {
+ [FILE] (entry, done) {
const mode = entry.mode & 0o7777 || this.fmode
const oner = er => {
- try { fs.closeSync(fd) } catch (_) {}
- if (er)
- this[ONERROR](er, entry)
+ let closeError
+ try {
+ fs.closeSync(fd)
+ } catch (e) {
+ closeError = e
+ }
+ if (er || closeError)
+ this[ONERROR](er || closeError, entry)
+ done()
}
let stream
@@ -570,11 +790,14 @@ class UnpackSync extends Unpack {
})
}
- [DIRECTORY] (entry) {
+ [DIRECTORY] (entry, done) {
const mode = entry.mode & 0o7777 || this.dmode
const er = this[MKDIR](entry.absolute, mode)
- if (er)
- return this[ONERROR](er, entry)
+ if (er) {
+ this[ONERROR](er, entry)
+ done()
+ return
+ }
if (entry.mtime && !this.noMtime) {
try {
fs.utimesSync(entry.absolute, entry.atime || new Date(), entry.mtime)
@@ -585,12 +808,13 @@ class UnpackSync extends Unpack {
fs.chownSync(entry.absolute, this[UID](entry), this[GID](entry))
} catch (er) {}
}
+ done()
entry.resume()
}
[MKDIR] (dir, mode) {
try {
- return mkdir.sync(dir, {
+ return mkdir.sync(normPath(dir), {
uid: this.uid,
gid: this.gid,
processUid: this.processUid,
@@ -607,9 +831,10 @@ class UnpackSync extends Unpack {
}
}
- [LINK] (entry, linkpath, link) {
+ [LINK] (entry, linkpath, link, done) {
try {
fs[link + 'Sync'](linkpath, entry.absolute)
+ done()
entry.resume()
} catch (er) {
return this[ONERROR](er, entry)
diff --git a/lib/write-entry.js b/lib/write-entry.js
index 63f74948..239e4233 100644
--- a/lib/write-entry.js
+++ b/lib/write-entry.js
@@ -6,8 +6,16 @@ const Header = require('./header.js')
const ReadEntry = require('./read-entry.js')
const fs = require('fs')
const path = require('path')
+const normPath = require('./normalize-windows-path.js')
+const stripSlash = require('./strip-trailing-slashes.js')
+
+const prefixPath = (path, prefix) => {
+ if (!prefix)
+ return path
+ path = normPath(path).replace(/^\.(\/|$)/, '')
+ return stripSlash(prefix) + '/' + path
+}
-const types = require('./types.js')
const maxReadSize = 16 * 1024 * 1024
const PROCESS = Symbol('process')
const FILE = Symbol('file')
@@ -24,8 +32,13 @@ const OPENFILE = Symbol('openfile')
const ONOPENFILE = Symbol('onopenfile')
const CLOSE = Symbol('close')
const MODE = Symbol('mode')
+const AWAITDRAIN = Symbol('awaitDrain')
+const ONDRAIN = Symbol('ondrain')
+const PREFIX = Symbol('prefix')
+const HAD_ERROR = Symbol('hadError')
const warner = require('./warn-mixin.js')
const winchars = require('./winchars.js')
+const stripAbsolutePath = require('./strip-absolute-path.js')
const modeFix = require('./mode-fix.js')
@@ -35,40 +48,52 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
super(opt)
if (typeof p !== 'string')
throw new TypeError('path is required')
- this.path = p
+ this.path = normPath(p)
// suppress atime, ctime, uid, gid, uname, gname
this.portable = !!opt.portable
// until node has builtin pwnam functions, this'll have to do
- this.myuid = process.getuid && process.getuid()
+ this.myuid = process.getuid && process.getuid() || 0
this.myuser = process.env.USER || ''
this.maxReadSize = opt.maxReadSize || maxReadSize
this.linkCache = opt.linkCache || new Map()
this.statCache = opt.statCache || new Map()
this.preservePaths = !!opt.preservePaths
- this.cwd = opt.cwd || process.cwd()
+ this.cwd = normPath(opt.cwd || process.cwd())
this.strict = !!opt.strict
this.noPax = !!opt.noPax
this.noMtime = !!opt.noMtime
this.mtime = opt.mtime || null
+ this.prefix = opt.prefix ? normPath(opt.prefix) : null
+
+ this.fd = null
+ this.blockLen = null
+ this.blockRemain = null
+ this.buf = null
+ this.offset = null
+ this.length = null
+ this.pos = null
+ this.remain = null
if (typeof opt.onwarn === 'function')
this.on('warn', opt.onwarn)
- if (!this.preservePaths && path.win32.isAbsolute(p)) {
- // absolutes on posix are also absolutes on win32
- // so we only need to test this one to get both
- const parsed = path.win32.parse(p)
- this.warn('stripping ' + parsed.root + ' from absolute path', p)
- this.path = p.substr(parsed.root.length)
+ if (!this.preservePaths) {
+ const s = stripAbsolutePath(this.path)
+ if (s[0]) {
+ this.warn('stripping ' + s[0] + ' from absolute path', this.path)
+ this.path = s[1]
+ }
}
this.win32 = !!opt.win32 || process.platform === 'win32'
if (this.win32) {
+ // force the \ to / normalization, since we might not *actually*
+ // be on windows, but want \ to be considered a path separator.
this.path = winchars.decode(this.path.replace(/\\/g, '/'))
p = p.replace(/\\/g, '/')
}
- this.absolute = opt.absolute || path.resolve(this.cwd, p)
+ this.absolute = normPath(opt.absolute || path.resolve(this.cwd, p))
if (this.path === '')
this.path = './'
@@ -79,6 +104,12 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
this[LSTAT]()
}
+ emit (ev, ...data) {
+ if (ev === 'error')
+ this[HAD_ERROR] = true
+ return super.emit(ev, ...data)
+ }
+
[LSTAT] () {
fs.lstat(this.absolute, (er, stat) => {
if (er)
@@ -111,13 +142,19 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
return modeFix(mode, this.type === 'Directory')
}
+ [PREFIX] (path) {
+ return prefixPath(path, this.prefix)
+ }
+
[HEADER] () {
if (this.type === 'Directory' && this.portable)
this.noMtime = true
this.header = new Header({
- path: this.path,
- linkpath: this.linkpath,
+ path: this[PREFIX](this.path),
+ // only apply the prefix to hard links.
+ linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
+ : this.linkpath,
// only the permissions and setuid/setgid/sticky bitflags
// not the higher-order bits that specify file type
mode: this[MODE](this.stat.mode),
@@ -132,14 +169,15 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
ctime: this.portable ? null : this.stat.ctime
})
- if (this.header.encode() && !this.noPax)
- this.write(new Pax({
+ if (this.header.encode() && !this.noPax) {
+ super.write(new Pax({
atime: this.portable ? null : this.header.atime,
ctime: this.portable ? null : this.header.ctime,
gid: this.portable ? null : this.header.gid,
mtime: this.noMtime ? null : this.mtime || this.header.mtime,
- path: this.path,
- linkpath: this.linkpath,
+ path: this[PREFIX](this.path),
+ linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
+ : this.linkpath,
size: this.header.size,
uid: this.portable ? null : this.header.uid,
uname: this.portable ? null : this.header.uname,
@@ -147,7 +185,8 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
ino: this.portable ? null : this.stat.ino,
nlink: this.portable ? null : this.stat.nlink
}).encode())
- this.write(this.header.block)
+ }
+ super.write(this.header.block)
}
[DIRECTORY] () {
@@ -167,14 +206,14 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
}
[ONREADLINK] (linkpath) {
- this.linkpath = linkpath
+ this.linkpath = normPath(linkpath)
this[HEADER]()
this.end()
}
[HARDLINK] (linkpath) {
this.type = 'Link'
- this.linkpath = path.relative(this.cwd, linkpath)
+ this.linkpath = normPath(path.relative(this.cwd, linkpath))
this.stat.size = 0
this[HEADER]()
this.end()
@@ -207,75 +246,111 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
}
[ONOPENFILE] (fd) {
- const blockLen = 512 * Math.ceil(this.stat.size / 512)
- const bufLen = Math.min(blockLen, this.maxReadSize)
- const buf = Buffer.allocUnsafe(bufLen)
- this[READ](fd, buf, 0, buf.length, 0, this.stat.size, blockLen)
+ this.fd = fd
+ if (this[HAD_ERROR])
+ return this[CLOSE]()
+
+ this.blockLen = 512 * Math.ceil(this.stat.size / 512)
+ this.blockRemain = this.blockLen
+ const bufLen = Math.min(this.blockLen, this.maxReadSize)
+ this.buf = Buffer.allocUnsafe(bufLen)
+ this.offset = 0
+ this.pos = 0
+ this.remain = this.stat.size
+ this.length = this.buf.length
+ this[READ]()
}
- [READ] (fd, buf, offset, length, pos, remain, blockRemain) {
+ [READ] () {
+ const { fd, buf, offset, length, pos } = this
fs.read(fd, buf, offset, length, pos, (er, bytesRead) => {
- if (er)
- return this[CLOSE](fd, _ => this.emit('error', er))
- this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead)
+ if (er) {
+ // ignoring the error from close(2) is a bad practice, but at
+ // this point we already have an error, don't need another one
+ return this[CLOSE](() => this.emit('error', er))
+ }
+ this[ONREAD](bytesRead)
})
}
- [CLOSE] (fd, cb) {
- fs.close(fd, cb)
+ [CLOSE] (cb) {
+ fs.close(this.fd, cb)
}
- [ONREAD] (fd, buf, offset, length, pos, remain, blockRemain, bytesRead) {
- if (bytesRead <= 0 && remain > 0) {
+ [ONREAD] (bytesRead) {
+ if (bytesRead <= 0 && this.remain > 0) {
const er = new Error('encountered unexpected EOF')
er.path = this.absolute
er.syscall = 'read'
er.code = 'EOF'
- this[CLOSE](fd)
- return this.emit('error', er)
+ return this[CLOSE](() => this.emit('error', er))
}
- if (bytesRead > remain) {
+ if (bytesRead > this.remain) {
const er = new Error('did not encounter expected EOF')
er.path = this.absolute
er.syscall = 'read'
er.code = 'EOF'
- this[CLOSE](fd)
- return this.emit('error', er)
+ return this[CLOSE](() => this.emit('error', er))
}
// null out the rest of the buffer, if we could fit the block padding
- if (bytesRead === remain) {
- for (let i = bytesRead; i < length && bytesRead < blockRemain; i++) {
- buf[i + offset] = 0
- bytesRead ++
- remain ++
+ // at the end of this loop, we've incremented bytesRead and this.remain
+ // to be incremented up to the blockRemain level, as if we had expected
+ // to get a null-padded file, and read it until the end. then we will
+ // decrement both remain and blockRemain by bytesRead, and know that we
+ // reached the expected EOF, without any null buffer to append.
+ if (bytesRead === this.remain) {
+ for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) {
+ this.buf[i + this.offset] = 0
+ bytesRead++
+ this.remain++
}
}
- const writeBuf = offset === 0 && bytesRead === buf.length ?
- buf : buf.slice(offset, offset + bytesRead)
- remain -= bytesRead
- blockRemain -= bytesRead
- pos += bytesRead
- offset += bytesRead
-
- this.write(writeBuf)
-
- if (!remain) {
- if (blockRemain)
- this.write(Buffer.alloc(blockRemain))
- this.end()
- this[CLOSE](fd, _ => _)
- return
+ const writeBuf = this.offset === 0 && bytesRead === this.buf.length ?
+ this.buf : this.buf.slice(this.offset, this.offset + bytesRead)
+
+ const flushed = this.write(writeBuf)
+ if (!flushed)
+ this[AWAITDRAIN](() => this[ONDRAIN]())
+ else
+ this[ONDRAIN]()
+ }
+
+ [AWAITDRAIN] (cb) {
+ this.once('drain', cb)
+ }
+
+ write (writeBuf) {
+ if (this.blockRemain < writeBuf.length) {
+ const er = new Error('writing more data than expected')
+ er.path = this.absolute
+ return this.emit('error', er)
+ }
+ this.remain -= writeBuf.length
+ this.blockRemain -= writeBuf.length
+ this.pos += writeBuf.length
+ this.offset += writeBuf.length
+ return super.write(writeBuf)
+ }
+
+ [ONDRAIN] () {
+ if (!this.remain) {
+ if (this.blockRemain)
+ super.write(Buffer.alloc(this.blockRemain))
+ return this[CLOSE](/* istanbul ignore next - legacy */
+ er => er ? this.emit('error', er) : this.end())
}
- if (offset >= length) {
- buf = Buffer.allocUnsafe(length)
- offset = 0
+ if (this.offset >= this.length) {
+ // if we only have a smaller bit left to read, alloc a smaller buffer
+ // otherwise, keep it the same length it was before.
+ this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length))
+ this.offset = 0
}
- length = buf.length - offset
- this[READ](fd, buf, offset, length, pos, remain, blockRemain)
+ this.length = this.buf.length - this.offset
+ this[READ]()
}
})
@@ -296,20 +371,31 @@ class WriteEntrySync extends WriteEntry {
this[ONOPENFILE](fs.openSync(this.absolute, 'r'))
}
- [READ] (fd, buf, offset, length, pos, remain, blockRemain) {
+ [READ] () {
let threw = true
try {
+ const { fd, buf, offset, length, pos } = this
const bytesRead = fs.readSync(fd, buf, offset, length, pos)
- this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead)
+ this[ONREAD](bytesRead)
threw = false
} finally {
- if (threw)
- try { this[CLOSE](fd) } catch (er) {}
+ // ignoring the error from close(2) is a bad practice, but at
+ // this point we already have an error, don't need another one
+ if (threw) {
+ try {
+ this[CLOSE](() => {})
+ } catch (er) {}
+ }
}
}
- [CLOSE] (fd) {
- fs.closeSync(fd)
+ [AWAITDRAIN] (cb) {
+ cb()
+ }
+
+ [CLOSE] (cb) {
+ fs.closeSync(this.fd)
+ cb()
}
}
@@ -328,7 +414,9 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass {
if (this.type === 'Directory' && this.portable)
this.noMtime = true
- this.path = readEntry.path
+ this.prefix = opt.prefix || null
+
+ this.path = normPath(readEntry.path)
this.mode = this[MODE](readEntry.mode)
this.uid = this.portable ? null : readEntry.uid
this.gid = this.portable ? null : readEntry.gid
@@ -338,26 +426,29 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass {
this.mtime = this.noMtime ? null : opt.mtime || readEntry.mtime
this.atime = this.portable ? null : readEntry.atime
this.ctime = this.portable ? null : readEntry.ctime
- this.linkpath = readEntry.linkpath
+ this.linkpath = normPath(readEntry.linkpath)
if (typeof opt.onwarn === 'function')
this.on('warn', opt.onwarn)
- if (path.isAbsolute(this.path) && !this.preservePaths) {
- const parsed = path.parse(this.path)
- this.warn(
- 'stripping ' + parsed.root + ' from absolute path',
- this.path
- )
- this.path = this.path.substr(parsed.root.length)
+ if (!this.preservePaths) {
+ const s = stripAbsolutePath(this.path)
+ if (s[0]) {
+ this.warn(
+ 'stripping ' + s[0] + ' from absolute path',
+ this.path
+ )
+ this.path = s[1]
+ }
}
this.remain = readEntry.size
this.blockRemain = readEntry.startBlockSize
this.header = new Header({
- path: this.path,
- linkpath: this.linkpath,
+ path: this[PREFIX](this.path),
+ linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
+ : this.linkpath,
// only the permissions and setuid/setgid/sticky bitflags
// not the higher-order bits that specify file type
mode: this.mode,
@@ -377,8 +468,9 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass {
ctime: this.portable ? null : this.ctime,
gid: this.portable ? null : this.gid,
mtime: this.noMtime ? null : this.mtime,
- path: this.path,
- linkpath: this.linkpath,
+ path: this[PREFIX](this.path),
+ linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
+ : this.linkpath,
size: this.size,
uid: this.portable ? null : this.uid,
uname: this.portable ? null : this.uname,
@@ -391,6 +483,10 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass {
readEntry.pipe(this)
}
+ [PREFIX] (path) {
+ return prefixPath(path, this.prefix)
+ }
+
[MODE] (mode) {
return modeFix(mode, this.type === 'Directory')
}
@@ -405,7 +501,7 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass {
end () {
if (this.blockRemain)
- this.write(Buffer.alloc(this.blockRemain))
+ super.write(Buffer.alloc(this.blockRemain))
return super.end()
}
})
diff --git a/map.js b/map.js
new file mode 100644
index 00000000..adeceef6
--- /dev/null
+++ b/map.js
@@ -0,0 +1,9 @@
+const {basename} = require('path')
+
+const map = test =>
+ test === 'index.js' || test === 'map.js' ? test
+ : test === 'unpack.js' ? ['lib/unpack.js', 'lib/mkdir.js']
+ : test === 'load-all.js' ? []
+ : `lib/${test}`
+
+module.exports = test => map(basename(test))
diff --git a/package-lock.json b/package-lock.json
index 2c50d03d..6268f47c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,25 +1,192 @@
{
"name": "tar",
- "version": "4.4.8",
+ "version": "4.4.19",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.14.5"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz",
+ "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.15.0",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz",
+ "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz",
+ "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.15.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.2.tgz",
+ "integrity": "sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg==",
+ "dev": true
+ },
+ "@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz",
+ "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.15.0",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.15.0",
+ "@babel/types": "^7.15.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/types": {
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz",
+ "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.14.9",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
"ajv": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
- "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
- "co": "^4.6.0",
- "fast-deep-equal": "^1.0.0",
+ "fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.3.0"
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
}
},
"ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "append-transform": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz",
+ "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==",
+ "dev": true,
+ "requires": {
+ "default-require-extensions": "^2.0.0"
+ }
+ },
+ "archy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+ "dev": true
+ },
+ "arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true
},
"argparse": {
@@ -32,10 +199,13 @@
}
},
"asn1": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
- "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
- "dev": true
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
},
"assert-plus": {
"version": "1.0.0",
@@ -43,6 +213,15 @@
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"dev": true
},
+ "async-hook-domain": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-1.1.3.tgz",
+ "integrity": "sha512-ZovMxSbADV3+biB7oR1GL5lGyptI24alp0LWHlmz1OFc5oL47pz3EiIF6nXOkDW7yLqih4NtsiYduzdDW0i+Wg==",
+ "dev": true,
+ "requires": {
+ "source-map-support": "^0.5.11"
+ }
+ },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -56,31 +235,36 @@
"dev": true
},
"aws4": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
- "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
"dev": true
},
"balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"bcrypt-pbkdf": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
- "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"dev": true,
- "optional": true,
"requires": {
"tweetnacl": "^0.14.3"
}
},
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
+ },
"bind-obj-methods": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz",
- "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.2.tgz",
+ "integrity": "sha512-bUkRdEOppT1Xg/jG0+bp0JSjUD9U0r7skxb/42WeBUjfBpW6COQTIgQmKX5J2Z3aMXcORKgN2N+d7IQwTK3pag==",
"dev": true
},
"bl": {
@@ -93,22 +277,31 @@
"safe-buffer": "^5.1.1"
}
},
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
- "dev": true
- },
"brace-expansion": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+ "dev": true
+ },
"buffer-alloc": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
@@ -132,9 +325,46 @@
"dev": true
},
"buffer-from": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
- "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "caching-transform": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz",
+ "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==",
+ "dev": true,
+ "requires": {
+ "hasha": "^3.0.0",
+ "make-dir": "^2.0.0",
+ "package-hash": "^3.0.0",
+ "write-file-atomic": "^2.4.2"
+ },
+ "dependencies": {
+ "write-file-atomic": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
+ "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.2"
+ }
+ }
+ }
+ },
+ "caller": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/caller/-/caller-1.0.1.tgz",
+ "integrity": "sha1-uFGGD3Dhlds9J3OVqhp+I+ow7PU=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"caseless": {
@@ -143,27 +373,74 @@
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
"dev": true
},
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
"chmodr": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.2.0.tgz",
"integrity": "sha512-Y5uI7Iq/Az6HgJEL6pdw7THVd7jbVOTPwsmcPOBjQL8e3N+pz872kzK5QxYGEy21iRys+iHWV0UZQXDFJo1hyA==",
"dev": true
},
+ "chokidar": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ }
+ },
"chownr": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
- "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g=="
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+ },
+ "cliui": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0",
+ "wrap-ansi": "^2.0.0"
+ }
},
- "clean-yaml-object": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz",
- "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=",
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
- "co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"color-support": {
@@ -173,20 +450,43 @@
"dev": true
},
"combined-stream": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
- "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
},
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
+ "convert-source-map": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
+ "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
+ }
+ },
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -194,24 +494,29 @@
"dev": true
},
"coveralls": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz",
- "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz",
+ "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==",
"dev": true,
"requires": {
- "js-yaml": "^3.6.1",
- "lcov-parse": "^0.0.10",
- "log-driver": "^1.2.5",
- "minimist": "^1.2.0",
- "request": "^2.79.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
+ "js-yaml": "^3.13.1",
+ "lcov-parse": "^1.0.0",
+ "log-driver": "^1.2.7",
+ "minimist": "^1.2.5",
+ "request": "^2.88.2"
+ }
+ },
+ "cp-file": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz",
+ "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^2.0.0",
+ "nested-error-stacks": "^2.0.0",
+ "pify": "^4.0.1",
+ "safe-buffer": "^5.0.1"
}
},
"cross-spawn": {
@@ -222,6 +527,17 @@
"requires": {
"lru-cache": "^4.0.1",
"which": "^1.2.9"
+ },
+ "dependencies": {
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
}
},
"dashdash": {
@@ -234,12 +550,27 @@
}
},
"debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "default-require-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz",
+ "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=",
"dev": true,
"requires": {
- "ms": "2.0.0"
+ "strip-bom": "^3.0.0"
}
},
"delayed-stream": {
@@ -249,40 +580,73 @@
"dev": true
},
"diff": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
- "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "diff-frag": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/diff-frag/-/diff-frag-1.1.1.tgz",
+ "integrity": "sha512-y0YLhUGviNXaypPimkzmOCaZf8ruocRb+dpOL/lfoicxBua2gkExddlbWxIP56Z5BpSg4gL5sAWhBN2iQm4HVQ==",
"dev": true
},
"ecc-jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
- "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"dev": true,
- "optional": true,
"requires": {
- "jsbn": "~0.1.0"
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
}
},
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
"end-of-stream": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
- "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true
+ },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
+ "esm": {
+ "version": "3.2.25",
+ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+ "dev": true
+ },
"esprima": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
},
"events-to-array": {
@@ -292,9 +656,9 @@
"dev": true
},
"extend": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
- "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
"extsprintf": {
@@ -304,17 +668,69 @@
"dev": true
},
"fast-deep-equal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
- "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-cache-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+ "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^2.0.0",
+ "pkg-dir": "^3.0.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "findit": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
- "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz",
+ "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=",
+ "dev": true
+ },
+ "flow-parser": {
+ "version": "0.157.0",
+ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.157.0.tgz",
+ "integrity": "sha512-p0vdtrM8oAMlscIXpX0e/eGWll5NPteVChNtlQncbIbivH+BdiwXHN5QO6myAfmebd027r9RiQKdUPsFAiEVgQ==",
"dev": true
},
+ "flow-remove-types": {
+ "version": "2.157.0",
+ "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.157.0.tgz",
+ "integrity": "sha512-nqK4QAi3cMC4xDGeOJZgj2EXtb81p8s4r2WgHP3vMnGxmBW2qKYfsPm+dMX0GTHezNF39/O00AteldLQeSQLQw==",
+ "dev": true,
+ "requires": {
+ "flow-parser": "^0.157.0",
+ "pirates": "^3.0.2",
+ "vlq": "^0.2.1"
+ }
+ },
"foreground-child": {
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz",
@@ -332,13 +748,13 @@
"dev": true
},
"form-data": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
- "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
- "combined-stream": "1.0.6",
+ "combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
@@ -355,11 +771,11 @@
"dev": true
},
"fs-minipass": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
- "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+ "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
"requires": {
- "minipass": "^2.2.1"
+ "minipass": "^2.6.0"
}
},
"fs.realpath": {
@@ -368,10 +784,29 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
"function-loop": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.1.tgz",
- "integrity": "sha1-gHa7MF6OajzO7ikgdl8zDRkPNAw=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.2.tgz",
+ "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"getpass": {
@@ -384,9 +819,9 @@
}
},
"glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -397,10 +832,25 @@
"path-is-absolute": "^1.0.0"
}
},
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
"graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"har-schema": {
@@ -410,30 +860,66 @@
"dev": true
},
"har-validator": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
- "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"dev": true,
"requires": {
- "ajv": "^5.1.0",
+ "ajv": "^6.12.3",
"har-schema": "^2.0.0"
}
},
- "http-signature": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
- "assert-plus": "^1.0.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
+ "function-bind": "^1.1.1"
}
},
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "hasha": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz",
+ "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=",
+ "dev": true,
+ "requires": {
+ "is-stream": "^1.0.1"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"inflight": {
@@ -452,6 +938,63 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz",
+ "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@@ -476,10 +1019,144 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
"dev": true
},
+ "istanbul-lib-coverage": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
+ "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
+ "dev": true
+ },
+ "istanbul-lib-hook": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz",
+ "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==",
+ "dev": true,
+ "requires": {
+ "append-transform": "^1.0.0"
+ }
+ },
+ "istanbul-lib-instrument": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz",
+ "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==",
+ "dev": true,
+ "requires": {
+ "@babel/generator": "^7.4.0",
+ "@babel/parser": "^7.4.3",
+ "@babel/template": "^7.4.0",
+ "@babel/traverse": "^7.4.3",
+ "@babel/types": "^7.4.0",
+ "istanbul-lib-coverage": "^2.0.5",
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-lib-processinfo": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-1.0.0.tgz",
+ "integrity": "sha512-FY0cPmWa4WoQNlvB8VOcafiRoB5nB+l2Pz2xGuXHRSy1KM8QFOYfz/rN+bGMCAeejrY3mrpF5oJHcN0s/garCg==",
+ "dev": true,
+ "requires": {
+ "archy": "^1.0.0",
+ "cross-spawn": "^6.0.5",
+ "istanbul-lib-coverage": "^2.0.3",
+ "rimraf": "^2.6.3",
+ "uuid": "^3.3.2"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
+ "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
+ "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "rimraf": "^2.6.3",
+ "source-map": "^0.6.1"
+ }
+ },
+ "istanbul-reports": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz",
+ "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0"
+ }
+ },
+ "jackspeak": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz",
+ "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^4.1.0"
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
"js-yaml": {
- "version": "3.11.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
- "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
@@ -490,8 +1167,19 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
- "dev": true,
- "optional": true
+ "dev": true
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
},
"json-schema": {
"version": "0.2.3",
@@ -500,9 +1188,9 @@
"dev": true
},
"json-schema-traverse": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
- "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stringify-safe": {
@@ -524,9 +1212,45 @@
}
},
"lcov-parse": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
- "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz",
+ "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash.flattendeep": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
"dev": true
},
"log-driver": {
@@ -535,10 +1259,19 @@
"integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==",
"dev": true
},
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
"lru-cache": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
- "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"dev": true,
"requires": {
"pseudomap": "^1.0.2",
@@ -553,19 +1286,44 @@
}
}
},
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "merge-source-map": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
+ "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.6.1"
+ }
+ },
"mime-db": {
- "version": "1.33.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz",
+ "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==",
"dev": true
},
"mime-types": {
- "version": "2.1.18",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "version": "2.1.32",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz",
+ "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==",
"dev": true,
"requires": {
- "mime-db": "~1.33.0"
+ "mime-db": "1.49.0"
}
},
"minimatch": {
@@ -578,39 +1336,39 @@
}
},
"minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"minipass": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.4.tgz",
- "integrity": "sha512-mlouk1OHlaUE8Odt1drMtG1bAJA4ZA6B/ehysgV0LUIrDHdKgo1KorZq3pK0b/7Z7LJIQ12MNM6aC+Tn6lUZ5w==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
}
},
"minizlib": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.1.tgz",
- "integrity": "sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+ "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
"requires": {
- "minipass": "^2.2.1"
+ "minipass": "^2.9.0"
}
},
"mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"requires": {
- "minimist": "0.0.8"
+ "minimist": "^1.2.5"
}
},
"ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"mutate-fs": {
@@ -619,2925 +1377,1878 @@
"integrity": "sha512-WI5pPPUNiWqaK2XdK94AVpxIc8GmZEXYlLfFbWuc4gUtBGHTK92jdPqFdx/lilxgb5Ep7tQ15NqCcJEOeq6wdA==",
"dev": true
},
+ "nested-error-stacks": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz",
+ "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node-modules-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
+ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
+ "dev": true
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
"nyc": {
- "version": "11.8.0",
- "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.8.0.tgz",
- "integrity": "sha512-PUFq1PSsx5OinSk5g5aaZygcDdI3QQT5XUlbR9QRMihtMS6w0Gm8xj4BxmKeeAlpQXC5M2DIhH16Y+KejceivQ==",
+ "version": "14.1.1",
+ "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz",
+ "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==",
"dev": true,
"requires": {
"archy": "^1.0.0",
- "arrify": "^1.0.1",
- "caching-transform": "^1.0.0",
- "convert-source-map": "^1.5.1",
- "debug-log": "^1.0.1",
- "default-require-extensions": "^1.0.0",
- "find-cache-dir": "^0.1.1",
- "find-up": "^2.1.0",
- "foreground-child": "^1.5.3",
- "glob": "^7.0.6",
- "istanbul-lib-coverage": "^1.1.2",
- "istanbul-lib-hook": "^1.1.0",
- "istanbul-lib-instrument": "^1.10.0",
- "istanbul-lib-report": "^1.1.3",
- "istanbul-lib-source-maps": "^1.2.3",
- "istanbul-reports": "^1.4.0",
- "md5-hex": "^1.2.0",
+ "caching-transform": "^3.0.2",
+ "convert-source-map": "^1.6.0",
+ "cp-file": "^6.2.0",
+ "find-cache-dir": "^2.1.0",
+ "find-up": "^3.0.0",
+ "foreground-child": "^1.5.6",
+ "glob": "^7.1.3",
+ "istanbul-lib-coverage": "^2.0.5",
+ "istanbul-lib-hook": "^2.0.7",
+ "istanbul-lib-instrument": "^3.3.0",
+ "istanbul-lib-report": "^2.0.8",
+ "istanbul-lib-source-maps": "^3.0.6",
+ "istanbul-reports": "^2.2.4",
+ "js-yaml": "^3.13.1",
+ "make-dir": "^2.1.0",
"merge-source-map": "^1.1.0",
- "micromatch": "^3.1.10",
- "mkdirp": "^0.5.0",
- "resolve-from": "^2.0.0",
- "rimraf": "^2.6.2",
- "signal-exit": "^3.0.1",
+ "resolve-from": "^4.0.0",
+ "rimraf": "^2.6.3",
+ "signal-exit": "^3.0.2",
"spawn-wrap": "^1.4.2",
- "test-exclude": "^4.2.0",
- "yargs": "11.1.0",
- "yargs-parser": "^8.0.0"
- },
- "dependencies": {
- "align-text": {
- "version": "0.1.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2",
- "longest": "^1.0.1",
- "repeat-string": "^1.5.2"
- }
- },
- "amdefine": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "bundled": true,
- "dev": true
- },
- "ansi-styles": {
- "version": "2.2.1",
- "bundled": true,
- "dev": true
- },
- "append-transform": {
- "version": "0.4.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "default-require-extensions": "^1.0.0"
- }
- },
- "archy": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "arr-diff": {
- "version": "4.0.0",
- "bundled": true,
- "dev": true
- },
- "arr-flatten": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true
- },
- "arr-union": {
- "version": "3.1.0",
- "bundled": true,
- "dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "bundled": true,
- "dev": true
- },
- "arrify": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true
- },
- "assign-symbols": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "async": {
- "version": "1.5.2",
- "bundled": true,
- "dev": true
- },
- "atob": {
- "version": "2.1.1",
- "bundled": true,
- "dev": true
- },
- "babel-code-frame": {
- "version": "6.26.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "chalk": "^1.1.3",
- "esutils": "^2.0.2",
- "js-tokens": "^3.0.2"
- }
- },
- "babel-generator": {
- "version": "6.26.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "babel-messages": "^6.23.0",
- "babel-runtime": "^6.26.0",
- "babel-types": "^6.26.0",
- "detect-indent": "^4.0.0",
- "jsesc": "^1.3.0",
- "lodash": "^4.17.4",
- "source-map": "^0.5.7",
- "trim-right": "^1.0.1"
- }
- },
- "babel-messages": {
- "version": "6.23.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "babel-runtime": "^6.22.0"
- }
- },
- "babel-runtime": {
- "version": "6.26.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "core-js": "^2.4.0",
- "regenerator-runtime": "^0.11.0"
- }
- },
- "babel-template": {
- "version": "6.26.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "babel-runtime": "^6.26.0",
- "babel-traverse": "^6.26.0",
- "babel-types": "^6.26.0",
- "babylon": "^6.18.0",
- "lodash": "^4.17.4"
- }
- },
- "babel-traverse": {
- "version": "6.26.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "babel-code-frame": "^6.26.0",
- "babel-messages": "^6.23.0",
- "babel-runtime": "^6.26.0",
- "babel-types": "^6.26.0",
- "babylon": "^6.18.0",
- "debug": "^2.6.8",
- "globals": "^9.18.0",
- "invariant": "^2.2.2",
- "lodash": "^4.17.4"
- }
- },
- "babel-types": {
- "version": "6.26.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "babel-runtime": "^6.26.0",
- "esutils": "^2.0.2",
- "lodash": "^4.17.4",
- "to-fast-properties": "^1.0.3"
- }
- },
- "babylon": {
- "version": "6.18.0",
- "bundled": true,
- "dev": true
- },
- "balanced-match": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "base": {
- "version": "0.11.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "cache-base": "^1.0.1",
- "class-utils": "^0.3.5",
- "component-emitter": "^1.2.1",
- "define-property": "^1.0.0",
- "isobject": "^3.0.1",
- "mixin-deep": "^1.2.0",
- "pascalcase": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- },
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "bundled": true,
- "dev": true
- }
- }
- },
- "brace-expansion": {
- "version": "1.1.11",
- "bundled": true,
- "dev": true,
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "braces": {
- "version": "2.3.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "builtin-modules": {
- "version": "1.1.1",
- "bundled": true,
- "dev": true
- },
- "cache-base": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "collection-visit": "^1.0.0",
- "component-emitter": "^1.2.1",
- "get-value": "^2.0.6",
- "has-value": "^1.0.0",
- "isobject": "^3.0.1",
- "set-value": "^2.0.0",
- "to-object-path": "^0.3.0",
- "union-value": "^1.0.0",
- "unset-value": "^1.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- }
- }
- },
- "caching-transform": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "md5-hex": "^1.2.0",
- "mkdirp": "^0.5.1",
- "write-file-atomic": "^1.1.4"
- }
- },
- "camelcase": {
- "version": "1.2.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "center-align": {
- "version": "0.1.3",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "align-text": "^0.1.3",
- "lazy-cache": "^1.0.3"
- }
- },
- "chalk": {
- "version": "1.1.3",
- "bundled": true,
- "dev": true,
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
- "class-utils": {
- "version": "0.3.6",
- "bundled": true,
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "define-property": "^0.2.5",
- "isobject": "^3.0.0",
- "static-extend": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- }
- }
- },
- "cliui": {
- "version": "2.1.0",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "center-align": "^0.1.1",
- "right-align": "^0.1.1",
- "wordwrap": "0.0.2"
- },
- "dependencies": {
- "wordwrap": {
- "version": "0.0.2",
- "bundled": true,
- "dev": true,
- "optional": true
- }
- }
- },
- "code-point-at": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true
- },
- "collection-visit": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "map-visit": "^1.0.0",
- "object-visit": "^1.0.0"
- }
- },
- "commondir": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true
- },
- "component-emitter": {
- "version": "1.2.1",
- "bundled": true,
- "dev": true
- },
- "concat-map": {
- "version": "0.0.1",
- "bundled": true,
- "dev": true
- },
- "convert-source-map": {
- "version": "1.5.1",
- "bundled": true,
- "dev": true
- },
- "copy-descriptor": {
- "version": "0.1.1",
- "bundled": true,
- "dev": true
- },
- "core-js": {
- "version": "2.5.6",
- "bundled": true,
- "dev": true
- },
- "cross-spawn": {
- "version": "4.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "lru-cache": "^4.0.1",
- "which": "^1.2.9"
- }
- },
- "debug": {
- "version": "2.6.9",
- "bundled": true,
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "debug-log": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true
- },
- "decamelize": {
- "version": "1.2.0",
- "bundled": true,
- "dev": true
- },
- "decode-uri-component": {
- "version": "0.2.0",
- "bundled": true,
- "dev": true
- },
- "default-require-extensions": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "strip-bom": "^2.0.0"
- }
- },
- "define-property": {
- "version": "2.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.2",
- "isobject": "^3.0.1"
- },
- "dependencies": {
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- },
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "bundled": true,
- "dev": true
- }
- }
- },
- "detect-indent": {
- "version": "4.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "repeating": "^2.0.0"
- }
- },
- "error-ex": {
- "version": "1.3.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-arrayish": "^0.2.1"
- }
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "bundled": true,
- "dev": true
- },
- "esutils": {
- "version": "2.0.2",
- "bundled": true,
- "dev": true
- },
- "execa": {
- "version": "0.7.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "cross-spawn": "^5.0.1",
- "get-stream": "^3.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- },
- "dependencies": {
- "cross-spawn": {
- "version": "5.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "lru-cache": "^4.0.1",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- }
- }
- },
- "expand-brackets": {
- "version": "2.1.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "extend-shallow": {
- "version": "3.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "assign-symbols": "^1.0.0",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- },
- "kind-of": {
- "version": "6.0.2",
- "bundled": true,
- "dev": true
- }
- }
- },
- "fill-range": {
- "version": "4.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "find-cache-dir": {
- "version": "0.1.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "commondir": "^1.0.1",
- "mkdirp": "^0.5.1",
- "pkg-dir": "^1.0.0"
- }
- },
- "find-up": {
- "version": "2.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "locate-path": "^2.0.0"
- }
- },
- "for-in": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true
- },
- "foreground-child": {
- "version": "1.5.6",
- "bundled": true,
- "dev": true,
- "requires": {
- "cross-spawn": "^4",
- "signal-exit": "^3.0.0"
- }
- },
- "fragment-cache": {
- "version": "0.2.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "map-cache": "^0.2.2"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "get-caller-file": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true
- },
- "get-stream": {
- "version": "3.0.0",
- "bundled": true,
- "dev": true
- },
- "get-value": {
- "version": "2.0.6",
- "bundled": true,
- "dev": true
- },
- "glob": {
- "version": "7.1.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "globals": {
- "version": "9.18.0",
- "bundled": true,
- "dev": true
- },
- "graceful-fs": {
- "version": "4.1.11",
- "bundled": true,
- "dev": true
- },
- "handlebars": {
- "version": "4.0.11",
- "bundled": true,
- "dev": true,
- "requires": {
- "async": "^1.4.0",
- "optimist": "^0.6.1",
- "source-map": "^0.4.4",
- "uglify-js": "^2.6"
- },
- "dependencies": {
- "source-map": {
- "version": "0.4.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
- }
- }
- },
- "has-ansi": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "has-flag": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "has-value": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "get-value": "^2.0.6",
- "has-values": "^1.0.0",
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- }
- }
- },
- "has-values": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-number": "^3.0.0",
- "kind-of": "^4.0.0"
- },
- "dependencies": {
- "is-number": {
- "version": "3.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "kind-of": {
- "version": "4.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "hosted-git-info": {
- "version": "2.6.0",
- "bundled": true,
- "dev": true
- },
- "imurmurhash": {
- "version": "0.1.4",
- "bundled": true,
- "dev": true
- },
- "inflight": {
- "version": "1.0.6",
- "bundled": true,
- "dev": true,
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "bundled": true,
- "dev": true
- },
- "invariant": {
- "version": "2.2.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "loose-envify": "^1.0.0"
- }
- },
- "invert-kv": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- }
- },
- "is-arrayish": {
- "version": "0.2.1",
- "bundled": true,
- "dev": true
- },
- "is-buffer": {
- "version": "1.1.6",
- "bundled": true,
- "dev": true
- },
- "is-builtin-module": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "builtin-modules": "^1.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- }
- },
- "is-descriptor": {
- "version": "0.1.6",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "bundled": true,
- "dev": true
- }
- }
- },
- "is-extendable": {
- "version": "0.1.1",
- "bundled": true,
- "dev": true
- },
- "is-finite": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true
- },
- "is-number": {
+ "test-exclude": "^5.2.3",
+ "uuid": "^3.3.2",
+ "yargs": "^13.2.2",
+ "yargs-parser": "^13.0.0"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "opener": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+ "dev": true
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "own-or": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz",
+ "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=",
+ "dev": true
+ },
+ "own-or-env": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz",
+ "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==",
+ "dev": true,
+ "requires": {
+ "own-or": "^1.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "package-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz",
+ "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.15",
+ "hasha": "^3.0.0",
+ "lodash.flattendeep": "^4.4.0",
+ "release-zalgo": "^1.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
"version": "3.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- }
- },
- "is-odd": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-number": "^4.0.0"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "bundled": true,
- "dev": true
- }
- }
- },
- "is-plain-object": {
- "version": "2.0.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "isobject": "^3.0.1"
- },
- "dependencies": {
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- }
- }
- },
- "is-stream": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true
- },
- "is-utf8": {
- "version": "0.2.1",
- "bundled": true,
- "dev": true
- },
- "is-windows": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true
- },
- "isarray": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "isexe": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true
- },
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- },
- "istanbul-lib-coverage": {
- "version": "1.2.0",
- "bundled": true,
- "dev": true
- },
- "istanbul-lib-hook": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "append-transform": "^0.4.0"
- }
- },
- "istanbul-lib-instrument": {
- "version": "1.10.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "babel-generator": "^6.18.0",
- "babel-template": "^6.16.0",
- "babel-traverse": "^6.18.0",
- "babel-types": "^6.18.0",
- "babylon": "^6.18.0",
- "istanbul-lib-coverage": "^1.2.0",
- "semver": "^5.3.0"
- }
- },
- "istanbul-lib-report": {
- "version": "1.1.3",
- "bundled": true,
- "dev": true,
- "requires": {
- "istanbul-lib-coverage": "^1.1.2",
- "mkdirp": "^0.5.1",
- "path-parse": "^1.0.5",
- "supports-color": "^3.1.2"
- },
- "dependencies": {
- "supports-color": {
- "version": "3.2.3",
- "bundled": true,
- "dev": true,
- "requires": {
- "has-flag": "^1.0.0"
- }
- }
- }
- },
- "istanbul-lib-source-maps": {
- "version": "1.2.3",
- "bundled": true,
- "dev": true,
- "requires": {
- "debug": "^3.1.0",
- "istanbul-lib-coverage": "^1.1.2",
- "mkdirp": "^0.5.1",
- "rimraf": "^2.6.1",
- "source-map": "^0.5.3"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "istanbul-reports": {
- "version": "1.4.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "handlebars": "^4.0.3"
- }
- },
- "js-tokens": {
- "version": "3.0.2",
- "bundled": true,
- "dev": true
- },
- "jsesc": {
- "version": "1.3.0",
- "bundled": true,
- "dev": true
- },
- "kind-of": {
- "version": "3.2.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- },
- "lazy-cache": {
- "version": "1.0.4",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "lcid": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "invert-kv": "^1.0.0"
- }
- },
- "load-json-file": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^2.2.0",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0",
- "strip-bom": "^2.0.0"
- }
- },
- "locate-path": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
- },
- "dependencies": {
- "path-exists": {
- "version": "3.0.0",
- "bundled": true,
- "dev": true
- }
- }
- },
- "lodash": {
- "version": "4.17.10",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
"dev": true
- },
- "longest": {
- "version": "1.0.1",
- "bundled": true,
+ }
+ }
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "pirates": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz",
+ "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==",
+ "dev": true,
+ "requires": {
+ "node-modules-regexp": "^1.0.0"
+ }
+ },
+ "pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0"
+ }
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+ "dev": true
+ },
+ "prop-types": {
+ "version": "15.7.2",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+ "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.8.1"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+ "dev": true
+ },
+ "pump": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
+ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+ "dev": true
+ },
+ "react": {
+ "version": "16.14.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
+ "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1",
+ "prop-types": "^15.6.2"
+ }
+ },
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
+ "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0",
+ "read-pkg": "^3.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
- },
- "loose-envify": {
+ }
+ }
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "release-zalgo": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
+ "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
+ "dev": true,
+ "requires": {
+ "es6-error": "^4.0.1"
+ }
+ },
+ "request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-inject": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/require-inject/-/require-inject-1.4.4.tgz",
+ "integrity": "sha512-5Y5ctRN84+I4iOZO61gm+48tgP/6Hcd3VZydkaEM3MCuOvnHRsTJYQBOc01faI/Z9at5nsCAJVHhlfPA6Pc0Og==",
+ "dev": true,
+ "requires": {
+ "caller": "^1.0.1"
+ }
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "spawn-wrap": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz",
+ "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==",
+ "dev": true,
+ "requires": {
+ "foreground-child": "^1.5.6",
+ "mkdirp": "^0.5.0",
+ "os-homedir": "^1.0.1",
+ "rimraf": "^2.6.2",
+ "signal-exit": "^3.0.2",
+ "which": "^1.3.0"
+ },
+ "dependencies": {
+ "which": {
"version": "1.3.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "js-tokens": "^3.0.0"
- }
- },
- "lru-cache": {
- "version": "4.1.3",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
+ "isexe": "^2.0.0"
}
- },
- "map-cache": {
- "version": "0.2.2",
- "bundled": true,
+ }
+ }
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
+ "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "stack-utils": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz",
+ "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"dev": true
- },
- "map-visit": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "object-visit": "^1.0.0"
- }
- },
- "md5-hex": {
- "version": "1.3.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "md5-o-matic": "^0.1.1"
- }
- },
- "md5-o-matic": {
- "version": "0.1.1",
- "bundled": true,
+ }
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
- },
- "mem": {
- "version": "1.1.0",
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "tap": {
+ "version": "14.11.0",
+ "resolved": "https://registry.npmjs.org/tap/-/tap-14.11.0.tgz",
+ "integrity": "sha512-z8qnNFVyIjLh/bNoTLFRkEk09XZUDAZbCkz/BjvHHly3ao5H+y60gPnedALfheEjA6dA4tpp/mrKq2NWlMuq0A==",
+ "dev": true,
+ "requires": {
+ "@types/react": "^16.9.16",
+ "async-hook-domain": "^1.1.3",
+ "bind-obj-methods": "^2.0.0",
+ "browser-process-hrtime": "^1.0.0",
+ "chokidar": "^3.3.0",
+ "color-support": "^1.1.0",
+ "coveralls": "^3.0.11",
+ "diff": "^4.0.1",
+ "esm": "^3.2.25",
+ "findit": "^2.0.0",
+ "flow-remove-types": "^2.112.0",
+ "foreground-child": "^1.3.3",
+ "fs-exists-cached": "^1.0.0",
+ "function-loop": "^1.0.2",
+ "glob": "^7.1.6",
+ "import-jsx": "^3.1.0",
+ "ink": "^2.6.0",
+ "isexe": "^2.0.0",
+ "istanbul-lib-processinfo": "^1.0.0",
+ "jackspeak": "^1.4.0",
+ "minipass": "^3.1.1",
+ "mkdirp": "^0.5.4",
+ "nyc": "^14.1.1",
+ "opener": "^1.5.1",
+ "own-or": "^1.0.0",
+ "own-or-env": "^1.0.1",
+ "react": "^16.12.0",
+ "rimraf": "^2.7.1",
+ "signal-exit": "^3.0.0",
+ "source-map-support": "^0.5.16",
+ "stack-utils": "^1.0.3",
+ "tap-mocha-reporter": "^5.0.0",
+ "tap-parser": "^10.0.1",
+ "tap-yaml": "^1.0.0",
+ "tcompare": "^3.0.0",
+ "treport": "^1.0.2",
+ "trivial-deferred": "^1.0.1",
+ "ts-node": "^8.5.2",
+ "typescript": "^3.7.2",
+ "which": "^2.0.2",
+ "write-file-atomic": "^3.0.1",
+ "yaml": "^1.7.2",
+ "yapool": "^1.0.0"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "mimic-fn": "^1.0.0"
+ "@babel/highlight": "^7.10.4"
}
},
- "merge-source-map": {
- "version": "1.1.0",
+ "@babel/core": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "source-map": "^0.6.1"
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.10.5",
+ "@babel/helper-module-transforms": "^7.10.5",
+ "@babel/helpers": "^7.10.4",
+ "@babel/parser": "^7.10.5",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.5",
+ "@babel/types": "^7.10.5",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.19",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
},
"dependencies": {
"source-map": {
- "version": "0.6.1",
+ "version": "0.5.7",
"bundled": true,
"dev": true
}
}
},
- "micromatch": {
- "version": "3.1.10",
+ "@babel/generator": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
+ "@babel/types": "^7.10.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
},
"dependencies": {
- "kind-of": {
- "version": "6.0.2",
+ "source-map": {
+ "version": "0.5.7",
"bundled": true,
"dev": true
}
}
},
- "mimic-fn": {
- "version": "1.2.0",
- "bundled": true,
- "dev": true
- },
- "minimatch": {
- "version": "3.0.4",
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "brace-expansion": "^1.1.7"
+ "@babel/types": "^7.10.4"
}
},
- "minimist": {
- "version": "0.0.8",
- "bundled": true,
- "dev": true
- },
- "mixin-deep": {
- "version": "1.3.1",
+ "@babel/helper-builder-react-jsx": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "for-in": "^1.0.2",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
- "mkdirp": {
- "version": "0.5.1",
+ "@babel/helper-builder-react-jsx-experimental": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "minimist": "0.0.8"
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-module-imports": "^7.10.4",
+ "@babel/types": "^7.10.5"
}
},
- "ms": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true
- },
- "nanomatch": {
- "version": "1.2.9",
+ "@babel/helper-function-name": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "fragment-cache": "^0.2.1",
- "is-odd": "^2.0.0",
- "is-windows": "^1.0.2",
- "kind-of": "^6.0.2",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "arr-diff": {
- "version": "4.0.0",
- "bundled": true,
- "dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "bundled": true,
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "bundled": true,
- "dev": true
- }
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
- "normalize-package-data": {
- "version": "2.4.0",
+ "@babel/helper-get-function-arity": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "hosted-git-info": "^2.1.4",
- "is-builtin-module": "^1.0.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
+ "@babel/types": "^7.10.4"
}
},
- "npm-run-path": {
- "version": "2.0.2",
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "path-key": "^2.0.0"
+ "@babel/types": "^7.10.5"
}
},
- "number-is-nan": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true
- },
- "object-assign": {
- "version": "4.1.1",
- "bundled": true,
- "dev": true
- },
- "object-copy": {
- "version": "0.1.0",
+ "@babel/helper-module-imports": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "copy-descriptor": "^0.1.0",
- "define-property": "^0.2.5",
- "kind-of": "^3.0.3"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
+ "@babel/types": "^7.10.4"
}
},
- "object-visit": {
- "version": "1.0.1",
+ "@babel/helper-module-transforms": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- }
+ "@babel/helper-module-imports": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.10.4",
+ "@babel/helper-simple-access": "^7.10.4",
+ "@babel/helper-split-export-declaration": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.5",
+ "lodash": "^4.17.19"
}
},
- "object.pick": {
- "version": "1.3.0",
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "isobject": "^3.0.1"
- },
- "dependencies": {
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- }
+ "@babel/types": "^7.10.4"
}
},
- "once": {
- "version": "1.4.0",
+ "@babel/helper-plugin-utils": {
+ "version": "7.10.4",
+ "bundled": true,
+ "dev": true
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "wrappy": "1"
+ "@babel/helper-member-expression-to-functions": "^7.10.4",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
- "optimist": {
- "version": "0.6.1",
+ "@babel/helper-simple-access": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "minimist": "~0.0.1",
- "wordwrap": "~0.0.2"
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
- "os-homedir": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true
- },
- "os-locale": {
- "version": "2.1.0",
+ "@babel/helper-split-export-declaration": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "execa": "^0.7.0",
- "lcid": "^1.0.0",
- "mem": "^1.1.0"
+ "@babel/types": "^7.10.4"
}
},
- "p-finally": {
- "version": "1.0.0",
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.4",
"bundled": true,
"dev": true
},
- "p-limit": {
- "version": "1.2.0",
+ "@babel/helpers": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "p-try": "^1.0.0"
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
- "p-locate": {
- "version": "2.0.0",
+ "@babel/highlight": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "p-limit": "^1.1.0"
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
}
},
- "p-try": {
- "version": "1.0.0",
+ "@babel/parser": {
+ "version": "7.10.5",
"bundled": true,
"dev": true
},
- "parse-json": {
- "version": "2.2.0",
+ "@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "error-ex": "^1.2.0"
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-transform-parameters": "^7.10.4"
}
},
- "pascalcase": {
- "version": "0.1.1",
- "bundled": true,
- "dev": true
- },
- "path-exists": {
- "version": "2.1.0",
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.10.4",
"bundled": true,
"dev": true,
"requires": {
- "pinkie-promise": "^2.0.0"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
- "path-is-absolute": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true
- },
- "path-key": {
- "version": "2.0.1",
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
},
- "path-parse": {
- "version": "1.0.5",
+ "@babel/plugin-transform-destructuring": {
+ "version": "7.10.4",
"bundled": true,
- "dev": true
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
},
- "path-type": {
- "version": "1.1.0",
+ "@babel/plugin-transform-parameters": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "graceful-fs": "^4.1.2",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
- "pify": {
- "version": "2.3.0",
+ "@babel/plugin-transform-react-jsx": {
+ "version": "7.10.4",
"bundled": true,
- "dev": true
+ "dev": true,
+ "requires": {
+ "@babel/helper-builder-react-jsx": "^7.10.4",
+ "@babel/helper-builder-react-jsx-experimental": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-jsx": "^7.10.4"
+ }
},
- "pinkie": {
- "version": "2.0.4",
+ "@babel/template": {
+ "version": "7.10.4",
"bundled": true,
- "dev": true
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
},
- "pinkie-promise": {
- "version": "2.0.1",
+ "@babel/traverse": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "pinkie": "^2.0.0"
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.10.5",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-split-export-declaration": "^7.10.4",
+ "@babel/parser": "^7.10.5",
+ "@babel/types": "^7.10.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.19"
}
},
- "pkg-dir": {
- "version": "1.0.0",
+ "@babel/types": {
+ "version": "7.10.5",
"bundled": true,
"dev": true,
"requires": {
- "find-up": "^1.0.0"
- },
- "dependencies": {
- "find-up": {
- "version": "1.1.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "path-exists": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- }
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
}
},
- "posix-character-classes": {
- "version": "0.1.1",
+ "@types/color-name": {
+ "version": "1.1.1",
"bundled": true,
"dev": true
},
- "pseudomap": {
- "version": "1.0.2",
+ "@types/prop-types": {
+ "version": "15.7.3",
"bundled": true,
"dev": true
},
- "read-pkg": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "load-json-file": "^1.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^1.0.0"
- }
- },
- "read-pkg-up": {
- "version": "1.0.1",
+ "@types/react": {
+ "version": "16.9.43",
"bundled": true,
"dev": true,
"requires": {
- "find-up": "^1.0.0",
- "read-pkg": "^1.0.0"
- },
- "dependencies": {
- "find-up": {
- "version": "1.1.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "path-exists": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- }
+ "@types/prop-types": "*",
+ "csstype": "^2.2.0"
}
},
- "regenerator-runtime": {
- "version": "0.11.1",
+ "@types/yoga-layout": {
+ "version": "1.9.2",
"bundled": true,
"dev": true
},
- "regex-not": {
- "version": "1.0.2",
+ "ansi-escapes": {
+ "version": "4.3.1",
"bundled": true,
"dev": true,
"requires": {
- "extend-shallow": "^3.0.2",
- "safe-regex": "^1.1.0"
+ "type-fest": "^0.11.0"
}
},
- "repeat-element": {
- "version": "1.1.2",
- "bundled": true,
- "dev": true
- },
- "repeat-string": {
- "version": "1.6.1",
+ "ansi-regex": {
+ "version": "5.0.0",
"bundled": true,
"dev": true
},
- "repeating": {
- "version": "2.0.1",
+ "ansi-styles": {
+ "version": "3.2.1",
"bundled": true,
"dev": true,
"requires": {
- "is-finite": "^1.0.0"
+ "color-convert": "^1.9.0"
}
},
- "require-directory": {
- "version": "2.1.1",
+ "ansicolors": {
+ "version": "0.3.2",
"bundled": true,
"dev": true
},
- "require-main-filename": {
- "version": "1.0.1",
+ "arrify": {
+ "version": "2.0.1",
"bundled": true,
"dev": true
},
- "resolve-from": {
+ "astral-regex": {
"version": "2.0.0",
"bundled": true,
"dev": true
},
- "resolve-url": {
- "version": "0.2.1",
- "bundled": true,
- "dev": true
- },
- "ret": {
- "version": "0.1.15",
+ "auto-bind": {
+ "version": "4.0.0",
"bundled": true,
"dev": true
},
- "right-align": {
- "version": "0.1.3",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "align-text": "^0.1.1"
- }
- },
- "rimraf": {
- "version": "2.6.2",
+ "caller-callsite": {
+ "version": "2.0.0",
"bundled": true,
"dev": true,
"requires": {
- "glob": "^7.0.5"
+ "callsites": "^2.0.0"
}
},
- "safe-regex": {
- "version": "1.1.0",
+ "caller-path": {
+ "version": "2.0.0",
"bundled": true,
"dev": true,
"requires": {
- "ret": "~0.1.10"
+ "caller-callsite": "^2.0.0"
}
},
- "semver": {
- "version": "5.5.0",
- "bundled": true,
- "dev": true
- },
- "set-blocking": {
+ "callsites": {
"version": "2.0.0",
"bundled": true,
"dev": true
},
- "set-value": {
- "version": "2.0.0",
+ "cardinal": {
+ "version": "2.1.1",
"bundled": true,
"dev": true,
"requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.3",
- "split-string": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "ansicolors": "~0.3.2",
+ "redeyed": "~2.1.0"
}
},
- "shebang-command": {
- "version": "1.2.0",
+ "chalk": {
+ "version": "2.4.2",
"bundled": true,
"dev": true,
"requires": {
- "shebang-regex": "^1.0.0"
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
}
},
- "shebang-regex": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "signal-exit": {
- "version": "3.0.2",
- "bundled": true,
- "dev": true
- },
- "slide": {
- "version": "1.1.6",
+ "ci-info": {
+ "version": "2.0.0",
"bundled": true,
"dev": true
},
- "snapdragon": {
- "version": "0.8.2",
+ "cli-cursor": {
+ "version": "3.1.0",
"bundled": true,
"dev": true,
"requires": {
- "base": "^0.11.1",
- "debug": "^2.2.0",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "map-cache": "^0.2.2",
- "source-map": "^0.5.6",
- "source-map-resolve": "^0.5.0",
- "use": "^3.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "restore-cursor": "^3.1.0"
}
},
- "snapdragon-node": {
- "version": "2.1.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "define-property": "^1.0.0",
- "isobject": "^3.0.0",
- "snapdragon-util": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- },
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "bundled": true,
- "dev": true
- }
+ "cli-truncate": {
+ "version": "2.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "slice-ansi": "^3.0.0",
+ "string-width": "^4.2.0"
}
},
- "snapdragon-util": {
- "version": "3.0.1",
+ "color-convert": {
+ "version": "1.9.3",
"bundled": true,
"dev": true,
"requires": {
- "kind-of": "^3.2.0"
+ "color-name": "1.1.3"
}
},
- "source-map": {
- "version": "0.5.7",
+ "color-name": {
+ "version": "1.1.3",
"bundled": true,
"dev": true
},
- "source-map-resolve": {
- "version": "0.5.1",
+ "convert-source-map": {
+ "version": "1.7.0",
"bundled": true,
"dev": true,
"requires": {
- "atob": "^2.0.0",
- "decode-uri-component": "^0.2.0",
- "resolve-url": "^0.2.1",
- "source-map-url": "^0.4.0",
- "urix": "^0.1.0"
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "bundled": true,
+ "dev": true
+ }
}
},
- "source-map-url": {
- "version": "0.4.0",
+ "csstype": {
+ "version": "2.6.11",
"bundled": true,
"dev": true
},
- "spawn-wrap": {
- "version": "1.4.2",
+ "debug": {
+ "version": "4.1.1",
"bundled": true,
"dev": true,
"requires": {
- "foreground-child": "^1.5.6",
- "mkdirp": "^0.5.0",
- "os-homedir": "^1.0.1",
- "rimraf": "^2.6.2",
- "signal-exit": "^3.0.2",
- "which": "^1.3.0"
+ "ms": "^2.1.1"
}
},
- "spdx-correct": {
- "version": "3.0.0",
+ "emoji-regex": {
+ "version": "8.0.0",
"bundled": true,
- "dev": true,
- "requires": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
+ "dev": true
},
- "spdx-exceptions": {
- "version": "2.1.0",
+ "escape-string-regexp": {
+ "version": "1.0.5",
"bundled": true,
"dev": true
},
- "spdx-expression-parse": {
- "version": "3.0.0",
+ "esprima": {
+ "version": "4.0.1",
"bundled": true,
- "dev": true,
- "requires": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
+ "dev": true
+ },
+ "events-to-array": {
+ "version": "1.1.2",
+ "bundled": true,
+ "dev": true
+ },
+ "gensync": {
+ "version": "1.0.0-beta.1",
+ "bundled": true,
+ "dev": true
+ },
+ "globals": {
+ "version": "11.12.0",
+ "bundled": true,
+ "dev": true
},
- "spdx-license-ids": {
+ "has-flag": {
"version": "3.0.0",
"bundled": true,
"dev": true
},
- "split-string": {
+ "import-jsx": {
"version": "3.1.0",
"bundled": true,
"dev": true,
"requires": {
- "extend-shallow": "^3.0.0"
+ "@babel/core": "^7.5.5",
+ "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
+ "@babel/plugin-transform-destructuring": "^7.5.0",
+ "@babel/plugin-transform-react-jsx": "^7.3.0",
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
}
},
- "static-extend": {
- "version": "0.1.2",
+ "ink": {
+ "version": "2.7.1",
"bundled": true,
"dev": true,
"requires": {
- "define-property": "^0.2.5",
- "object-copy": "^0.1.0"
+ "ansi-escapes": "^4.2.1",
+ "arrify": "^2.0.1",
+ "auto-bind": "^4.0.0",
+ "chalk": "^3.0.0",
+ "cli-cursor": "^3.1.0",
+ "cli-truncate": "^2.1.0",
+ "is-ci": "^2.0.0",
+ "lodash.throttle": "^4.1.1",
+ "log-update": "^3.0.0",
+ "prop-types": "^15.6.2",
+ "react-reconciler": "^0.24.0",
+ "scheduler": "^0.18.0",
+ "signal-exit": "^3.0.2",
+ "slice-ansi": "^3.0.0",
+ "string-length": "^3.1.0",
+ "widest-line": "^3.1.0",
+ "wrap-ansi": "^6.2.0",
+ "yoga-layout-prebuilt": "^1.9.3"
},
"dependencies": {
- "define-property": {
- "version": "0.2.5",
+ "ansi-styles": {
+ "version": "4.2.1",
"bundled": true,
"dev": true,
"requires": {
- "is-descriptor": "^0.1.0"
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
}
- }
- }
- },
- "string-width": {
- "version": "2.1.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "ansi-regex": {
+ },
+ "chalk": {
"version": "3.0.0",
"bundled": true,
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "bundled": true,
"dev": true
},
- "strip-ansi": {
+ "has-flag": {
"version": "4.0.0",
"bundled": true,
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "bundled": true,
"dev": true,
"requires": {
- "ansi-regex": "^3.0.0"
+ "has-flag": "^4.0.0"
}
}
}
},
- "strip-ansi": {
- "version": "3.0.1",
+ "is-ci": {
+ "version": "2.0.0",
"bundled": true,
"dev": true,
"requires": {
- "ansi-regex": "^2.0.0"
+ "ci-info": "^2.0.0"
}
},
- "strip-bom": {
- "version": "2.0.0",
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "bundled": true,
+ "dev": true
+ },
+ "json5": {
+ "version": "2.1.3",
"bundled": true,
"dev": true,
"requires": {
- "is-utf8": "^0.2.0"
+ "minimist": "^1.2.5"
}
},
- "strip-eof": {
- "version": "1.0.0",
+ "lodash": {
+ "version": "4.17.19",
"bundled": true,
"dev": true
},
- "supports-color": {
- "version": "2.0.0",
+ "lodash.throttle": {
+ "version": "4.1.1",
"bundled": true,
"dev": true
},
- "test-exclude": {
- "version": "4.2.1",
+ "log-update": {
+ "version": "3.4.0",
"bundled": true,
"dev": true,
"requires": {
- "arrify": "^1.0.1",
- "micromatch": "^3.1.8",
- "object-assign": "^4.1.0",
- "read-pkg-up": "^1.0.1",
- "require-main-filename": "^1.0.1"
+ "ansi-escapes": "^3.2.0",
+ "cli-cursor": "^2.1.0",
+ "wrap-ansi": "^5.0.0"
},
"dependencies": {
- "arr-diff": {
- "version": "4.0.0",
+ "ansi-escapes": {
+ "version": "3.2.0",
"bundled": true,
"dev": true
},
- "array-unique": {
- "version": "0.3.2",
+ "ansi-regex": {
+ "version": "4.1.0",
"bundled": true,
"dev": true
},
- "braces": {
- "version": "2.3.2",
+ "cli-cursor": {
+ "version": "2.1.0",
"bundled": true,
"dev": true,
"requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "restore-cursor": "^2.0.0"
}
},
- "expand-brackets": {
- "version": "2.1.4",
+ "emoji-regex": {
+ "version": "7.0.3",
"bundled": true,
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-descriptor": {
- "version": "0.1.6",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- }
- },
- "kind-of": {
- "version": "5.1.0",
- "bundled": true,
- "dev": true
- }
- }
+ "dev": true
},
- "extglob": {
- "version": "2.0.4",
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
"bundled": true,
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
+ "dev": true
},
- "fill-range": {
- "version": "4.0.0",
+ "mimic-fn": {
+ "version": "1.2.0",
"bundled": true,
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
+ "dev": true
},
- "is-accessor-descriptor": {
- "version": "1.0.0",
+ "onetime": {
+ "version": "2.0.1",
"bundled": true,
"dev": true,
"requires": {
- "kind-of": "^6.0.0"
+ "mimic-fn": "^1.0.0"
}
},
- "is-data-descriptor": {
- "version": "1.0.0",
+ "restore-cursor": {
+ "version": "2.0.0",
"bundled": true,
"dev": true,
"requires": {
- "kind-of": "^6.0.0"
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
}
},
- "is-descriptor": {
- "version": "1.0.2",
+ "string-width": {
+ "version": "3.1.0",
"bundled": true,
"dev": true,
"requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
}
},
- "is-number": {
- "version": "3.0.0",
+ "strip-ansi": {
+ "version": "5.2.0",
"bundled": true,
"dev": true,
"requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "ansi-regex": "^4.1.0"
}
},
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "bundled": true,
- "dev": true
- },
- "micromatch": {
- "version": "3.1.10",
+ "wrap-ansi": {
+ "version": "5.1.0",
"bundled": true,
"dev": true,
"requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
}
}
}
},
- "to-fast-properties": {
- "version": "1.0.3",
- "bundled": true,
- "dev": true
- },
- "to-object-path": {
- "version": "0.3.0",
+ "loose-envify": {
+ "version": "1.4.0",
"bundled": true,
"dev": true,
"requires": {
- "kind-of": "^3.0.2"
+ "js-tokens": "^3.0.0 || ^4.0.0"
}
},
- "to-regex": {
- "version": "3.0.2",
+ "mimic-fn": {
+ "version": "2.1.0",
"bundled": true,
- "dev": true,
- "requires": {
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "regex-not": "^1.0.2",
- "safe-regex": "^1.1.0"
- }
+ "dev": true
},
- "to-regex-range": {
- "version": "2.1.1",
+ "minimist": {
+ "version": "1.2.5",
+ "bundled": true,
+ "dev": true
+ },
+ "minipass": {
+ "version": "3.1.3",
"bundled": true,
"dev": true,
"requires": {
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1"
+ "yallist": "^4.0.0"
},
"dependencies": {
- "is-number": {
- "version": "3.0.0",
+ "yallist": {
+ "version": "4.0.0",
"bundled": true,
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- }
+ "dev": true
}
}
},
- "trim-right": {
- "version": "1.0.1",
+ "ms": {
+ "version": "2.1.2",
+ "bundled": true,
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
"bundled": true,
"dev": true
},
- "uglify-js": {
- "version": "2.8.29",
+ "onetime": {
+ "version": "5.1.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
- "source-map": "~0.5.1",
- "uglify-to-browserify": "~1.0.0",
- "yargs": "~3.10.0"
- },
- "dependencies": {
- "yargs": {
- "version": "3.10.0",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "camelcase": "^1.0.2",
- "cliui": "^2.1.0",
- "decamelize": "^1.0.0",
- "window-size": "0.1.0"
- }
- }
+ "mimic-fn": "^2.1.0"
}
},
- "uglify-to-browserify": {
- "version": "1.0.2",
+ "path-parse": {
+ "version": "1.0.6",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
- "union-value": {
- "version": "1.0.0",
+ "prop-types": {
+ "version": "15.7.2",
"bundled": true,
"dev": true,
"requires": {
- "arr-union": "^3.1.0",
- "get-value": "^2.0.6",
- "is-extendable": "^0.1.1",
- "set-value": "^0.4.3"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "set-value": {
- "version": "0.4.3",
- "bundled": true,
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.1",
- "to-object-path": "^0.3.0"
- }
- }
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.8.1"
}
},
- "unset-value": {
- "version": "1.0.0",
+ "punycode": {
+ "version": "2.1.1",
"bundled": true,
- "dev": true,
- "requires": {
- "has-value": "^0.3.1",
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "has-value": {
- "version": "0.3.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "get-value": "^2.0.3",
- "has-values": "^0.1.4",
- "isobject": "^2.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- }
- }
- }
- },
- "has-values": {
- "version": "0.1.4",
- "bundled": true,
- "dev": true
- },
- "isobject": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true
- }
- }
+ "dev": true
},
- "urix": {
- "version": "0.1.0",
+ "react-is": {
+ "version": "16.13.1",
"bundled": true,
"dev": true
},
- "use": {
- "version": "3.1.0",
+ "react-reconciler": {
+ "version": "0.24.0",
"bundled": true,
"dev": true,
"requires": {
- "kind-of": "^6.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "6.0.2",
- "bundled": true,
- "dev": true
- }
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1",
+ "prop-types": "^15.6.2",
+ "scheduler": "^0.18.0"
}
},
- "validate-npm-package-license": {
- "version": "3.0.3",
+ "redeyed": {
+ "version": "2.1.1",
"bundled": true,
"dev": true,
"requires": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
+ "esprima": "~4.0.0"
}
},
- "which": {
- "version": "1.3.0",
+ "resolve": {
+ "version": "1.17.0",
"bundled": true,
"dev": true,
"requires": {
- "isexe": "^2.0.0"
+ "path-parse": "^1.0.6"
}
},
- "which-module": {
- "version": "2.0.0",
+ "resolve-from": {
+ "version": "3.0.0",
"bundled": true,
"dev": true
},
- "window-size": {
- "version": "0.1.0",
+ "restore-cursor": {
+ "version": "3.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "scheduler": {
+ "version": "0.18.0",
"bundled": true,
"dev": true,
- "optional": true
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1"
+ }
},
- "wordwrap": {
- "version": "0.0.3",
+ "semver": {
+ "version": "5.7.1",
"bundled": true,
"dev": true
},
- "wrap-ansi": {
- "version": "2.1.0",
+ "signal-exit": {
+ "version": "3.0.3",
+ "bundled": true,
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "3.0.0",
"bundled": true,
"dev": true,
"requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1"
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.2.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
+ "string-length": {
+ "version": "3.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "astral-regex": "^1.0.0",
+ "strip-ansi": "^5.2.0"
},
"dependencies": {
- "is-fullwidth-code-point": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "bundled": true,
+ "dev": true
+ },
+ "astral-regex": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
+ "dev": true
},
- "string-width": {
- "version": "1.0.2",
+ "strip-ansi": {
+ "version": "5.2.0",
"bundled": true,
"dev": true,
"requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
+ "ansi-regex": "^4.1.0"
}
}
}
},
- "wrappy": {
- "version": "1.0.2",
+ "string-width": {
+ "version": "4.2.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
},
- "write-file-atomic": {
- "version": "1.3.4",
+ "strip-ansi": {
+ "version": "6.0.0",
"bundled": true,
"dev": true,
"requires": {
- "graceful-fs": "^4.1.11",
- "imurmurhash": "^0.1.4",
- "slide": "^1.1.5"
+ "ansi-regex": "^5.0.0"
}
},
- "y18n": {
- "version": "3.2.1",
+ "supports-color": {
+ "version": "5.5.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
},
- "yallist": {
- "version": "2.1.2",
+ "tap-parser": {
+ "version": "10.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "events-to-array": "^1.0.1",
+ "minipass": "^3.0.0",
+ "tap-yaml": "^1.0.0"
+ }
+ },
+ "tap-yaml": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "yaml": "^1.5.0"
+ }
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
"bundled": true,
"dev": true
},
- "yargs": {
- "version": "11.1.0",
+ "treport": {
+ "version": "1.0.2",
"bundled": true,
"dev": true,
"requires": {
- "cliui": "^4.0.0",
- "decamelize": "^1.1.1",
- "find-up": "^2.1.0",
- "get-caller-file": "^1.0.1",
- "os-locale": "^2.0.0",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^2.0.0",
- "which-module": "^2.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^9.0.2"
+ "cardinal": "^2.1.1",
+ "chalk": "^3.0.0",
+ "import-jsx": "^3.1.0",
+ "ink": "^2.6.0",
+ "ms": "^2.1.2",
+ "string-length": "^3.1.0",
+ "tap-parser": "^10.0.1",
+ "unicode-length": "^2.0.2"
},
"dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "bundled": true,
- "dev": true
- },
- "camelcase": {
- "version": "4.1.0",
- "bundled": true,
- "dev": true
- },
- "cliui": {
- "version": "4.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "string-width": "^2.1.1",
- "strip-ansi": "^4.0.0",
- "wrap-ansi": "^2.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
+ "ansi-styles": {
+ "version": "4.2.1",
"bundled": true,
"dev": true,
"requires": {
- "ansi-regex": "^3.0.0"
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
}
},
- "yargs-parser": {
- "version": "9.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "camelcase": "^4.1.0"
- }
- }
- }
- },
- "yargs-parser": {
- "version": "8.1.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "camelcase": "^4.1.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "4.1.0",
+ "chalk": {
+ "version": "3.0.0",
"bundled": true,
- "dev": true
- }
- }
- }
- }
- },
- "oauth-sign": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
- "dev": true
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "dev": true,
- "requires": {
- "wrappy": "1"
- }
- },
- "opener": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz",
- "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=",
- "dev": true
- },
- "os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
- "dev": true
- },
- "own-or": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz",
- "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=",
- "dev": true
- },
- "own-or-env": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz",
- "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==",
- "dev": true,
- "requires": {
- "own-or": "^1.0.0"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true
- },
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
- "dev": true
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
- "dev": true
- },
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
- "pump": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
- "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true
- },
- "qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "request": {
- "version": "2.87.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
- "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
- "dev": true,
- "requires": {
- "aws-sign2": "~0.7.0",
- "aws4": "^1.6.0",
- "caseless": "~0.12.0",
- "combined-stream": "~1.0.5",
- "extend": "~3.0.1",
- "forever-agent": "~0.6.1",
- "form-data": "~2.3.1",
- "har-validator": "~5.0.3",
- "http-signature": "~1.2.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.17",
- "oauth-sign": "~0.8.2",
- "performance-now": "^2.1.0",
- "qs": "~6.5.1",
- "safe-buffer": "^5.1.1",
- "tough-cookie": "~2.3.3",
- "tunnel-agent": "^0.6.0",
- "uuid": "^3.1.0"
- }
- },
- "rimraf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
- "dev": true,
- "requires": {
- "glob": "^7.0.5"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
- "source-map-support": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz",
- "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
- },
- "sshpk": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
- "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
- "dev": true,
- "requires": {
- "asn1": "~0.2.3",
- "assert-plus": "^1.0.0",
- "bcrypt-pbkdf": "^1.0.0",
- "dashdash": "^1.12.0",
- "ecc-jsbn": "~0.1.1",
- "getpass": "^0.1.1",
- "jsbn": "~0.1.0",
- "tweetnacl": "~0.14.0"
- }
- },
- "stack-utils": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz",
- "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "bundled": true,
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "type-fest": {
+ "version": "0.11.0",
+ "bundled": true,
+ "dev": true
+ },
+ "unicode-length": {
+ "version": "2.0.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "punycode": "^2.0.0",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "widest-line": {
+ "version": "3.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "string-width": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.2.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
+ "yaml": {
+ "version": "1.10.0",
+ "bundled": true,
+ "dev": true
+ },
+ "yoga-layout-prebuilt": {
+ "version": "1.9.6",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "@types/yoga-layout": "1.9.2"
+ }
+ }
}
},
- "tap": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/tap/-/tap-12.0.1.tgz",
- "integrity": "sha512-iEJytWaZy8risvfRjuV4+ST+Lrrui/MW2ZCWn01ZaMn0NKFej4+PpBy6bXGOg9+cEGNmI7d3Sdka/zTUZUGidA==",
+ "tap-mocha-reporter": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz",
+ "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==",
"dev": true,
"requires": {
- "bind-obj-methods": "^2.0.0",
- "bluebird": "^3.5.1",
- "clean-yaml-object": "^0.1.0",
"color-support": "^1.1.0",
- "coveralls": "^3.0.1",
- "foreground-child": "^1.3.3",
- "fs-exists-cached": "^1.0.0",
- "function-loop": "^1.0.1",
- "glob": "^7.0.0",
- "isexe": "^2.0.0",
- "js-yaml": "^3.11.0",
- "minipass": "^2.3.0",
- "mkdirp": "^0.5.1",
- "nyc": "^11.8.0",
- "opener": "^1.4.1",
- "os-homedir": "^1.0.2",
- "own-or": "^1.0.0",
- "own-or-env": "^1.0.1",
- "rimraf": "^2.6.2",
- "signal-exit": "^3.0.0",
- "source-map-support": "^0.5.6",
- "stack-utils": "^1.0.0",
- "tap-mocha-reporter": "^3.0.7",
- "tap-parser": "^7.0.0",
- "tmatch": "^4.0.0",
- "trivial-deferred": "^1.0.1",
- "tsame": "^2.0.0",
- "write-file-atomic": "^2.3.0",
- "yapool": "^1.0.0"
+ "debug": "^4.1.1",
+ "diff": "^4.0.1",
+ "escape-string-regexp": "^2.0.0",
+ "glob": "^7.0.5",
+ "tap-parser": "^10.0.0",
+ "tap-yaml": "^1.0.0",
+ "unicode-length": "^2.0.2"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ }
}
},
- "tap-mocha-reporter": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-3.0.7.tgz",
- "integrity": "sha512-GHVXJ38C3oPRpM3YUc43JlGdpVZYiKeT1fmAd3HH2+J+ZWwsNAUFvRRdoGsXLw9+gU9o+zXpBqhS/oXyRQYwlA==",
+ "tap-parser": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz",
+ "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==",
"dev": true,
"requires": {
- "color-support": "^1.1.0",
- "debug": "^2.1.3",
- "diff": "^1.3.2",
- "escape-string-regexp": "^1.0.3",
- "glob": "^7.0.5",
- "js-yaml": "^3.3.1",
- "readable-stream": "^2.1.5",
- "tap-parser": "^5.1.0",
- "unicode-length": "^1.0.0"
+ "events-to-array": "^1.0.1",
+ "minipass": "^3.0.0",
+ "tap-yaml": "^1.0.0"
},
"dependencies": {
- "tap-parser": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz",
- "integrity": "sha512-BIsIaGqv7uTQgTW1KLTMNPSEQf4zDDPgYOBRdgOfuB+JFOLRBfEu6cLa/KvMvmqggu1FKXDfitjLwsq4827RvA==",
+ "minipass": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
+ "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"dev": true,
"requires": {
- "events-to-array": "^1.0.1",
- "js-yaml": "^3.2.7",
- "readable-stream": "^2"
+ "yallist": "^4.0.0"
}
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
}
}
},
- "tap-parser": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz",
- "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==",
+ "tap-yaml": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz",
+ "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==",
"dev": true,
"requires": {
- "events-to-array": "^1.0.1",
- "js-yaml": "^3.2.7",
- "minipass": "^2.2.0"
+ "yaml": "^1.5.0"
}
},
"tar-fs": {
@@ -3567,11 +3278,26 @@
"xtend": "^4.0.0"
}
},
- "tmatch": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz",
- "integrity": "sha512-Ynn2Gsp+oCvYScQXeV+cCs7citRDilq0qDXA6tuvFwDgiYyyaq7D5vKUlAPezzZR5NDobc/QMeN6e5guOYmvxg==",
- "dev": true
+ "tcompare": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-3.0.5.tgz",
+ "integrity": "sha512-+tmloQj1buaShBX+LP1i1NF5riJm110Yr0flIJAEoKf01tFVoMZvW2jq1JLqaW8fspOUVPm5NKKW5qLwT0ETDQ==",
+ "dev": true,
+ "requires": {
+ "diff-frag": "^1.0.1"
+ }
+ },
+ "test-exclude": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
+ "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3",
+ "minimatch": "^3.0.4",
+ "read-pkg-up": "^4.0.0",
+ "require-main-filename": "^2.0.0"
+ }
},
"to-buffer": {
"version": "1.1.1",
@@ -3579,13 +3305,29 @@
"integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
"dev": true
},
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
"tough-cookie": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
- "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"dev": true,
"requires": {
- "punycode": "^1.4.1"
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
}
},
"trivial-deferred": {
@@ -3594,11 +3336,18 @@
"integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=",
"dev": true
},
- "tsame": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/tsame/-/tsame-2.0.0.tgz",
- "integrity": "sha512-dAuzcnOPdqZYojylFQzEes95UDjve3HqKrlTCeLZKSDPMTsn3smzHZqsJj/sWD8wOUkg0RD++B11evyLn2+bIw==",
- "dev": true
+ "ts-node": {
+ "version": "8.10.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
+ "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
+ "dev": true,
+ "requires": {
+ "arg": "^4.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "source-map-support": "^0.5.17",
+ "yn": "3.1.1"
+ }
},
"tunnel-agent": {
"version": "0.6.0",
@@ -3613,17 +3362,57 @@
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
"dev": true,
- "optional": true
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "typescript": {
+ "version": "3.9.10",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
+ "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
+ "dev": true
},
"unicode-length": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz",
- "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz",
+ "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==",
"dev": true,
"requires": {
- "punycode": "^1.3.2",
+ "punycode": "^2.0.0",
"strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
}
},
"util-deprecate": {
@@ -3633,11 +3422,21 @@
"dev": true
},
"uuid": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
- "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"dev": true
},
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
@@ -3649,15 +3448,74 @@
"extsprintf": "^1.2.0"
}
},
+ "vlq": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
+ "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==",
+ "dev": true
+ },
"which": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
- "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -3665,14 +3523,15 @@
"dev": true
},
"write-file-atomic": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz",
- "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
"dev": true,
"requires": {
- "graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.2"
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
}
},
"xtend": {
@@ -3681,16 +3540,112 @@
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
"dev": true
},
+ "y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "dev": true
+ },
"yallist": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
- "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k="
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+ },
+ "yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true
},
"yapool": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz",
"integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=",
"dev": true
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ },
+ "yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true
}
}
}
diff --git a/package.json b/package.json
index 26606954..0185237c 100644
--- a/package.json
+++ b/package.json
@@ -2,35 +2,41 @@
"author": "Isaac Z. Schlueter (http://blog.izs.me/)",
"name": "tar",
"description": "tar for node",
- "version": "4.4.8",
+ "version": "4.4.19",
+ "publishConfig": {
+ "tag": "v4-legacy"
+ },
"repository": {
"type": "git",
"url": "https://github.com/npm/node-tar.git"
},
"scripts": {
- "test": "tap test/*.js --100 -J --coverage-report=text -c",
+ "test:posix": "tap",
+ "test:win32": "tap --lines=98 --branches=98 --statements=98 --functions=98",
+ "test": "node test/fixtures/test.js",
"preversion": "npm test",
"postversion": "npm publish",
- "postpublish": "git push origin --all; git push origin --tags",
+ "postpublish": "git push origin --follow-tags",
"genparse": "node scripts/generate-parse-fixtures.js",
"bench": "for i in benchmarks/*/*.js; do echo $i; for j in {1..5}; do node $i || break; done; done"
},
"dependencies": {
- "chownr": "^1.1.1",
- "fs-minipass": "^1.2.5",
- "minipass": "^2.3.4",
- "minizlib": "^1.1.1",
- "mkdirp": "^0.5.0",
- "safe-buffer": "^5.1.2",
- "yallist": "^3.0.2"
+ "chownr": "^1.1.4",
+ "fs-minipass": "^1.2.7",
+ "minipass": "^2.9.0",
+ "minizlib": "^1.3.3",
+ "mkdirp": "^0.5.5",
+ "safe-buffer": "^5.2.1",
+ "yallist": "^3.1.1"
},
"devDependencies": {
"chmodr": "^1.2.0",
- "end-of-stream": "^1.4.1",
+ "end-of-stream": "^1.4.4",
"events-to-array": "^1.1.2",
"mutate-fs": "^2.1.1",
- "rimraf": "^2.6.2",
- "tap": "^12.0.1",
+ "require-inject": "^1.4.4",
+ "rimraf": "^2.7.1",
+ "tap": "^14.11.0",
"tar-fs": "^1.16.3",
"tar-stream": "^1.6.2"
},
@@ -41,5 +47,9 @@
"files": [
"index.js",
"lib/"
- ]
+ ],
+ "tap": {
+ "coverage-map": "map.js",
+ "check-coverage": true
+ }
}
diff --git a/test/create.js b/test/create.js
index 2adc9e53..9aa66d19 100644
--- a/test/create.js
+++ b/test/create.js
@@ -1,5 +1,6 @@
'use strict'
+const isWindows = process.platform === 'win32'
const t = require('tap')
const c = require('../lib/create.js')
const list = require('../lib/list.js')
@@ -7,11 +8,12 @@ const fs = require('fs')
const path = require('path')
const dir = path.resolve(__dirname, 'fixtures/create')
const tars = path.resolve(__dirname, 'fixtures/tars')
-const rimraf = require('rimraf')
-const mkdirp = require('mkdirp')
const spawn = require('child_process').spawn
const Pack = require('../lib/pack.js')
const mutateFS = require('mutate-fs')
+const {promisify} = require('util')
+const rimraf = promisify(require('rimraf'))
+const mkdirp = promisify(require('mkdirp'))
const readtar = (file, cb) => {
const child = spawn('tar', ['tf', file])
@@ -21,12 +23,11 @@ const readtar = (file, cb) => {
cb(code, signal, Buffer.concat(out).toString()))
}
-t.teardown(_ => rimraf.sync(dir))
+t.teardown(() => rimraf(dir))
-t.test('setup', t => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- t.end()
+t.test('setup', async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
t.test('no cb if sync or without file', t => {
@@ -88,7 +89,7 @@ t.test('create file', t => {
})
t.test('with specific mode', t => {
- const mode = 0o740
+ const mode = isWindows ? 0o666 : 0o740
t.test('sync', t => {
const file = path.resolve(dir, 'sync-mode.tar')
c({
diff --git a/test/extract.js b/test/extract.js
index f6c992b1..8c1064de 100644
--- a/test/extract.js
+++ b/test/extract.js
@@ -6,49 +6,47 @@ const path = require('path')
const fs = require('fs')
const extractdir = path.resolve(__dirname, 'fixtures/extract')
const tars = path.resolve(__dirname, 'fixtures/tars')
-const mkdirp = require('mkdirp')
-const rimraf = require('rimraf')
+const {promisify} = require('util')
+const mkdirp = promisify(require('mkdirp'))
+const rimraf = promisify(require('rimraf'))
const mutateFS = require('mutate-fs')
-t.teardown(_ => rimraf.sync(extractdir))
+t.teardown(_ => rimraf(extractdir))
t.test('basic extracting', t => {
const file = path.resolve(tars, 'utf8.tar')
const dir = path.resolve(extractdir, 'basic')
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
- const check = t => {
+ const check = async t => {
fs.lstatSync(dir + '/Ω.txt')
fs.lstatSync(dir + '/🌟.txt')
t.throws(_ => fs.lstatSync(dir + '/long-path/r/e/a/l/l/y/-/d/e/e/p/-' +
'/f/o/l/d/e/r/-/p/a/t/h/Ω.txt'))
- rimraf.sync(dir)
+ await rimraf(dir)
t.end()
}
const files = [ '🌟.txt', 'Ω.txt' ]
t.test('sync', t => {
x({ file: file, sync: true, C: dir }, files)
- check(t)
+ return check(t)
})
t.test('async promisey', t => {
- return x({ file: file, cwd: dir }, files).then(_ => {
- check(t)
- })
+ return x({ file: file, cwd: dir }, files).then(_ => check(t))
})
t.test('async cb', t => {
return x({ file: file, cwd: dir }, files, er => {
if (er)
throw er
- check(t)
+ return check(t)
})
})
@@ -59,32 +57,31 @@ t.test('file list and filter', t => {
const file = path.resolve(tars, 'utf8.tar')
const dir = path.resolve(extractdir, 'filter')
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
- const check = t => {
+ const check = async t => {
fs.lstatSync(dir + '/Ω.txt')
t.throws(_ => fs.lstatSync(dir + '/🌟.txt'))
t.throws(_ => fs.lstatSync(dir + '/long-path/r/e/a/l/l/y/-/d/e/e/p/-' +
'/f/o/l/d/e/r/-/p/a/t/h/Ω.txt'))
- rimraf.sync(dir)
+ await rimraf(dir)
t.end()
}
const filter = path => path === 'Ω.txt'
t.test('sync', t => {
- x({ filter: filter, file: file, sync: true, C: dir }, [ '🌟.txt', 'Ω.txt' ])
- check(t)
+ x({ filter: filter, file: file, sync: true, C: dir }, ['🌟.txt', 'Ω.txt'])
+ return check(t)
})
t.test('async promisey', t => {
- return x({ filter: filter, file: file, cwd: dir }, [ '🌟.txt', 'Ω.txt' ]).then(_ => {
- check(t)
+ return x({ filter: filter, file: file, cwd: dir }, ['🌟.txt', 'Ω.txt']).then(_ => {
+ return check(t)
})
})
@@ -92,7 +89,7 @@ t.test('file list and filter', t => {
return x({ filter: filter, file: file, cwd: dir }, [ '🌟.txt', 'Ω.txt' ], er => {
if (er)
throw er
- check(t)
+ return check(t)
})
})
@@ -103,29 +100,28 @@ t.test('no file list', t => {
const file = path.resolve(tars, 'body-byte-counts.tar')
const dir = path.resolve(extractdir, 'no-list')
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
- const check = t => {
+ const check = async t => {
t.equal(fs.lstatSync(path.resolve(dir, '1024-bytes.txt')).size, 1024)
t.equal(fs.lstatSync(path.resolve(dir, '512-bytes.txt')).size, 512)
t.equal(fs.lstatSync(path.resolve(dir, 'one-byte.txt')).size, 1)
t.equal(fs.lstatSync(path.resolve(dir, 'zero-byte.txt')).size, 0)
- rimraf.sync(dir)
+ await rimraf(dir)
t.end()
}
t.test('sync', t => {
x({ file: file, sync: true, C: dir })
- check(t)
+ return check(t)
})
t.test('async promisey', t => {
return x({ file: file, cwd: dir }).then(_ => {
- check(t)
+ return check(t)
})
})
@@ -133,7 +129,7 @@ t.test('no file list', t => {
return x({ file: file, cwd: dir }, er => {
if (er)
throw er
- check(t)
+ return check(t)
})
})
@@ -145,29 +141,28 @@ t.test('read in itty bits', t => {
const file = path.resolve(tars, 'body-byte-counts.tar')
const dir = path.resolve(extractdir, 'no-list')
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
- const check = t => {
+ const check = async t => {
t.equal(fs.lstatSync(path.resolve(dir, '1024-bytes.txt')).size, 1024)
t.equal(fs.lstatSync(path.resolve(dir, '512-bytes.txt')).size, 512)
t.equal(fs.lstatSync(path.resolve(dir, 'one-byte.txt')).size, 1)
t.equal(fs.lstatSync(path.resolve(dir, 'zero-byte.txt')).size, 0)
- rimraf.sync(dir)
+ await rimraf(dir)
t.end()
}
t.test('sync', t => {
x({ file: file, sync: true, C: dir, maxReadSize: maxReadSize })
- check(t)
+ return check(t)
})
t.test('async promisey', t => {
return x({ file: file, cwd: dir, maxReadSize: maxReadSize }).then(_ => {
- check(t)
+ return check(t)
})
})
@@ -175,7 +170,7 @@ t.test('read in itty bits', t => {
return x({ file: file, cwd: dir, maxReadSize: maxReadSize }, er => {
if (er)
throw er
- check(t)
+ return check(t)
})
})
@@ -210,16 +205,15 @@ t.test('read fail', t => {
t.end()
})
-t.test('sync gzip error edge case test', t => {
- const zlib = require('minizlib')
+t.test('sync gzip error edge case test', async t => {
const file = path.resolve(__dirname, 'fixtures/sync-gzip-fail.tgz')
const dir = path.resolve(__dirname, 'sync-gzip-fail')
const cwd = process.cwd()
- mkdirp.sync(dir + '/x')
+ await mkdirp(dir + '/x')
process.chdir(dir)
- t.teardown(() => {
+ t.teardown(async () => {
process.chdir(cwd)
- rimraf.sync(dir)
+ await rimraf(dir)
})
x({
diff --git a/test/fixtures/test.js b/test/fixtures/test.js
new file mode 100644
index 00000000..e1a34da7
--- /dev/null
+++ b/test/fixtures/test.js
@@ -0,0 +1,20 @@
+const platform = process.platform === 'win32' ? 'win32' : 'posix'
+const {spawn} = require('child_process')
+const c = spawn(process.execPath, [
+ process.env.npm_execpath,
+ 'run',
+ `test:${platform}`,
+ '--',
+ ...process.argv.slice(2),
+], {
+ stdio: 'inherit',
+})
+c.on('close', (code, signal) => {
+ process.exitCode = code
+ if (signal) {
+ process.kill(process.pid, signal)
+ setTimeout(() => {}, 200)
+ }
+})
+process.on('SIGTERM', () => c.kill('SIGTERM'))
+process.on('SIGINT', () => c.kill('SIGINT'))
diff --git a/test/header.js b/test/header.js
index ae4ece36..d20e54ba 100644
--- a/test/header.js
+++ b/test/header.js
@@ -557,3 +557,59 @@ t.test('dir with long body', t => {
t.equal(h.size, 0)
t.end()
})
+
+t.test('null block, global extended header', t => {
+ const h = new Header(Buffer.alloc(512), 0, {
+ undef: undefined,
+ blerg: 'bloo',
+ }, {
+ path: '/global.path',
+ foo: 'global foo'
+ })
+ t.match(h, {
+ cksumValid: false,
+ needPax: false,
+ path: '',
+ type: 'File',
+ mode: null,
+ uid: null,
+ gid: null,
+ size: null,
+ mtime: null,
+ cksum: null,
+ linkpath: '',
+ uname: null,
+ gname: null,
+ devmaj: 0,
+ devmin: 0,
+ atime: null,
+ ctime: null,
+ nullBlock: true,
+ blerg: 'bloo',
+ foo: 'global foo',
+ })
+ t.end()
+})
+
+t.test('gnutar-generated 10gb file size', t => {
+ const b = Buffer.from(
+ '313067622e696d67000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000030303030363634003030303137353000303030313735300080000000' +
+ '0000000280000000313334373434303132303500303131313437002030000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0075737461722020006973616163730000000000000000000000000000000000' +
+ '0000000000000000006973616163730000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000' +
+ '0000000000000000000000000000000000000000000000000000000000000000', 'hex')
+ const h = new Header(b)
+ t.equal(h.size, 1024 * 1024 * 1024 * 10, 'should be 10gb file')
+ t.end()
+})
diff --git a/test/index.js b/test/index.js
new file mode 100644
index 00000000..3be46922
--- /dev/null
+++ b/test/index.js
@@ -0,0 +1,73 @@
+const t = require('tap')
+const tar = require('../')
+t.match(tar, {
+ create: Function,
+ c: Function,
+ replace: Function,
+ r: Function,
+ list: Function,
+ t: Function,
+ update: Function,
+ u: Function,
+ extract: Function,
+ x: Function,
+ Pack: Function,
+ Unpack: Function,
+ Parse: Function,
+ ReadEntry: Function,
+ WriteEntry: Function,
+ Header: Function,
+ Pax: Function,
+ types: {
+ name: new Map([
+ ['0', 'File'],
+ ['', 'OldFile'],
+ ['1', 'Link'],
+ ['2', 'SymbolicLink'],
+ ['3', 'CharacterDevice'],
+ ['4', 'BlockDevice'],
+ ['5', 'Directory'],
+ ['6', 'FIFO'],
+ ['7', 'ContiguousFile'],
+ ['g', 'GlobalExtendedHeader'],
+ ['x', 'ExtendedHeader'],
+ ['A', 'SolarisACL'],
+ ['D', 'GNUDumpDir'],
+ ['I', 'Inode'],
+ ['K', 'NextFileHasLongLinkpath'],
+ ['L', 'NextFileHasLongPath'],
+ ['M', 'ContinuationFile'],
+ ['N', 'OldGnuLongPath'],
+ ['S', 'SparseFile'],
+ ['V', 'TapeVolumeHeader'],
+ ['X', 'OldExtendedHeader'],
+ ]),
+ code: new Map([
+ ['File', '0'],
+ ['OldFile', ''],
+ ['Link', '1'],
+ ['SymbolicLink', '2'],
+ ['CharacterDevice', '3'],
+ ['BlockDevice', '4'],
+ ['Directory', '5'],
+ ['FIFO', '6'],
+ ['ContiguousFile', '7'],
+ ['GlobalExtendedHeader', 'g'],
+ ['ExtendedHeader', 'x'],
+ ['SolarisACL', 'A'],
+ ['GNUDumpDir', 'D'],
+ ['Inode', 'I'],
+ ['NextFileHasLongLinkpath', 'K'],
+ ['NextFileHasLongPath', 'L'],
+ ['ContinuationFile', 'M'],
+ ['OldGnuLongPath', 'N'],
+ ['SparseFile', 'S'],
+ ['TapeVolumeHeader', 'V'],
+ ['OldExtendedHeader', 'X'],
+ ]),
+ }
+})
+t.match(tar.Pack.Sync, Function)
+t.match(tar.WriteEntry.Sync, Function)
+t.match(tar.WriteEntry.Tar, Function)
+t.match(tar.Pax.parse, Function)
diff --git a/test/large-numbers.js b/test/large-numbers.js
index 0e23d260..e323611c 100644
--- a/test/large-numbers.js
+++ b/test/large-numbers.js
@@ -7,29 +7,56 @@ const t = require('tap')
t.test('parse', t => {
const cases = new Map([
- ['ffffffffffffffffffffff20', -1],
- ['800000000000100000000020', 68719476736],
- ['fffffffffffffffe1ecc8020', -31536000],
- ['fffffffffffffff000000020', -268435456],
- ['800000010203040506070020', 72623859790382850],
- ['ffffffffffffffffffffff00', -1],
- ['800000000000100000000000', 68719476736],
- ['fffffffffffffffe1ecc8000', -31536000],
- ['fffffffffffffff000000000', -268435456],
- ['800000010203040506070000', 72623859790382850]
+ ['ffffffffffffffffffffffff', -1],
+ ['800000000000100000000020', 17592186044448],
+ ['fffffffffffffffe1ecc8020', -8073215968],
+ ['fffffffffffffff000000020', -68719476704],
+ ['80000000001fffffffffffff', 9007199254740991], // MAX_SAFE_INTEGER
+ ['ffffffffffe0000000000001', -9007199254740991], // MIN_SAFE_INTEGER
+ ['800000000000100000000000', 17592186044416],
+ ['fffffffffffffffe1ecc8000', -8073216000],
+ ['fffffffffffffff000000000', -68719476736],
+ ['800000000000000353b66200', 14289363456]
])
t.plan(cases.size)
cases.forEach((value, hex) =>
t.equal(parse(Buffer.from(hex, 'hex')), value))
})
+t.test('parse out of range', t => {
+ const cases = [
+ '800000030000000000000000',
+ '800000000020000000000000', // MAX_SAFE_INTEGER + 1
+ 'ffffffffffe0000000000000', // MIN_SAFE_INTEGER - 1
+ 'fffffffffdd0000000000000',
+ ]
+ t.plan(cases.length)
+ cases.forEach((hex) =>
+ t.throws(_ => parse(Buffer.from(hex, 'hex')),
+ TypeError('parsed number outside of javascript safe integer range')))
+})
+
+t.test('parse invalid base256 encoding', t => {
+ const cases = [
+ '313233343536373131', // octal encoded
+ '700000030000000000000000', // does not start with 0x80 or 0xff
+ ]
+ t.plan(cases.length)
+ cases.forEach((hex) =>
+ t.throws(_ => parse(Buffer.from(hex, 'hex')),
+ TypeError('invalid base256 encoding')))
+})
+
t.test('encode', t => {
const cases = new Map([
- ['ffffffffffffffffffffff20', -1],
- ['800000000000100000000020', 68719476736],
- ['fffffffffffffffe1ecc8020', -31536000],
- ['fffffffffffffff000000020', -268435456],
- ['800000010203040506070020', 72623859790382850]
+ ['ffffffffffffffffffffffff', -1],
+ ['800000000000100000000020', 17592186044448],
+ ['800000000000100000000000', 17592186044416],
+ ['fffffffffffffffe1ecc8020', -8073215968],
+ ['fffffffffffffff000000020', -68719476704],
+ ['fffffffffffffff000000000', -68719476736], // Allows us to test the case where there's a trailing 00
+ ['80000000001fffffffffffff', 9007199254740991], // MAX_SAFE_INTEGER
+ ['ffffffffffe0000000000001', -9007199254740991] // MIN_SAFE_INTEGER
])
t.plan(2)
t.test('alloc', t => {
@@ -43,3 +70,18 @@ t.test('encode', t => {
t.equal(encode(value, Buffer.allocUnsafe(12)).toString('hex'), hex))
})
})
+
+t.test('encode unsafe numbers', t => {
+ const cases = [
+ Number.MAX_VALUE,
+ Number.MAX_SAFE_INTEGER + 1,
+ Number.MIN_SAFE_INTEGER - 1,
+ Number.MIN_VALUE,
+ ]
+
+ t.plan(cases.length)
+ cases.forEach((value) =>
+ t.throws(_ => encode(value),
+ TypeError('cannot encode number outside of javascript safe integer range')))
+})
+
diff --git a/test/map.js b/test/map.js
new file mode 100644
index 00000000..fcd4e47f
--- /dev/null
+++ b/test/map.js
@@ -0,0 +1,7 @@
+const t = require('tap')
+const map = require('../map.js')
+t.equal(map('test/index.js'), 'index.js')
+t.same(map('test/unpack.js'), ['lib/unpack.js', 'lib/mkdir.js'])
+t.same(map('test/load-all.js'), [])
+t.equal(map(__filename), 'map.js')
+t.equal(map('test/asdf'), 'lib/asdf')
diff --git a/test/normalize-windows-path.js b/test/normalize-windows-path.js
new file mode 100644
index 00000000..e631c8ac
--- /dev/null
+++ b/test/normalize-windows-path.js
@@ -0,0 +1,27 @@
+const t = require('tap')
+
+const realPlatform = process.platform
+const fakePlatform = realPlatform === 'win32' ? 'posix' : 'win32'
+const requireInject = require('require-inject')
+
+t.test('posix', t => {
+ if (realPlatform === 'win32')
+ process.env.TESTING_TAR_FAKE_PLATFORM = fakePlatform
+ else
+ delete process.env.TESTING_TAR_FAKE_PLATFORM
+ const normPath = requireInject('../lib/normalize-windows-path.js')
+ t.equal(normPath('/some/path/back\\slashes'), '/some/path/back\\slashes')
+ t.equal(normPath('c:\\foo\\bar'), 'c:\\foo\\bar')
+ t.end()
+})
+
+t.test('win32', t => {
+ if (realPlatform !== 'win32')
+ process.env.TESTING_TAR_FAKE_PLATFORM = fakePlatform
+ else
+ delete process.env.TESTING_TAR_FAKE_PLATFORM
+ const normPath = requireInject('../lib/normalize-windows-path.js')
+ t.equal(normPath('/some/path/back\\slashes'), '/some/path/back/slashes')
+ t.equal(normPath('c:\\foo\\bar'), 'c:/foo/bar')
+ t.end()
+})
diff --git a/test/pack.js b/test/pack.js
index ef02a15d..6b06c681 100644
--- a/test/pack.js
+++ b/test/pack.js
@@ -20,6 +20,8 @@ const EE = require('events').EventEmitter
const rimraf = require('rimraf')
const mkdirp = require('mkdirp')
const ReadEntry = require('../lib/read-entry.js')
+const isWindows = process.platform === 'win32'
+const normPath = require('../lib/normalize-windows-path.js')
const ctime = new Date('2017-05-10T01:03:12.000Z')
const atime = new Date('2017-04-17T00:00:00.000Z')
@@ -58,7 +60,7 @@ t.test('pack a file', t => {
cksumValid: true,
needPax: false,
path: 'one-byte.txt',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 1,
mtime: mtime,
cksum: Number,
@@ -102,7 +104,7 @@ t.test('pack a file with a prefix', t => {
cksumValid: true,
needPax: false,
path: 'package/.dotfile',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 2,
mtime: mtime,
cksum: Number,
@@ -143,7 +145,7 @@ t.test('pack a dir', t => {
cksumValid: true,
needPax: false,
path: 'dir/',
- mode: 0o755,
+ mode: Number,
size: 0,
mtime: null,
cksum: Number,
@@ -171,7 +173,7 @@ t.test('pack a dir', t => {
cksumValid: true,
needPax: false,
path: 'dir/x',
- mode: 0o644,
+ mode: Number,
size: 0,
mtime: mtime,
cksum: Number,
@@ -211,7 +213,7 @@ t.test('use process cwd if cwd not specified', t => {
cksumValid: true,
needPax: false,
path: 'dir/',
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
size: 0,
mtime: mtime,
cksum: Number,
@@ -239,7 +241,7 @@ t.test('use process cwd if cwd not specified', t => {
cksumValid: true,
needPax: false,
path: 'dir/x',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 0,
mtime: mtime,
cksum: Number,
@@ -277,7 +279,7 @@ t.test('filter', t => {
cksumValid: true,
needPax: false,
path: 'dir/',
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
size: 0,
mtime: mtime,
cksum: Number,
@@ -323,7 +325,7 @@ t.test('add the same dir twice (exercise cache code)', t => {
cksumValid: true,
needPax: false,
path: 'dir/',
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
size: 0,
mtime: mtime,
cksum: Number,
@@ -571,7 +573,7 @@ t.test('pipe into a slow reader', t => {
cksumValid: true,
needPax: false,
path: 'long-path/',
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
size: 0,
mtime: mtime,
cksum: Number,
@@ -629,7 +631,7 @@ t.test('pipe into a slow gzip reader', t => {
cksumValid: true,
needPax: false,
path: 'long-path/',
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
size: 0,
mtime: mtime,
cksum: Number,
@@ -695,11 +697,12 @@ t.test('warnings', t => {
const data = Buffer.concat(out)
t.equal(data.length, 2048)
t.match(warnings, [[
- /stripping .* from absolute path/, f
+ /stripping .* from absolute path/,
+ normPath(f),
]])
t.match(new Header(data), {
- path: f.replace(/^(\/|[a-z]:\\\\)/, '')
+ path: normPath(f).replace(/^(\/|[a-z]:\/)/i, ''),
})
t.end()
})
@@ -724,7 +727,7 @@ t.test('warnings', t => {
t.equal(warnings.length, 0)
t.match(new Header(data), {
- path: f
+ path: normPath(f),
})
t.end()
})
@@ -737,7 +740,10 @@ t.test('warnings', t => {
strict: true,
cwd: files
}).end(f).on('error', e => {
- t.match(e, { message: /stripping .* from absolute path/, data: f })
+ t.match(e, {
+ message: /stripping .* from absolute path/,
+ data: normPath(f),
+ })
t.end()
})
})
@@ -791,7 +797,7 @@ t.test('no dir recurse', t => {
t.end()
})
-t.test('follow', t => {
+t.test('follow', { skip: isWindows && 'file symlinks not available' }, t => {
const check = (out, t) => {
const data = Buffer.concat(out)
t.equal(data.length, 2048)
@@ -800,8 +806,8 @@ t.test('follow', t => {
cksumValid: true,
needPax: false,
path: 'symlink',
- mode: 0o644,
- size: 26
+ mode: isWindows ? 0o666 : 0o644,
+ size: 26,
})
t.match(data.slice(512).toString(), /this link is like diamond\n\0+$/)
t.end()
@@ -1055,3 +1061,97 @@ t.test('prefix and subdirs', t => {
return t.test('./', t => runTest(t, './', Pack.Sync))
})
})
+
+// https://github.com/npm/node-tar/issues/284
+t.test('prefix and hard links', t => {
+ const dir = path.resolve(fixtures, 'pack-prefix-hardlinks')
+ t.teardown(_ => rimraf.sync(dir))
+ mkdirp.sync(dir + '/in/z/b/c')
+ fs.writeFileSync(dir + '/in/target', 'ddd')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/b/c/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/b/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/y')
+
+ const expect = [
+ 'out/x/\0',
+ {
+ type: 'File',
+ size: 3,
+ path: 'out/x/target',
+ linkpath: '',
+ },
+ 'ddd\0\0\0\0\0\0\0\0\0\0\0',
+ {
+ path: 'out/x/y',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ 'out/x/z/\0',
+ 'out/x/z/b/\0',
+ {
+ path: 'out/x/z/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ 'out/x/z/b/c/\0',
+ {
+ path: 'out/x/z/b/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ path: 'out/x/z/b/c/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ '\0',
+ '\0',
+ ]
+
+ const check = (out, t) => {
+ const data = Buffer.concat(out)
+ expect.forEach((e, i) => {
+ if (typeof e === 'string')
+ t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e)
+ else
+ t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e)
+ })
+ t.end()
+ }
+
+ const runTest = (t, path, Class) => {
+ const p = new Class({
+ cwd: dir + '/in',
+ prefix: 'out/x',
+ noDirRecurse: true,
+ })
+ const out = []
+ p.on('data', d => out.push(d))
+ p.on('end', () => check(out, t))
+ p.write(path)
+ if (path === '.')
+ path = './'
+ p.write(`${path}target`)
+ p.write(`${path}y`)
+ p.write(`${path}z`)
+ p.write(`${path}z/b`)
+ p.write(`${path}z/d`)
+ p.write(`${path}z/b/c`)
+ p.write(`${path}z/b/d`)
+ p.write(`${path}z/b/c/d`)
+ p.end()
+ }
+
+ t.test('async', t => {
+ t.test('.', t => runTest(t, '.', Pack))
+ return t.test('./', t => runTest(t, './', Pack))
+ })
+
+ t.test('sync', t => {
+ t.test('.', t => runTest(t, '.', Pack.Sync))
+ return t.test('./', t => runTest(t, './', Pack.Sync))
+ })
+
+ t.end()
+})
diff --git a/test/parse.js b/test/parse.js
index 6ef3ce72..6092c833 100644
--- a/test/parse.js
+++ b/test/parse.js
@@ -172,6 +172,15 @@ t.test('onentry gets added to entry event', t => {
})
t.test('drain event timings', t => {
+ let sawOndone = false
+ const ondone = function () {
+ sawOndone = true
+ this.emit('prefinish')
+ this.emit('finish')
+ this.emit('end')
+ this.emit('close')
+ }
+
// write 1 header and body, write 2 header, verify false return
// wait for drain event before continuing.
// write 2 body, 3 header and body, 4 header, verify false return
@@ -311,6 +320,7 @@ t.test('drain event timings', t => {
let currentEntry
let autoPipe = true
const p = new Parse({
+ ondone,
onentry: entry => {
t.equal(entry.path, expect.shift())
currentEntry = entry
@@ -361,6 +371,7 @@ t.test('drain event timings', t => {
p.once('drain', go)
p.on('end', _ => {
clearInterval(interval)
+ t.ok(sawOndone)
t.end()
})
go()
@@ -595,3 +606,27 @@ t.test('end while consuming', t => {
mp.end(data)
mp.pipe(p)
})
+
+t.test('header that throws', t => {
+ const expect = { message: 'invalid base256 encoding' }
+ const p = new Parse()
+ p.on('warn', (m, d) => {
+ t.match(d, expect)
+ t.end()
+ })
+ const h = new Header({
+ path: 'path',
+ mode: 0o07777, // gonna make this one invalid
+ uid: 1234,
+ gid: 4321,
+ size: 99,
+ type: 'File',
+ size: 1,
+ })
+ h.encode()
+ const buf = h.block
+ const bad = Buffer.from([0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
+ bad.copy(buf, 100)
+ t.throws(() => new Header(buf), expect, 'the header with that buffer throws')
+ p.write(buf)
+})
diff --git a/test/path-reservations.js b/test/path-reservations.js
new file mode 100644
index 00000000..c495f310
--- /dev/null
+++ b/test/path-reservations.js
@@ -0,0 +1,149 @@
+const t = require('tap')
+const requireInject = require('require-inject')
+
+// load up the posix and windows versions of the reserver
+if (process.platform === 'win32')
+ process.env.TESTING_TAR_FAKE_PLATFORM = 'posix'
+const { reserve } = require('../lib/path-reservations.js')()
+delete process.env.TESTING_TAR_FAKE_PLATFORM
+if (process.platform !== 'win32')
+ process.env.TESTING_TAR_FAKE_PLATFORM = 'win32'
+const { reserve: winReserve } = requireInject('../lib/path-reservations.js')()
+
+t.test('basic race', t => {
+ // simulate the race conditions we care about
+ let didFile = false
+ const file = done => {
+ t.equal(didFile, false, 'only call file once')
+ didFile = true
+ t.equal(didLink, false, 'do file before link')
+ setTimeout(done)
+ }
+
+ let didLink = false
+ const link = done => {
+ t.equal(didLink, false, 'only call once')
+ t.equal(didFile, true, 'do file before link')
+ didLink = true
+ // make sure this one is super duper cleared lol
+ // the subsequent calls are no-ops, but verify as much
+ done()
+ done()
+ done()
+ }
+
+ let didDir = false
+ const dir = done => {
+ t.equal(didDir, false, 'only do dir once')
+ t.equal(didLink, true, 'do link before dir')
+ didDir = true
+ done()
+ }
+
+ let didDir2 = false
+ const dir2 = done => {
+ t.equal(didDir, true, 'did dir before dir2')
+ t.equal(didDir2, false, 'only do dir2 once')
+ didDir2 = true
+ done()
+ }
+
+ let didDir3 = false
+ const dir3 = done => {
+ t.equal(didDir2, true, 'did dir2 before dir3')
+ t.equal(didDir3, false, 'only do dir3 once')
+ didDir3 = true
+ done()
+ t.end()
+ }
+
+ t.ok(reserve(['a/b/c/d'], file), 'file starts right away')
+ t.notOk(reserve(['a/B/c////D', 'a/b/e'], link), 'link waits')
+ t.notOk(reserve(['a/b/e/f'], dir), 'dir waits')
+ t.notOk(reserve(['a/b'], dir2), 'dir2 waits')
+ t.notOk(reserve(['a/b/x'], dir3), 'dir3 waits')
+})
+
+t.test('unicode shenanigans', t => {
+ const e1 = Buffer.from([0xc3, 0xa9])
+ const e2 = Buffer.from([0x65, 0xcc, 0x81])
+ let didCafe1 = false
+ const cafe1 = done => {
+ t.equal(didCafe1, false, 'did cafe1 only once')
+ t.equal(didCafe2, false, 'did cafe1 before cafe2')
+ didCafe1 = true
+ setTimeout(done)
+ }
+ let didCafe2 = false
+ const cafe2 = done => {
+ t.equal(didCafe1, true, 'did cafe1 before cafe2')
+ t.equal(didCafe2, false, 'did cafe2 only once')
+ didCafe2 = true
+ done()
+ t.end()
+ }
+ const cafePath1 = `c/a/f/${e1}`
+ const cafePath2 = `c/a/f/${e2}`
+ t.ok(reserve([cafePath1], cafe1))
+ t.notOk(reserve([cafePath2], cafe2))
+})
+
+t.test('absolute paths and trailing slash', t => {
+ let calledA1 = false
+ let calledA2 = false
+ const a1 = done => {
+ t.equal(calledA1, false, 'called a1 only once')
+ t.equal(calledA2, false, 'called a1 before 2')
+ calledA1 = true
+ setTimeout(done)
+ }
+ const a2 = done => {
+ t.equal(calledA1, true, 'called a1 before 2')
+ t.equal(calledA2, false, 'called a2 only once')
+ calledA2 = true
+ done()
+ if (calledR2)
+ t.end()
+ }
+ let calledR1 = false
+ let calledR2 = false
+ const r1 = done => {
+ t.equal(calledR1, false, 'called r1 only once')
+ t.equal(calledR2, false, 'called r1 before 2')
+ calledR1 = true
+ setTimeout(done)
+ }
+ const r2 = done => {
+ t.equal(calledR1, true, 'called r1 before 2')
+ t.equal(calledR2, false, 'called r1 only once')
+ calledR2 = true
+ done()
+ if (calledA2)
+ t.end()
+ }
+ t.ok(reserve(['/p/a/t/h'], a1))
+ t.notOk(reserve(['/p/a/t/h/'], a2))
+ t.ok(reserve(['p/a/t/h'], r1))
+ t.notOk(reserve(['p/a/t/h/'], r2))
+})
+
+t.test('on windows, everything collides with everything', t => {
+ const reserve = winReserve
+ let called1 = false
+ let called2 = false
+ const f1 = done => {
+ t.equal(called1, false, 'only call 1 once')
+ t.equal(called2, false, 'call 1 before 2')
+ called1 = true
+ setTimeout(done)
+ }
+ const f2 = done => {
+ t.equal(called1, true, 'call 1 before 2')
+ t.equal(called2, false, 'only call 2 once')
+ called2 = true
+ done()
+ t.end()
+ }
+ t.equal(reserve(['some/path'], f1), true)
+ t.equal(reserve(['other/path'], f2), false)
+})
diff --git a/test/read-entry.js b/test/read-entry.js
index e0feb7ed..40662ea4 100644
--- a/test/read-entry.js
+++ b/test/read-entry.js
@@ -6,7 +6,7 @@ const Header = require('../lib/header.js')
t.test('create read entry', t => {
const h = new Header({
- path: 'foo.txt',
+ path: 'oof.txt',
mode: 0o755,
uid: 24561,
gid: 20,
@@ -20,17 +20,17 @@ t.test('create read entry', t => {
})
h.encode()
- const entry = new ReadEntry(h, { x: 'y' }, { z: 0, a: null, b: undefined })
+ const entry = new ReadEntry(h, { x: 'y', path: 'foo.txt' }, { z: 0, a: null, b: undefined })
t.ok(entry.header.cksumValid, 'header checksum should be valid')
t.match(entry, {
- extended: { x: 'y' },
+ extended: { x: 'y', path: 'foo.txt' },
globalExtended: { z: 0, a: null, b: undefined },
header: {
cksumValid: true,
needPax: false,
- path: 'foo.txt',
+ path: 'oof.txt',
mode: 0o755,
uid: 24561,
gid: 20,
diff --git a/test/replace.js b/test/replace.js
index b6821582..1ce30d46 100644
--- a/test/replace.js
+++ b/test/replace.js
@@ -4,59 +4,29 @@ const t = require('tap')
const r = require('../lib/replace.js')
const path = require('path')
const fs = require('fs')
-const mkdirp = require('mkdirp')
-const rimraf = require('rimraf')
const mutateFS = require('mutate-fs')
const list = require('../lib/list.js')
+const {resolve} = require('path')
const fixtures = path.resolve(__dirname, 'fixtures')
-const dir = path.resolve(fixtures, 'replace')
const tars = path.resolve(fixtures, 'tars')
-const file = dir + '/body-byte-counts.tar'
-const fileNoNulls = dir + '/no-null-eof.tar'
-const fileTruncHead = dir + '/truncated-head.tar'
-const fileTruncBody = dir + '/truncated-body.tar'
-const fileNonExistent = dir + '/does-not-exist.tar'
-const fileZeroByte = dir + '/zero.tar'
-const fileEmpty = dir + '/empty.tar'
-const fileCompressed = dir + '/compressed.tgz'
const zlib = require('zlib')
const spawn = require('child_process').spawn
-t.teardown(_ => rimraf.sync(dir))
-
-const reset = cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- const data = fs.readFileSync(tars + '/body-byte-counts.tar')
- fs.writeFileSync(file, data)
-
- const dataNoNulls = data.slice(0, data.length - 1024)
- fs.writeFileSync(fileNoNulls, dataNoNulls)
-
- const dataTruncHead = Buffer.concat([dataNoNulls, data.slice(0, 500)])
- fs.writeFileSync(fileTruncHead, dataTruncHead)
-
- const dataTruncBody = Buffer.concat([dataNoNulls, data.slice(0, 700)])
- fs.writeFileSync(fileTruncBody, dataTruncBody)
-
- fs.writeFileSync(fileZeroByte, '')
- fs.writeFileSync(fileEmpty, Buffer.alloc(1024))
-
- fs.writeFileSync(fileCompressed, zlib.gzipSync(data))
-
- if (cb)
- cb()
+const data = fs.readFileSync(tars + '/body-byte-counts.tar')
+const dataNoNulls = data.slice(0, data.length - 1024)
+const fixtureDef = {
+ 'body-byte-counts.tar': data,
+ 'no-null-eof.tar': dataNoNulls,
+ 'truncated-head.tar': Buffer.concat([dataNoNulls, data.slice(0, 500)]),
+ 'truncated-body.tar': Buffer.concat([dataNoNulls, data.slice(0, 700)]),
+ 'zero.tar': Buffer.from(''),
+ 'empty.tar': Buffer.alloc(512),
+ 'compressed.tgz': zlib.gzipSync(data),
}
-t.test('setup', t => {
- reset(t.end)
-})
-
t.test('basic file add to archive (good or truncated)', t => {
- t.beforeEach(reset)
-
const check = (file, t) => {
const c = spawn('tar', ['tf', file], { stdio: [ 0, 'pipe', 2 ] })
const out = []
@@ -64,7 +34,7 @@ t.test('basic file add to archive (good or truncated)', t => {
c.on('close', (code, signal) => {
t.equal(code, 0)
t.equal(signal, null)
- const actual = Buffer.concat(out).toString().trim().split('\n')
+ const actual = Buffer.concat(out).toString().trim().split(/\r?\n/)
t.same(actual, [
'1024-bytes.txt',
'512-bytes.txt',
@@ -76,50 +46,68 @@ t.test('basic file add to archive (good or truncated)', t => {
})
}
- ;[file,
- fileNoNulls,
- fileTruncHead,
- fileTruncBody
- ].forEach(file => {
- const fileList = [ path.basename(__filename) ]
- t.test(path.basename(file), t => {
- t.test('sync', t => {
+ const files = [
+ 'body-byte-counts.tar',
+ 'no-null-eof.tar',
+ 'truncated-head.tar',
+ 'truncated-body.tar',
+ ]
+ const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => {
+ s[k] = v
+ return s
+ }, {})
+ const fileList = [path.basename(__filename)]
+ t.test('sync', t => {
+ t.plan(files.length)
+ const dir = t.testdir(td)
+ for (const file of files) {
+ t.test(file, t => {
r({
sync: true,
- file: file,
- cwd: __dirname
+ file: resolve(dir, file),
+ cwd: __dirname,
}, fileList)
- check(file, t)
+ check(resolve(dir, file), t)
})
+ }
+ })
- t.test('async cb', t => {
+ t.test('async cb', t => {
+ t.plan(files.length)
+ const dir = t.testdir(td)
+ for (const file of files) {
+ t.test(file, t => {
r({
- file: file,
- cwd: __dirname
+ file: resolve(dir, file),
+ cwd: __dirname,
}, fileList, er => {
if (er)
throw er
- check(file, t)
+ check(resolve(dir, file), t)
})
})
+ }
+ })
- t.test('async promise', t => {
+ t.test('async', t => {
+ t.plan(files.length)
+ const dir = t.testdir(td)
+ for (const file of files) {
+ t.test(file, t => {
r({
- file: file,
- cwd: __dirname
- }, fileList).then(_ => check(file, t))
+ file: resolve(dir, file),
+ cwd: __dirname,
+ }, fileList).then(() => {
+ check(resolve(dir, file), t)
+ })
})
-
- t.end()
- })
+ }
})
t.end()
})
t.test('add to empty archive', t => {
- t.beforeEach(reset)
-
const check = (file, t) => {
const c = spawn('tar', ['tf', file])
const out = []
@@ -135,70 +123,91 @@ t.test('add to empty archive', t => {
})
}
- ;[fileNonExistent,
- fileEmpty,
- fileZeroByte
- ].forEach(file => {
- t.test(path.basename(file), t => {
- t.test('sync', t => {
+ const files = [
+ 'empty.tar',
+ 'zero.tar',
+ ]
+ const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => {
+ s[k] = v
+ return s
+ }, {})
+ files.push('not-existing.tar')
+
+ t.test('sync', t => {
+ const dir = t.testdir(td)
+ t.plan(files.length)
+ for (const file of files) {
+ t.test(file, t => {
r({
sync: true,
- file: file,
- cwd: __dirname
+ file: resolve(dir, file),
+ cwd: __dirname,
}, [path.basename(__filename)])
- check(file, t)
+ check(resolve(dir, file), t)
})
+ }
+ })
- t.test('async cb', t => {
+ t.test('async cb', t => {
+ const dir = t.testdir(td)
+ t.plan(files.length)
+ for (const file of files) {
+ t.test(file, t => {
r({
- file: file,
- cwd: __dirname
+ file: resolve(dir, file),
+ cwd: __dirname,
}, [path.basename(__filename)], er => {
if (er)
throw er
- check(file, t)
+ check(resolve(dir, file), t)
})
})
+ }
+ })
- t.test('async promise', t => {
+ t.test('async', async t => {
+ const dir = t.testdir(td)
+ t.plan(files.length)
+ for (const file of files) {
+ t.test(file, t => {
r({
- file: file,
- cwd: __dirname
- }, [path.basename(__filename)]).then(_ => check(file, t))
+ file: resolve(dir, file),
+ cwd: __dirname,
+ }, [path.basename(__filename)]).then(() => {
+ check(resolve(dir, file), t)
+ })
})
-
- t.end()
- })
+ }
})
t.end()
})
-t.test('cannot append to gzipped archives', t => {
- reset()
+t.test('cannot append to gzipped archives', async t => {
+ const dir = t.testdir({
+ 'compressed.tgz': fixtureDef['compressed.tgz'],
+ })
+ const file = resolve(dir, 'compressed.tgz')
const expect = new Error('cannot append to compressed archives')
const expectT = new TypeError('cannot append to compressed archives')
t.throws(_ => r({
- file: fileCompressed,
+ file,
cwd: __dirname,
gzip: true
}, [path.basename(__filename)]), expectT)
t.throws(_ => r({
- file: fileCompressed,
+ file,
cwd: __dirname,
sync: true
}, [path.basename(__filename)]), expect)
- r({
- file: fileCompressed,
+ return r({
+ file,
cwd: __dirname,
- }, [path.basename(__filename)], er => {
- t.match(er, expect)
- t.end()
- })
+ }, [path.basename(__filename)], er => t.match(er, expect))
})
t.test('other throws', t => {
@@ -209,37 +218,61 @@ t.test('other throws', t => {
})
t.test('broken open', t => {
+ const dir = t.testdir({
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ })
+ const file = resolve(dir, 'body-byte-counts.tar')
const poop = new Error('poop')
t.teardown(mutateFS.fail('open', poop))
- t.throws(_ => r({ sync: true, file: file }, ['README.md']), poop)
- r({ file: file }, ['README.md'], er => {
+ t.throws(_ => r({ sync: true, file }, ['README.md']), poop)
+ r({ file }, ['README.md'], er => {
t.match(er, poop)
t.end()
})
})
t.test('broken fstat', t => {
+ const td = {
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ }
const poop = new Error('poop')
- t.teardown(mutateFS.fail('fstat', poop))
- t.throws(_ => r({ sync: true, file: file }, ['README.md']), poop)
- r({ file: file }, ['README.md'], er => {
- t.match(er, poop)
+ t.test('sync', t => {
+ const dir = t.testdir(td)
+ const file = resolve(dir, 'body-byte-counts.tar')
+ t.teardown(mutateFS.fail('fstat', poop))
+ t.throws(_ => r({ sync: true, file }, ['README.md']), poop)
t.end()
})
+ t.test('async', t => {
+ const dir = t.testdir(td)
+ const file = resolve(dir, 'body-byte-counts.tar')
+ t.teardown(mutateFS.fail('fstat', poop))
+ r({ file }, ['README.md'], async er => {
+ t.match(er, poop)
+ t.end()
+ })
+ })
+ t.end()
})
t.test('broken read', t => {
+ const dir = t.testdir({
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ })
+ const file = resolve(dir, 'body-byte-counts.tar')
const poop = new Error('poop')
t.teardown(mutateFS.fail('read', poop))
- t.throws(_ => r({ sync: true, file: file }, ['README.md']), poop)
- r({ file: file }, ['README.md'], er => {
+ t.throws(_ => r({ sync: true, file }, ['README.md']), poop)
+ r({ file }, ['README.md'], er => {
t.match(er, poop)
t.end()
})
})
-t.test('mtime cache', t => {
- t.beforeEach(reset)
+t.test('mtime cache', async t => {
+ const td = {
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ }
let mtimeCache
@@ -250,7 +283,7 @@ t.test('mtime cache', t => {
c.on('close', (code, signal) => {
t.equal(code, 0)
t.equal(signal, null)
- const actual = Buffer.concat(out).toString().trim().split('\n')
+ const actual = Buffer.concat(out).toString().trim().split(/\r?\n/)
t.same(actual, [
'1024-bytes.txt',
'512-bytes.txt',
@@ -271,9 +304,11 @@ t.test('mtime cache', t => {
}
t.test('sync', t => {
+ const dir = t.testdir(td)
+ const file = resolve(dir, 'body-byte-counts.tar')
r({
sync: true,
- file: file,
+ file,
cwd: __dirname,
mtimeCache: mtimeCache = new Map()
}, [path.basename(__filename)])
@@ -281,8 +316,10 @@ t.test('mtime cache', t => {
})
t.test('async cb', t => {
+ const dir = t.testdir(td)
+ const file = resolve(dir, 'body-byte-counts.tar')
r({
- file: file,
+ file,
cwd: __dirname,
mtimeCache: mtimeCache = new Map()
}, [path.basename(__filename)], er => {
@@ -293,8 +330,10 @@ t.test('mtime cache', t => {
})
t.test('async promise', t => {
+ const dir = t.testdir(td)
+ const file = resolve(dir, 'body-byte-counts.tar')
r({
- file: file,
+ file,
cwd: __dirname,
mtimeCache: mtimeCache = new Map()
}, [path.basename(__filename)]).then(_ => check(file, t))
@@ -304,40 +343,58 @@ t.test('mtime cache', t => {
})
t.test('create tarball out of another tarball', t => {
- const out = path.resolve(dir, 'out.tar')
-
- t.beforeEach(cb => {
- fs.writeFile(out, fs.readFileSync(path.resolve(tars, 'dir.tar')), cb)
- })
+ const td = {
+ 'out.tar': fs.readFileSync(path.resolve(tars, 'dir.tar')),
+ }
- const check = t => {
+ const check = (out, t) => {
const expect = [
'dir/',
'Ω.txt',
'🌟.txt',
'long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt'
]
- list({ f: out, sync: true, onentry: entry => {
- t.equal(entry.path, expect.shift())
- }})
+ list({
+ f: out,
+ sync: true,
+ onentry: entry => {
+ t.equal(entry.path, expect.shift())
+ }})
t.same(expect, [])
t.end()
}
t.test('sync', t => {
+ const dir = t.testdir(td)
+ const out = resolve(dir, 'out.tar')
r({
f: out,
cwd: tars,
sync: true
}, ['@utf8.tar'])
- check(t)
+ check(out, t)
+ })
+
+ t.test('async cb', t => {
+ const dir = t.testdir(td)
+ const out = resolve(dir, 'out.tar')
+ r({
+ f: out,
+ cwd: tars,
+ }, ['@utf8.tar'], er => {
+ if (er)
+ throw er
+ check(out, t)
+ })
})
t.test('async', t => {
+ const dir = t.testdir(td)
+ const out = resolve(dir, 'out.tar')
r({
f: out,
- cwd: tars
- }, ['@utf8.tar'], _ => check(t))
+ cwd: tars,
+ }, ['@utf8.tar']).then(() => check(out, t))
})
t.end()
diff --git a/test/strip-absolute-path.js b/test/strip-absolute-path.js
new file mode 100644
index 00000000..c50e2858
--- /dev/null
+++ b/test/strip-absolute-path.js
@@ -0,0 +1,52 @@
+const t = require('tap')
+const stripAbsolutePath = require('../lib/strip-absolute-path.js')
+const cwd = process.cwd()
+const requireInject = require('require-inject')
+
+t.test('basic', t => {
+ const cases = {
+ '/': ['/', ''],
+ '////': ['////', ''],
+ 'c:///a/b/c': ['c:///', 'a/b/c'],
+ '\\\\foo\\bar\\baz': ['\\\\foo\\bar\\', 'baz'],
+ '//foo//bar//baz': ['//', 'foo//bar//baz'],
+ 'c:\\c:\\c:\\c:\\\\d:\\e/f/g': ['c:\\c:\\c:\\c:\\\\d:\\', 'e/f/g'],
+ }
+
+ for (const [input, [root, stripped]] of Object.entries(cases))
+ t.strictSame(stripAbsolutePath(input, cwd), [root, stripped], input)
+ t.end()
+})
+
+t.test('drive-local paths', t => {
+ const env = process.env
+ t.teardown(() => process.env = env)
+ const cwd = 'D:\\safety\\land'
+ const realPath = require('path')
+ // be windowsy
+ const path = {
+ ...realPath.win32,
+ win32: realPath.win32,
+ posix: realPath.posix,
+ }
+ const stripAbsolutePath = requireInject('../lib/strip-absolute-path.js', { path })
+ const cases = {
+ '/': ['/', ''],
+ '////': ['////', ''],
+ 'c:///a/b/c': ['c:///', 'a/b/c'],
+ '\\\\foo\\bar\\baz': ['\\\\foo\\bar\\', 'baz'],
+ '//foo//bar//baz': ['//', 'foo//bar//baz'],
+ 'c:\\c:\\c:\\c:\\\\d:\\e/f/g': ['c:\\c:\\c:\\c:\\\\d:\\', 'e/f/g'],
+ 'c:..\\system\\explorer.exe': ['c:', '..\\system\\explorer.exe'],
+ 'd:..\\..\\unsafe\\land': ['d:', '..\\..\\unsafe\\land'],
+ 'c:foo': ['c:', 'foo'],
+ 'D:mark': ['D:', 'mark'],
+ '//?/X:/y/z': ['//?/X:/', 'y/z'],
+ '\\\\?\\X:\\y\\z': ['\\\\?\\X:\\', 'y\\z'],
+ }
+ for (const [input, [root, stripped]] of Object.entries(cases)) {
+ if (!t.strictSame(stripAbsolutePath(input, cwd), [root, stripped], input))
+ break
+ }
+ t.end()
+})
diff --git a/test/strip-trailing-slashes.js b/test/strip-trailing-slashes.js
new file mode 100644
index 00000000..198797bf
--- /dev/null
+++ b/test/strip-trailing-slashes.js
@@ -0,0 +1,7 @@
+const t = require('tap')
+const stripSlash = require('../lib/strip-trailing-slashes.js')
+const short = '///a///b///c///'
+const long = short.repeat(10) + '/'.repeat(1000000)
+
+t.equal(stripSlash(short), '///a///b///c')
+t.equal(stripSlash(long), short.repeat(9) + '///a///b///c')
diff --git a/test/unpack.js b/test/unpack.js
index 33a9d2f6..bc1cc270 100644
--- a/test/unpack.js
+++ b/test/unpack.js
@@ -17,22 +17,31 @@ const files = path.resolve(fixtures, 'files')
const tars = path.resolve(fixtures, 'tars')
const parses = path.resolve(fixtures, 'parse')
const unpackdir = path.resolve(fixtures, 'unpack')
-const rimraf = require('rimraf')
-const mkdirp = require('mkdirp')
+const {promisify} = require('util')
+const rimraf = promisify(require('rimraf'))
+const mkdirp = promisify(require('mkdirp'))
const mutateFS = require('mutate-fs')
const eos = require('end-of-stream')
+const normPath = require('../lib/normalize-windows-path.js')
+const requireInject = require('require-inject')
-t.teardown(_ => rimraf.sync(unpackdir))
+// On Windows in particular, the "really deep folder path" file
+// often tends to cause problems, which don't indicate a failure
+// of this library, it's just what happens on Windows with super
+// long file paths.
+const isWindows = process.platform === 'win32'
+const isLongFile = f => f.match(/r.e.a.l.l.y.-.d.e.e.p.-.f.o.l.d.e.r.-.p.a.t.h/)
-t.test('setup', t => {
- rimraf.sync(unpackdir)
- mkdirp.sync(unpackdir)
- t.end()
+t.teardown(_ => rimraf(unpackdir))
+
+t.test('setup', async () => {
+ await rimraf(unpackdir)
+ await mkdirp(unpackdir)
})
t.test('basic file unpack tests', t => {
const basedir = path.resolve(unpackdir, 'basic')
- t.teardown(_ => rimraf.sync(basedir))
+ t.teardown(_ => rimraf(basedir))
const cases = {
'emptypax.tar': {
@@ -79,16 +88,20 @@ t.test('basic file unpack tests', t => {
t.test(tarfile, t => {
const tf = path.resolve(tars, tarfile)
const dir = path.resolve(basedir, tarfile)
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ const linkdir = path.resolve(basedir, tarfile + '.link')
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await rimraf(linkdir)
+ await mkdirp(dir)
+ fs.symlinkSync(dir, linkdir, 'junction')
})
const check = t => {
const expect = cases[tarfile]
Object.keys(expect).forEach(file => {
const f = path.resolve(dir, file)
+ if (isWindows && isLongFile(file))
+ return
t.equal(fs.readFileSync(f, 'utf8'), expect[file], file)
})
t.end()
@@ -99,12 +112,12 @@ t.test('basic file unpack tests', t => {
t.test('async unpack', t => {
t.plan(2)
t.test('strict', t => {
- const unpack = new Unpack({ cwd: dir, strict: true })
+ const unpack = new Unpack({ cwd: linkdir, strict: true })
fs.createReadStream(tf).pipe(unpack)
eos(unpack, _ => check(t))
})
t.test('loose', t => {
- const unpack = new Unpack({ cwd: dir })
+ const unpack = new Unpack({ cwd: linkdir })
fs.createReadStream(tf).pipe(unpack)
eos(unpack, _ => check(t))
})
@@ -113,12 +126,12 @@ t.test('basic file unpack tests', t => {
t.test('sync unpack', t => {
t.plan(2)
t.test('strict', t => {
- const unpack = new UnpackSync({ cwd: dir })
+ const unpack = new UnpackSync({ cwd: linkdir })
unpack.end(fs.readFileSync(tf))
check(t)
})
t.test('loose', t => {
- const unpack = new UnpackSync({ cwd: dir })
+ const unpack = new UnpackSync({ cwd: linkdir })
unpack.end(fs.readFileSync(tf))
check(t)
})
@@ -130,7 +143,7 @@ t.test('basic file unpack tests', t => {
t.test('cwd default to process cwd', t => {
const u = new Unpack()
const us = new UnpackSync()
- const cwd = process.cwd()
+ const cwd = normPath(process.cwd())
t.equal(u.cwd, cwd)
t.equal(us.cwd, cwd)
t.end()
@@ -142,8 +155,8 @@ t.test('links!', t => {
const stripData = fs.readFileSync(tars + '/links-strip.tar')
t.plan(6)
- t.beforeEach(cb => mkdirp(dir, cb))
- t.afterEach(cb => rimraf(dir, cb))
+ t.beforeEach(() => mkdirp(dir))
+ t.afterEach(() => rimraf(dir))
const check = t => {
const hl1 = fs.lstatSync(dir + '/hardlink-1')
@@ -152,9 +165,12 @@ t.test('links!', t => {
t.equal(hl1.ino, hl2.ino)
t.equal(hl1.nlink, 2)
t.equal(hl2.nlink, 2)
- const sym = fs.lstatSync(dir + '/symlink')
- t.ok(sym.isSymbolicLink())
- t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2')
+ if (!isWindows) {
+ // doesn't work on win32 without special privs
+ const sym = fs.lstatSync(dir + '/symlink')
+ t.ok(sym.isSymbolicLink())
+ t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2')
+ }
t.end()
}
const checkForStrip = t => {
@@ -167,21 +183,16 @@ t.test('links!', t => {
t.equal(hl1.ino, hl3.ino)
t.equal(hl1.nlink, 3)
t.equal(hl2.nlink, 3)
- const sym = fs.lstatSync(dir + '/symlink')
- t.ok(sym.isSymbolicLink())
- t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2')
+ if (!isWindows) {
+ const sym = fs.lstatSync(dir + '/symlink')
+ t.ok(sym.isSymbolicLink())
+ t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2')
+ }
t.end()
}
const checkForStrip3 = t => {
- t.ok(fs.lstatSync(dir + '/3').isDirectory())
- let err = null
- try {
- fs.lstatSync(dir + '/3/hardlink-3')
- } catch(e) {
- err = e
- }
- // can't be extracted because we've passed it in the tar (specially crafted tar for this not to work)
- t.equal(err.code, 'ENOENT')
+ // strips the linkpath entirely, so the link doesn't get extracted.
+ t.throws(() => fs.lstatSync(dir + '/3'), { code: 'ENOENT' })
t.end()
}
@@ -202,7 +213,7 @@ t.test('links!', t => {
t.test('sync strip', t => {
const unpack = new UnpackSync({ cwd: dir, strip: 1 })
- unpack.end(fs.readFileSync(tars + '/links-strip.tar'))
+ unpack.end(stripData)
checkForStrip(t)
})
@@ -237,7 +248,7 @@ t.test('links without cleanup (exercise clobbering code)', t => {
t.plan(6)
mkdirp.sync(dir)
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
t.beforeEach(cb => {
// clobber this junk
@@ -256,9 +267,11 @@ t.test('links without cleanup (exercise clobbering code)', t => {
t.equal(hl1.ino, hl2.ino)
t.equal(hl1.nlink, 2)
t.equal(hl2.nlink, 2)
- const sym = fs.lstatSync(dir + '/symlink')
- t.ok(sym.isSymbolicLink())
- t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2')
+ if (!isWindows) {
+ const sym = fs.lstatSync(dir + '/symlink')
+ t.ok(sym.isSymbolicLink())
+ t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2')
+ }
t.end()
}
@@ -306,7 +319,7 @@ t.test('links without cleanup (exercise clobbering code)', t => {
t.test('nested dir dupe', t => {
const dir = path.resolve(unpackdir, 'nested-dir')
mkdirp.sync(dir + '/d/e/e/p')
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const expect = {
'd/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/a.txt': 'short\n',
'd/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc': 'cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
@@ -335,14 +348,15 @@ t.test('nested dir dupe', t => {
zip.end(data)
})
-t.test('symlink in dir path', t => {
+t.test('symlink in dir path', {
+ skip: isWindows && 'symlinks not fully supported',
+}, t => {
const dir = path.resolve(unpackdir, 'symlink-junk')
- t.teardown(_ => rimraf.sync(dir))
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.teardown(_ => rimraf(dir))
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
const data = makeTar([
@@ -396,18 +410,22 @@ t.test('symlink in dir path', t => {
const warnings = []
const u = new Unpack({ cwd: dir, onwarn: (w,d) => warnings.push([w,d]) })
u.on('close', _ => {
- t.equal(fs.lstatSync(dir + '/d/i').mode & 0o7777, 0o755)
- t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, 0o751)
+ t.equal(fs.lstatSync(dir + '/d/i').mode & 0o7777, isWindows ? 0o666 : 0o755)
+ t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, isWindows ? 0o666 : 0o751)
t.ok(fs.lstatSync(dir + '/d/i/r/file').isFile(), 'got file')
- t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink')
- t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x'))
+ if (!isWindows) {
+ t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink')
+ t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x'))
+ }
+ if (!isWindows) {
+ t.equal(warnings[0][0], 'Cannot extract through symbolic link')
+ t.match(warnings[0][1], {
+ name: 'SylinkError',
+ path: dir + '/d/i/r/symlink/',
+ symlink: dir + '/d/i/r/symlink',
+ })
+ }
t.equal(warnings.length, 1)
- t.equal(warnings[0][0], 'Cannot extract through symbolic link')
- t.match(warnings[0][1], {
- name: 'SylinkError',
- path: dir + '/d/i/r/symlink/',
- symlink: dir + '/d/i/r/symlink'
- })
t.end()
})
u.end(data)
@@ -420,10 +438,12 @@ t.test('symlink in dir path', t => {
onwarn: (w,d) => warnings.push([w,d])
})
u.end(data)
- t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, 0o751)
+ t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, isWindows ? 0o666 : 0o751)
t.ok(fs.lstatSync(dir + '/d/i/r/file').isFile(), 'got file')
- t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink')
- t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x'))
+ if (!isWindows) {
+ t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink')
+ t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x'))
+ }
t.equal(warnings.length, 1)
t.equal(warnings[0][0], 'Cannot extract through symbolic link')
t.match(warnings[0][1], {
@@ -583,7 +603,7 @@ t.test('symlink in dir path', t => {
t.test('unsupported entries', t => {
const dir = path.resolve(unpackdir, 'unsupported-entries')
mkdirp.sync(dir)
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const unknown = new Header({ path: 'qux', type: 'File', size: 4 })
unknown.type = 'Z'
unknown.encode()
@@ -660,11 +680,10 @@ t.test('unsupported entries', t => {
t.test('file in dir path', t => {
const dir = path.resolve(unpackdir, 'file-junk')
- t.teardown(_ => rimraf.sync(dir))
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.teardown(_ => rimraf(dir))
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
const data = makeTar([
@@ -734,7 +753,7 @@ t.test('file in dir path', t => {
t.test('set umask option', t => {
const dir = path.resolve(unpackdir, 'umask')
mkdirp.sync(dir)
- t.tearDown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const data = makeTar([
{
@@ -750,22 +769,24 @@ t.test('set umask option', t => {
umask: 0o027,
cwd: dir
}).on('close', _ => {
- t.equal(fs.statSync(dir + '/d/i/r').mode & 0o7777, 0o750)
- t.equal(fs.statSync(dir + '/d/i/r/dir').mode & 0o7777, 0o751)
+ t.equal(fs.statSync(dir + '/d/i/r').mode & 0o7777, isWindows ? 0o666 : 0o750)
+ t.equal(fs.statSync(dir + '/d/i/r/dir').mode & 0o7777, isWindows ? 0o666 : 0o751)
t.end()
}).end(data)
})
t.test('absolute paths', t => {
const dir = path.join(unpackdir, 'absolute-paths')
- t.teardown(_ => rimraf.sync(dir))
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.teardown(_ => rimraf(dir))
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
const absolute = path.resolve(dir, 'd/i/r/absolute')
+ const root = path.parse(absolute).root
+ const extraAbsolute = root + root + root + absolute
+ t.ok(path.isAbsolute(extraAbsolute))
t.ok(path.isAbsolute(absolute))
const parsed = path.parse(absolute)
const relative = absolute.substr(parsed.root.length)
@@ -773,7 +794,7 @@ t.test('absolute paths', t => {
const data = makeTar([
{
- path: absolute,
+ path: extraAbsolute,
type: 'File',
size: 1,
atime: new Date('1979-07-01T19:10:00.000Z'),
@@ -787,9 +808,10 @@ t.test('absolute paths', t => {
t.test('warn and correct', t => {
const check = t => {
- t.same(warnings, [[
- 'stripping / from absolute path',
- absolute
+ const r = normPath(root)
+ t.match(warnings, [[
+ `stripping ${r}${r}${r}${r} from absolute path`,
+ normPath(absolute),
]])
t.ok(fs.lstatSync(path.resolve(dir, relative)).isFile(), 'is file')
t.end()
@@ -818,6 +840,22 @@ t.test('absolute paths', t => {
})
t.test('preserve absolute path', t => {
+ // if we use the extraAbsolute path here, we end up creating a dir
+ // like C:\C:\C:\C:\path\to\absolute, which is both 100% valid on
+ // windows, as well as SUUUUUPER annoying.
+ const data = makeTar([
+ {
+ path: isWindows ? absolute : extraAbsolute,
+ type: 'File',
+ size: 1,
+ atime: new Date('1979-07-01T19:10:00.000Z'),
+ ctime: new Date('2011-03-27T22:16:31.000Z'),
+ mtime: new Date('2011-03-27T22:16:31.000Z'),
+ },
+ 'a',
+ '',
+ '',
+ ])
const check = t => {
t.same(warnings, [])
t.ok(fs.lstatSync(absolute).isFile(), 'is file')
@@ -853,11 +891,10 @@ t.test('absolute paths', t => {
t.test('.. paths', t => {
const dir = path.join(unpackdir, 'dotted-paths')
- t.teardown(_ => rimraf.sync(dir))
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.teardown(_ => rimraf(dir))
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
const fmode = 0o755
@@ -916,7 +953,7 @@ t.test('.. paths', t => {
const check = t => {
t.same(warnings, [])
t.ok(fs.lstatSync(resolved).isFile(), 'is file')
- t.equal(fs.lstatSync(resolved).mode & 0o777, fmode, 'mode is 0755')
+ t.equal(fs.lstatSync(resolved).mode & 0o777, isWindows ? 0o666 : fmode)
t.end()
}
@@ -952,20 +989,46 @@ t.test('.. paths', t => {
t.test('fail all stats', t => {
const poop = new Error('poop')
poop.code = 'EPOOP'
- let unmutate
- const dir = path.join(unpackdir, 'stat-fail')
+ const dir = normPath(path.join(unpackdir, 'stat-fail'))
+ const {
+ stat,
+ fstat,
+ lstat,
+ statSync,
+ fstatSync,
+ lstatSync,
+ } = fs
+ const unmutate = () => Object.assign(fs, {
+ stat,
+ fstat,
+ lstat,
+ statSync,
+ fstatSync,
+ lstatSync,
+ })
+ const mutate = () => {
+ fs.stat = fs.lstat = fs.fstat = (...args) => {
+ // don't fail statting the cwd, or we get different errors
+ if (normPath(args[0]) === dir)
+ return lstat(dir, args.pop())
+ process.nextTick(() => args.pop()(poop))
+ }
+ fs.statSync = fs.lstatSync = fs.fstatSync = (...args) => {
+ if (normPath(args[0]) === dir)
+ return lstatSync(dir)
+ throw poop
+ }
+ }
const warnings = []
- t.beforeEach(cb => {
+ t.beforeEach(async () => {
warnings.length = 0
- mkdirp.sync(dir)
- unmutate = mutateFS.statFail(poop)
- cb()
+ await mkdirp(dir)
+ mutate()
})
- t.afterEach(cb => {
+ t.afterEach(async () => {
unmutate()
- rimraf.sync(dir)
- cb()
+ await rimraf(dir)
})
const data = makeTar([
@@ -1036,18 +1099,18 @@ t.test('fail all stats', t => {
String,
{
code: 'EISDIR',
- path: path.resolve(dir, 'd/i/r/file'),
- syscall: 'open'
- }
+ path: normPath(path.resolve(dir, 'd/i/r/file')),
+ syscall: 'open',
+ },
],
[
String,
{
- dest: path.resolve(dir, 'd/i/r/link'),
- path: path.resolve(dir, 'd/i/r/file'),
- syscall: 'link'
- }
- ]
+ dest: normPath(path.resolve(dir, 'd/i/r/link')),
+ path: normPath(path.resolve(dir, 'd/i/r/file')),
+ syscall: 'link',
+ },
+ ],
]
new UnpackSync({
cwd: dir,
@@ -1064,14 +1127,16 @@ t.test('fail symlink', t => {
poop.code = 'EPOOP'
const unmutate = mutateFS.fail('symlink', poop)
const dir = path.join(unpackdir, 'symlink-fail')
- t.teardown(_ => (unmutate(), rimraf.sync(dir)))
+ t.teardown(async _ => {
+ unmutate()
+ await rimraf(dir)
+ })
const warnings = []
- t.beforeEach(cb => {
+ t.beforeEach(async () => {
warnings.length = 0
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ await rimraf(dir)
+ await mkdirp(dir)
})
const data = makeTar([
@@ -1126,14 +1191,16 @@ t.test('fail chmod', t => {
poop.code = 'EPOOP'
const unmutate = mutateFS.fail('chmod', poop)
const dir = path.join(unpackdir, 'chmod-fail')
- t.teardown(_ => (unmutate(), rimraf.sync(dir)))
+ t.teardown(async _ => {
+ unmutate()
+ await rimraf(dir)
+ })
const warnings = []
- t.beforeEach(cb => {
+ t.beforeEach(async () => {
warnings.length = 0
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ await rimraf(dir)
+ await mkdirp(dir)
})
const data = makeTar([
@@ -1187,19 +1254,17 @@ t.test('fail mkdir', t => {
poop.code = 'EPOOP'
let unmutate
const dir = path.join(unpackdir, 'mkdir-fail')
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const warnings = []
- t.beforeEach(cb => {
+ t.beforeEach(async () => {
warnings.length = 0
- rimraf.sync(dir)
- mkdirp.sync(dir)
+ await rimraf(dir)
+ await mkdirp(dir)
unmutate = mutateFS.fail('mkdir', poop)
- cb()
})
- t.afterEach(cb => {
+ t.afterEach(async () => {
unmutate()
- cb()
})
const data = makeTar([
@@ -1215,15 +1280,14 @@ t.test('fail mkdir', t => {
''
])
- const expect = [ [
- 'ENOENT: no such file or directory, lstat \'' +
- path.resolve(dir, 'dir') + '\'',
+ const expect = [[
+ 'ENOENT: no such file or directory',
{
code: 'ENOENT',
syscall: 'lstat',
- path: path.resolve(dir, 'dir')
- }
- ] ]
+ path: normPath(path.resolve(dir, 'dir')),
+ },
+ ]]
const check = t => {
t.match(warnings, expect)
@@ -1231,13 +1295,6 @@ t.test('fail mkdir', t => {
t.end()
}
- t.test('async', t => {
- new Unpack({
- cwd: dir,
- onwarn: (w, d) => warnings.push([w, d])
- }).on('close', _ => check(t)).end(data)
- })
-
t.test('sync', t => {
new UnpackSync({
cwd: dir,
@@ -1246,6 +1303,13 @@ t.test('fail mkdir', t => {
check(t)
})
+ t.test('async', t => {
+ new Unpack({
+ cwd: dir,
+ onwarn: (w, d) => warnings.push([w, d]),
+ }).on('close', _ => check(t)).end(data)
+ })
+
t.end()
})
@@ -1254,14 +1318,16 @@ t.test('fail write', t => {
poop.code = 'EPOOP'
const unmutate = mutateFS.fail('write', poop)
const dir = path.join(unpackdir, 'write-fail')
- t.teardown(_ => (unmutate(), rimraf.sync(dir)))
+ t.teardown(async _ => {
+ unmutate()
+ await rimraf(dir)
+ })
const warnings = []
- t.beforeEach(cb => {
+ t.beforeEach(async () => {
warnings.length = 0
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ await rimraf(dir)
+ await mkdirp(dir)
})
const data = makeTar([
@@ -1305,15 +1371,14 @@ t.test('fail write', t => {
t.test('skip existing', t => {
const dir = path.join(unpackdir, 'skip-newer')
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const date = new Date('2011-03-27T22:16:31.000Z')
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
fs.writeFileSync(dir + '/x', 'y')
fs.utimesSync(dir + '/x', date, date)
- cb()
})
const data = makeTar([
@@ -1358,15 +1423,14 @@ t.test('skip existing', t => {
t.test('skip newer', t => {
const dir = path.join(unpackdir, 'skip-newer')
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const date = new Date('2013-12-19T17:00:00.000Z')
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
fs.writeFileSync(dir + '/x', 'y')
fs.utimesSync(dir + '/x', date, date)
- cb()
})
const data = makeTar([
@@ -1411,12 +1475,11 @@ t.test('skip newer', t => {
t.test('no mtime', t => {
const dir = path.join(unpackdir, 'skip-newer')
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
const date = new Date('2011-03-27T22:16:31.000Z')
@@ -1477,7 +1540,7 @@ t.test('no mtime', t => {
t.test('unpack big enough to pause/drain', t => {
const dir = path.resolve(unpackdir, 'drain-clog')
mkdirp.sync(dir)
- t.tearDown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const stream = fs.createReadStream(fixtures + '/parses.tar')
const u = new Unpack({
cwd: dir,
@@ -1600,11 +1663,16 @@ t.test('set owner', t => {
const unl = mutateFS.fail('lchown', poop)
const unf = mutateFS.fail('fchown', poop)
- t.teardown(_ => (un(), unf(), unl()))
+ t.teardown(async () => {
+ un()
+ unf()
+ unl()
+ await rimraf(dir)
+ })
t.test('sync', t => {
mkdirp.sync(dir)
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
let warned = false
const u = new Unpack.Sync({
cwd: dir,
@@ -1622,7 +1690,7 @@ t.test('set owner', t => {
t.test('async', t => {
mkdirp.sync(dir)
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
let warned = false
const u = new Unpack({
cwd: dir,
@@ -1638,11 +1706,6 @@ t.test('set owner', t => {
u.end(data)
})
- t.test('cleanup', t => {
- rimraf.sync(dir)
- t.end()
- })
-
t.end()
})
@@ -1666,7 +1729,7 @@ t.test('set owner', t => {
t.test('sync', t => {
mkdirp.sync(dir)
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
called = 0
const u = new Unpack.Sync({ cwd: dir, preserveOwner: true })
u.end(data)
@@ -1676,7 +1739,7 @@ t.test('set owner', t => {
t.test('async', t => {
mkdirp.sync(dir)
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
called = 0
const u = new Unpack({ cwd: dir, preserveOwner: true })
u.end(data)
@@ -1695,15 +1758,15 @@ t.test('set owner', t => {
const un = mutateFS.fail('chown', poop)
const unf = mutateFS.fail('fchown', poop)
const unl = mutateFS.fail('lchown', poop)
- t.teardown(_ => {
- rimraf.sync(dir)
+ t.teardown(async _ => {
un()
unf()
unl()
+ await rimraf(dir)
})
- t.beforeEach(cb => mkdirp(dir, cb))
- t.afterEach(cb => rimraf(dir, cb))
+ t.beforeEach(() => mkdirp(dir))
+ t.afterEach(() => rimraf(dir))
const check = t => {
const dirStat = fs.statSync(dir + '/foo')
@@ -1755,11 +1818,11 @@ t.test('unpack when dir is not writable', t => {
])
const dir = path.resolve(unpackdir, 'nowrite-dir')
- t.beforeEach(cb => mkdirp(dir, cb))
- t.afterEach(cb => rimraf(dir, cb))
+ t.beforeEach(() => mkdirp(dir))
+ t.afterEach(() => rimraf(dir))
const check = t => {
- t.equal(fs.statSync(dir + '/a').mode & 0o7777, 0o744)
+ t.equal(fs.statSync(dir + '/a').mode & 0o7777, isWindows ? 0o666 : 0o744)
t.equal(fs.readFileSync(dir + '/a/b', 'utf8'), 'a')
t.end()
}
@@ -1792,8 +1855,8 @@ t.test('transmute chars on windows', t => {
])
const dir = path.resolve(unpackdir, 'winchars')
- t.beforeEach(cb => mkdirp(dir, cb))
- t.afterEach(cb => rimraf(dir, cb))
+ t.beforeEach(() => mkdirp(dir))
+ t.afterEach(() => rimraf(dir))
const hex = 'ef80bcef81bcef80beef80bfef80ba2e747874'
const uglyName = Buffer.from(hex, 'hex').toString()
@@ -1828,8 +1891,17 @@ t.test('transmute chars on windows', t => {
t.test('safely transmute chars on windows with absolutes', t => {
// don't actually make the directory
- const poop = new Error('poop')
- t.teardown(mutateFS.fail('mkdir', poop))
+ const fsMock = {
+ ...fs,
+ mkdir: (path, mode, cb) => process.nextTick(cb),
+ mkdirSync: (path) => {},
+ }
+ const mkdirp = requireInject('mkdirp', { fs: fsMock })
+ const Unpack = requireInject('../lib/unpack.js', {
+ fs: fsMock,
+ mkdirp,
+ '../lib/mkdir.js': requireInject('../lib/mkdir.js', { fs: fsMock, mkdirp }),
+ })
const data = makeTar([
{
@@ -1852,8 +1924,11 @@ t.test('safely transmute chars on windows with absolutes', t => {
})
u.on('entry', entry => {
t.equal(entry.path, uglyPath)
+ entry.skipped = true
+ entry.resume()
t.end()
})
+ u.on('error', () => {})
u.end(data)
})
@@ -1873,10 +1948,10 @@ t.test('use explicit chmod when required by umask', t => {
''
])
- const check = t => {
+ const check = async t => {
const st = fs.statSync(basedir + '/x/y/z')
- t.equal(st.mode & 0o777, 0o775)
- rimraf.sync(basedir)
+ t.equal(st.mode & 0o777, isWindows ? 0o666 : 0o775)
+ await rimraf(basedir)
t.end()
}
@@ -1961,11 +2036,11 @@ t.test('chown implicit dirs and also the entries', t => {
''
])
- const check = t => {
+ const check = async t => {
currentTest = null
t.equal(chowns, 8)
chowns = 0
- rimraf.sync(basedir)
+ await rimraf(basedir)
t.end()
}
@@ -2015,7 +2090,7 @@ t.test('chown implicit dirs and also the entries', t => {
t.test('bad cwd setting', t => {
const basedir = path.resolve(unpackdir, 'bad-cwd')
mkdirp.sync(basedir)
- t.teardown(_ => rimraf.sync(basedir))
+ t.teardown(_ => rimraf(basedir))
const cases = [
// the cwd itself
@@ -2057,17 +2132,17 @@ t.test('bad cwd setting', t => {
t.throws(_ => new Unpack.Sync(opt).end(data), {
name: 'CwdError',
- message: 'ENOTDIR: Cannot cd into \'' + cwd + '\'',
- path: cwd,
- code: 'ENOTDIR'
+ message: 'ENOTDIR: Cannot cd into \'' + normPath(cwd) + '\'',
+ path: normPath(cwd),
+ code: 'ENOTDIR',
})
new Unpack(opt).on('error', er => {
t.match(er, {
name: 'CwdError',
- message: 'ENOTDIR: Cannot cd into \'' + cwd + '\'',
- path: cwd,
- code: 'ENOTDIR'
+ message: 'ENOTDIR: Cannot cd into \'' + normPath(cwd) + '\'',
+ path: normPath(cwd),
+ code: 'ENOTDIR',
})
t.end()
}).end(data)
@@ -2079,17 +2154,17 @@ t.test('bad cwd setting', t => {
t.throws(_ => new Unpack.Sync(opt).end(data), {
name: 'CwdError',
- message: 'ENOENT: Cannot cd into \'' + cwd + '\'',
- path: cwd,
- code: 'ENOENT'
+ message: 'ENOENT: Cannot cd into \'' + normPath(cwd) + '\'',
+ path: normPath(cwd),
+ code: 'ENOENT',
})
new Unpack(opt).on('error', er => {
t.match(er, {
name: 'CwdError',
- message: 'ENOENT: Cannot cd into \'' + cwd + '\'',
- path: cwd,
- code: 'ENOENT'
+ message: 'ENOENT: Cannot cd into \'' + normPath(cwd) + '\'',
+ path: normPath(cwd),
+ code: 'ENOENT',
})
t.end()
}).end(data)
@@ -2101,7 +2176,7 @@ t.test('bad cwd setting', t => {
t.test('transform', t => {
const basedir = path.resolve(unpackdir, 'transform')
- t.teardown(_ => rimraf.sync(basedir))
+ t.teardown(_ => rimraf(basedir))
const cases = {
'emptypax.tar': {
@@ -2149,10 +2224,9 @@ t.test('transform', t => {
t.test(tarfile, t => {
const tf = path.resolve(tars, tarfile)
const dir = path.resolve(basedir, tarfile)
- t.beforeEach(cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- cb()
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
})
const check = t => {
@@ -2200,7 +2274,7 @@ t.test('transform', t => {
t.test('transform error', t => {
const dir = path.resolve(unpackdir, 'transform-error')
mkdirp.sync(dir)
- t.teardown(_ => rimraf.sync(dir))
+ t.teardown(_ => rimraf(dir))
const tarfile = path.resolve(tars, 'body-byte-counts.tar')
const tardata = fs.readFileSync(tarfile)
@@ -2273,13 +2347,12 @@ t.test('futimes/fchown failures', t => {
const poop = new Error('poop')
const second = new Error('second error')
- const reset = cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- }
+ t.beforeEach(async () => {
+ await rimraf(dir)
+ await mkdirp(dir)
+ })
- reset()
- t.teardown(() => rimraf.sync(dir))
+ t.teardown(() => rimraf(dir))
const methods = ['utimes', 'chown']
methods.forEach(method => {
@@ -2294,13 +2367,11 @@ t.test('futimes/fchown failures', t => {
t.test('async unpack', t => {
t.plan(2)
t.test('strict', t => {
- reset()
const unpack = new Unpack({ cwd: dir, strict: true, forceChown: fc })
unpack.on('finish', t.end)
unpack.end(tardata)
})
t.test('loose', t => {
- reset()
const unpack = new Unpack({ cwd: dir, forceChown: fc })
unpack.on('finish', t.end)
unpack.on('warn', t.fail)
@@ -2310,13 +2381,11 @@ t.test('futimes/fchown failures', t => {
t.test('sync unpack', t => {
t.plan(2)
t.test('strict', t => {
- reset()
const unpack = new Unpack.Sync({ cwd: dir, strict: true, forceChown: fc })
unpack.end(tardata)
t.end()
})
t.test('loose', t => {
- reset()
const unpack = new Unpack.Sync({ cwd: dir, forceChown: fc })
unpack.on('warn', t.fail)
unpack.end(tardata)
@@ -2336,14 +2405,12 @@ t.test('futimes/fchown failures', t => {
t.test('async unpack', t => {
t.plan(2)
t.test('strict', t => {
- reset()
const unpack = new Unpack({ cwd: dir, strict: true, forceChown: fc })
t.plan(3)
unpack.on('error', er => t.equal(er, poop))
unpack.end(tardata)
})
t.test('loose', t => {
- reset()
const unpack = new Unpack({ cwd: dir, forceChown: fc })
t.plan(3)
unpack.on('warn', (m, er) => t.equal(er, poop))
@@ -2353,14 +2420,12 @@ t.test('futimes/fchown failures', t => {
t.test('sync unpack', t => {
t.plan(2)
t.test('strict', t => {
- reset()
const unpack = new Unpack.Sync({ cwd: dir, strict: true, forceChown: fc })
t.plan(3)
unpack.on('error', er => t.equal(er, poop))
unpack.end(tardata)
})
t.test('loose', t => {
- reset()
const unpack = new Unpack.Sync({ cwd: dir, forceChown: fc })
t.plan(3)
unpack.on('warn', (m, er) => t.equal(er, poop))
@@ -2376,7 +2441,7 @@ t.test('futimes/fchown failures', t => {
t.test('onentry option is preserved', t => {
const basedir = path.resolve(unpackdir, 'onentry-method')
mkdirp.sync(basedir)
- t.teardown(() => rimraf.sync(basedir))
+ t.teardown(() => rimraf(basedir))
let oecalls = 0
const onentry = entry => oecalls++
@@ -2431,7 +2496,7 @@ t.test('onentry option is preserved', t => {
t.test('do not reuse hardlinks, only nlink=1 files', t => {
const basedir = path.resolve(unpackdir, 'hardlink-reuse')
mkdirp.sync(basedir)
- t.teardown(() => rimraf.sync(basedir))
+ t.teardown(() => rimraf(basedir))
const now = new Date('2018-04-30T18:30:39.025Z')
@@ -2490,3 +2555,287 @@ t.test('do not reuse hardlinks, only nlink=1 files', t => {
t.end()
})
+
+t.test('trying to unpack a javascript file should fail', t => {
+ const data = fs.readFileSync(__filename)
+ const dataGzip = Buffer.concat([Buffer.from([0x1f, 0x8b]), data])
+ const basedir = path.resolve(unpackdir, 'bad-archive')
+ t.test('abort if gzip has an error', t => {
+ t.plan(2)
+ const expect = {
+ message: /^zlib/,
+ errno: Number,
+ code: /^Z/,
+ }
+ const opts = {
+ cwd: basedir,
+ gzip: true,
+ }
+ new Unpack(opts)
+ .once('error', er => t.match(er, expect, 'async emits'))
+ .on('error', () => { /* zlib emits a few times here */ })
+ .end(dataGzip)
+ const skip = !/^v([0-9]|1[0-4])\./.test(process.version) ? false
+ : 'node prior to v14 did not raise sync zlib errors properly'
+ t.test('sync throws', { skip }, t => {
+ t.plan(1)
+ t.throws(() => new UnpackSync(opts).end(dataGzip), expect, 'sync throws')
+ })
+ })
+
+ t.end()
+})
+
+t.test('drop entry from dirCache if no longer a directory', {
+ skip: isWindows && 'symlinks not fully supported',
+}, t => {
+ const dir = path.resolve(unpackdir, 'dir-cache-error')
+ mkdirp.sync(dir + '/sync/y')
+ mkdirp.sync(dir + '/async/y')
+ const data = makeTar([
+ {
+ path: 'x',
+ type: 'Directory',
+ },
+ {
+ path: 'x',
+ type: 'SymbolicLink',
+ linkpath: './y',
+ },
+ {
+ path: 'x/ginkoid',
+ type: 'File',
+ size: 'ginkoid'.length,
+ },
+ 'ginkoid',
+ '',
+ '',
+ ])
+ t.plan(2)
+ const WARNINGS = {}
+ const check = (t, path) => {
+ t.equal(fs.statSync(path + '/x').isDirectory(), true)
+ t.equal(fs.lstatSync(path + '/x').isSymbolicLink(), true)
+ t.equal(fs.statSync(path + '/y').isDirectory(), true)
+ t.strictSame(fs.readdirSync(path + '/y'), [])
+ t.throws(() => fs.readFileSync(path + '/x/ginkoid'), { code: 'ENOENT' })
+ t.strictSame(WARNINGS[path], [
+ 'Cannot extract through symbolic link',
+ ])
+ t.end()
+ }
+ t.test('async', t => {
+ const path = dir + '/async'
+ new Unpack({ cwd: path })
+ .on('warn', (msg) => WARNINGS[path] = [msg])
+ .on('end', () => check(t, path))
+ .end(data)
+ })
+ t.test('sync', t => {
+ const path = dir + '/sync'
+ new UnpackSync({ cwd: path })
+ .on('warn', (msg) => WARNINGS[path] = [msg])
+ .end(data)
+ check(t, path)
+ })
+})
+
+t.test('using strip option when top level file exists', t => {
+ const dir = path.resolve(unpackdir, 'strip-with-top-file')
+ mkdirp.sync(dir + '/sync/y')
+ mkdirp.sync(dir + '/async/y')
+ const data = makeTar([
+ {
+ path: 'top',
+ type: 'File',
+ size: 0,
+ },
+ {
+ path: 'x',
+ type: 'Directory',
+ },
+ {
+ path: 'x/a',
+ type: 'File',
+ size: 'a'.length,
+ },
+ 'a',
+ {
+ path: 'y',
+ type: 'GNUDumpDir',
+ },
+ {
+ path: 'y/b',
+ type: 'File',
+ size: 'b'.length,
+ },
+ 'b',
+ '',
+ '',
+ ])
+ t.plan(2)
+ const check = (t, path) => {
+ t.equal(fs.statSync(path).isDirectory(), true)
+ t.equal(fs.readFileSync(path + '/a', 'utf8'), 'a')
+ t.equal(fs.readFileSync(path + '/b', 'utf8'), 'b')
+ t.throws(() => fs.statSync(path + '/top'), { code: 'ENOENT' })
+ t.end()
+ }
+ t.test('async', t => {
+ const path = dir + '/async'
+ new Unpack({ cwd: path, strip: 1 })
+ .on('end', () => check(t, path))
+ .end(data)
+ })
+ t.test('sync', t => {
+ const path = dir + '/sync'
+ new UnpackSync({ cwd: path, strip: 1 }).end(data)
+ check(t, path)
+ })
+})
+
+t.test('dirCache pruning unicode normalized collisions', {
+ skip: isWindows && 'symlinks not fully supported',
+}, t => {
+ const data = makeTar([
+ {
+ type: 'Directory',
+ path: 'foo',
+ },
+ {
+ type: 'File',
+ path: 'foo/bar',
+ size: 1,
+ },
+ 'x',
+ {
+ type: 'Directory',
+ // café
+ path: Buffer.from([0x63, 0x61, 0x66, 0xc3, 0xa9]).toString(),
+ },
+ {
+ type: 'SymbolicLink',
+ // cafe with a `
+ path: Buffer.from([0x63, 0x61, 0x66, 0x65, 0xcc, 0x81]).toString(),
+ linkpath: 'foo',
+ },
+ {
+ type: 'Directory',
+ path: 'foo',
+ },
+ {
+ type: 'File',
+ path: Buffer.from([0x63, 0x61, 0x66, 0xc3, 0xa9]).toString() + '/bar',
+ size: 1,
+ },
+ 'y',
+ '',
+ '',
+ ])
+
+ const check = (path, dirCache, t) => {
+ path = path.replace(/\\/g, '/')
+ t.strictSame([...dirCache.entries()], [
+ [`${path}/foo`, true],
+ ])
+ t.equal(fs.readFileSync(path + '/foo/bar', 'utf8'), 'x')
+ t.end()
+ }
+
+ t.test('sync', t => {
+ const path = t.testdir()
+ const dirCache = new Map()
+ new UnpackSync({ cwd: path, dirCache }).end(data)
+ check(path, dirCache, t)
+ })
+ t.test('async', t => {
+ const path = t.testdir()
+ const dirCache = new Map()
+ new Unpack({ cwd: path, dirCache })
+ .on('close', () => check(path, dirCache, t))
+ .end(data)
+ })
+
+ t.end()
+})
+
+t.test('dircache prune all on windows when symlink encountered', t => {
+ if (process.platform !== 'win32') {
+ process.env.TESTING_TAR_FAKE_PLATFORM = 'win32'
+ t.teardown(() => {
+ delete process.env.TESTING_TAR_FAKE_PLATFORM
+ })
+ }
+ const symlinks = []
+ const Unpack = requireInject('../lib/unpack.js', {
+ fs: {
+ ...fs,
+ symlink: (target, dest, cb) => {
+ symlinks.push(['async', target, dest])
+ process.nextTick(cb)
+ },
+ symlinkSync: (target, dest) => symlinks.push(['sync', target, dest]),
+ },
+ })
+ const UnpackSync = Unpack.Sync
+
+ const data = makeTar([
+ {
+ type: 'Directory',
+ path: 'foo',
+ },
+ {
+ type: 'File',
+ path: 'foo/bar',
+ size: 1,
+ },
+ 'x',
+ {
+ type: 'Directory',
+ // café
+ path: Buffer.from([0x63, 0x61, 0x66, 0xc3, 0xa9]).toString(),
+ },
+ {
+ type: 'SymbolicLink',
+ // cafe with a `
+ path: Buffer.from([0x63, 0x61, 0x66, 0x65, 0xcc, 0x81]).toString(),
+ linkpath: 'safe/actually/but/cannot/be/too/careful',
+ },
+ {
+ type: 'File',
+ path: 'bar/baz',
+ size: 1,
+ },
+ 'z',
+ '',
+ '',
+ ])
+
+ const check = (path, dirCache, t) => {
+ // symlink blew away all dirCache entries before it
+ path = path.replace(/\\/g, '/')
+ t.strictSame([...dirCache.entries()], [
+ [`${path}/bar`, true],
+ ])
+ t.equal(fs.readFileSync(`${path}/foo/bar`, 'utf8'), 'x')
+ t.equal(fs.readFileSync(`${path}/bar/baz`, 'utf8'), 'z')
+ t.end()
+ }
+
+ t.test('sync', t => {
+ const path = t.testdir()
+ const dirCache = new Map()
+ new UnpackSync({ cwd: path, dirCache }).end(data)
+ check(path, dirCache, t)
+ })
+
+ t.test('async', t => {
+ const path = t.testdir()
+ const dirCache = new Map()
+ new Unpack({ cwd: path, dirCache })
+ .on('close', () => check(path, dirCache, t))
+ .end(data)
+ })
+
+ t.end()
+})
diff --git a/test/update.js b/test/update.js
index 0d3394f7..70e9b8e1 100644
--- a/test/update.js
+++ b/test/update.js
@@ -4,58 +4,28 @@ const t = require('tap')
const u = require('../lib/update.js')
const path = require('path')
const fs = require('fs')
-const mkdirp = require('mkdirp')
-const rimraf = require('rimraf')
const mutateFS = require('mutate-fs')
+const {resolve} = require('path')
const fixtures = path.resolve(__dirname, 'fixtures')
-const dir = path.resolve(fixtures, 'update')
const tars = path.resolve(fixtures, 'tars')
-const file = dir + '/body-byte-counts.tar'
-const fileNoNulls = dir + '/no-null-eof.tar'
-const fileTruncHead = dir + '/truncated-head.tar'
-const fileTruncBody = dir + '/truncated-body.tar'
-const fileNonExistent = dir + '/does-not-exist.tar'
-const fileZeroByte = dir + '/zero.tar'
-const fileEmpty = dir + '/empty.tar'
-const fileCompressed = dir + '/compressed.tgz'
const zlib = require('zlib')
const spawn = require('child_process').spawn
-t.teardown(_ => rimraf.sync(dir))
-
-const reset = cb => {
- rimraf.sync(dir)
- mkdirp.sync(dir)
- const data = fs.readFileSync(tars + '/body-byte-counts.tar')
- fs.writeFileSync(file, data)
-
- const dataNoNulls = data.slice(0, data.length - 1024)
- fs.writeFileSync(fileNoNulls, dataNoNulls)
-
- const dataTruncHead = Buffer.concat([dataNoNulls, data.slice(0, 500)])
- fs.writeFileSync(fileTruncHead, dataTruncHead)
-
- const dataTruncBody = Buffer.concat([dataNoNulls, data.slice(0, 700)])
- fs.writeFileSync(fileTruncBody, dataTruncBody)
-
- fs.writeFileSync(fileZeroByte, '')
- fs.writeFileSync(fileEmpty, Buffer.alloc(1024))
-
- fs.writeFileSync(fileCompressed, zlib.gzipSync(data))
-
- if (cb)
- cb()
+const data = fs.readFileSync(tars + '/body-byte-counts.tar')
+const dataNoNulls = data.slice(0, data.length - 1024)
+const fixtureDef = {
+ 'body-byte-counts.tar': data,
+ 'no-null-eof.tar': dataNoNulls,
+ 'truncated-head.tar': Buffer.concat([dataNoNulls, data.slice(0, 500)]),
+ 'truncated-body.tar': Buffer.concat([dataNoNulls, data.slice(0, 700)]),
+ 'zero.tar': Buffer.from(''),
+ 'empty.tar': Buffer.alloc(512),
+ 'compressed.tgz': zlib.gzipSync(data),
}
-t.test('setup', t => {
- reset(t.end)
-})
-
t.test('basic file add to archive (good or truncated)', t => {
- t.beforeEach(reset)
-
const check = (file, t) => {
const c = spawn('tar', ['tf', file])
const out = []
@@ -63,7 +33,7 @@ t.test('basic file add to archive (good or truncated)', t => {
c.on('close', (code, signal) => {
t.equal(code, 0)
t.equal(signal, null)
- const actual = Buffer.concat(out).toString().trim().split('\n')
+ const actual = Buffer.concat(out).toString().trim().split(/\r?\n/)
t.same(actual, [
'1024-bytes.txt',
'512-bytes.txt',
@@ -75,50 +45,68 @@ t.test('basic file add to archive (good or truncated)', t => {
})
}
- ;[file,
- fileNoNulls,
- fileTruncHead,
- fileTruncBody
- ].forEach(file => {
- t.test(path.basename(file), t => {
- const fileList = [path.basename(__filename)]
- t.test('sync', t => {
+ const files = [
+ 'body-byte-counts.tar',
+ 'no-null-eof.tar',
+ 'truncated-head.tar',
+ 'truncated-body.tar',
+ ]
+ const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => {
+ s[k] = v
+ return s
+ }, {})
+ const fileList = [path.basename(__filename)]
+ t.test('sync', t => {
+ t.plan(files.length)
+ const dir = t.testdir(td)
+ for (const file of files) {
+ t.test(file, t => {
u({
sync: true,
- file: file,
- cwd: __dirname
+ file: resolve(dir, file),
+ cwd: __dirname,
}, fileList)
- check(file, t)
+ check(resolve(dir, file), t)
})
+ }
+ })
- t.test('async cb', t => {
+ t.test('async cb', t => {
+ t.plan(files.length)
+ const dir = t.testdir(td)
+ for (const file of files) {
+ t.test(file, t => {
u({
- file: file,
- cwd: __dirname
+ file: resolve(dir, file),
+ cwd: __dirname,
}, fileList, er => {
if (er)
throw er
- check(file, t)
+ check(resolve(dir, file), t)
})
})
+ }
+ })
- t.test('async promise', t => {
+ t.test('async', t => {
+ t.plan(files.length)
+ const dir = t.testdir(td)
+ for (const file of files) {
+ t.test(file, t => {
u({
- file: file,
- cwd: __dirname
- }, fileList).then(_ => check(file, t))
+ file: resolve(dir, file),
+ cwd: __dirname,
+ }, fileList).then(() => {
+ check(resolve(dir, file), t)
+ })
})
-
- t.end()
- })
+ }
})
t.end()
})
t.test('add to empty archive', t => {
- t.beforeEach(reset)
-
const check = (file, t) => {
const c = spawn('tar', ['tf', file])
const out = []
@@ -126,7 +114,7 @@ t.test('add to empty archive', t => {
c.on('close', (code, signal) => {
t.equal(code, 0)
t.equal(signal, null)
- const actual = Buffer.concat(out).toString().trim().split('\n')
+ const actual = Buffer.concat(out).toString().trim().split(/\r?\n/)
t.same(actual, [
path.basename(__filename)
])
@@ -134,66 +122,89 @@ t.test('add to empty archive', t => {
})
}
- ;[fileNonExistent,
- fileEmpty,
- fileZeroByte
- ].forEach(file => {
- t.test(path.basename(file), t => {
- const fileList = [path.basename(__filename)]
- t.test('sync', t => {
+ const files = [
+ 'empty.tar',
+ 'zero.tar',
+ ]
+ const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => {
+ s[k] = v
+ return s
+ }, {})
+ files.push('not-existing.tar')
+
+ t.test('sync', t => {
+ const dir = t.testdir(td)
+ t.plan(files.length)
+ for (const file of files) {
+ t.test(file, t => {
u({
sync: true,
- file: file,
- cwd: __dirname
- }, fileList)
- check(file, t)
+ file: resolve(dir, file),
+ cwd: __dirname,
+ }, [path.basename(__filename)])
+ check(resolve(dir, file), t)
})
+ }
+ })
- t.test('async cb', t => {
+ t.test('async cb', t => {
+ const dir = t.testdir(td)
+ t.plan(files.length)
+ for (const file of files) {
+ t.test(file, t => {
u({
- file: file,
- cwd: __dirname
- }, fileList, er => {
+ file: resolve(dir, file),
+ cwd: __dirname,
+ }, [path.basename(__filename)], er => {
if (er)
throw er
- check(file, t)
+ check(resolve(dir, file), t)
})
})
+ }
+ })
- t.test('async promise', t => {
+ t.test('async', async t => {
+ const dir = t.testdir(td)
+ t.plan(files.length)
+ for (const file of files) {
+ t.test(file, t => {
u({
- file: file,
- cwd: __dirname
- }, fileList).then(_ => check(file, t))
+ file: resolve(dir, file),
+ cwd: __dirname,
+ }, [path.basename(__filename)]).then(() => {
+ check(resolve(dir, file), t)
+ })
})
-
- t.end()
- })
+ }
})
t.end()
})
t.test('cannot append to gzipped archives', t => {
- reset()
+ const dir = t.testdir({
+ 'compressed.tgz': fixtureDef['compressed.tgz'],
+ })
+ const file = resolve(dir, 'compressed.tgz')
const expect = new Error('cannot append to compressed archives')
const expectT = new TypeError('cannot append to compressed archives')
t.throws(_ => u({
- file: fileCompressed,
+ file,
cwd: __dirname,
gzip: true
}, [path.basename(__filename)]), expectT)
t.throws(_ => u({
- file: fileCompressed,
+ file,
cwd: __dirname,
sync: true
}, [path.basename(__filename)]), expect)
u({
- file: fileCompressed,
+ file,
cwd: __dirname,
}, [path.basename(__filename)], er => {
t.match(er, expect)
@@ -209,88 +220,150 @@ t.test('other throws', t => {
})
t.test('broken open', t => {
+ const dir = t.testdir({
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ })
+ const file = resolve(dir, 'body-byte-counts.tar')
const poop = new Error('poop')
t.teardown(mutateFS.fail('open', poop))
t.throws(_ => u({ sync: true, file: file }, ['README.md']), poop)
- u({ file: file }, ['README.md'], er => {
+ u({ file }, ['README.md'], er => {
t.match(er, poop)
t.end()
})
})
t.test('broken fstat', t => {
+ const td = {
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ }
const poop = new Error('poop')
- t.teardown(mutateFS.fail('fstat', poop))
- t.throws(_ => u({ sync: true, file: file }, ['README.md']), poop)
- u({ file: file }, ['README.md'], er => {
- t.match(er, poop)
+ t.test('sync', t => {
+ const dir = t.testdir(td)
+ const file = resolve(dir, 'body-byte-counts.tar')
+ t.teardown(mutateFS.fail('fstat', poop))
+ t.throws(_ => u({ sync: true, file }, ['README.md']), poop)
t.end()
})
+ t.test('async', t => {
+ const dir = t.testdir(td)
+ const file = resolve(dir, 'body-byte-counts.tar')
+ t.teardown(mutateFS.fail('fstat', poop))
+ u({ file }, ['README.md'], async er => {
+ t.match(er, poop)
+ t.end()
+ })
+ })
+ t.end()
})
t.test('broken read', t => {
+ const dir = t.testdir({
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ })
+ const file = resolve(dir, 'body-byte-counts.tar')
const poop = new Error('poop')
t.teardown(mutateFS.fail('read', poop))
- t.throws(_ => u({ sync: true, file: file }, ['README.md']), poop)
- u({ file: file }, ['README.md'], er => {
+ t.throws(_ => u({ sync: true, file }, ['README.md']), poop)
+ u({ file }, ['README.md'], er => {
t.match(er, poop)
t.end()
})
})
t.test('do not add older file', t => {
- reset()
+ const dir = t.testdir({
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ '1024-bytes.txt': '.'.repeat(1024),
+ foo: 'foo',
+ })
+ const file = resolve(dir, 'body-byte-counts.tar')
- const f = dir + '/1024-bytes.txt'
- fs.writeFileSync(f, new Array(1025).join('.'))
+ const f = resolve(dir, '1024-bytes.txt')
const oldDate = new Date('1997-04-10T16:57:47.000Z')
fs.utimesSync(f, oldDate, oldDate)
+ // file size should not change
+ const expect = fixtureDef['body-byte-counts.tar'].length
const check = t => {
- t.equal(fs.statSync(file).size, 5120)
+ t.equal(fs.statSync(file).size, expect)
t.end()
}
t.test('sync', t => {
- u({ file: file, cwd: dir, sync: true }, ['1024-bytes.txt'])
+ u({
+ mtimeCache: new Map(),
+ file,
+ cwd: dir,
+ sync: true,
+ filter: path => path === '1024-bytes.txt',
+ }, ['1024-bytes.txt', 'foo'])
check(t)
})
t.test('async', t => {
- u({ file: file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(t))
+ u({ file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(t))
+ })
+
+ t.test('async cb', t => {
+ u({ file, cwd: dir }, ['1024-bytes.txt'], er => {
+ if (er)
+ throw er
+ check(t)
+ })
})
t.end()
})
t.test('do add newer file', t => {
- t.beforeEach(cb => {
- reset()
- const f = dir + '/1024-bytes.txt'
- fs.writeFileSync(f, new Array(1025).join('.'))
- const newDate = new Date('2017-05-01T22:06:43.736Z')
+ const setup = t => {
+ const dir = t.testdir({
+ 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'],
+ '1024-bytes.txt': '.'.repeat(1024),
+ foo: 'foo',
+ })
+
+ const f = resolve(dir, '1024-bytes.txt')
+ const newDate = new Date(Date.now() + 24 * 60 * 60 * 1000)
fs.utimesSync(f, newDate, newDate)
- cb()
- })
+ return dir
+ }
- const check = t => {
- t.equal(fs.statSync(file).size, 6656)
+ // a chunk for the header, then 2 for the body
+ const expect = fixtureDef['body-byte-counts.tar'].length + 512 + 1024
+ const check = (file, t) => {
+ t.equal(fs.statSync(file).size, expect)
t.end()
}
t.test('sync', t => {
+ const dir = setup(t)
+ const file = resolve(dir, 'body-byte-counts.tar')
u({
mtimeCache: new Map(),
- file: file,
+ file,
cwd: dir,
sync: true,
- filter: path => path === '1024-bytes.txt'
- }, ['1024-bytes.txt', 'compressed.tgz'])
- check(t)
+ filter: path => path === '1024-bytes.txt',
+ }, ['1024-bytes.txt', 'foo'])
+ check(file, t)
})
t.test('async', t => {
- u({ file: file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(t))
+ const dir = setup(t)
+ const file = resolve(dir, 'body-byte-counts.tar')
+ u({ file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(file, t))
+ })
+
+ t.test('async cb', t => {
+ const dir = setup(t)
+ const file = resolve(dir, 'body-byte-counts.tar')
+ u({ file, cwd: dir }, ['1024-bytes.txt'], er => {
+ if (er)
+ throw er
+ check(file, t)
+ })
})
t.end()
diff --git a/test/write-entry.js b/test/write-entry.js
index c31d28e5..ac8cf862 100644
--- a/test/write-entry.js
+++ b/test/write-entry.js
@@ -1,9 +1,22 @@
'use strict'
const t = require('tap')
+
+// make our tests verify that windows link targets get turned into / paths
+const fs = require('fs')
+const {readlink, readlinkSync} = fs
+fs.readlink = (path, cb) => {
+ readlink(path, (er, path) => {
+ if (er)
+ return cb(er)
+ else
+ cb(null, path.replace(/\//g, '\\'))
+ })
+}
+fs.readlinkSync = path => readlinkSync(path).replace(/\//g, '\\')
+
const ReadEntry = require('../lib/read-entry.js')
const makeTar = require('./make-tar.js')
const WriteEntry = require('../lib/write-entry.js')
-const fs = require('fs')
const path = require('path')
const fixtures = path.resolve(__dirname, 'fixtures')
const files = path.resolve(fixtures, 'files')
@@ -15,6 +28,7 @@ const Parser = require('../lib/parse.js')
const rimraf = require('rimraf')
const mkdirp = require('mkdirp')
const isWindows = process.platform === 'win32'
+const normPath = require('../lib/normalize-windows-path.js')
t.test('set up', t => {
const one = fs.statSync(files + '/hardlink-1')
@@ -23,7 +37,7 @@ t.test('set up', t => {
fs.unlinkSync(files + '/hardlink-2')
fs.linkSync(files + '/hardlink-1', files + '/hardlink-2')
}
- chmodr.sync(files, 0o644)
+ chmodr.sync(files, isWindows ? 0o666 : 0o644)
t.end()
})
@@ -50,7 +64,7 @@ t.test('100 byte filename', t => {
cksumValid: true,
needPax: false,
path: '100-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 100,
linkpath: null,
uname: 'isaacs',
@@ -78,7 +92,7 @@ t.test('100 byte filename', t => {
cksumValid: true,
needPax: false,
path: '100-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 100,
linkpath: '',
uname: 'isaacs',
@@ -126,7 +140,7 @@ t.test('directory', t => {
cksumValid: true,
needPax: false,
path: 'dir/',
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
size: 0,
linkpath: null,
uname: 'isaacs',
@@ -142,7 +156,7 @@ t.test('directory', t => {
cksumValid: true,
needPax: false,
path: 'dir/',
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
size: 0,
linkpath: null,
uname: 'isaacs',
@@ -166,7 +180,7 @@ t.test('empty path for cwd', t => {
cksumValid: true,
needPax: false,
path: './',
- mode: fs.statSync('./').mode & 0o7777,
+ mode: isWindows ? 0o777 : fs.statSync('./').mode & 0o7777,
size: 0,
linkpath: null,
uname: 'isaacs',
@@ -178,7 +192,9 @@ t.test('empty path for cwd', t => {
})
})
-t.test('symlink', t => {
+t.test('symlink', {
+ skip: isWindows && 'symlinks not fully supported',
+}, t => {
const ws = new WriteEntry('symlink', { cwd: files })
let out = []
ws.on('data', c => out.push(c))
@@ -217,7 +233,7 @@ t.test('zero-byte file', t => {
path: 'files/zero-byte.txt',
cksumValid: true,
needPax: false,
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 0,
linkpath: null,
uname: 'isaacs',
@@ -229,6 +245,22 @@ t.test('zero-byte file', t => {
})
})
+t.test('zero-byte file, but close fails', t => {
+ const poop = new Error('poop')
+ t.tearDown(mutateFS.fail('close', poop))
+
+ const ws = new WriteEntry('files/1024-bytes.txt', { cwd: fixtures })
+
+ ws.on('end', _ =>
+ t.fail('should not get an end, because the close fails'))
+
+ ws.on('error', er => {
+ t.match(er, { message: 'poop' })
+ t.end()
+ })
+ ws.resume()
+})
+
t.test('hardlinks', t => {
const h1 = 'hardlink-1'
const h2 = 'hardlink-2'
@@ -253,7 +285,7 @@ t.test('hardlinks', t => {
path: 'files/hardlink-2',
cksumValid: true,
needPax: false,
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 0,
linkpath: 'files/hardlink-1',
uname: 'isaacs',
@@ -285,7 +317,7 @@ t.test('hardlinks far away', t => {
path: 'files/hardlink-2',
cksumValid: true,
needPax: false,
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 26,
linkpath: null,
uname: 'isaacs',
@@ -309,7 +341,7 @@ t.test('really deep path', t => {
cksumValid: true,
needPax: true,
path: 'long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 100,
linkpath: null,
uname: 'isaacs',
@@ -334,7 +366,7 @@ t.test('no pax', t => {
cksumValid: true,
needPax: true,
path: 'long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 100,
linkpath: null,
uname: 'isaacs',
@@ -362,10 +394,15 @@ t.test('nonexistent file', t => {
})
t.test('absolute path', t => {
- const f = path.resolve(files, '512-bytes.txt')
+ const absolute = path.resolve(files, '512-bytes.txt')
+ const { root } = path.parse(absolute)
+ const f = root + root + root + absolute
+ const warn = normPath(isWindows ? root : root + root + root + root)
t.test('preservePaths=false strict=false', t => {
const warnings = []
- const ws = new WriteEntry(f, {
+ // on windows, c:\c:\c:\... is a valid path, so just use the
+ // single-root absolute version of it.
+ const ws = new WriteEntry(isWindows ? absolute : f, {
cwd: files,
onwarn: (m, p) => warnings.push([m, p])
})
@@ -375,14 +412,15 @@ t.test('absolute path', t => {
out = Buffer.concat(out)
t.equal(out.length, 1024)
t.match(warnings, [[
- /stripping .* from absolute path/, f
+ `stripping ${warn} from absolute path`,
+ normPath(isWindows ? absolute : f),
]])
t.match(ws.header, {
cksumValid: true,
needPax: false,
- path: f.replace(/^(\/|[a-z]:\\\\)/, ''),
- mode: 0o644,
+ path: normPath(absolute.replace(/^(\/|[a-z]:[/\\])*/i, '')),
+ mode: isWindows ? 0o666 : 0o644,
size: 512,
linkpath: null,
uname: 'isaacs',
@@ -401,7 +439,7 @@ t.test('absolute path', t => {
t.test('strict=' + strict, t => {
const warnings = []
- const ws = new WriteEntry(f, {
+ const ws = new WriteEntry(isWindows ? absolute : f, {
cwd: files,
strict: strict,
preservePaths: true,
@@ -416,8 +454,8 @@ t.test('absolute path', t => {
t.match(ws.header, {
cksumValid: true,
needPax: false,
- path: f,
- mode: 0o644,
+ path: normPath(isWindows ? absolute : f),
+ mode: isWindows ? 0o666 : 0o644,
size: 512,
linkpath: null,
uname: 'isaacs',
@@ -433,11 +471,13 @@ t.test('absolute path', t => {
t.test('preservePaths=false strict=true', t => {
t.throws(_ => {
- new WriteEntry(f, {
+ new WriteEntry(isWindows ? absolute : f, {
strict: true,
cwd: files
})
- }, { message: /stripping .* from absolute path/, data: f })
+ }, {
+ message: /stripping .* from absolute path/
+ })
t.end()
})
@@ -458,7 +498,7 @@ t.test('no user environ, sets uname to empty string', t => {
cksumValid: true,
needPax: false,
path: '512-bytes.txt',
- mode: 0o644,
+ mode: isWindows ? 0o666 : 0o644,
size: 512,
uname: '',
linkpath: null,
@@ -497,17 +537,17 @@ t.test('an unsuppored type', {
t.test('readlink fail', t => {
const expect = {
- message: 'EINVAL: invalid argument, readlink \'' + __filename + '\'',
- code: 'EINVAL',
syscall: 'readlink',
- path: __filename
+ path: String,
}
// pretend everything is a symbolic link, then read something that isn't
- t.tearDown(mutateFS.statType('SymbolicLink'))
- t.throws(_ => new WriteEntry.Sync('write-entry.js', { cwd: __dirname }),
- expect)
+ t.teardown(mutateFS.statType('SymbolicLink'))
+ t.throws(_ => {
+ return new WriteEntry.Sync('write-entry.js', { cwd: __dirname })
+ }, expect)
new WriteEntry('write-entry.js', { cwd: __dirname }).on('error', er => {
t.match(er, expect)
+ t.equal(normPath(er.path), normPath(__filename))
t.end()
})
})
@@ -528,10 +568,16 @@ t.test('read fail', t => {
code: 'EISDIR',
syscall: 'read'
}
- // pretend everything is a symbolic link, then read something that isn't
- t.tearDown(mutateFS.statType('File'))
- t.throws(_ => new WriteEntry.Sync('fixtures', { cwd: __dirname }),
- expect)
+ // pretend everything is a file, then read something that isn't
+ t.teardown(mutateFS.statMutate((er, st) => {
+ if (er)
+ return [er, st]
+ st.isFile = () => true
+ st.size = 123
+ }))
+ t.throws(_ => new WriteEntry.Sync('fixtures', {
+ cwd: __dirname,
+ }), expect)
new WriteEntry('fixtures', { cwd: __dirname }).on('error', er => {
t.match(er, expect)
t.end()
@@ -542,7 +588,7 @@ t.test('read invalid EOF', t => {
t.tearDown(mutateFS.mutate('read', (er, br) => [er, 0]))
const expect = {
message: 'encountered unexpected EOF',
- path: __filename,
+ path: normPath(__filename),
syscall: 'read',
code: 'EOF'
}
@@ -562,7 +608,7 @@ t.test('read overflow expectation', t => {
const f = '512-bytes.txt'
const expect = {
message: 'did not encounter expected EOF',
- path: path.resolve(files, f),
+ path: normPath(path.resolve(files, f)),
syscall: 'read',
code: 'EOF'
}
@@ -570,7 +616,7 @@ t.test('read overflow expectation', t => {
new WriteEntry(f, { cwd: files, maxReadSize: 2 }).on('error', er => {
t.match(er, expect)
t.end()
- })
+ }).resume()
})
t.test('short reads', t => {
@@ -900,13 +946,27 @@ t.test('portable dir entries, no mtime', t => {
})
})
+t.test('writing more data than is appropriate', t => {
+ const path = t.testdir({
+ file: 'hello',
+ })
+ const wss = new WriteEntry(`${path}/file`)
+ wss.on('error', er => {
+ t.match(er, {
+ message: 'writing more data than expected',
+ })
+ t.end()
+ })
+ wss.on('stat', () => wss.write(Buffer.from('some more stuff')))
+})
+
t.test('write entry from read entry', t => {
const data = makeTar([
{
path: '$',
type: 'File',
size: 10,
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
uid: 123,
gid: 321,
ctime: new Date('1979-07-01'),
@@ -947,7 +1007,7 @@ t.test('write entry from read entry', t => {
path: '$',
type: 'Directory',
size: 0,
- mode: 0o755,
+ mode: isWindows ? 0o777 : 0o755,
uid: 123,
gid: 321,
ctime: new Date('1979-07-01'),
@@ -1114,3 +1174,530 @@ t.test('write entry from read entry', t => {
t.end()
})
+
+// https://github.com/npm/node-tar/issues/284
+t.test('prefix and hard links', t => {
+ const dir = path.resolve(fixtures, 'writeentry-prefix-hardlinks')
+ rimraf.sync(dir)
+ t.teardown(_ => rimraf.sync(dir))
+ mkdirp.sync(dir + '/in/z/b/c')
+ fs.writeFileSync(dir + '/in/target', 'ddd')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/b/c/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/b/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/y')
+ const long = 'y'.repeat(250)
+ fs.linkSync(dir + '/in/target', dir + '/in/' + long)
+
+ const expect = [
+ {
+ type: 'Directory',
+ path: 'out/x/',
+ },
+ {
+ type: 'File',
+ size: 3,
+ path: 'out/x/target',
+ },
+ 'ddd\0',
+ {
+ path: 'out/x/y',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ path: 'PaxHeader/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ type: 'ExtendedHeader',
+ },
+ new RegExp('^266 path=out.x.' + long + '[\\w\\W]*linkpath=out.x.target'),
+ {
+ path: 'out/x/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ type: 'Directory',
+ path: 'out/x/z/',
+ },
+ {
+ type: 'Directory',
+ path: 'out/x/z/b/',
+ },
+ {
+ path: 'out/x/z/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ type: 'Directory',
+ path: 'out/x/z/b/c/',
+ },
+ {
+ path: 'out/x/z/b/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ path: 'out/x/z/b/c/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ ]
+
+ const check = (out, t) => {
+ const data = Buffer.concat(out)
+ expect.forEach((e, i) => {
+ if (typeof e === 'string')
+ t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e)
+ else if (e instanceof RegExp)
+ t.match(data.slice(i * 512, (i + 1) * 512).toString(), e)
+ else
+ t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e)
+ })
+ }
+
+ const runTest = async (t, path, Class) => {
+ const linkCache = new Map()
+ const statCache = new Map()
+ const opt = {
+ cwd: dir + '/in',
+ prefix: 'out/x',
+ noDirRecurse: true,
+ linkCache,
+ statCache,
+ }
+ const out = []
+ const entry = (path) => new Promise(resolve => {
+ const p = new Class(path, opt)
+ p.on('end', resolve)
+ p.on('data', d => out.push(d))
+ })
+
+ await entry(path)
+ if (path === '.')
+ path = './'
+ await entry(`${path}target`)
+ await entry(`${path}y`)
+ await entry(`${path}${long}`)
+ await entry(`${path}z`)
+ await entry(`${path}z/b`)
+ await entry(`${path}z/d`)
+ await entry(`${path}z/b/c`)
+ await entry(`${path}z/b/d`)
+ await entry(`${path}z/b/c/d`)
+ check(out, t)
+ }
+
+ t.test('async', t => {
+ t.test('.', t => runTest(t, '.', WriteEntry))
+ return t.test('./', t => runTest(t, './', WriteEntry))
+ })
+
+ t.test('sync', t => {
+ t.test('.', t => runTest(t, '.', WriteEntry.Sync))
+ return t.test('./', t => runTest(t, './', WriteEntry.Sync))
+ })
+
+ t.end()
+})
+
+t.test('prefix and hard links from tar entries', t => {
+ const long = 'y'.repeat(250)
+ const expect = [
+ {
+ type: 'Directory',
+ path: 'out/x/',
+ },
+ {
+ type: 'File',
+ size: 3,
+ path: 'out/x/target',
+ },
+ 'ddd\0',
+ {
+ path: 'out/x/y',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ path: 'PaxHeader/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ type: 'ExtendedHeader',
+ },
+ new RegExp('^266 path=out.x.' + long + '[\\w\\W]*linkpath=out.x.target'),
+ {
+ path: 'out/x/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ type: 'Directory',
+ path: 'out/x/z/',
+ },
+ {
+ type: 'Directory',
+ path: 'out/x/z/b/',
+ },
+ {
+ path: 'out/x/z/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ type: 'Directory',
+ path: 'out/x/z/b/c/',
+ },
+ {
+ path: 'out/x/z/b/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ {
+ path: 'out/x/z/b/c/d',
+ type: 'Link',
+ linkpath: 'out/x/target',
+ },
+ ]
+
+ const data = makeTar([
+ {
+ type: 'Directory',
+ path: './',
+ },
+ {
+ type: 'File',
+ size: 3,
+ path: 'target',
+ },
+ 'ddd\0',
+ {
+ path: 'y',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ path: 'PaxHeader/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ type: 'ExtendedHeader',
+ size: ('260 path=' + long + '\n19 linkpath=target\n').length,
+ },
+ '260 path=' + long + '\n19 linkpath=target\n',
+ {
+ path: 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/',
+ },
+ {
+ path: 'z/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/c/',
+ },
+ {
+ path: 'z/b/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ path: 'z/b/c/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ '',
+ '',
+ ])
+
+ const check = (out, t) => {
+ const data = Buffer.concat(out)
+ expect.forEach((e, i) => {
+ if (typeof e === 'string')
+ t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e)
+ else if (e instanceof RegExp)
+ t.match(data.slice(i * 512, (i + 1) * 512).toString(), e)
+ else
+ t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e)
+ })
+ }
+
+ const runTest = async (t, path) => {
+ const linkCache = new Map()
+ const statCache = new Map()
+ const opt = {
+ prefix: 'out/x',
+ noDirRecurse: true,
+ linkCache,
+ statCache,
+ }
+ const out = []
+ const parser = new Parser({
+ strict: true,
+ onentry: readEntry => {
+ const p = new WriteEntry.Tar(readEntry, opt)
+ p.on('data', d => out.push(d))
+ },
+ })
+ parser.on('end', () => check(out, t))
+ parser.end(data)
+ }
+
+ t.test('.', t => runTest(t, '.'))
+ t.test('./', t => runTest(t, './'))
+
+ t.end()
+})
+
+t.test('hard links and no prefix', t => {
+ const dir = path.resolve(fixtures, 'writeentry-prefix-hardlinks')
+ t.teardown(_ => rimraf.sync(dir))
+ mkdirp.sync(dir + '/in/z/b/c')
+ fs.writeFileSync(dir + '/in/target', 'ddd')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/b/c/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/b/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/z/d')
+ fs.linkSync(dir + '/in/target', dir + '/in/y')
+
+ const expect = [
+ {
+ type: 'Directory',
+ path: './',
+ },
+ {
+ type: 'File',
+ size: 3,
+ path: 'target',
+ },
+ 'ddd\0',
+ {
+ path: 'y',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/',
+ },
+ {
+ path: 'z/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/c/',
+ },
+ {
+ path: 'z/b/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ path: 'z/b/c/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ ]
+
+ const check = (out, t) => {
+ const data = Buffer.concat(out)
+ expect.forEach((e, i) => {
+ if (typeof e === 'string')
+ t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e)
+ else
+ t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e)
+ })
+ }
+
+ const runTest = async (t, path, Class) => {
+ const linkCache = new Map()
+ const statCache = new Map()
+ const opt = {
+ cwd: dir + '/in',
+ linkCache,
+ statCache,
+ }
+ const out = []
+ const entry = (path) => new Promise(resolve => {
+ const p = new Class(path, opt)
+ p.on('end', resolve)
+ p.on('data', d => out.push(d))
+ })
+
+ await entry(path)
+ if (path === '.')
+ path = './'
+ await entry(`${path}target`)
+ await entry(`${path}y`)
+ await entry(`${path}z`)
+ await entry(`${path}z/b`)
+ await entry(`${path}z/d`)
+ await entry(`${path}z/b/c`)
+ await entry(`${path}z/b/d`)
+ await entry(`${path}z/b/c/d`)
+ check(out, t)
+ }
+
+ t.test('async', t => {
+ t.test('.', t => runTest(t, '.', WriteEntry))
+ return t.test('./', t => runTest(t, './', WriteEntry))
+ })
+
+ t.test('sync', t => {
+ t.test('.', t => runTest(t, '.', WriteEntry.Sync))
+ return t.test('./', t => runTest(t, './', WriteEntry.Sync))
+ })
+
+ t.end()
+})
+
+t.test('hard links from tar entries and no prefix', t => {
+ const expect = [
+ {
+ type: 'Directory',
+ path: './',
+ },
+ {
+ type: 'File',
+ size: 3,
+ path: 'target',
+ },
+ 'ddd\0',
+ {
+ path: 'y',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/',
+ },
+ {
+ path: 'z/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/c/',
+ },
+ {
+ path: 'z/b/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ path: 'z/b/c/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ ]
+
+ const data = makeTar([
+ {
+ type: 'Directory',
+ path: './',
+ },
+ {
+ type: 'File',
+ size: 3,
+ path: 'target',
+ },
+ 'ddd\0',
+ {
+ path: 'y',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/',
+ },
+ {
+ path: 'z/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ type: 'Directory',
+ path: 'z/b/c/',
+ },
+ {
+ path: 'z/b/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ {
+ path: 'z/b/c/d',
+ type: 'Link',
+ linkpath: 'target',
+ },
+ ])
+
+ const check = (out, t) => {
+ const data = Buffer.concat(out)
+ expect.forEach((e, i) => {
+ if (typeof e === 'string')
+ t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e)
+ else if (e instanceof RegExp)
+ t.match(data.slice(i * 512, (i + 1) * 512).toString(), e)
+ else
+ t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e)
+ })
+ }
+
+ const runTest = async (t, path) => {
+ const linkCache = new Map()
+ const statCache = new Map()
+ const opt = {
+ noDirRecurse: true,
+ linkCache,
+ statCache,
+ }
+ const out = []
+ const parser = new Parser({
+ onentry: readEntry => {
+ const p = new WriteEntry.Tar(readEntry, opt)
+ p.on('data', d => out.push(d))
+ },
+ })
+ parser.on('end', () => check(out, t))
+ parser.end(data)
+ }
+
+ t.test('.', t => runTest(t, '.'))
+ t.test('./', t => runTest(t, './'))
+
+ t.end()
+})
+
+t.test('myuid set by getuid() if available, otherwise 0', t => {
+ const {getuid} = process
+ process.getuid = null
+ const noUid = new WriteEntry(__filename)
+ t.equal(noUid.myuid, 0, 'set to zero if no getuid function')
+ process.getuid = () => 123456789
+ const hasUid = new WriteEntry(__filename)
+ t.equal(hasUid.myuid, 123456789, 'set to process.getuid()')
+ process.getuid = getuid
+ t.end()
+})