diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1049a88 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +.idea +.datadrive +deployment diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..45d9a25 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM cae-artifactory.jpl.nasa.gov:17001/node:14.15.0 + +ENV HOME . + +RUN apt-get update && \ + apt-get install zip && \ + mkdir -p /usr/src/app + +WORKDIR /usr/src/app + +RUN npm config set @gov.nasa.jpl.m2020.cs3:registry https://cae-artifactory.jpl.nasa.gov:443/artifactory/api/npm/npm-release-local/ diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..a1cc7be --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,169 @@ +/** +* The following flags can be used to control stages of the pipeline to be run. +*/ +def PIPELINE_CONTROL = [ + ci_skip: false +] + +pipeline { + agent { + dockerfile { + label 'cae-linux-build' + reuseNode true + } + } + + environment { + BASE_NAME = "deployment/dist/ddrv-cli-bundle" + EXT_NAME = "zip" + FILE_NAME = "${BASE_NAME}.${EXT_NAME}" + ARTIFACTORY_FILE_NAME = "${BASE_NAME}-${env.BRANCH_NAME}-${env.BUILD_NUMBER}.${EXT_NAME}" + HOME="." /* to resolve EACCES: permission denied, mkdir '/.npm'*/ + GH4JPL=credentials("eb12d339-d336-48d7-baab-c0ebcbe7eba0") + GH_TOKEN="${GH4JPL_PSW}" + GH_URL="https://github.jpl.nasa.gov/api/v3" + } + + stages { + // "Borrowed" from https://github.com/MarkAckert/staging-zowe-ims-plugin/blob/master/Jenkinsfile + stage('Check for Skip CI') { + steps { + script { + def result = sh (returnStatus: true, script: 'git log -1 | grep \'.*\\[skip ci\\].*\'') + if (result == 0) { + echo '"skip ci" spotted in the git commit. Aborting...' + PIPELINE_CONTROL.ci_skip = true + } + } + } + } + + stage("Prerequisites") { + when { expression { return PIPELINE_CONTROL.ci_skip == false } } + + steps { + sh("npm config set @gov.nasa.jpl.m2020.cs3:registry https://cae-artifactory.jpl.nasa.gov:443/artifactory/api/npm/npm-release-local/") + sh("make install") + } + } + + stage('Test') { + when { expression { return PIPELINE_CONTROL.ci_skip == false } } + + steps { + sh("make test") + } + } + + stage('Package') { + when { + allOf { + expression { return PIPELINE_CONTROL.ci_skip == false } + anyOf { + branch "master" + branch "develop" + } + } + } + steps { + sh("make package") + sh("cp ${FILE_NAME} ${ARTIFACTORY_FILE_NAME}") + } + } + + stage('Artifactory - Build') { + when { + allOf { + expression { return PIPELINE_CONTROL.ci_skip == false } + anyOf { + branch "master" + branch "develop" + } + } + } + steps { + script { + def server = Artifactory.newServer url: 'https://cae-artifactory.jpl.nasa.gov/artifactory', credentialsId: 'f5ab4184-4891-47f6-920e-99e2b85b3f5c' + // Create Upload Spec + //target needs to end with / + def uploadSpec = """ + {"files": [{ + "pattern": "${ARTIFACTORY_FILE_NAME}", + "target": "general-develop/gov/nasa/jpl/ammos/ids/datadrive/" + }]}""" + // Upload to Artifactory. + def buildInfo = server.upload spec: uploadSpec + server.publishBuildInfo buildInfo + } + } + } + + stage('Dry Run Release Github') { + when { + allOf { + branch "master" + expression { return PIPELINE_CONTROL.ci_skip == false } + } + } + steps { + sh ("make release-dry-run") + } + } + + stage('Release Github') { + when { + beforeInput true + allOf { + branch "master" + expression { return PIPELINE_CONTROL.ci_skip == false } + } + } + options { + timeout(time: 1, unit: 'HOURS') + } + input { + message "Does dry run look okay?" + ok "Yes, release!" + } + steps { + sh ("make release") + } + } + + stage('Artifactory - Version') { + when { + allOf { + branch "master" + expression { return PIPELINE_CONTROL.ci_skip == false } + } + } + environment { + RELEASE_VERSION = sh(script: 'cat src/release.txt', returnStdout: true).trim() + } + steps { + sh("cp ${FILE_NAME} ${BASE_NAME}-${RELEASE_VERSION}.${EXT_NAME}") + script { + def server = Artifactory.newServer url: 'https://cae-artifactory.jpl.nasa.gov/artifactory', credentialsId: 'f5ab4184-4891-47f6-920e-99e2b85b3f5c' + // Create Upload Spec + //target needs to end with / + def uploadSpec = """ + {"files": [{ + "pattern": "${BASE_NAME}-${RELEASE_VERSION}.${EXT_NAME}", + "target": "general-develop/gov/nasa/jpl/ammos/ids/datadrive/" + }]}""" + // Upload to Artifactory. + def buildInfo = server.upload spec: uploadSpec + server.publishBuildInfo buildInfo + } + } + } + } + post { + success { + deleteDir() + } + failure { + deleteDir() + } + } +} diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..3cc19ce --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,13 @@ +COPYRIGHT + +Copyright (c) 2024 California Institute of Technology (“Caltech”). U.S. Government sponsorship acknowledged. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of Caltech nor its operating division, the Jet Propulsion Laboratory, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ba46896 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +export NAME ?= datadrive-commandline +export RELEASE_NAME ?= latest + +install: + npm --prefix src/ install + +package: + npm --prefix src/ run package + +build: + docker build -t $(NAME):$(RELEASE_NAME) . + +test: + npm --prefix src/ test + +release: + npm --prefix src/ run semantic-release + +release-dry-run: + npm --prefix src/ run semantic-release-dry-run \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1109c5d --- /dev/null +++ b/README.md @@ -0,0 +1,182 @@ +# DataDrive-CommandLine +DataDrive Command Line clients + +This project will provide command line applications to interface with Datadrive/OCS. The DataDrive command line supplements tools within the OCS suite by providing a way of listening to OCS events without having to interface with AWS. + +## Installation +### From Github Release +Please visit https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/releases to get the latest and past releases. Each zip contains binaries for Linux, Windows and OSX. + +### From Source +#### Prerequisites +- NodeJS: tested with v14.15.0, versions newer should also work +#### Steps +- Clone this repository and go to `[cloned_folder]` +- Run `make package` + - Note: Make sure you have artifactory set as another npm registry by creating or updating `~/.npmrc` file with the following content added or appended. + - `@gov.nasa.jpl.m2020.cs3:registry=https://cae-artifactory.jpl.nasa.gov:443/artifactory/api/npm/npm-release-local/` + - Please reference for a more detailed read up. +- Built binary will be located in `[cloned_folder]/deployment/dist` + +## Getting Started +Now that the DataDrive CLI has been installed, please log into CSSO using the CSSO CLI via the command `csso_login`. This can be downloaded from the [csso_login](https://github.jpl.nasa.gov/M2020-CS3/csso_login/releases) Github repository. Installation instructions are also included in link above. Note: Please run `csso_login` from the extracted folder if you did not put `csso_login` into your system PATH. + +### Configure CLI +To configure the CLI, please run the following command: +- `./ddrv config -d [datadrive_middleware_hostname] -p [pep_hostname]` +- Ex: `./ddrv config -d datadrive-middle-dev.dev.m20.jpl.nasa.gov -p data.dev.m20.jpl.nasa.gov` +The command above will create a configuration JSON file in `~/.datadrive/datadrive.json`. Note: You should only need to run this once unless `~/.datadrive/datadrive.json` file is deleted. + +### Basic Subscriptions +To listen for file new files that have been added in a specific package and download the file to a specified folder. +- Ex: + - `./ddrv subscribe -p [ocs_package_name] -o [output_directory_path_here] -r` + - Note: `-r` flag is to retain the ocs path + - Note: `--help` flag displays help information + - Note: Underneath the covers, this CLI uses the web socket API from the DataDrive Middleware, which itself polls a SQS queue that receives update events from OCS's SNS. + +### Subscriptions with Wildcard filtering +Similar to **Basic Subscriptions** above, but filter for only files that match a wildcard filter. +- Ex: `./ddrv subscribe -p [ocs_package_name] -o [output_directory_path_here] -r -f [wildcard_filter]` +- `-f` flag should be followed by a wildcard filter. For example, `nick*.txt` will match `nick_09-24-2019.txt` and not `nick_09-24-2019.gif`. +- **Basic Subscriptions** essentially is running the `-f` flag with `*` as its value. + +### Subscriptions with Regex filtering +Similar to **Basic Subscriptions** above, but filter for only files that match a regex filter. +- Ex: `./ddrv subscribe -p [ocs_package_name] -o [output_directory_path_here] -r -x [regex_filter]` +- `-x` flag should be followed by a regex filter. For example, `nick.*\.txt` will match `nick_09-24-2019.txt` and not `nick_09-24-2019.gif`. +- The regex filter uses ElasticSearch's regex syntax and does not take anchor strings indicating beginning `^` or end `$`. Values put into the filter will always be anchored and the regex filter provided must match the entire string. For more information on the regex expression syntax, please visit . +- The regex filter requires a "/" when matching a path, otherwise it will match the expression against the file basename + +### Skip Unchanged +`-S` or `--skip-unchanged`: Only download files that are new or have changed. + +Uses the OCS index event field `s3_object_changed` which indicates if associated file is considered changed in S3. +If a user specifies the skip-unchanged flag, then for each OCS file event, the CLI will: + +- check if the OCS event indicates that file is unchanged; +- check if local filesystem already contains a file with same name in the output location. +- If both S3 unchanged and local file exists, then OCS file event will be skipped. + +Note: Skipping only applies to OCS events. When performing Playback, all files are assumed to be changed, even if they actually weren't. + +### Subscriptions with Saved Search +Instead of defining a `ocs_package_name` with the `-p` flag, you can subscribe to a saved search that can be created in the DataDrive UI using the `-s` flag. +- Ex: `./ddrv subscribe -p [saved_search_name] -o [output_directory_path_here] -r` +- Note: The above command uses the `-r` flag which will retain the ocs path. + +### Subscriptions with your own script +You can run a single script that will be called for every notification. +- Ex: `./ddrv subscribe -p [ocs_package_name] -o [output_directory_path_here] -r -x [regex_filter] --plugin-path [path_to_script]` +- `--plugin-path` flag's value should be an absolute path to your script. +- Please reference for examples scripts that you can take inspiration from. +- You must inherit from `DdPlugin` class and implement `processItem` function. + +### Playback events +You can "playback" events that have since happened from a certain date. When "playback" is enabled, the CLI will query OCS for documents (that have not been deleted) since the last saved checkpoint date. +- `-P` flag is used to denote the use of the playback option. +- The checkpoint date is saved in `YYYY-MM-DDTHH:mm:ss.SSSZZ` format in the `/.datadrive/checkpoint.txt` file in the specified output folder. + +## Unit Test +To run unit tests, go to `src/` folder and run the command `npm test`. Note: To avoid confusion, the commands below is for manual testing without packaging files into a single binary. + +## Manual Tests +Please note, these test cases are for **developers** performing manual test from the source code. For others that are performing these tests via the published binary, you would start commands below with `ddrv` instead of `node ddrv.js`. +### Test 1 - Subscriptions Only +#### Steps +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o tmp -p DataDrive-Dev-Congruent-1` or `./ddrv subscribe -o tmp -p DataDrive-Dev-Congruent-1` +- Upload a file into the specified package in the example above "DataDrive-Dev-Congruent-1" +#### Expected Results +- File should be downloaded into the specified folder. In example above, the `tmp` folder. +- A date should be written into the `/.datadrive/checkpoint.txt` file under the specified folder. + - Ex: `2019-09-08T11:51:28.000-0700` + +### Test 2 - Subscriptions and Playback Events +#### Steps +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o /tmp -p DataDrive-Dev-Congruent-1 -P` or `./ddrv subscribe -o tmp -p DataDrive-Dev-Congruent-1 -P` +#### Expected Results +- Files since the date listed in `/.datadrive/checkpoint.txt` will be downloaded into the specified folder. +- The CLI will now be listening for new files uploaded into the specified package. +- Reference **Subscription Only** for expected results for file subscriptions. + +### Test 3 - Playback Events on Deleted File +#### Steps +- Upload files into specified package then delete these files. +- Make sure `/.datadrive/checkpoint.txt` file has a date/time that is earlier than the date/time for uploaded files above. +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o tmp -p DataDrive-Dev-Congruent-1 -P` or `./ddrv subscribe -o tmp -p DataDrive-Dev-Congruent-1 -P` +#### Expected Results +- Files uploaded above will **NOT** be downloaded by the CLI. + +### Test 4 - Adjusting checkpoint.txt +#### Steps +- Upload files into specified package. +- Go into `/.datadrive/checkpoint.txt` file and adjust the date to an earlier time before uploaded files. + - Note: The time format must be in a valid format such as... Ex: `2019-09-08T11:51:28.000-0700`. +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o tmp -p DataDrive-Dev-Congruent-1 -P` or `./ddrv subscribe -o tmp -p DataDrive-Dev-Congruent-1 -P` +#### Expected Results +- Files since given date will be downloaded. + +### Test 5 - Same file name +#### Steps +- CLI tries to download a file with the same file name from the middleware (even if the contents are different) +#### Expected Results +- An error will be given as the file already exists. + +### Test 6 - Wildcard Filter +#### Steps +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o tmp -p DataDrive-Dev-Congruent-1 -f 'msl*.txt'` or `./ddrv subscribe -o tmp -p DataDrive-Dev-Congruent-1 -f 'msl*.txt'` +- Upload a file with a file name "msl_sol_123.txt". +- Upload a file with a file name "europa_day_2345.txt". +#### Expected Results +- "msl_sol_123.txt" file will be downloaded to the `tmp` directory. +#### Cleanup +- Delete "msl_sol_123.txt" from both DataDrive web app and files in the `tmp` directory. + +### Test 7 - Regex Filter +#### Steps +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o tmp -p DataDrive-Dev-Congruent-1 -x 'msl.*\.txt'` or `./ddrv subscribe -o tmp -p DataDrive-Dev-Congruent-1 -x 'msl.*\.txt'` +- Upload a file with a file name "msl_sol_123.txt". +- Upload a file with a file name "europa_day_2345.txt". +#### Expected Results +- "msl_sol_123.txt" file will be downloaded to the `tmp` directory. +#### Cleanup +- Delete "msl_sol_123.txt" from both DataDrive web app and files in the `tmp` directory. + +### Test 8 - Regex Filter and Wildcard Filter +#### Steps +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o tmp -p DataDrive-Dev-Congruent-1 -x 'msl.*\.txt' -f 'msl*.txt'` or `ddrv subscribe -o tmp -p DataDrive-Dev-Congruent-1 -x 'msl.*\.txt' -f 'msl*.txt'` +#### Expected Results +- An error will be returned to the user as you cannot specify both regex and wildcard filter together. + +### Test9 - Test out subscripts for a saved search +#### Steps +- Ensure that there is a folder called `tmp_ss` created where you will be downloading file. +- Ensure that a saved search has been created. This can be done using the DataDrive UI. Create a saved search that will filter based on a directory path in `ocs_path` field and with value of `/jeff` +- Run the command line such as the example below. Note: the `-s` flag is for the saved search name created above. + - Ex: `node ddrv.js subscribe -o tmp_ss -s 'jeffliu_saved_search_2' -r` +- Upload a file with a name "seeme123.txt" into `/jeff` folder. +- Upload a file with a name "seemenot123.txt" not into `/jeff` folder. +#### Expected Results +- "seeme123.txt" file will be downloaded to the `tmp_ss` directory under `/jeff` folder. +#### Cleanup +- Delete "seeme123.txt" from files in the `tmp_ss` directory. +- Delete "seemenot123.txt" from files in the `tmp_ss` directory. + +### Test 10 - Adjusting checkpoint.txt for a saved search +#### Steps +- This test case depends on test 9 above. Make sure that you run test 9 first. +- Go into `tmp_ss/.datadrive/checkpoint.txt` file and adjust the date to an earlier time before uploaded files in test 9. + - Note: The time format must be in a valid format such as... Ex: `2019-09-08T11:51:28.000-0700`. +- Run the command line such as the example below. + - Ex: `node ddrv.js subscribe -o tmp_ss -s 'jeffliu_saved_search_2' -P` +#### Expected Results +- Files since given date will be downloaded. In this case, "seeme123.txt" should be downloaded. +#### Cleanup +- Delete "seeme123.txt" from files in the `tmp_ss` directory. diff --git a/bin/publish.bat b/bin/publish.bat new file mode 100644 index 0000000..a38d4b2 --- /dev/null +++ b/bin/publish.bat @@ -0,0 +1,3 @@ +@echo off +set DD_ROOT=".." +node %DD_ROOT%\src\dd-package-publish.js -p DataDrive-Dev-1 -s C:\temp\datadrive_git_repos\ddcli_110818\publish_bucket\ \ No newline at end of file diff --git a/bin/subscribe.bat b/bin/subscribe.bat new file mode 100644 index 0000000..04979ff --- /dev/null +++ b/bin/subscribe.bat @@ -0,0 +1,3 @@ +@echo off +set DD_ROOT=".." +node %DD_ROOT%\src\dd-package-subscribe.js -p DataDrive-Dev-1 -o C:\temp\datadrive_git_repos\ddcli_110818\subscribe_bucket\ \ No newline at end of file diff --git a/etc/run.examples b/etc/run.examples new file mode 100644 index 0000000..13e7183 --- /dev/null +++ b/etc/run.examples @@ -0,0 +1,2 @@ +node ddrv-publish.js -p DataDrive-Dev-Congruent-1 -s sourceDir +node dd-package-publish.js -p DataDrive-Experiment-1 -s C:\temp\datadrive_git_repos\ddcli_110818\publish_bucket\ diff --git a/etc/sample_sns_mesg b/etc/sample_sns_mesg new file mode 100644 index 0000000..143c9b9 --- /dev/null +++ b/etc/sample_sns_mesg @@ -0,0 +1,21 @@ +First example: +{ +"package_id": "H1OFOQyZ7", +"dataset_id": "test", +"ocs_full_name": "test", +"ocs_url": "test", +"event_type": "OBJ_REMOVED_DELETED", +"user": "test", +"event_time": "test" +} + +Sample file: +{ +"package_id": "H1OFOQyZ7", +"dataset_id": "test", +"ocs_full_name": "test", +"ocs_url": "test", +"event_type": "OBJ_INDEXED", +"user": "test", +"event_time": "test" +} \ No newline at end of file diff --git a/src/CHANGELOG.md b/src/CHANGELOG.md new file mode 100644 index 0000000..383eb74 --- /dev/null +++ b/src/CHANGELOG.md @@ -0,0 +1,154 @@ +## [1.7.3](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.7.2...v1.7.3) (2022-01-12) + + +### Bug Fixes + +* update jenkins node ([#86](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/86)) ([d09e2b3](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/d09e2b3)), closes [#72](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/72) [#79](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/79) + +## [1.7.2](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.7.1...v1.7.2) (2021-08-23) + + +### Bug Fixes + +* Binary error ([#81](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/81)) ([c658b02](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/c658b02)), closes [#72](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/72) [#79](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/79) + +## [1.7.1](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.7.0...v1.7.1) (2021-08-23) + + +### Bug Fixes + +* use cae-artifactory to avoid docker-hub limits + upgrade to node 14.15 since it is already tested + minor update in README sample command ([#79](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/79)) ([d91afcb](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/d91afcb)) + +# [1.7.0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.6.2...v1.7.0) (2021-05-11) + + +### Features + +* Update node version ([#72](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/issues/72)) ([eca60ad](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/eca60ad)) + +## [1.6.2](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.6.1...v1.6.2) (2020-11-25) + + +### Bug Fixes + +* fixed bug where you could not use regex filter ([560bedc](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/560bedc)) + +## [1.6.1](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.6.0...v1.6.1) (2020-11-20) + + +### Bug Fixes + +* resolved csso token renewal bug; originally reported in MSTRIAGE-2837 ([a232626](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/a232626)) + +# [1.6.0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.5.0...v1.6.0) (2020-11-17) + + +### Features + +* added playback for saved searches ([511f3be](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/511f3be)) +* added support for subscribing to a saved search ([86da2e0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/86da2e0)) +* updated to 6.5.0 ocs-js-client library ([06b7185](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/06b7185)) + +# [1.5.0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.4.4...v1.5.0) (2020-09-22) + + +### Features + +* updated to 6.5.0 ocs-js-client library ([333448f](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/333448f)) + +## [1.4.4](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.4.3...v1.4.4) (2020-08-24) + + +### Bug Fixes + +* added better log message when you cannot connect to DataDrive middleware ([5292324](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/5292324)) +* changed the way token expiration is checked and added unit tests ([a205be3](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/a205be3)) +* check if csso token is about to expire and if so, reload the CSSO Token; note: this DOES NOT renew the csso token ([c940401](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/c940401)) +* reason why web socket connect is closed is now displayed as opposed to debug log ([c590fde](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/c590fde)) + +## [1.4.3](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.4.2...v1.4.3) (2020-06-23) + + +### Bug Fixes + +* added better debugging statements and added missing semi-colons ([8e55236](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/8e55236)) +* fix bug where CLI version number is not shown ([40415ca](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/40415ca)) + +## [1.4.2](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.4.1...v1.4.2) (2020-04-28) + + +### Bug Fixes + +* updated pkg libary to 4.4.7 to fix "Maximum call stack size exceeded" error ([9344162](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/9344162)) + +## [1.4.1](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.4.0...v1.4.1) (2020-03-25) + + +### Bug Fixes + +* added validation for datadrive upload status messages, ignore and then suppress logging for those messages ([9b92515](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/9b92515)) + +# [1.4.0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.3.1...v1.4.0) (2020-03-24) + + +### Features + +* updated OCS JS library to 6.4.x ([bf4c32e](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/bf4c32e)) + +## [1.3.1](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.3.0...v1.3.1) (2020-03-24) + + +### Bug Fixes + +* updated OCS JS library to 6.3.x ([70c2c45](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/70c2c45)) + +# [1.3.0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.2.1...v1.3.0) (2020-03-24) + + +### Bug Fixes + +* added ability to set datadrive middleware hostname and pep hostname via environment variables ([b76a0b2](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/b76a0b2)) +* added flag to not load configs in DdSubConfig class; ([7486f65](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/7486f65)) +* removed "Pulse authentication issue: no auth token" error message ([51f0f6e](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/51f0f6e)) +* removed functions that interact with csso "authorization_token" as that is now deprecated and no longer being used ([a0752b9](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/a0752b9)) +* updated how cookies are passed into requests to ensure that this will work with the new CSSO proxy ([5924320](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/5924320)) + + +### Features + +* added "show" command to list package names and descriptions ([75615d5](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/75615d5)) + +## [1.2.1](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.2.0...v1.2.1) (2019-09-27) + + +### Bug Fixes + +* validHTTPResponse function incorrectly accepted 400 status codes ([d2d1054](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/d2d1054)) + +# [1.2.0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.1.0...v1.2.0) (2019-09-24) + + +### Features + +* added ability to run a nodejs script upon receipt of an event ([e6541b2](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/e6541b2)) + +# [1.1.0](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/compare/v1.0.0...v1.1.0) (2019-09-21) + + +### Features + +* added playbacks, and regex filtering ([4278cd6](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/4278cd6)) + +# 1.0.0 (2019-09-11) + + +### Features + +* automate the release to Github and generation of release notes ([7f722ea](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/7f722ea)) + +# 1.0.0 (2019-09-11) + + +### Features + +* automate the release to Github and generation of release notes ([7f722ea](https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine/commit/7f722ea)) diff --git a/src/README.TXT b/src/README.TXT new file mode 100644 index 0000000..99dbaea --- /dev/null +++ b/src/README.TXT @@ -0,0 +1,23 @@ +This is the M2020 DataDrive CLI bundle. + +Once installed, you must configure DataDrive by running "ddrv config". Use "ddrv config --help" to see +the available options, including the default values. + +The DataDrive CLI extends functionality of the OCS Command line tools by adding support for +the following commands: +1) subscribe: Package-based subscriptions, where files added to OCS is automatically downloaded to the + local system; +2) publish: Package-based publish sessions, where files added to a local directory can be automatically + push to a remote OCS package. + +For help information, use "ddrv [command] --help". + +Additional help is available at: + +TODO: ADD Help URL + +You can also learn more about the OCS CLI by visiting: + +https://github.jpl.nasa.gov/M2020-CS3/m2020-data-lake/wiki/The-OCS-Command-Line-Interface-%28CLI%29 + + diff --git a/src/buildScript.js b/src/buildScript.js new file mode 100644 index 0000000..5e96108 --- /dev/null +++ b/src/buildScript.js @@ -0,0 +1,199 @@ +'use strict'; + +const shelljs = require('shelljs'); +const minimist = require('minimist'); +const fs = require('fs-extra'); +const path = require('path'); + +const WORKSPACE = process.env.WORKSPACE || process.cwd(); +const DIST_DIR = `${__dirname}-dist`; +const SVC_NAME = 'cli'; //path.basename(__dirname); +const ZIP_FILE = `ddrv-${SVC_NAME}-bundle.zip`; +const DEPLOY_DIR = '../deployment'; +const PKG_DIR = './ddrv-cli'; + +//console.log(`DIST_DIR = ${DIST_DIR}`) +//console.log(`DEPLOY_DIR = ${DEPLOY_DIR}`) +//console.log(`PKG_DIR = ${PKG_DIR}`) + + +const README_FILE = 'README.TXT'; + +const { + clean, + build, + deploy +} = minimist(process.argv.slice(2)); + +let logLevel = 0; + +function upLevel(lvlDelta) { + logLevel += lvlDelta; +} + +function log(msg) { + console.log(' '.repeat(logLevel) + msg); +} + +function err(msg) { + console.error(' '.repeat(logLevel) + msg); +} + +function doClean() { + doBuildClean(); + doDeployClean(); +} + +function doBuildClean() { + log(`Remove distribution directory ${DIST_DIR} `); + shelljs.cd(`${DIST_DIR}/..`); + fs.removeSync(DIST_DIR); +} + +function doDeployClean() { + let deplDir = path.resolve(DIST_DIR, DEPLOY_DIR); + log(`Remove deployment directory ${deplDir} `); + shelljs.cd(`${deplDir}/..`); + fs.removeSync(deplDir); +} + +function doInit() { + log(`Initializing distribution directory ${DIST_DIR}.`); + fs.emptyDirSync(DIST_DIR); +} + +function doCopyRecursive(fromDir, toDir) { + const files = fs.readdirSync(fromDir); + if (!files || files.length === 0) { + err(`Directory ${fromDir} is empty or not readable???.`); + process.exit(1); + } + + // For each file in the directory + for (let i = 0; i < files.length; i++) { + // get the full path of the file + const fromFilePath = path.join(fromDir, files[i]); + const toFilePath = path.join(toDir, files[i]); + + // Recurse if directory. + const _stats = fs.lstatSync(fromFilePath); + if (_stats.isDirectory()) { + if (files[i] === 'core' || files[i] === 'plugins' || files[i] === 'exceptions') { + log(`Copying directory ${fromFilePath}...`); + upLevel(1); + doCopyRecursive(fromFilePath, toFilePath); + upLevel(-1); + } + } else { + log(`Copying file ${files[i]}`); + fs.copySync(fromFilePath, toFilePath); + } + + } +} + +function doCopy() { + log(`Copying files from ${__dirname} to ${DIST_DIR}.`); + upLevel(1); + doCopyRecursive(__dirname, DIST_DIR); + shelljs.cd(DIST_DIR); + //log('Editing package.json'); + //shelljs.sed('-i', /file..*ocs-js-client/, 'file:./ocs-js-client', 'package.json'); + //log('Getting the OCS client'); + //shelljs.exec('git clone --depth 1 https://github.jpl.nasa.gov/MIPL/DataDrive-CommandLine.git'); + fs.removeSync(`${DIST_DIR}/DataDrive-CommandLine.git`); + // shelljs.rm('-r', './DataDrive-CommandLine/test'); + // shelljs.rm('-r', './DataDrive-CommandLine/docs'); + upLevel(-1); +} + +function doConfig() { + log(`Setting up NPM config params in ${DIST_DIR}.`); + if (process.env.VENUE || process.env.BRANCH) { + log(`Found environment variables VENUE=${process.env.VENUE} and BRANCH=${process.env.BRANCH}`); + const NPMRC = `${DIST_DIR}/.npmrc`; + if (process.env.VENUE) { + fs.writeFileSync(NPMRC, `venue = "${process.env.VENUE}"\n`); + } + if (process.env.BRANCH) { + fs.appendFileSync(NPMRC, `branch = "${process.env.BRANCH}"\n`); + } + } else { + log('No environment variables for VENUE/BRANCH. Deployment will use the defaults from package.json'); + } +} + +function doInstall() { + log(`Running NPM INSTALL in ${DIST_DIR}.`); + shelljs.cd(DIST_DIR); + shelljs.exec('npm install --production'); +} + +function doBuild(clean = true) { + log(`Building ${__dirname} in ${DIST_DIR}:`); + upLevel(1); + doInit(); + doCopy(); + doConfig(); + doInstall(); + upLevel(-1); +} + +function doPackage() { + shelljs.cd(DIST_DIR); + for (const tgtOS of ['linux', 'macos', 'win']) { + log(`Packaging the DataDrive CLI for ${tgtOS}`); + fs.ensureDirSync(`${PKG_DIR}/${tgtOS}-x64`); + shelljs.exec(`pkg . -t ${tgtOS}-x64 --output ${PKG_DIR}/${tgtOS}-x64/ddrv`); + shelljs.chmod(555, `${PKG_DIR}/${tgtOS}-x64/ddrv*`); + } + // Move the README + log(`Copying ${README_FILE}.`); + shelljs.cp(`${README_FILE}`, `${PKG_DIR}`); + shelljs.cd(PKG_DIR); + // ZIP it up, ready for staging. + shelljs.exec(`zip -rq ${ZIP_FILE} .`); + shelljs.mv(`${ZIP_FILE}`, '..'); +} + +function doStage() { + let stageDir = path.resolve(DIST_DIR, DEPLOY_DIR); + stageDir = `${stageDir}/dist`; + + log(`Staging ${DIST_DIR} to ${stageDir}/${ZIP_FILE}:`); + fs.ensureDirSync(stageDir); + shelljs.cd(DIST_DIR); + const _ret = shelljs.mv(`${ZIP_FILE}`, `${stageDir}/${ZIP_FILE}`); + if (_ret.code !== 0) { + err(_ret.stderr); + } +} + +function doDeploy() { + log(`Deploying service ${SVC_NAME}`); + upLevel(1); + doBuild(); + doPackage(); + doStage(); + doBuildClean(); + + upLevel(-1); +} + +function ensureProjectDir() { + process.chdir(WORKSPACE); +} + +// ------------------------------------------------------------------------------------------------- +// Start of "main". +// ------------------------------------------------------------------------------------------------- +ensureProjectDir(); +if (deploy) { + doDeploy(); + //log(`Deploy option currently not supported`); +} else if (clean) { + doClean(); +} else if (build) { + doBuild(); +} + diff --git a/src/core/AxiosWrapper.js b/src/core/AxiosWrapper.js new file mode 100644 index 0000000..4def206 --- /dev/null +++ b/src/core/AxiosWrapper.js @@ -0,0 +1,29 @@ +/** + * @author wphyo + * Created on 1/7/22. + */ +const axios = require('axios') + +class AxiosWrapper { + async request(options) { + try { + let result = await axios.request(options) + return result.data + } catch (e) { + // TODO better handling of axios exception + let err = new Error() + if (e['response'] === undefined) { + err.message = `No response key. ${e.toString()}` + err.statusCode = 503 + throw err + } + err.message = JSON.stringify(e.response.data) + err.statusCode = e.response.status + throw err + } + } + static builder() { + return new AxiosWrapper() + } +} +exports.AxiosWrapper = AxiosWrapper diff --git a/src/core/DataDriveMWServiceSettings.js b/src/core/DataDriveMWServiceSettings.js new file mode 100644 index 0000000..e29d37e --- /dev/null +++ b/src/core/DataDriveMWServiceSettings.js @@ -0,0 +1,52 @@ +/** + * @author wphyo + * Created on 6/1/22. + */ +const AxiosWrapper = require('./AxiosWrapper').AxiosWrapper +const https = require('https'); +const DdUtils = require('./DdUtils') +const DdLogger = require('./DdLogger').logger + +class DataDriveMWServiceSettings { + constructor(ddHost, cssoToken) { + this._datadriveHost = ddHost; + this._cssoToken = cssoToken; + this._ocsVenue = null; + this._ocsUrl = null; + this._pepUrl = null; + } + + static builder(ddHost, cssoToken) { + return new DataDriveMWServiceSettings(ddHost, cssoToken) + } + + getOcsEndpointHost() { + return this._ocsUrl + } + + getOcsApiStage() { + return this._ocsVenue; + } + + async loadSettings() { + const options = { + method: 'GET', + url: `${this._datadriveHost}/`, + headers: { + Cookie: `ssosession=${this._cssoToken}` + }, + httpsAgent: new https.Agent({rejectUnauthorized: false}), + } + try { + const ddSetting = await AxiosWrapper.builder().request(options) + this._ocsUrl = ddSetting['ocs_endpoint'] + this._ocsVenue = ddSetting['ocs_stage'] + DdLogger.debug("OCS Settings from DataDrive middleware [Url: " + this._ocsUrl + ", Stage: " + this._ocsVenue + "]"); + + } catch (e) { + DdUtils.errorAndExit(`Error occurred while querying DataDrive host for OCS settings. URL: "${options['url']}" Status code: ${e.statusCode} Error: ${e.message}`); + } + } +} + +exports.DataDriveMWServiceSettings = DataDriveMWServiceSettings diff --git a/src/core/DdCliConfigFileIO.js b/src/core/DdCliConfigFileIO.js new file mode 100644 index 0000000..1168d95 --- /dev/null +++ b/src/core/DdCliConfigFileIO.js @@ -0,0 +1,162 @@ +/** + * @author wphyo + * Created on 1/8/22. + */ +'use strict'; + + +const DdUtils = require('./DdUtils.js'); +const jsonTryParse = require('../core/utils').jsonTryParse +const DdLogger = require('./DdLogger.js').logger; +const DdConstants = require('./DdConstants.js'); + + +//required for writing files synchronously +const fs = require('fs'); +const fse = require('fs-extra'); + +//Setup the env config using user home dir + +const DD_CFG_FILE = DdUtils.getDdCfgFilepath(); + +//Setup scripts to be called +const DD_CFG_SCRIPT = "dd-config"; + +let SINGLETON_INSTANCE = null + +class DdCliConfigFileIO { + constructor() { + if (SINGLETON_INSTANCE === null) { + this.__failOnError = true + this.__cachedConfig = null + SINGLETON_INSTANCE = this + } + return SINGLETON_INSTANCE + } + + setFailOnError(value) { + this.__failOnError = value + return this + } + + static builder() { + return new DdCliConfigFileIO() + } + + /** + * Tests for existence of DataDrive config file + * @return {boolean} + */ + ddCfgFileExists() { + return DdUtils.fileExists(DD_CFG_FILE) + } + + readConfig(failOnError = true) { + if (this.__cachedConfig !== null) { + return this.__cachedConfig + } + if (!this.ddCfgFileExists()) { + if (failOnError) { + DdUtils.errorAndExit(`ERROR reading the configuration file ${DD_CFG_FILE}.\nRun '${DD_CFG_SCRIPT}' to save a valid configuration.`); + } + return null + } + let fileData = null + try { + fileData = fs.readFileSync(DD_CFG_FILE, 'utf8') + } catch (e) { + if (e.code !== 'ENOENT') { + if (failOnError) { + DdUtils.errorAndExit(`ERROR reading the configuration file ${DD_CFG_FILE}.\n${e}`) + } else { + return null + } + } + } + + let tempConfig = jsonTryParse(fileData) + if (tempConfig['error'] !== undefined) { + if (failOnError) { + DdUtils.errorAndExit(`ERROR reading the configuration file ${DD_CFG_FILE}. Run '${DD_CFG_SCRIPT}' to save a valid configuration.`); + } else { + return null + } + } + tempConfig = tempConfig['result'] + + // Fill in missing values with NULLs. + if (!tempConfig.hasOwnProperty(DdConstants.PROP_DATADRIVE_HOST)) { + tempConfig[DdConstants.PROP_DATADRIVE_HOST] = null; + } + + if (!tempConfig.hasOwnProperty(DdConstants.PROP_PEP_HOST)) { + tempConfig[DdConstants.PROP_PEP_HOST] = null; + } + + this.__cachedConfig = tempConfig; + + return this.__cachedConfig; + } + + /** + * This only writes DataDrive specific configuration, ignoring + * anything that is for OCS. + */ + writeConfig(opt) { + //don't fail if file does not already exist, but check for null + let _cfg = this.readConfig(false); + if (!_cfg) { + _cfg = {}; + } + // Overwrite the current configuration with the supplied values. + if (opt.datadriveHost || opt.pepHost) { + if (opt.datadriveHost) { + _cfg[DdConstants.PROP_DATADRIVE_HOST] = opt.datadriveHost; + } + if (opt.pepHost) { + _cfg[DdConstants.PROP_PEP_HOST] = opt.pepHost; + } + } + // Write to the config file. + try { + console.log(DD_CFG_FILE, _cfg) + fse.outputFileSync(DD_CFG_FILE, JSON.stringify(_cfg, null, 2)) + } catch (error) { + DdUtils.errorAndExit(`Unable to write to the DataDrive configuration file ${DD_CFG_FILE}. Make sure that the path exists and that the directory is accessible to the logged in user.`) + } + this.__cachedConfig = _cfg + } + + getConfigValue(cfgName) { + let cfg = this.readConfig(this.__failOnError); + if (cfg[cfgName] !== undefined) { + return cfg[cfgName] + } + return null + } + + /** + * Get environment variable value + * @param {string} envName + */ + getEnvValue(envName) { + if (envName in process.env) { + return process.env[envName] + } + return null + } + + getDatadriveHost() { + return this.getEnvValue(DdConstants.ENV_DATADRIVE_HOST) || this.getConfigValue(DdConstants.PROP_DATADRIVE_HOST); + } + + getPepHost() { + return this.getEnvValue(DdConstants.ENV_PEP_HOST) || this.getConfigValue(DdConstants.PROP_PEP_HOST); + } + + getDebugEnabled() { + return this.getEnvValue(DdConstants.ENV_DEBUG_ENABLED) || this.getConfigValue(DdConstants.PROP_DEBUG_ENABLED); + } +} + +exports.DdCliConfigFileIO = DdCliConfigFileIO diff --git a/src/core/DdConfig.js b/src/core/DdConfig.js new file mode 100644 index 0000000..044f49e --- /dev/null +++ b/src/core/DdConfig.js @@ -0,0 +1,173 @@ +const fs = require('fs'); +const path = require('path'); +const globToRegExp = require('glob-to-regexp'); +const DdConsts = require('./DdConstants.js'); +const SsoToken = require('./SsoToken.js'); +const DdUtils = require('./DdUtils.js'); +const DdLogger = require('./DdLogger.js').logger; +const {DdCliConfigFileIO} = require('./DdCliConfigFileIO'); +const OcsUtils = require('./OcsUtils.js'); +//OCS library +const OCS = require('@gov.nasa.jpl.m2020.cs3/ocs-js-client'); + +/** + * Definition of the DataDrive Web Socket client + * + * @type {DdConfig} + */ +class DdConfig { + /** + * @constructor + * @param {object} program - Command object from Commander library + * @param {boolean} load_config - Default: true; load configs such as hostnames and csso token; not loading config is used for unit tests + */ + constructor(program, load_config=true) { + this.ocsUtils = null + //lets assume the worst case... + this.wasConfiguredSuccessfully = false; + this.ssoTokenApi = undefined; + this.cssoToken = undefined; + this.dataDriveHost = undefined; + this.pepUrl = undefined; + this.ocsHost = undefined; + this.ocsAPIDeployment = undefined; + + if (load_config) { + let ddHost = DdCliConfigFileIO.builder().getDatadriveHost(); + + if (! ddHost) { + DdLogger.error('Missing required configuration: '+DdConsts.PROP_DATADRIVE_HOST); + DdLogger.error('Please check your configuration via the "dd-config" command.'); + return null; + } + let pepHost = DdCliConfigFileIO.builder().getPepHost(); + if (! pepHost) { + DdLogger.error('Missing required configuration: '+DdConsts.PROP_PEP_HOST); + DdLogger.error('Please check your configuration via the "dd-config" command.'); + return null; + } + + this.dataDriveHost = "https://" + ddHost; + this.pepUrl = "https://" + pepHost; + + //Check the environment for the DEBUG state + let debugEnvVal = DdCliConfigFileIO.builder().getDebugEnabled(); + if (DdUtils.isValueTrue(debugEnvVal)) + { + DdLogger.setDebugEnabled(true); + } + + //CSSO token + this.ssoTokenApi = new SsoToken(); + let token = this.ssoTokenApi.getToken(); + if (DdUtils.isEmptyOrNullString(token)) + { + throw Error(`Could not load CSSO credentials/token.`); + } + this.cssoToken = token; + } + }; + + getPepUrl() { + return this.pepUrl + } + + getDataDriveHost() { + return this.dataDriveHost + } + + getOcsHost() { + return this.ocsHost + } + + getOcsUtils() { + return this.ocsUtils + } + + //--------------------------------------------------------------------- + + setOcsSettings(host, venue) { + this.ocsHost = host; + this.ocsAPIDeployment = venue; + }; + + //--------------------------------------------------------------------- + + getCssoToken() { + return this.cssoToken; + }; + + getUserNameFromCssoToken() { + // Ex: ::<32 random characters> + const splits = this.cssoToken.split(":"); + return splits[1]; + } + + reloadCssoToken() { + this.ssoTokenApi.loadToken(); + let newToken = this.ssoTokenApi.getToken(); + if (newToken === this.cssoToken) { + DdLogger.info("CSSO token has not changed, NOT reloading..."); + return false + } + DdLogger.info("CSSO token has changed, reloading..."); + this.cssoToken = newToken; + return true + } + + /** + * Reload the CSSO Token from .cssotoken folder if ths token is about to expire; default is 1 hour before expiration + * Note: This actually DOES NOT renew the token for you, unfortunately, right now you have to do that seperately via a cron job. + * Note: This function also does not reconnect the websocket; this function will return true or false to denote whether or not + * csso token has been reloaded. + */ + reloadIfSSOTokenAboutToExpire() { + if (this.ssoTokenApi.isTokenAboutToExpired()) { + DdLogger.info("Attempting to reload CSSO token from 'ssosession' file because it is about to expire."); + return this.reloadCssoToken(); + } + return false; + } + + //--------------------------------------------------------------------- + + isConfigured() { + return this.wasConfiguredSuccessfully; + } + + configured() { + this.wasConfiguredSuccessfully = true; + } + + //--------------------------------------------------------------------- + + /** + * Create OCS client object based on ocsHost and ocsAPIDeployment + */ + createOcsClient() + { + //CREATE OCS CLIENT + let ocsConfig = { + ocsEndpointHost: this.ocsHost, + ocsApiStage: this.ocsAPIDeployment + }; + + let ocsClient = new OCS(ocsConfig); + return ocsClient; + } + + /** + * Initialize OCS client and ocsUtils class + */ + initiate_OcsClient() + { + + //create an OCS client + this.ocsClient = this.createOcsClient(); + + //create an OCS utils layer + this.ocsUtils = OcsUtils.builder(this.ocsClient, this.cssoToken) + } +} + +module.exports = DdConfig; diff --git a/src/core/DdConstants.js b/src/core/DdConstants.js new file mode 100644 index 0000000..1861176 --- /dev/null +++ b/src/core/DdConstants.js @@ -0,0 +1,87 @@ +'use strict'; + +const DdPackageJSON = require('../package.json'); + +const CLIENT_NAME = 'DataDrive CLI'; +const CLIENT_VERSION = DdPackageJSON.version; +const CLIENT_TITLE = CLIENT_NAME + " " + CLIENT_VERSION; + +//Event types from the OCS object event emitted +const OCS_EVENTYPE_OBJECT_INDEXED = 'OBJ_INDEXED'; +const OCS_EVENTYPE_OBJECT_REMOVED = 'OBJ_REMOVED_FROM_INDEX'; +const OCS_EVENTYPE_OBJECT_DELETED = 'OBJ_REMOVED_DELETED'; + +//OCS Package metadata field names +const OCS_PACKAGE_NAME = "name"; +const OCS_PACKAGE_DESCRIPTION = "description"; + +//This needs to be configurable at some point +//const DATADRIVE_HOST = "https://datadrive-mid-exp.m20-dev.jpl.nasa.gov/"; + +//Our Environment...er...Json file will be located +const CFG_FILEDIR = ".datadrive"; +const CFG_FILENAME = "datadrive.json"; + + +//OCS's versions of where their environment file will be located +const OCS_CFG_FILEDIR = ".ocs"; +const OCS_CFG_FILENAME = "ocs.json"; + +//Data drive configuration +const PROP_DATADRIVE_HOST = "datadriveHost"; +const ENV_DATADRIVE_HOST = "DATADRIVEHOST"; +const PROP_PEP_HOST = "pepHost"; +const ENV_PEP_HOST = "PEPHOST"; +const PROP_DEBUG_ENABLED = "debugEnabled"; +const ENV_DEBUG_ENABLED = "DEBUG"; + +const DEFAULT_DD_HOST = 'datadrive-mid.m20-dev.jpl.nasa.gov'; +const DEFAULT_PEP_HOST = 'data.m20-dev.jpl.nasa.gov'; + + +//OCS configuration +const PROP_OCS_HOST = "ocsEndpointHost"; +const PROP_OCS_API_DEPLOYMENT = "ocsApiStage"; + +//Event types... either OCS or PLAYBACK +const EVENTTYPE_OCS = 'OCS'; +const EVENTTYPE_PLAYBACK = 'PLAYBACK'; + +//S3 related constants +const S3_PROTOCOL = 's3://'; +const S3_URL_PATTERN = '^s3://([^/]+)/(.*?([^/]+))$'; +const S3_URL_REGEX = new RegExp(S3_URL_PATTERN); + +// This is for debug on nttooles Mac running middleware locally +//const DATADRIVE_HOST = "https://wphyo-mac.m20-dev.jpl.nasa.gov:8085"; + +module.exports = { + CLIENT_NAME, + CLIENT_VERSION, + CLIENT_TITLE, + OCS_EVENTYPE_OBJECT_INDEXED, + OCS_EVENTYPE_OBJECT_REMOVED, + OCS_EVENTYPE_OBJECT_DELETED, + CFG_FILEDIR, + CFG_FILENAME, + ENV_DATADRIVE_HOST, + ENV_PEP_HOST, + ENV_DEBUG_ENABLED, + PROP_DATADRIVE_HOST, + PROP_PEP_HOST, + PROP_OCS_HOST, + PROP_OCS_API_DEPLOYMENT, + PROP_DEBUG_ENABLED, + OCS_CFG_FILEDIR, + OCS_CFG_FILENAME, + OCS_PACKAGE_NAME, + OCS_PACKAGE_DESCRIPTION, + DEFAULT_DD_HOST, + DEFAULT_PEP_HOST, + EVENTTYPE_OCS, + EVENTTYPE_PLAYBACK, + S3_PROTOCOL, + S3_URL_PATTERN, + S3_URL_REGEX + //DATADRIVE_HOST +}; diff --git a/src/core/DdDirectoryListener.js b/src/core/DdDirectoryListener.js new file mode 100644 index 0000000..e3b4fa3 --- /dev/null +++ b/src/core/DdDirectoryListener.js @@ -0,0 +1,144 @@ + +//Libraries +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const chokidar = require('chokidar'); + +//Local imports +const DdLogger = require('./DdLogger.js').logger; +const DdUtils = require('./DdUtils.js'); +const DdPubConfig = require('./DdPubConfig.js'); + + + +let DdDirectoryListener = (function () { + + + //--------------------------------------------------------------------- + + /** + * Constructor. + * + * @constructor + */ + let DdDirectoryListener = function (pubConfig) { + this._config = pubConfig; + + this._directory = path.resolve(this._config.sourceDir); + + this._eventCallback = null; + this._errorCallback = null; + + this._watcher = null; + + }; + + + //--------------------------------------------------------------------- + + DdDirectoryListener.prototype.setMessageCallback = function(cb) { + this._eventCallback = cb; + }; + + //--------------------------------------------------------------------- + + DdDirectoryListener.prototype.setErrorCallback = function(cb) { + this._errorCallback = cb; + }; + + //--------------------------------------------------------------------- + + DdDirectoryListener.prototype.startSession = function() { + this.listen(); + }; + + //--------------------------------------------------------------------- + + DdDirectoryListener.prototype.isActive = function() { + return (null != this._watcher); + }; + + //--------------------------------------------------------------------- + + DdDirectoryListener.prototype.getDirectory = function() { + return this._directory; + }; + + + //--------------------------------------------------------------------- + + + + DdDirectoryListener.prototype.listen = function(url) { + + if (this._watcher) { + return; + } + + let that = this; + + this._watcher = chokidar.watch(this._directory, { + ignored: /[\/\\]\./, + persistent: true, + ignoreInitial: true + }); + + if (this._watcher) { + this._watcher.on('add', function (path) { + that.handleNewFileEvent(path, false); + }); + this._watcher.on('change', function (path) { + that.handleNewFileEvent(path, true); + }); + } + }; + + //--------------------------------------------------------------------- + + DdDirectoryListener.prototype.handleNewFileEvent = function(filepath, changeFlag) { + + if (DdUtils.isEmptyOrNullString(filepath)) { + return; + } + + + let fullpath = filepath; + if (! path.isAbsolute(fullpath)) { + fullpath = path.join(this._directory, filepath); + } + + + if (!this._config.satisfiesFilter(filepath)) { + return; + } + + + if (this._eventCallback) { + this._eventCallback(fullpath, changeFlag); + } + }; + + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + + //Stops the token refresh timer. + DdDirectoryListener.prototype.cancel = function() { + + //cleanup + if (this._watcher) + { + this._watcher.close(); + this._watcher = null; + } + }; + + //--------------------------------------------------------------------- + + return DdDirectoryListener; + +}()); + +module.exports = DdDirectoryListener; diff --git a/src/core/DdError.js b/src/core/DdError.js new file mode 100644 index 0000000..4a169d7 --- /dev/null +++ b/src/core/DdError.js @@ -0,0 +1,22 @@ +class QueueEmptyError extends Error { + constructor(message) { + super(message); + } +} +class MaxProcessSizeError extends Error { + constructor(message) { + super(message); + } +} + +class CannotWriteToLocalFileError extends Error { + constructor(message) { + super(message); + } +} + +module.exports = { + "QueueEmptyError": QueueEmptyError, + "MaxProcessSizeError": MaxProcessSizeError, + "CannotWriteToLocalFileError": CannotWriteToLocalFileError +}; \ No newline at end of file diff --git a/src/core/DdFileMetadata.js b/src/core/DdFileMetadata.js new file mode 100644 index 0000000..d0f97c8 --- /dev/null +++ b/src/core/DdFileMetadata.js @@ -0,0 +1,96 @@ +const moment = require('moment'); +const DdConsts = require('./DdConstants.js'); + +/** + * @typedef {Object} OCSPathObj + * @property {string} ocs_path + * @property {string} ocs_name + */ + +/** + * Splits ocs_full_name into ocs_path and ocs_name + * Ex: /jeff/Slowpoke.gif to "/jeff" and "Slowpoke.gif" + * @param {string} ocs_full_name + * @returns {OCSPathObj} + */ +function getOCSPathObj(ocs_full_name) { + let splits = ocs_full_name.split("/"); + let ocs_name = splits[splits.length - 1]; + let ocs_path_end_index = ocs_full_name.indexOf(ocs_name) - 1; + let ocs_path = ocs_full_name.substring(0, ocs_path_end_index); + return {'ocs_name': ocs_name, 'ocs_path': ocs_path}; +} + +class FileMetadata { + constructor() { + /** @type {Date} */ + this.ocs_updated_at = undefined; + /** @type {string} */ + this.ocs_full_name = undefined; + /** @type {string} */ + this.ocs_dataset_id = undefined; + /** @type {string} */ + this.ocs_package_id = undefined; + /** @type {string} */ + this.ocs_url = undefined; + /** @type {string} */ + this.ocs_path = undefined; + this.ocs_name = undefined; + /** @type {string} */ + this.ocs_owner = undefined; + /** @type {string} */ + this.download_url = undefined; + /** @type {string} */ + this.event_type = undefined; + } + + getOcsUpdatedAt() { + return this.ocs_updated_at + } + + getOcsName() { + return this.ocs_name + } + + /** + * Converts JSON object into FileMetadata object that is common amongst events + * @param {object} json + */ + unmarshall(json) { + this.ocs_full_name = json.ocs_full_name; + this.ocs_url = json.ocs_url; + this.download_url = json.ocs_download_url; + this.getOCSPathObj = getOCSPathObj(this.ocs_full_name); + this.ocs_path = this.getOCSPathObj.ocs_path; + this.ocs_name = this.getOCSPathObj.ocs_name; + } + + /** + * Converts OCS event JSON object into FileMetadata object; this is to make type checking easier during development + * @param {object} json + */ + unmarshallOCS(json) { + this.unmarshall(json); + this.ocs_updated_at = json.package_dataset_event_time ? moment(json.package_dataset_event_time).toDate() : undefined; + this.ocs_dataset_id = json.dataset_id; + this.ocs_package_id = json.package_id; + this.event_type = DdConsts.EVENTTYPE_OCS; + } + + /** + * Converts DataDrive PLAYBACK event JSON object into FileMetadata object; this is to make type checking easier during development + * @param {object} json + */ + unmarshallPlayback(json) { + this.unmarshall(json); + this.ocs_updated_at = json.ocs_updated_at ? moment(json.ocs_updated_at).toDate() : undefined; + this.ocs_dataset_id = json.ocs_dataset_id; + this.ocs_package_id = json.ocs_package_id; + this.ocs_owner = json.ocs_owner; + this.event_type = DdConsts.EVENTTYPE_PLAYBACK; + } +} + +module.exports = { + "FileMetadata": FileMetadata +}; diff --git a/src/core/DdLogger.js b/src/core/DdLogger.js new file mode 100644 index 0000000..241eeba --- /dev/null +++ b/src/core/DdLogger.js @@ -0,0 +1,114 @@ +/** + * @author nttoole + * Created on 6/5/18. + */ + +const winston = require('winston'); + +let debugEnabled = false; +const infoForUserFlag = true; + + +const { combine, timestamp, label, json, prettyPrint, printf } = winston.format; + + + +const logger = winston.createLogger({ + level: 'info', + format: combine( + label({ label: 'DataDrive' }), + timestamp(), + // json(({ level, message, label, timestamp }) => { + // return `${timestamp} [${label}] ${level}: ${message}`; + // }), + printf(({ level, message, label, timestamp }) => { + return `${timestamp} [${label}] ${level}: ${message}`; + }) + ), + transports: [ + new winston.transports.File({ filename: 'error.log', level: 'error' }), + new winston.transports.File({ filename: 'combined.log' }), + //new winston.transports.Console({format: winston.format.simple()}) winston.format.prettyPrint() + new winston.transports.Console({}) + ] +}); + + +if (debugEnabled) { + logger.level = "debug"; +} + +exports.logger = { + setDebugEnabled: (flag) => { + if (flag) { + logger.level = "debug"; + logger.log({ + level: 'debug', + message: "Debug logging enabled" + }); + } + else + logger.level = "info"; + }, + info: (msg) => logger.log({ + level: 'info', + message: msg + }), + debug: (msg) => logger.log({ + level: 'debug', + message: msg + }), + warn: msg => logger.log({ + level: 'warn', + message: msg + }), + error: msg => logger.log({ + level: 'error', + message: msg + }), + printError: (...args) => { + + if (args.length > 1) { + console.error(...args); + } else { + let err = args[0]; + let _msg; + if (err instanceof Error) { + _msg = `error: ${err.toString()}`; + } else if (typeof err === 'object') { + if (err.Message) { + _msg = `error: ${err.Message}`; + } else if (err.message) { + _msg = `error: ${err.message}`; + } else if (err.reason) { + _msg = `error: ${err.reason}\n ${err.exception}`; + } else { + _msg = JSON.stringify(err, null, 2); + } + } else { + if (err.toString().startsWith('ERROR') || err.toString().startsWith('error')) { + _msg = err; + } else { + _msg = `error: ${err.toString()}`; + } + } + + // Add causes, if any + if (err.causes) { + _msg = `${_msg}\nCaused By:`; + for (let c of err.causes) { + if (c.message) { + _msg = `${_msg}\n${c.message}`; + } else if (c.error.message) { + _msg = `${_msg}\n${c.error.message}`; + } else { + _msg = `${_msg}\n${c}`; + } + } + } + + logger.error(''); + logger.error(_msg); + } + }, +}; \ No newline at end of file diff --git a/src/core/DdOptions.js b/src/core/DdOptions.js new file mode 100644 index 0000000..e007f9d --- /dev/null +++ b/src/core/DdOptions.js @@ -0,0 +1,238 @@ +'use strict'; + +const os = require('os'); +const HOME = os.homedir(); +const path = require('path'); +const fs = require('fs'); + +const prog = require('commander'); +const Client = require('@gov.nasa.jpl.m2020.cs3/ocs-js-client'); +const DdConsts = require('./DdConstants.js'); + + + +let options = (function () { + + let parsed = false; + + let options = function () { + parsed = false; + }; + + // Make module-local variables visible. + options.program = prog; + + + //-------------------------------------------------------------------------- + // Mirror API of commander. + //-------------------------------------------------------------------------- + + options.version = function (...args) { + prog.version(...args); + }; + + options.option = function (...args) { + prog.option(...args); + }; + + options.parseTopArgs = function (...args) { + options.parseInternal(false, ...args); + }; + + options.parse = function (...args) { + options.setName(); + options.parseInternal(true, ...args); + }; + + options.parseInternal = function (addStandard, ...args) { + if (parsed) { + throw Error('You can only call parse() once.'); + } + // Add the standard options. + if (addStandard) { + addStandardOptions(); + } + + + + // Add the standard help if not already done. + //if (typeof prog._events['--help'] === 'undefined') { + prog.on('--help', printStandardHelp); + //} + + // Parse. + try { + prog.parse(...args); + parsed = true; + } catch (err) { + options.errorAndExit(err); + } + validateArgs(prog); + }; + + options.command = function (...args) { + prog.command(...args); + }; + + options.usage = function (...args) { + prog.usage(...args); + }; + + options.setArgs = function (...args) { + prog.arguments(...args); + }; + + options.setName = function () { + let cmdName = path.basename(require.main.filename); + cmdName = cmdName.replace(/^([^-]+)-([^.]+)\.js/, '$1-$2'); + prog.name(cmdName); + }; + + //-------------------------------------------------------------------------- + // Value added methods. + //-------------------------------------------------------------------------- + + options.setCustomHelp = function (printCustomHelp) { + if (parsed) { + throw Error('Cannot call setCustomHelp after calling parse'); + } + prog.on('--help', function () { + printCustomHelp(); + //printStandardHelp(); + }); + }; + + options.errorAndExit = function (err) { + printErrMessage(err); + process.exit(1); + }; + + options.exit = function (exitCode) { + process.exit(exitCode); + }; + + /** + * + * @param {string[]} args + */ + options.parseSubscriptionOptions = function(args) { + //DdOptions.setArgs('[FILE...]', 'The files or expressions to list.'); + + this.version('\n*** '+DdConsts.CLIENT_TITLE+' ***\n\n'); + this.option('-p, --package-name [pkg name]', 'The name of the package.'); + this.option('-o, --output-dir ', 'The output directory.'); + this.option('-f, --filter [value]', 'A wildcard expression to filter files based on OCS Full Name.', '*'); + this.option('-x, --regex [value]', 'A regex expression to filter files based on OCS Full Name. Please reference https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-regexp-query.html#regexp-syntax and NodeJS RegExp.'); + this.option('-s, --saved-search-name [value]', 'Name of your personnel saved search.') + this.option('-r, --retain-path', 'Use the S3 path as relative path when writing files'); + this.option('-P, --playback', 'Get events that has since happened after the last downloaded file.'); + this.option('-if, --include-full-path', 'If filter and regex expressions include only the name or the full path. defaulted to `NO`.'); + this.option('-O, --overwrite', 'Overwrite file if it already exists in that path.'); + this.option('-S, --skip-unchanged', 'Only download files that are new or have changed.'); + // DdOptions.option('--pluginsAsync', 'Execute custom plugins asynchronously, this will be ignored if plugins are not enabled.'); + // this.option('--pluginsDir [plugin dir]', 'Directory to load custom plugins.'); + this.option('--plugin-path [value]', 'Path to the custom plugin file that implements class DdPlugin.'); + this.option('--disable-download', 'Disable downloading of files. Make sure to still include an output-dir option.'); + //DdOptions.parseTopArgs(process.argv); + // Utils.setCustomHelp(function () { + // console.log(''); + // console.log(' You can use the * and ? wildcards in FILE, as well as [].'); + // }); + + this.parse(args); + }; + + //-------------------------------------------------------------------------- + // Internal methods. + //-------------------------------------------------------------------------- + + const validateArgs = function () { + let _msg = ''; + prog.options.forEach(function (opt) { + // if (opt.required !== 0 || opt.required === true) { + if ( opt.required === true) { + + let _name = optName(opt.long); +// console.log("DEBUG::Opt.required? = "+_name+" = "+opt.required); + if (!prog[_name]) { + _msg = _msg + `ERROR: ${opt.flags} is required.\n`; + } + } + }); + if (_msg !== '') { + options.errorAndExit(_msg); + } + }; + + let optName = function (longFlag) { + let _name = longFlag.replace('--', ''); + return _name.split('-').reduce(function (str, word) { + return str + word[0].toUpperCase() + word.slice(1); + }); + }; + + let printStandardHelp = function () { + console.log(''); + console.log(' NOTE that you have to specify flags separately ("-p -d" and NOT "-pd").'); + console.log(''); +// console.log(' For a full explanation of all options, consult the online documentation'); +// console.log(' at https://github.jpl.nasa.gov/M2020-CS3/m2020-data-lake/wiki/OCS-CLI-Reference'); + }; + + let addStandardOptions = function () { + prog.option('-q, --quiet', 'If specified, do not output progress messages', false); + }; + + let printErrMessage = function (...args) { + + if (args.length > 1) { + console.error(...args); + } else { + let err = args[0]; + let _msg; + if (err instanceof Error) { + _msg = `error: ${err.toString()}`; + } else if (typeof err === 'object') { + if (err.Message) { + _msg = `error: ${err.Message}`; + } else if (err.message) { + _msg = `error: ${err.message}`; + } else if (err.reason) { + _msg = `error: ${err.reason}\n ${err.exception}`; + } else { + _msg = JSON.stringify(err, null, 2); + } + } else { + if (err.toString().startsWith('ERROR') || err.toString().startsWith('error')) { + _msg = err; + } else { + _msg = `error: ${err.toString()}`; + } + } + + // Add causes, if any + if (err.causes) { + _msg = `${_msg}\nCaused By:`; + for (let c of err.causes) { + if (c.message) { + _msg = `${_msg}\n${c.message}`; + } else if (c.error.message) { + _msg = `${_msg}\n${c.error.message}`; + } else { + _msg = `${_msg}\n${c}`; + } + } + } + + console.error(''); + console.error(_msg); + + } + + }; + + + return options; +})(); + +module.exports = options; diff --git a/src/core/DdPlugin.js b/src/core/DdPlugin.js new file mode 100644 index 0000000..454abcb --- /dev/null +++ b/src/core/DdPlugin.js @@ -0,0 +1,10 @@ +class Plugin { + constructor() { + + } + + async processItem(item) { + } +} + +module.exports = Plugin; \ No newline at end of file diff --git a/src/core/DdPluginHandler.js b/src/core/DdPluginHandler.js new file mode 100644 index 0000000..a763bab --- /dev/null +++ b/src/core/DdPluginHandler.js @@ -0,0 +1,135 @@ +const { FileMetadata } = require('./DdFileMetadata.js'); +const fs = require('fs'); +const path = require('path'); +const DdLogger = require('./DdLogger.js').logger; +const DdSubConfig = require('./DdSubConfig'); +const DdPlugin = require('./DdPlugin.js'); +const DdUtils = require('./DdUtils.js'); +const _ = require('lodash'); + + +class PluginHandler { + /** + * Fires a single plugin. + * @param {DdSubConfig} config + */ + constructor(config) { + this.dict = {}; + this.config = config; + // Default plugins directory + if (!this.config.disableDownload) { + this.dict['FileDownloader'] = require('../plugins/FileDownloaderPlugin.js'); + } + // Custom plugins directory + if (this.config.pluginPath) { + this.dict['CustomPlugin'] = load_plugin(DdUtils.ensureAbsolutePath(this.config.pluginPath)); + } + } + + /** + * If plugin option is enabled, call every plugins in "plugins" folder's "processItem" function + * @param {FileMetadata} metadata + */ + async callProcessItem(metadata) { + for (let key in this.dict) { + try { + let config = _.cloneDeep(this.config); // Objects in JS is pass by reference; deep copy config so plugins cannot mess with upper level DdSubConfig class + let plug = new this.dict[key](config); + DdLogger.debug(`calling ${key}`); + await plug.processItem(metadata); + DdLogger.debug(`called ${key}`); + } catch (error) { + DdLogger.error(`An error occurred when invoking function processItem for ${key}`); + DdLogger.error(error.message); + DdLogger.debug(error.stack); + } + } + // await Promise.all(result); + } + // TODO: Look into adding checks to ensure each plugin is correct +} + +class MultiPluginHandler { + /** + * Fires plugins synchronously based on a given folder; Currently runs them randomly, need ordering if this eventually becomes a production feature. + * @param {DdSubConfig} config + */ + constructor(config) { + this.dict = {}; + this.config = config; + // Default plugins directory + // load_plugins(this.dict, path.join(process.cwd(), 'plugins')); + if (!this.config.disableDownload) { + this.dict['FileDownloader'] = load_plugin(path.join(process.cwd(), 'plugins', 'FileDownloaderPlugin.js')); + } + // Custom plugins directory + if (this.config.pluginsDir) { + load_plugins(this.dict, DdUtils.ensureAbsolutePath(this.config.pluginsDir)); + } + } + + /** + * If plugin option is enabled, call every plugins in "plugins" folder's "processItem" function + * @param {FileMetadata} metadata + */ + async callProcessItem(metadata) { + // let result = [] + for (let key in this.dict) { + try { + let config = _.cloneDeep(this.config); // Objects in JS is pass by reference; deep copy config so plugins cannot mess with upper level DdSubConfig class + let plug = new this.dict[key](config); + DdLogger.debug(`calling ${key}`); + await plug.processItem(metadata); + DdLogger.debug(`called ${key}`); + // result.push(plug.processItem(metadata)); + } catch (error) { + DdLogger.error(`An error occurred when invoking function processItem for ${key}`); + DdLogger.error(error); + } + } + // await Promise.all(result); + } + // TODO: Look into adding checks to ensure each plugin is correct +} + +/** + * @param {string} pluginPath + */ +let load_plugin = (pluginPath) => { + try { + let cls = require(pluginPath); + if (cls.prototype instanceof DdPlugin) { + return cls; + } + else { + throw new Error(`Plugin does not inherit from Plugin class.`); + } + } catch (error) { + DdUtils.errorAndExit(error); + } +}; + +/** + * @param {Object} dict + */ +let load_plugins = (dict, pluginsDir) => { + try { + let plugins = fs.readdirSync(pluginsDir); + for (let plugin of plugins) { + let cls = require(path.join(pluginsDir, plugin)); + if (cls.prototype instanceof DdPlugin) { + dict[plugin] = cls + } + else { + throw new Error(`Plugin ${plugin} does not inherit from Plugin class.`); + } + } + } catch (error) { + DdUtils.errorAndExit(error); + } +}; + +module.exports = { + 'PluginHandler': PluginHandler, + 'MultiPluginHandler': MultiPluginHandler, +}; \ No newline at end of file diff --git a/src/core/DdPubConfig.js b/src/core/DdPubConfig.js new file mode 100644 index 0000000..925dce4 --- /dev/null +++ b/src/core/DdPubConfig.js @@ -0,0 +1,329 @@ +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const upath = require('upath'); +//const argv = require('argv-parse'); +const globToRegExp = require('glob-to-regexp'); + + + +const DdConsts = require('./DdConstants.js'); +const SsoToken = require('./SsoToken.js'); +const DdUtils = require('./DdUtils.js'); +const DdLogger = require('./DdLogger.js').logger; +const {DdCliConfigFileIO} = require('./DdCliConfigFileIO'); + +/** + * Definition of the DataDrive Web Socket client + * + * @type {DdPubConfig} + */ +let DdPubConfig = (function () { + + + /** + * @constructor + */ + let DdPubConfig = function (program) { + + //lets assume the worst case... + this.wasConfiguredSuccessfully = false; + + //----------------- + + let ddHost = DdCliConfigFileIO.builder().getDatadriveHost(); + + if (! ddHost) { + DdLogger.error('Missing required configuration: '+DdConsts.PROP_DATADRIVE_HOST); + DdLogger.error('Please check your configuration via the "dd-config" command.'); + return null; + } + + this.dataDriveHost = "https://"+ddHost; + this.ocsHost = null; + this.ocsAPIDeployment = null; + + //Check the environment for the DEBUG state + let debugEnvVal = DdCliConfigFileIO.builder().getConfigValue(DdConsts.PROP_DEBUG_ENABLED); + if (DdUtils.isValueTrue(debugEnvVal)) + { + DdLogger.setDebugEnabled(true); + } + + + //----------------- + + //CSSO token + this.ssoTokenApi = new SsoToken(); + let token = this.ssoTokenApi.getToken(); + if (DdUtils.isEmptyOrNullString(token)) + { + throw Error(`Could not load CSSO credentials/token.`); + } + this.cssoToken = token; + + + + this.packageId = null; + this.packageName = null; + this.packageBucket = null; + this.retainPath = false; + this.overwriteEnabled = false; + + //----------------- + + //this.parseArgv(); + this.processOptions(program); + + this.debugEnabled = true; + + + }; + + + //--------------------------------------------------------------------- + + DdPubConfig.prototype.setOcsSettings = function(host, venue) { + this.ocsHost = host; + this.ocsAPIDeployment = venue; + }; + + + //--------------------------------------------------------------------- + + DdPubConfig.prototype.getCssoToken = function() { + return this.cssoToken; + }; + + //--------------------------------------------------------------------- + + DdPubConfig.prototype.processOptions = function (program) { + + this.packageName = program.packageName; + this.sourceDir = program.sourceDir; + this.fileWildcard = program.filter; + this.destRoot = program.destPrefix; + + this.retainPath = program.retainPath || false; + this.overwriteEnabled = program.overwrite || false; + this.packageId = null; + this.packageBucket = null; + + //examine glob to make filter decisions + this.filterIncludesPath = (this.fileWildcard.indexOf("/") > -1); + this.fileWildcardRegexObj = globToRegExp(this.fileWildcard); + + this.wasConfiguredSuccessfully = true; + }; + + + + // DdPubConfig.prototype.parseArgv = function () { + // + // let args = argv({ + // packageName: { //name of package to which files will be published + // type: 'string', + // alias: 'p' + // }, + // sourceDir: { //source directory to which we will be listening + // type: 'string', + // alias: 's' + // }, + // destRoot: { //root location in package to which all files will be added (default: "") + // type: 'string', + // alias: 'd' + // }, + // filter: { //client-side filter on which files will be published + // type: 'string', + // alias: 'f' + // }, + // overwrite: { //flag that determines if file can be overwritten (default: false) + // type: 'boolean', + // alias: 'o' + // }, + // retainPath: { //flag that determines if subdir path will be maintained (default: false) + // type: 'boolean', + // alias: 'r' + // } + // }); + // + // //check args + // if (!args.packageName) + // { + // DdLogger.error('Missing required argument: packageName'); + // return null; + // } + // if (!args.sourceDir) + // { + // DdLogger.error('Missing required argument: sourceDir'); + // return null; + // } + // + // //set defaults + // if (!args.filter) + // { + // args.filter = "*"; + // } + // if (!args.destRoot) + // { + // args.destRoot = ""; + // } + // if (!args.retainPath) + // { + // args.retainPath = false; + // } + // if (!args.overwrite) + // { + // args.overwrite = false; + // } + // + // this.packageName = args.packageName; + // this.sourceDir = args.sourceDir; + // this.fileWildcard = args.filter; + // this.destRoot = args.destRoot; + // this.retainPath = args.retainPath; + // this.overwriteEnabled = args.overwrite; + // this.packageId = null; + // + // + // //examine glob to make filter decisions + // this.filterIncludesPath = (this.fileWildcard.indexOf("/") > -1); + // this.fileWildcardRegexObj = globToRegExp(this.fileWildcard); + // + // this.wasConfiguredSuccessfully = true; + // }; + + //--------------------------------------------------------------------- + + DdPubConfig.prototype.isConfigured = function() + { + return this.wasConfiguredSuccessfully; + } + + //--------------------------------------------------------------------- + + DdPubConfig.prototype.isOverwriteEnabled = function() + { + return this.overwriteEnabled; + } + + //--------------------------------------------------------------------- + + + /** + * Returns an OCS path for the local filepath, which is + * relative to the OCS package. + * + * @param {string} filepath Local path of the file to be uploaded + * @return (string} Path part of OCS URL + */ + + DdPubConfig.prototype.getOcsPath = function(filepath) + { + let parent = path.dirname(filepath); + let basename = path.basename(filepath); + + let dbgPrefix = "DdPubConfig:;getOcsPath: "; + DdLogger.debug(dbgPrefix+" Parent = "+parent); + DdLogger.debug(dbgPrefix+" basename = "+basename); + + let srcRoot = this.sourceDir; + + //get the relative pat between srcDir and file's dir + let relativePath = path.relative(srcRoot, parent); + relativePath = upath.normalizeSafe(relativePath); + + DdLogger.debug(dbgPrefix+" relativePath = "+relativePath); + + //we are gonna build the prefix + let prefix = ""; + + //if we have a common destination root, use it + if (! DdUtils.isEmptyOrNullString(this.destRoot)) + { + prefix = upath.normalizeSafe(this.destRoot); + } + + DdLogger.debug(dbgPrefix+" prefix_A = "+prefix); + + //if we want to preserve the relative path, do so + if (this.retainPath) + { + prefix = upath.joinSafe(prefix, relativePath); + } + + DdLogger.debug(dbgPrefix+" prefix_B = "+prefix); + + //does OCS path include the filename? + // let ocsPkgPath = upath.joinSafe(prefix, basename); + let ocsPkgPath = prefix; + + DdLogger.debug(dbgPrefix+" ocsPkgPath_A = "+ocsPkgPath); + + //ensure we start with a slash? + if (!ocsPkgPath.startsWith("/")) { + ocsPkgPath = "/" + ocsPkgPath; + } + + DdLogger.debug(dbgPrefix+" ocsPkgPath-B = "+ocsPkgPath); + + return ocsPkgPath; + }; + + + //--------------------------------------------------------------------- + + + DdPubConfig.prototype.satisfiesFilter = function(fullpath) + { + let _glob = this.fileWildcard; + let _regex = this.fileWildcardRegexObj; + if (!_glob || !_regex) + return true; + + //Assume fullpath is target, but if filter + //is pathless, then just look at the basename? + var target = fullpath; + if (!this.filterIncludesPath) + { + //var basename = DdUtils.extractFilenameFromPath(fullpath); + var basename = path.basename(fullpath); + target = basename; + } + + let regexMatches = _regex.test(target); + return regexMatches; + }; + + + //--------------------------------------------------------------------- + + /** + * Returns a timeout for which we should wait before processing a new + * file event. The reason for this is to add a small delay in the case + * of Windows as apparently Antivirus services can sometimes hold onto + * a file early on, resulting in a read-access issue if we don't wait + * for that to finish. + * @return Timeout in milliseconds + */ + + DdPubConfig.prototype.getFileEventTimeout = function() + { + let sleepMs = 1; + if (DdUtils.isWindows()) { + sleepMs = 5000; + DdLogger.debug("Sleeping for " + sleepMs + " ms (Thanks Windows Antivirus)"); + } + + return sleepMs; + }; + + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + return DdPubConfig; + +})(); + +module.exports = DdPubConfig; diff --git a/src/core/DdQueue.js b/src/core/DdQueue.js new file mode 100644 index 0000000..1edefad --- /dev/null +++ b/src/core/DdQueue.js @@ -0,0 +1,148 @@ +const DdLogger = require('./DdLogger.js').logger; +const { QueueEmptyError, MaxProcessSizeError } = require('./DdError.js'); + +class Processor { + /** + * + * @param {Queue} queue + * @param {number} maxSize - the maximum number of items that can be dequeued at a time; currently we only support 1 + */ + constructor(queue, maxSize=1) { + /** + * counter that works with maxSize to ensure that only "maxSize" number of items can be dequeued + * @type {number} + */ + this.size = 0; + this.queue = queue; + this.maxSize = maxSize; + } + + /** + * Get an items from the queue and then return that item via a promise + */ + process() { + return new Promise((resolve, reject) => { + if (this.queue.isEmpty()) { + reject(new QueueEmptyError("Queue is empty.")); + } + else if (this.size < this.maxSize) { + let node = this.queue.dequeue(); + this.size += 1; + resolve(node); + } + else { + reject(new MaxProcessSizeError("Max process size reached.")); + } + }); + } +} + +class QueueNode { + constructor(key, value) { + /** @type {string | number} */ + this.key = key; + /** @type {object} */ + this.value = value; + this.prev = null; + this.next = null; + } +} + +class Queue { + constructor() { + /** @type {QueueNode} */ + this.head = null; + /** @type {QueueNode} */ + this.tail = null; + /** @type {Object.} */ + this.mapping = {}; + } + + isEmpty() { + return this.head === null && this.tail === null; + } + + /** + * + * @param {string | number} key + * @param {Object} value + */ + enqueue(key, value) { + DdLogger.debug("Called enqueue"); + let node; + if (key in this.mapping) { // case where the key already exist in the queue + node = this.pop(key); + } + else { + node = new QueueNode(key, value); + } + this.mapping[key] = node; + if (this.isEmpty()) { + this.head = node; + this.tail = node; + } + else { + this.tail.next = node; + node.prev = this.tail; + this.tail = node; + } + } + + dequeue() { + DdLogger.debug("Called dequeue"); + let result = null; + if (!this.isEmpty()) { + result = this.head; + let key = result.key; + delete this.mapping[key]; + this.head = this.head.next; + if (this.head) { + this.head.prev = null; + } + else { + this.tail = null; + } + } + return result; + } + + /** + * @param {string | number} key + */ + pop(key) { + DdLogger.debug("Called pop"); + let result = null; + result = this.mapping[key]; + delete this.mapping[key]; + // this is to link up prev node with next node + if (result.prev) { + result.prev.next = result.next; + } + if (result.next) { + result.next.prev = result.prev; + } + if (result === this.head) { + this.head = this.head.next; + } + if (result === this.tail) { + this.tail = this.tail.prev; + } + return result + } + + itemsToList() { + let items = []; + let node = this.head; + while (node) { + items.push(node.value); + node = node.next; + } + return items; + } +} + +module.exports = { + "Queue": Queue, + "QueueNode": QueueNode, + "Processor": Processor +}; \ No newline at end of file diff --git a/src/core/DdSubConfig.js b/src/core/DdSubConfig.js new file mode 100644 index 0000000..272d394 --- /dev/null +++ b/src/core/DdSubConfig.js @@ -0,0 +1,199 @@ +const fs = require('fs'); +const path = require('path'); +const globToRegExp = require('glob-to-regexp'); +const DdUtils = require('./DdUtils.js'); +const DdLogger = require('./DdLogger.js').logger; +const DdConfig = require('./DdConfig.js'); + +/** + * Definition of the DataDrive Config Class + * + * @type {DdSubConfig} + */ +class DdSubConfig extends DdConfig { + /** + * @constructor + * @param {object} program - Command object from Commander library + * @param {boolean} load_config - Default: true; load configs such as hostnames and csso token; not loading config is used for unit tests + */ + constructor(program, load_config=true) { + super(program, load_config=load_config); + this.validateOptions(program); + this.processOptions(program); + }; + + //--------------------------------------------------------------------- + + //Replaces parseArgv now that we are using the Commander for options processing + + /** + * Process options from Command object from Commander library + * @param {object} program - object from the commander library + */ + processOptions(program) { + this.packageName = program.packageName; + this.outputDir = program.outputDir; + // file path for location we are tracking the checkpoint file + this.checkpointPath = `${this.outputDir}/.datadrive/checkpoint.txt`; + // file path for location we are tracking the package name file of last time CLI was run + this.savedPackageNamePath = `${this.outputDir}/.datadrive/packagename.txt`; + // file path for location we are tracking the saved search name file of the last time CLI was run + this.savedSavedSearchNamePath = `${this.outputDir}/.datadrive/savedsearchname.txt`; + this.fileWildcard = program.filter; + this.fileWildcardRegexObj = globToRegExp(this.fileWildcard); + this.retainPath = program.retainPath || false; + this.playback = program.playback || false; + this.overwrite = program.overwrite || false; + this.disableDownload = program.disableDownload || false; + this.skipUnchanged = program.skipUnchanged || false; + + // this.pluginsAsync = program.pluginsAsync || false; + // this.pluginsDir = program.pluginsDir; + this.pluginPath = program.pluginPath; + + this.packageId = null; //will get populated later + + //examine glob to make filter decisions + this.filterIncludesPath = program.includeFullPath || false + this.fileRegex = program.regex; + this.fileRegexObj = this.fileRegex ? new RegExp(this.fileRegex) : undefined; + + //saved search + this.savedSearchName = program.savedSearchName; + this.savedSearchType = "personnel"; + + super.configured(); + }; + + /** + * Ensure options do not break rules specified in this function + * @param {object} program + */ + validateOptions(program) { + return // no rules specified yet + }; + + /** + * Ensure configs do not break rules specified in this function + * @returns {Promise} Promise object represents a boolean + */ + async validateConfigs() { + if (this.disableDownload && this.pluginPath === undefined) { + DdUtils.errorAndExit('Disable download option enabled but missing plugin path option.'); + } + + // default will be package name; meaning if you specify a package name, it will go down this code path + if (this.packageName) { + if (this.fileRegex !== undefined && this.fileWildcard !== '*') { + DdUtils.errorAndExit('Please specify only 1 filter option; regex or wildcard.'); + } + if (this.savedSearchName !== undefined) { + DdUtils.errorAndExit('Cannot specify a saved search and package name together.'); + } + await this.validateFolderStateFile(this.savedPackageNamePath, this.savedSavedSearchNamePath, this.packageName) + return true; + } + if (this.savedSearchName) { + await this.validateFolderStateFile(this.savedSavedSearchNamePath, this.savedPackageNamePath, this.savedSearchName); + return true; + } + DdUtils.errorAndExit('Please specify a package name or a saved search name.'); + }; + + /** + * Verifies that the specified filename that should exist (packagename.txt or savedsearchname.txt) exists and one that shouldn't does not + * @param {String} filenameShouldExist + * @param {String} filenameShouldNotExist + * @param {String} name + */ + async validateFolderStateFile(filenameShouldExist, filenameShouldNotExist, name) { + // if there is savedsearchname.txt file, we should immediately exist as this folder is for saved search + if (fs.existsSync(filenameShouldNotExist)) { + DdUtils.errorAndExit(`There is a ${filenameShouldNotExist} file in this folder. Exiting.`); + } + // make sure there is not a packagename.txt file or if there is, the package name matches this.PackageName + if (fs.existsSync(filenameShouldExist)) { + let file = await DdUtils.readFile(filenameShouldExist); + if (name !== file.trim()) { + DdUtils.errorAndExit(`Package name or saved search name specified (${name}) is not the same as the one specified in ${filenameShouldExist}.`); + } + } + } + + /** + * Returns a full output path for a given filename, + * prepending the config-held output directory. + * + * @param {string} filepath Relative file path (can be empty) + * @param {string} filename File name + * @return (string} Full path or null if missing required + * information + */ + + getOutputLocation(filepath, filename) + { + let _outputDir = this.outputDir; + if (DdUtils.isEmptyOrNullString(_outputDir)) + return null; + + //assume filepath is empty and filename goes directly + //into outputDir. But if filepath is non-empty, + //apprend it. + let _parentPath = _outputDir; + if (!DdUtils.isEmptyOrNullString(filepath)) + _parentPath = path.join(_outputDir, filepath); + + //now combine out parent path with filename for final result + const _outFilepath = path.join(_parentPath, filename); + + return _outFilepath; + }; + + /** + * Returns a full output path for a given file metadata object, + * prepending the config-held output directory. + * + * @param {OCS filemetadata} fileMetadata OCS file metadata object + * @return (string} Full path or null if missing required + * information + */ + + getOutputLocationViaMetadata(fileMetadata) + { + if (fileMetadata == null || + ! (fileMetadata.hasOwnProperty('ocs_path') && + fileMetadata.hasOwnProperty('ocs_name'))) + return null; + + let filename = fileMetadata.ocs_name; + let relativePath = (this.retainPath) ? fileMetadata.ocs_path : null; + let outFilepath = this.getOutputLocation(relativePath, filename); + + return outFilepath; + }; + + + satisfiesFilter(fullpath) + { + //Assume fullpath is target, but if filter + //is pathless, then just look at the basename? + var target = fullpath; + if (!this.filterIncludesPath) + { + var basename = DdUtils.extractFilenameFromUrl(fullpath); + target = basename; + } + + if (this.fileRegexObj) { // always do user given regex first and then wildcard + return DdUtils.filterFilePath(target, this.fileRegexObj); + } + else if (this.fileWildcardRegexObj) { + return DdUtils.filterFilePath(target, this.fileWildcardRegexObj); + } + else { + return false; + } + } +} + +module.exports = DdSubConfig; diff --git a/src/core/DdUploader.js b/src/core/DdUploader.js new file mode 100644 index 0000000..089618c --- /dev/null +++ b/src/core/DdUploader.js @@ -0,0 +1,260 @@ + + +const axios = require("axios/index"); +const FormData  = require('form-data'); +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const upath = require('upath'); +//const StreamConcat = require("concat-stream") +const request = require('request'); + +const DdLogger = require('./DdLogger.js').logger; + + +// Pass axios to the imported 'axios-debug' function. +//require('axios-debug')(axios); + +//Inspiration: https://github.jpl.nasa.gov/MIPL/DataDrive-Frontend/blob/develop/src/data/ocsLogic.js#L631 + + + +let DdUploader = (function () { + + const NO_RESPONSE_TIMEOUT = 5 * 60 * 1000; // 5 minute timeout to wait for lambda result + + //--------------------------------------------------------------------- + + /** + * Constructor + * @param ocsServiceUrl Base-URL of the DataDrive middleware + * @param cssotoken CSSO Token + */ + + let DdUploader = function (ocsServiceUrl, cssotoken) { + + this.serviceRoot = ocsServiceUrl; + this.cssoToken = cssotoken; + + this.requestTimeout = null; + + //------------------- + //Config maps + + this.axiosConfig = { + headers: { + Cookie: `ssosession=${this.cssoToken}` + }, +// withCredentials: true, //Do we include this? + }; + + this.streamConfig = {encoding: 'buffer'}; + + //------------------- + //massage data + + if (this.serviceRoot.endsWith("/")) { + let srLen = this.serviceRoot.length; + this.serviceRoot = this.serviceRoot.substring(0, srLen - 1); + } + + }; + + //--------------------------------------------------------------------- + + /** + * Check if the session is still valid by hitting the sso status endpoint. + */ + + DdUploader.prototype.isStillAuthenticated = function() { + return new bbPromise((resolve, reject) => { + axios.get(`${this.serviceRoot}/ssostatus`) + .then(response => { + if (response.status === 200 && + response['data'] !== undefined && + response['data']['authenticated'] !== undefined && + response['data']['authenticated'] === true) { + resolve(true); + return; + } + + reject(Error('No longer Authenticated')); + }) + .catch(err => { + reject(Error(err['message'])); + }); + + }); + }; + + //--------------------------------------------------------------------- + + DdUploader.prototype.isNullOrEmpty = function(input) { + input === null || input === undefined || input === '' + }; + + //--------------------------------------------------------------------- + + DdUploader.prototype.isNullOrEmptyObj = function(input) { + input === null || input === undefined || input === {} + }; + + //--------------------------------------------------------------------- + + DdUploader.prototype.isNullOrEmptyArr = function(input) { + input === null || input === undefined || !Array.isArray(input) || input.length < 1 + }; + + //--------------------------------------------------------------------- + + DdUploader.prototype.resetTimer = function() { + if (this.requestTimeout !== null) { + clearTimeout(this.requestTimeout); + this.requestTimeout = null; + } + } + + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + + DdUploader.prototype.autoUpload = function(filepath, pkg, bucket, path, isOverwrite, callback) { + + let that = this; + + let restUrl = `${this.serviceRoot}/api/UploadAutoForce`; + + let wrappedCB = function(filepath, err, statusCode, body) { + that.resetTimer(); + callback(filepath, err, statusCode, body); + }; + + this.autoUploadBackground(filepath, pkg, bucket, path, isOverwrite, restUrl, wrappedCB); + + that.resetTimer(); + this.requestTimeout = setTimeout(() => { + let errMsg = "Timeout reached while waiting for upload request to process"; + DdLogger.error(errMsg); + wrappedCB(filepath, errMsg, null, null); + }, NO_RESPONSE_TIMEOUT); + + + }; + + //--------------------------------------------------------------------- + + DdUploader.prototype.autoUploadBackground = function(filepath, ocspkg, s3Bucket, ocspath, + isOverwrite, url, callback) { + + let fileName = path.basename(filepath); + let fileStream = fs.createReadStream(filepath); + + let dbgMesg = "Upload request for: "+filepath+", pkg_id="+ocspkg+", ocs_path="+ocspath+",overwrite="+isOverwrite; + dbgMesg = dbgMesg + "\nUpload URL: "+url; + DdLogger.debug(dbgMesg); + + const _reqOptions = { + url: url, + method: 'POST', + headers: { + Cookie: request.cookie('ssosession=' + this.cssoToken ) + }, + + }; + + var req = request(_reqOptions, function (err, resp, body) { + + if (err) { + dbgMesg = dbgMesg + "\nUpload URL: "+url; + DdLogger.error("Upload error: "+err); + } else { + DdLogger.debug("Request for upload returned"); + } + + DdLogger.debug("Destroying stream associated with "+filepath); + fileStream.destroy(); + //fileStream.close(); + + + callback(filepath, err, resp, body); + + }); + + var form = req.form(); + + let s3Filename = this.createS3Name(s3Bucket, ocspath.toString(), + fileName.toString()); + + DdLogger.debug("s3Filename = "+s3Filename+" from components: bucket: "+s3Bucket+", ocspath: "+ocspath.toString()+", filename: "+fileName.toString()); + + //form.append('file', fileStream); + form.append('pkg_id', ocspkg.toString()); + form.append('ocs_path', ocspath.toString()); + form.append('overwrite', isOverwrite.toString()); + form.append('name', s3Filename); + //form.append('name', fileName.toString()); + form.append('file', fileStream); + + }; + + //--------------------------------------------------------------------- + + DdUploader.prototype.createS3Name = function(s3Bucket, path, filename) { + + if (s3Bucket === undefined || path === undefined) + { + return filename; + } + + // Remove potential trailing slashes from path + if (path !== null) + { + path = path.replace(/\/+$/, ""); + } + + return `s3://${s3Bucket}${path}/${filename}`; + } + + //--------------------------------------------------------------------- + + DdUploader.prototype.extractErrorMessage = function(axiosErr) { + + if (axiosErr['response'] !== undefined) { // it has response object + let responseObj = axiosErr['response']; + if (responseObj['data'] !== undefined) { // it has data object + let responseData = responseObj['data']; + if (typeof responseData === 'object') { // it's JSON object. + if (responseData['message'] !== undefined) { // it has message + return responseData['message']; + } + return JSON.stringify(responseData); + } + if (responseData !== '') { // assuming it's a string, it is not empty + return responseData; + } + + // TODO it may be JSON obj + + } + return `error with status: ${responseObj['status']}`; + } + + if (axiosErr['message'] !== undefined) { // it has error message + return axiosErr['message']; + } + + return 'unkonwn error'; + }; + + + //--------------------------------------------------------------------- + + + return DdUploader; + +})(); + +module.exports = DdUploader; diff --git a/src/core/DdUtils.js b/src/core/DdUtils.js new file mode 100644 index 0000000..0a44b69 --- /dev/null +++ b/src/core/DdUtils.js @@ -0,0 +1,658 @@ + + +'use strict'; + +const Validator = require('jsonschema').Validator; +const UrlLib  = require('url'); +const HttpLib = require('http'); +const OsLib = require('os'); +const FsLib = require('fs'); +const PathLib = require('path'); +const request = require('request'); +const util = require('util'); +const fs = require('fs'); +const path = require('path'); +const moment = require('moment'); + +const DdLogger = require('./DdLogger.js').logger; +const DdConstants = require('./DdConstants.js'); +const {AxiosWrapper} = require('./axios_wrapper') + +//Setup the env config using user home dir + +const HOME = OsLib.homedir(); +const SEP = PathLib.sep; +const CFG_FILEDIR = DdConstants.ENV_FILEDIR; +const CFG_FILENAME = DdConstants.ENV_FILENAME; +const CFG_FILE = `${HOME}${SEP}${CFG_FILEDIR}${SEP}${CFG_FILENAME}`; +// const env = require('dotenv').config({ +// path: CFG_FILE +// }); +// if (env.error) { +// throw env.error +// } + +let utils = (function () { + + const OCS_MESG_SCHEMA_NS = "/ocsMessage"; + const OCS_MESG_SCHEMA = { + "type": "object", + "properties": { + "package_id": {"type": "string"}, + "dataset_id": {"type": "string"}, + "ocs_full_name": {"type": "string"}, + "ocs_url": {"type": "string"}, + "package_dataset_event": {"type": "string"}, + "identity": {"type": "string"}, + "package_dataset_event_time": {"type": "number"}, + }, + "required": ["package_id", "dataset_id", "ocs_full_name", "ocs_url", + "package_dataset_event", "identity", + "package_dataset_event_time"] + }; + + const DD_SAVED_SEARCH_MESG_SCHEMA_NS = "/ssMessage"; + const DD_SAVED_SEARCH_MESG_SCHEMA = { + "type": "object", + "properties": { + "package_id": {"type": "string"}, + "dataset_id": {"type": "string"}, + "ocs_full_name": {"type": "string"}, + "ocs_url": {"type": "string"}, + "package_dataset_event": {"type": "string"}, + "identity": {"type": "string"}, + "package_dataset_event_time": {"type": "number"}, + "ss_type": {"type": "string"}, + "ss_name": {"type": "string"}, + "ss_owner": {"type": "string"} + }, + "required": ["package_id", "dataset_id", "ocs_full_name", "ocs_url", + "package_dataset_event", "identity", + "package_dataset_event_time", "ss_type", "ss_name", "ss_owner"] + } + + const OCS_ERR_SCHEMA_NS = "/ocsErrMessage"; + const OCS_ERR_SCHEMA = { + "type": "object", + "properties": { + "error": {"type": "Boolean"}, + "message": {"type": "string"}, + }, + "required": ["error", "message"] + }; + + const DD_UPLOAD_STATUS_NS = "/ddUploadStatusMessage" + const DD_UPLOAD_STATUS_SCHEMA = { + "type": "object", + "properties": { + "upload_status": {"type": "string"}, + "username": {"type": "string"}, + "failed": {"type": "boolean"}, + "upload_name": {"type": "string"}, + }, + "required": ["upload_status", "username", "upload_name", "failed"] + }; + + const validator = new Validator(); + validator.addSchema(OCS_MESG_SCHEMA, OCS_MESG_SCHEMA_NS); + validator.addSchema(DD_SAVED_SEARCH_MESG_SCHEMA, DD_SAVED_SEARCH_MESG_SCHEMA_NS); + validator.addSchema(OCS_ERR_SCHEMA, OCS_ERR_SCHEMA_NS); + validator.addSchema(DD_UPLOAD_STATUS_SCHEMA, DD_UPLOAD_STATUS_NS); + + let utils = function () { + //this.validator = new Validator(); + //this.validator.addSchema(OCS_MESG_SCHEMA, '/ocsMessage'); + //this.validator.addSchema(OCS_ERR_SCHEMA, '/ocsErrMessage'); + + + + }; + + /** + * Validates the JSON object and returns either TRUE if it matches + * the DataDrive Saved Search Message schema. + * @param {Object} mesgObj - The OCS file message object + * @return {boolean} - Either TRUE or FALSE + */ + utils.isValidDDSavedSearchMessage = function (mesgObj) { + let _rslt = utils.validateRequest(mesgObj, DD_SAVED_SEARCH_MESG_SCHEMA, validator); + if (_rslt === true) { + return true; + } + + return false; + } + + /** + * Validates the JSON object and returns either TRUE if it matches + * the DataDrive Upload Status Message schema. + * @private + * + * @param {Object} mesgObj - The OCS file message object + * @return {boolean} - Either TRUE or FALSE + */ + + utils.isValidDDUploadMessage = function (mesgObj) { + + let _rslt = utils.validateRequest(mesgObj, DD_UPLOAD_STATUS_SCHEMA, validator); + if (_rslt === true) { + return true; + } + + return false; + }; + + + /** + * Validates the JSON object and returns either TRUE if it matches + * the OCS Message schema or an error message. + * @private + * + * @param {Object} mesgObj - The OCS file message object + * @return {boolean} - Either TRUE or FALSE + */ + + utils.isErrorOcsMessage = function (mesgObj) { + + let _rslt = utils.validateRequest(mesgObj, OCS_ERR_SCHEMA, validator); + if (_rslt === true) { + return true; + } + + return false; + }; + + + /** + * Validates the JSON object and returns either TRUE if it matches + * the OCS Message schema or an error message. + * @private + * + * @param {Object} mesgObj - The OCS file message object + * @return {boolean|string} - Either TRUE, or an erro message. + */ + + utils.isValidOcsMessage = function (mesgObj) { + + let _rslt = utils.validateRequest(mesgObj, OCS_MESG_SCHEMA, validator); + if (_rslt === true) { + return true; + } + return false; + }; + + /** + * Validates the input parameters and returns either TRUE or an error message. + * @private + * + * @param {JSON} request - The request object (see {}) + * @param {JSON} schema - The schema against which to validate + * @param {function} validator - The validator to use. + * @return {boolean|string} - Either TRUE, or an error message. + */ + utils.validateRequest = function (request, schema, validator) { + let _results = validator.validate(request, schema); + let _ret = true; + if (!_results.valid) { + _ret = 'Invalid input parameters:'; + for (let e of _results.errors) { + _ret = _ret + ' ' + e.toString(); + } + } + return _ret; + }; + + /** + * Check if the current file location can be written to based on DdSubConfig's overwrite property + * + * @param {string} filepath - Path to file location + * @param {Object} config - DdSubConfig that contains information on how to check if we can write to file path + */ + utils.canWriteToLocalFile = function (filepath, config) { + // check if file exists + if (fs.existsSync(filepath)) { + if (config.overwrite) { + // overwrite flag is set to true + return true; + } + return false; // default for file exist is to not overwrite + } + // can write b/c file does not exist + return true; + }; + + /** + * Makes sure that parent directory(s) exists; if not create them recursively + * @param {string} filepath - Path to file location + */ + utils.ensureDirectory = function(filepath) { + let fpParsed = path.parse(filepath); + fs.mkdirSync(fpParsed.dir, {recursive: true}); + } + + /** + * Makes sure that the file path returned is always an absolute path + * @param {string} filepath - file path + * @returns {string} + */ + utils.ensureAbsolutePath = function(filepath) { + if (path.isAbsolute(filepath)) { + return filepath; + } + return path.resolve(filepath); + } + + /** + * Instructions for checking the file system should be here; currently this only checks if the directory exists + * @param {string} path - path to the given directory + */ + utils.fsChecks = function(path) { + // check if directory exists + if (fs.existsSync(path)) { + return true; + } + return false; + } + + utils.extractFilenameFromUrl = function (url) { + let _parsedUrl = UrlLib.parse(url); + let _basename = PathLib.basename(_parsedUrl.pathname); + + return _basename; + }; + + utils.downloadFromUrl = function (url, dest, cb) { + + let _file = fs.createWriteStream(dest); + let request = HttpLib.get(url, function (response) { + response.pipe(_file); + _file.on('finish', function () { + _file.close(cb); // close() is async, call cb after close completes. + }); + }).on('error', function (err) { // Handle errors + fs.unlink(dest); // Delete the file async. (But we don't check the result) + if (cb) + cb(err.message); + }); + } + + //-------------------------------------------- + + utils.isOcsUnauthError = function (err) { + + if (!err) + return false; + + if (!err.message) + return false; + + let _mesg = err.message; + + let flag = _mesg.startsWith("UNAUTHORIZED: "); + return flag; + } + + //-------------------------------------------- + + utils.preauthThen = function(url, token, callMeIfSuccessfull) { + + const reqOptions = { + url: url, + method: 'GET', + headers: { + Cookie: request.cookie('ssosession=' + token) + } + }; + + DdLogger.info("Sending initial HTTP request to "+url+"\n"); + request(reqOptions, (err, res, body) => { + if (err) { + DdLogger.error("Request error: "+err); + return; + } + if (res.headers['set-cookie'] === undefined || res.headers['set-cookie'].length < 1) + { + DdLogger.error('no cookies in http response'); + return; + } + + // TODO check body to see if it's authenticated. + let auth_token = ''; + res.headers['set-cookie'].forEach(e => { + if (e.startsWith('authorization_token')) + { + auth_token = e.split(';', 1)[0].replace('authorization_token=', ''); + DdLogger.debug("Auth_Token = ["+auth_token+"]\n"); + + } + }); //end_forEach + + if (auth_token === '') + { + DdLogger.error('no auth token'); + return; + } + + callMeIfSuccessfull(); + } + ); + + } + + //-------------------------------------------- + + utils.isEmptyOrNullString = function (str) { + + if (!str) + return true; + + if (str === "") + return true; + + return false; + } + + //-------------------------------------------- + + utils.fileExists = function(filepath) { + + try { + if (FsLib.existsSync(filepath)) { + return true; + } + } catch(err) { + } + + return false; + }; + + //-------------------------------------------- + + utils.isWindows = function() { + var opsys = process.platform; + if (opsys == "win32" || opsys == "win64") { + return true; + } + return false; + }; + + /** + * Given wildcard glob regex and user specified regex, check whichever one is valid + * then return whether given filename matches either one. If both glob and regex are + * valid, default to glob + * + * @param {string} filename - file name + * @param {RegExp} regex - regex object based on "--regex" option + */ + utils.filterFilePath = function(filename, regex) { + let regexMatches = regex.test(filename); + return regexMatches; + } + + //--------------------------------------------------------------- + + utils.getCurrentTimeMillis = function() { + let myDate = new Date(); + return myDate.getTime(); + }; + + //--------------------------------------------------------------- + + utils.getCfgFilepath = function(subdir, filename) { + let HOME = OsLib.homedir(); + let SEP = PathLib.sep; + let CFG_FILE = `${HOME}${SEP}${subdir}${SEP}${filename}`; + + return CFG_FILE; + }; + + //--------------------------------------------------------------- + + utils.getDdCfgFilepath = function() { + return utils.getCfgFilepath(DdConstants.CFG_FILEDIR, + DdConstants.CFG_FILENAME); + }; + + utils.getOcsCfgFilepath = function() { + return utils.getCfgFilepath(DdConstants.OCS_CFG_FILEDIR, + DdConstants.OCS_CFG_FILENAME); + + }; + + /** + * Print error message and exit the application + * @param {string|Error} err + */ + utils.errorAndExit = function (err) { + if (err instanceof Error) { + DdLogger.error(err.message); + DdLogger.debug(err.stack); + } + else { + DdLogger.error(err); + } + process.exit(1); + }; + + //--------------------------------------------------------------- + + utils.isValueTrue = function(value) { + if (value) + { + let boolValue = value.toString().toLowerCase() === 'true' ? true : false; + return boolValue; + } + return false; + }; + + //--------------------------------------------------------------- + // TODO: JEFF... need to create regex query for this + // get playback event from DataDrive middleware + utils.getPlaybackEvents = async function(startTime, endTime, config) { + DdLogger.info(`start: ${startTime}, end: ${endTime}`); + let response; + if (config.packageName) { + DdLogger.debug(`getPlaybackEvents with package name: ${config.packageName}`) + response = await utils.getPlaybackPackageEvents(startTime, endTime, config); + } + else { + DdLogger.debug(`getPlaybackEvents with saved search name: ${config.savedSearchName}`) + response = await utils.getPlaybackSavedSearchEvents(startTime, endTime, config); + } + return response + // if (utils.validHTTPResponse(response)) { + // DdLogger.debug(JSON.stringify(response)); // TODO: Remove me + // return response; + // } + // else { + // throw Error(`getPlaybackEvents returned a status code: ${response.statusCode} and body: ${JSON.stringify(response.body)}`); + // } + }; + + utils.getPlaybackPackageEvents = async function(startTime, endTime, config) { + let body = { + start_time: startTime, + end_time: endTime, + all_pkg: false, + pkg: [config.packageId] + }; + if (config.fileRegexObj) { + body['regex'] = config.fileRegex; + } + else { + body['glob_regex'] = config.fileWildcard; + } + const options = { + method: 'POST', + url: `${config.dataDriveHost}/api/playback/v2`, + headers: { + 'Content-Type': 'application/json', + Cookie: `ssosession=${config.cssoToken}` + }, + data: body, + } + DdLogger.debug(`getPlaybackPackageEvents request options: ${JSON.stringify(options)}`); + let allResults = [] + let esResult = await AxiosWrapper.builder().request(options) + while (esResult['results'].length > 0) { + allResults.push(esResult['results']) + body['pagination_marker'] = esResult['marker'] + esResult = await AxiosWrapper.builder().request(options) + } + return allResults.flat(2) + // return this.executeDdRequest(url, method, body, config.cssoToken) + }; + + utils.getPlaybackSavedSearchEvents = async function(startTime, endTime, config) { + let body = { + start_time: startTime, + end_time: endTime, + ss_name: config.savedSearchName + }; // currently we will only query for personnel saved searches + const options = { + method: 'POST', + url: `${config.dataDriveHost}/api/ss/playback/v2`, + headers: { + 'Content-Type': 'application/json', + Cookie: `ssosession=${config.cssoToken}` + }, + data: body, + } + DdLogger.debug(`getPlaybackSavedSearchEvents request options: ${JSON.stringify(options)}`); + let allResults = [] + let esResult = await AxiosWrapper.builder().request(options) + while (esResult['results'].length > 0) { + allResults.push(esResult['results']) + body['pagination_marker'] = esResult['marker'] + esResult = await AxiosWrapper.builder().request(options) + } + return allResults.flat(2) + }; + + //--------------------------------------------------------------- + // Get saved search; This is used to verify that a saved search exists + /** + * + * @param {String} ss_type "personnel" or "general" + * @param {String} name name of saved search + * @param {String} owner this is for "general" saved search only; name of the owner for a "general" saved search + * @param {DdSubConfig} config config that stores information about DataDrive + */ + utils.getSavedSearch = async function(ss_type, name, owner, config) { + let url; + if (ss_type === "general") { + url = `${config.dataDriveHost}/api/saved_search/get/${owner}/${name}`; + } + else { + url = `${config.dataDriveHost}/api/saved_search/get/${name}`; + } + return this.executeDdRequest(url, "GET", null, config.cssoToken); + } + + utils.verifySavedSearch = async function(ss_type, name, owner, config, callback) { + let response = await this.getSavedSearch(ss_type, name, owner, config); + if (utils.validHTTPResponse(response)) { + callback() + } + else { + this.errorAndExit('Saved search specified does not exist.'); + } + } + + /** + * Helper function to build and execute a request to DataDrive Middleware Server + * @param {*} url URL of the request + * @param {*} method HTTP Method of the request; this has to be all upper case + * @param {*} body Body of the request + * @param {*} cssoToken CSSO Token that will be passed into `ssosession` header; this will log in the user + * @returns {Promise} Promise with Response object + */ + utils.executeDdRequest = function(url, method, body, cssoToken) { + const reqOptions = { + url: url, + method: method, + headers: { + Cookie: request.cookie('ssosession=' + cssoToken ) + }, + json: true + }; + if (body) { + reqOptions['body'] = body; + } + DdLogger.debug(`Executing DdRequest with reqOptions: ${JSON.stringify(reqOptions)}`); + const requestAsync = util.promisify(request); + let promise = requestAsync(reqOptions); + return promise; + } + + //--------------------------------------------------------------- + // comparator to help sort array of objects with ocs_updated_at field as the field to sort by + utils.playbackEventsComparator = function(event1, event2) { + return new Date(event1.ocs_updated_at).getTime() - new Date(event2.ocs_updated_at).getTime(); + } + + /** + * Check if status code returned from HTTP response is either 2xx (success) or 3xx (redirection) + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + * @param {HttpLib.IncomingMessage} response + */ + utils.validHTTPResponse = function(response) { + if (response.statusCode) { + if (response.statusCode >= 200 && response.statusCode < 400) { + return true; + } + } + return false; + } + + /** + * Write Date object to File + * @param {string} filePath + * @param {Date} date + * @returns {Promise} + */ + utils.writeDateToFile = function(filePath, date) { + // write to file in the folder the date + // for multiple download workers, you want to maybe use a queue or something like that + // this is to make sure there are no file read/write collisions + const fsWriteFileAsync = util.promisify(fs.writeFile); + let dateStr = moment(date).format('YYYY-MM-DDTHH:mm:ss.SSSZZ'); // write to local time zone + return fsWriteFileAsync(filePath, dateStr); + } + + /** + * Write Date object to File + * @param {string} filePath + * @param {string} packageName + * @returns {Promise} + */ + utils.writePackageNameToFile = function(filePath, packageName) { + // write package name to file + const fsWriteFileAsync = util.promisify(fs.writeFile); + return fsWriteFileAsync(filePath, packageName); + } + + /** + * Read checkpoint date from given file path + * @param {string} filePath + * @returns {Promise} + */ + utils.getCheckPointDate = function(filePath) { + const fsReadFileAsync = util.promisify(fs.readFile); + return fsReadFileAsync(filePath); + } + + /** + * Read contents from given file path + * @param {string} filePath + * @returns {Promise} + */ + utils.readFile = function(filePath) { + const fsReadFileAsync = util.promisify(fs.readFile); + return fsReadFileAsync(filePath, 'utf8'); + } + + return utils; +})(); + +module.exports = utils; diff --git a/src/core/DdWsClient.js b/src/core/DdWsClient.js new file mode 100644 index 0000000..80d6742 --- /dev/null +++ b/src/core/DdWsClient.js @@ -0,0 +1,229 @@ +//TPS imports +const WebSocket = require('ws'); +// const request = require('request'); +// const Validator = require('jsonschema').Validator; +// const UrlLib = require('url'); +// const HttpLib = require('http'); +// const PathLib = require('path'); + +//Local imports +const DdUtils = require('./DdUtils.js'); +const DdLogger = require('./DdLogger.js').logger; +const {jsonTryParse} = require('./utils') +const WebsocketException = require('./exceptions/WebsocketException') + +const MAX_FAILED_ATTEMPTS = 3 //max number of failed to connect attempts before quitting +const REATTEMPT_WAIT_MS = 10000 //time to wait before attempting reconnection +const CHECK_IS_ALIVE_INTERVAL_MS = 2000 + +class DataDriveWsClient { + static builder(config) { + return new DataDriveWsClient(config) + } + constructor(config) { + this._wsHost = null; + this._cssoToken = null; + this._packageId = null; + this._packageName = null; + + this.__eventMsgHandler = _ => {} + this.__errMsgHandler = _ => {} + this.__finalConnectionClosedHandler = _ => {}; + + this._isActive = true; + this._wsClient = null; + this.useReconn = true; + + this._connOpenTime = null; + this._connCloseTime = null; + this._isAlive = true + + this._sequentialClosedEvents = 0; + this.updateConfig(config); + DdLogger.debug(`Connecting to web socket with ${JSON.stringify(config)}.`) + } + + updateConfig(newConfig) { // TODO validation + this._wsHost = newConfig.wsHost; + this._cssoToken = newConfig.cssoToken; + this._packageId = newConfig.packageId; + this._packageName = newConfig.packageName; + this._savedSearchName = newConfig.savedSearchName; + this._savedSearchOwner = newConfig.savedSearchOwner; + } + + setMessageCallback(handler) { + this.__eventMsgHandler = handler + return this + } + setErrorCallback(handler) { + this.__errMsgHandler = handler + return this + } + setFinalConnectionClosedCallback(handler) { + this.__finalConnectionClosedHandler = handler + } + + isActive() { + return this._isActive + } + + close() { + this.useReconn = false; + this._wsClient.close(); + } + + handleWsMessage(wsMessage) { + if (DdUtils.isEmptyOrNullString(wsMessage)) { + DdLogger.error("WS::HandleMessage: empty mesg"); + return + } + let wsJsonMsg = jsonTryParse(wsMessage) + if (wsJsonMsg['error'] !== undefined) { + DdLogger.error(`WS::HandleMessage: non json message: ${wsMessage}`); + return + } + wsJsonMsg = wsJsonMsg['result'] + DdLogger.debug(`WS::HandleMessage: Message receieved: ${JSON.stringify(wsJsonMsg)}`); + // handle datadrive upload status message, which for right now we want to ignore + if (DdUtils.isValidDDUploadMessage(wsJsonMsg)) { + // We want to ignore DataDrive Upload Messages because they aren't useful to the DataDrive CLI + // As such, we will print it to debug in case we ever need to read it. + DdLogger.debug(`WS::HandleMessage: Receieved DataDrive Upload Message: ${JSON.stringify(wsJsonMsg)}`); + return; + } + //handle formatted error message from WS host + if (DdUtils.isErrorOcsMessage(wsJsonMsg)) { + DdLogger.error(`WS::HandleMessage: Received error message from WS host: ${JSON.stringify(wsJsonMsg)}`); + this.__errMsgHandler(wsJsonMsg) + return; + } + + //check if we actually received a valid file message that is either OCS message or one that builds on top of an OCS message (ie. Saved Search Message) + let ocsValidResult = DdUtils.isValidOcsMessage(wsJsonMsg); + if (ocsValidResult !== true) { + DdLogger.error("WS::HandleMessage: Could not validate WS-based OCS message: " + wsMessage); + DdLogger.error("WS::HandleMessage: More info: " + ocsValidResult); + return; + } + this.__eventMsgHandler(wsJsonMsg) + } + + __onOpen() { + this._connOpenTime = DdUtils.getCurrentTimeMillis(); + this._connCloseTime = null; + this._isActive = true; + this._isAlive = true + this._sequentialClosedEvents = 0; //since we have an open event, zero out close event count + DdLogger.info('Connected to DataDrive WS service '); + // Silence upload status events as we don't care about them and will want to ignore them. + this._wsClient.send(JSON.stringify({send_upload_status_msg: false})) + + //send websocket the packageId in which we are interested + if (this._packageId) { + DdLogger.debug("Requesting OCS events from package '" + this._packageName + "' (" + this._packageId + ")..."); + this._wsClient.send(JSON.stringify({ + client_type: 'dd_cli', + all_pkg: false, + pkg: [this._packageId], + })); + } else if (this._savedSearchName) { + DdLogger.debug("Requesting Saved Search events '" + this._savedSearchName + "' ..."); + this._wsClient.send(JSON.stringify({ + client_type: "NA", + all_pkg: false, + pkg: ["invalidId"]})) // this disables package level events + let payload = { + 'interested_saved_searches': [ + { + type: 'personal', + owner: this._savedSearchOwner, + name: this._savedSearchName + } + ] + }; + this._wsClient.send(JSON.stringify(payload)); + } else { + DdUtils.errorAndExit("Error during web socket open. Package Name was not provided or incorrect, or saved search name was not provided.") + } + } + + __onClose(event) { + this._connCloseTime = DdUtils.getCurrentTimeMillis(); + let connTimeInfo = ""; + if (!(this._connCloseTime === null || this._connOpenTime === null)) { + let connTime = this._connCloseTime - this._connOpenTime; + connTimeInfo = "(alive for " + (connTime / 1000) + " seconds)"; + } + + DdLogger.info("Disconnected from websocket " + connTimeInfo + ""); + DdLogger.info("WS.close(): " + JSON.stringify(event)); + + this._isActive = false; + this._sequentialClosedEvents = this._sequentialClosedEvents + 1; + + if (this.useReconn) { + if (this._sequentialClosedEvents >= MAX_FAILED_ATTEMPTS) { + DdLogger.error("WS.close(): Maximum connection attempts have failed. Giving up."); + //console.log("WS.close(): Maximum connection attempts have failed. Giving up."); + this.__finalConnectionClosedHandler(); + return; + } + let reconnTime = REATTEMPT_WAIT_MS * this._sequentialClosedEvents; + DdLogger.info("WS.close(): We are going to try reconnecting shortly..."); + const instance = this + //console.log("WS.close(): We are going to try reconnecting shortly..."); + setTimeout(() => instance.buildWebSocketClient(), reconnTime); + } + } + + __onError(errMessage) { + let now = DdUtils.getCurrentTimeMillis(); + DdLogger.error("Error happened with websocket [" + now + "] : " + JSON.stringify(errMessage)); + this.__errMsgHandler(errMessage) + } + + __onMessage(message) { + try { + this.handleWsMessage(message) + } catch (error) { + DdLogger.printError(error); + DdLogger.error("Error occurred while handling WS message: " + JSON.stringify(message)); + } + } + + __checkSocketStatus() { + if (this._isAlive === false) { + DdLogger.error('closing socket coz isAlive is false. This is a temporary workaround') + throw new WebsocketException('closing socket coz isAlive is false') + } + this._isAlive = false + this._wsClient.ping(() => {}) + } + + startSession() { + this.buildWebSocketClient() + return this + } + + buildWebSocketClient() { + const instance = this + const wsOptions = { + // rejectUnauthorized: false, // enable this when testing it locally where https is using self-signed certs + headers: { + Cookie: `ssosession=${this._cssoToken}` + } + }; + + DdLogger.debug("Connecting to " + this._wsHost + "...\n"); + //console.log("Connecting to "+this._wsHost+"...\n"); + this._wsClient = new WebSocket(this._wsHost, [], wsOptions); + this._wsClient.on('pong', () => instance._isAlive = true) // result of ping. if it responds, it's still alive + this._wsClient.on('open', () => instance.__onOpen()) + this._wsClient.on('close', event => instance.__onClose(event)) + this._wsClient.on('error', errEvent => instance.__onError(errEvent)) + this._wsClient.on('message', message => instance.__onMessage(message)) + setInterval(() => instance.__checkSocketStatus(), CHECK_IS_ALIVE_INTERVAL_MS) + } +} +exports.DataDriveWsClient = DataDriveWsClient diff --git a/src/core/EmptyPromise.js b/src/core/EmptyPromise.js new file mode 100644 index 0000000..ebbca10 --- /dev/null +++ b/src/core/EmptyPromise.js @@ -0,0 +1,42 @@ +/** + * @author wphyo + * Created on 11/24/20. + */ +const bbPromise = require('bluebird'); +class EmptyPromise { + constructor() { + this._callbacks = null; + this._done = false; + let instance = this; + this._p = new bbPromise((resolve, reject) => {instance._callbacks = { resolve, reject }}); + } + + done() { + return this._done; + } + + resolve(obj) { + this._callbacks.resolve(obj); + this._done = true; + return this._p; + } + + reject(obj) { + this._callbacks.reject(obj); + this._done = true; + return this._p; + } + + get() { + return this._p; + } + + static builder() { + return new EmptyPromise(); + } +} +exports.EmptyPromise = EmptyPromise; +/** + * @author wphyo + * Created on 6/1/22. + */ diff --git a/src/core/OcsCfg.js b/src/core/OcsCfg.js new file mode 100644 index 0000000..9e4942f --- /dev/null +++ b/src/core/OcsCfg.js @@ -0,0 +1,69 @@ +import {jsonTryParse} from "./utils"; + +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const DdConsts = require('./DdConstants.js'); +const SsoToken = require('./SsoToken.js'); +const DdUtils = require('./DdUtils.js'); +const DdLogger = require('./DdLogger.js').logger; +const DEFAULT_CWD = '/' + +class OcsConfig { + constructor() { + this.__ocsConfigFile = DdUtils.getOcsCfgFilepath() + this.__cachedConfig = null + } + + ocsCfgFileExists() { + return DdUtils.fileExists(this.__ocsConfigFile) + } + + __loadOcsConfig(ocsConfigData) { + const nullConfig = { + ocsEndpointHost: null, + ocsApiStage: null, + pkg: null, + cwd: DEFAULT_CWD, + } + this.__cachedConfig = {...nullConfig, ...ocsConfigData} + } + + getOcsConfig(failOnError=true) { + if (this.__cachedConfig !== null) { + return this.__cachedConfig + } + if (!this.ocsCfgFileExists()) { + if (failOnError) { + DdUtils.errorAndExit(`ERROR reading the configuration file ${this.__ocsConfigFile}.\nRun the OCS configuration command to save a valid configuration.`) + } + return null + } + + let _fileCfg = {}; // Config as read from the file. + + // Read the metadata. + try { + const _data = fs.readFileSync(this.__ocsConfigFile, 'utf8') + const jsonData = jsonTryParse(_data) + if (jsonData['error'] !== undefined) { + if (failOnError) { + DdUtils.errorAndExit(`ERROR reading the OCS configuration file ${OCS_CFG_FILE}. Run the OCS configuration command to save a valid configuration.`); + } + return null + } + this.__loadOcsConfig(jsonData['result']) + return this.__cachedConfig + } catch (error) { + if (error.code !== 'ENOENT') { + if (failOnError) { + DdUtils.errorAndExit(`ERROR reading the OCS configuration file ${OCS_CFG_FILE}.\n${error}`); + } + return null + } + } + } +} + +module.exports = OcsConfig; diff --git a/src/core/OcsUtils.js b/src/core/OcsUtils.js new file mode 100644 index 0000000..b4cafdd --- /dev/null +++ b/src/core/OcsUtils.js @@ -0,0 +1,180 @@ +const util = require('util'); +const DdConsts = require('./DdConstants.js'); +const SsoToken = require('./SsoToken.js'); +const DdUtils = require('./DdUtils.js'); +const DdLogger = require('./DdLogger.js').logger; +const {EmptyPromise} = require('./EmptyPromise') + +class OcsUtils { + static builder(ocsClient, ocsToken) { + return new OcsUtils(ocsClient, ocsToken) + } + constructor(ocsClient, ocsToken) { + this._ocsClient = ocsClient; + this._token = ocsToken; + } + + __validateOCSResult (err, result, methodName) { + if (err !== null) { + return `${methodName}-ends-in-error: ${err.toString()}`; + } + if (result === null || result === undefined) { + return `result for ${methodName} is NULL or UNDEFINED`; + } + if (result['statusCode'] !== 200) { // status return is not 200 + if (result['error'] !== undefined && result['error'] !== null) { // there is an error message + let errMsg = JSON.stringify(result['error']); + DdLogger.error(`ocs-api-error for ${methodName}: ${errMsg}`, this._user); + return errMsg; + } else { + return `ocs status for ${methodName} returned is not 200. code: ${result['statusCode']}`; + } + } + return undefined; + } + + async __executeOCS (param, methodName) { + DdLogger.debug(`${methodName} : ${util.inspect(param, {depth: null})}`); + const instance = this; + + let promise = EmptyPromise.builder() + this._ocsClient[methodName](param, (err, result) => { + let validateOCSResponse = instance.__validateOCSResult(err, result, methodName); // checking the result + if (validateOCSResponse !== undefined) { + DdLogger.error("Error occurred while requesting all package information from OCS."); + DdLogger.printError(validateOCSResponse); + + if (DdUtils.isOcsUnauthError(validateOCSResponse)) { // TODO + DdLogger.error("Please ensure your OCS CSSO login credentials are valid."); + } + promise.reject(new Error(validateOCSResponse)); + return; + } + promise.resolve(result['data']); + }); + return await promise.get(); + } + + toBucketKey(s3Url) { + if (!s3Url.startsWith(DdConsts.S3_PROTOCOL)) { + return undefined + } + const _matches = s3Url.match(DdConsts.S3_URL_REGEX); + return { + bucket: _matches[1], + key: _matches[2] + } + } + + /** + * Returns a permalink to an object indexed in OCS. Copied via https://github.jpl.nasa.gov/M2020-CS3/m2020-data-lake repo + * + * @param {string} pepUrl - The URL of the PEP server + * @param {string} url - The URL of the data object that was indexed in OCS. Typeically, this is an S3 URL. + * @return {string} - A permalink to the URL. + */ + getPermalinkviaPEP(pepUrl, url) { + const _bucketKey = this.toBucketKey(url) + if (_bucketKey && _bucketKey.bucket && _bucketKey.key) { + // This is an S3 URL. + if (pepUrl) { + return `${pepUrl}/${_bucketKey.bucket}/${_bucketKey.key}` + } else { + throw Error('The PEP server information is not defined. The configuration needs to be updated.') + } + } else { + // Not an S3 URL, so we just return as is. Assume the resource is already protected by CSSO. + return url + } + } + + createLsQuery(packageId, ocsFullname, expr) { + let patternsArray = [ `${ocsFullname}` ]; + let searchDoc = { + packageName: packageId, + patterns: patternsArray, + dirOnly: false, + recursive: false, + }; + + if (expr) + { + searchDoc.expr = expr; + } + + return searchDoc; + } + + createLsRequest(packageId, ocsFullname, expr) { + + let lsQueryObj = this.createLsQuery(packageId, ocsFullname, expr); + return { + csso: { + sessionToken: this._token + }, + input: lsQueryObj + } + } + + /** + * + * @param packageName : String + * @return {Promise<{packageS3Bucket: (null|*), packageId: *}|{packageS3Bucket: null, packageId: null}>} + */ + async translatePackageNameToId(packageName) { + if (!this._ocsClient) { + throw new Error("No OCS client available"); + } + if (!this._token) { + throw new Error("No OCS token set"); + } + if (DdUtils.isEmptyOrNullString(packageName)) { + throw new Error("No packageName parameter"); + } + let _descAllPkgsReq = { + csso: { + sessionToken: this._token + } + } + const ocsPkgs = await this.__executeOCS(_descAllPkgsReq, 'describeAllPackages') + if(ocsPkgs.length < 1) { + DdLogger.warn('no package found in OCS') + return { + packageId: null, + packageS3Bucket: null, + } + } + const filteredPkg = ocsPkgs.filter(e => e['name'] === packageName) + if (filteredPkg.length < 1) { + DdLogger.debug(`no package name: ${packageName} in OCS`) + return { + packageId: null, + packageS3Bucket: null, + } + } + return { + packageId: filteredPkg[0]['package_id'], + packageS3Bucket: filteredPkg[0]['s3Bucket'] === undefined ? null : filteredPkg[0]['s3Bucket'] + } + } + + async getOcsFileMetadata(packageName, ocsFullname) { + if (!ocsFullname || ocsFullname === "") { + DdLogger.error("getOcsFileMetadata: Missing ocsFullname parameter"); + return + } + const ocsFileArray = await this.__executeOCS(this.createLsRequest(packageName, ocsFullname, null), 'searchLS') + + if (ocsFileArray.length < 1) { + DdLogger.debug(`no file found for ${ocsFullname}`) + return {} + } + if (ocsFileArray.length > 1) { + DdLogger.warn(`OCS sent multiple results (count = ${ocsFileArray.length}) for the OCS LS query for: ${ocsFullname}`); + DdLogger.warn("If this issue exists beyond G6.0 testing, please inform OCS/CS3 team (its their bug?)"); + } + return ocsFileArray[0] + } +} + +module.exports = OcsUtils diff --git a/src/core/SsoToken.js b/src/core/SsoToken.js new file mode 100644 index 0000000..ac5711b --- /dev/null +++ b/src/core/SsoToken.js @@ -0,0 +1,107 @@ +/** + * @author wphyo + * Created on 6/1/22. + */ +// Interface to the OCS SSO token and also a facility to keep it +// active through periodic URL cookie-based requests to an OCS service URL. +// + +'use strict'; + +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const request = require('request'); + +const DdUtils = require('./DdUtils'); +const DdLogger = require('./DdLogger.js').logger; + +class SsoToken { + constructor() { + this.__ssoTokenValue = null // This should be a string value + this.__ssoTokenExpiration = null // This should be a string value + + this.__intervalMinutes = 1; + this.__intervalSecPerMin = 60; + this.__intervalMsecPerSec = 1000; + this.__intervalMillis = this.__intervalMinutes * this.__intervalSecPerMin * this.__intervalMsecPerSec; + + this.__timerObj = null; + this.__checkAuthToken = true; + + //timestamps on auth requests and success + this.__performAuthMetrics = true; + this.__lastAuthAttempt = null; + this.__lastAuthSuccess = null; + this.__lastAuthAttemptMax = 3; + this.__lastAuthTimeout = this.__lastAuthAttemptMax * this.__intervalMillis; + } + + loadToken(sessionPath=null, expirationPath=null) { + try { + //CSSO token + const homedir = os.homedir(); + let sesPath = sessionPath !== null ? sessionPath : path.join(homedir, ".cssotoken", "ssosession") + let expPath = expirationPath !== null ? expirationPath : path.join(homedir, ".cssotoken", "expiration") + + //console.log("sesPath "+sesPath); + this.__ssoTokenValue = fs.readFileSync(sesPath, 'utf8'); + this.__ssoTokenExpiration = fs.readFileSync(expPath, 'utf8'); + + if ( DdUtils.isEmptyOrNullString(this.__ssoTokenValue)) { + DdUtils.errorAndExit('SsoToken:: Empty cssotoken. Consider re-initing your credentials'); + } + } catch (error) { + DdLogger.error(error.message); + DdLogger.debug(error.stack); + DdUtils.errorAndExit('SsoToken:: Error occurred during retrieval of cssotoken.') + } + } + + isTokenAboutToExpired(hours=1) { + this.getTokenExpiration() + if (!this.__ssoTokenExpiration) { + DdUtils.errorAndExit('SsoToken:: Empty cssotoken. Consider re-initing your credentials'); + return false + } + // Check that it has not expired. + // Note that the expiration time written by CSSO is in seconds, not milliseconds. + const _expireTime = Number.parseInt(this.__ssoTokenExpiration) + let expireDate = new Date(_expireTime * 1000) // Date object should be in milliseconds, so multiply it by 1000 + expireDate.setHours(expireDate.getHours() - hours) + let date = new Date(Date.now()) + return date >= expireDate + } + + getToken() { + if (DdUtils.isEmptyOrNullString(this.__ssoTokenValue)) { + this.loadToken() + } + return this.__ssoTokenValue; + } + + setToken() { + // validate input; make sure it is a string + if (typeof value != "string") { + throw Error('Token should be a string') + } + this.__ssoTokenValue = value + } + + getTokenExpiration() { + if (DdUtils.isEmptyOrNullString(this.__ssoTokenExpiration)) { + this.loadToken() + } + return this.__ssoTokenExpiration + } + + setTokenExpiration(tokenExpirationValue) { + // validate input to be of length 10 and is a string + if (typeof tokenExpirationValue != "string" || tokenExpirationValue.length !== 10) { + throw Error('Token should be a string and of length 10') + } + this.__ssoTokenExpiration = tokenExpirationValue + } +} + +module.exports = SsoToken; diff --git a/src/core/axios_wrapper.js b/src/core/axios_wrapper.js new file mode 100644 index 0000000..988cdc5 --- /dev/null +++ b/src/core/axios_wrapper.js @@ -0,0 +1,23 @@ +/** + * @author wphyo + * Created on 10/1/20. + */ +const axios = require('axios') + +class AxiosWrapper { + async request(options) { + try { + let result = await axios.request(options) + return result.data + } catch (e) { + let err = new Error() + err.message = JSON.stringify(e.response.data) + err.statusCode = e.response.status + throw err + } + } + static builder() { + return new AxiosWrapper() + } +} +exports.AxiosWrapper = AxiosWrapper diff --git a/src/core/exceptions/WebsocketException.js b/src/core/exceptions/WebsocketException.js new file mode 100644 index 0000000..6e13668 --- /dev/null +++ b/src/core/exceptions/WebsocketException.js @@ -0,0 +1,11 @@ +/** + * @author wphyo + * Created on 7/19/21. + */ +class WebsocketException extends Error { + constructor(message) { + super(message) + this.name = 'WebsocketException' + } +} +module.exports = WebsocketException diff --git a/src/core/utils.js b/src/core/utils.js new file mode 100644 index 0000000..0a6fdd6 --- /dev/null +++ b/src/core/utils.js @@ -0,0 +1,39 @@ +/** + * @author wphyo + * Created on 6/1/22. + */ +const Validator = require('jsonschema').Validator; +const v = new Validator(); + +const isValidJson = (obj, schema) => { + if (obj === null || obj === undefined) { + return false; + } + return v.validate(obj, schema).valid; +}; + + +/** + * + * @param input + * @return {{result: undefined, error: string}|{result: any, error: undefined}} + */ +const jsonTryParse = (input) => { + try { + return { + result: JSON.parse(input), + error: undefined + }; + } catch (error) { + return { + result: undefined, + error: error.toString() + } + } +} + + +module.exports = { + isValidJson, + jsonTryParse, +} diff --git a/src/ddrv-config.js b/src/ddrv-config.js new file mode 100644 index 0000000..35c4471 --- /dev/null +++ b/src/ddrv-config.js @@ -0,0 +1,98 @@ +'use strict'; + + +const DdConsts = require('./core/DdConstants.js'); +const DdUtils = require('./core/DdUtils.js'); +const DdOptions = require('./core/DdOptions.js'); +const DdLogger = require('./core/DdLogger.js').logger; +const {DdCliConfigFileIO} = require('./core/DdCliConfigFileIO'); + +const Table = require('easy-table'); + + +//get initial state +let _dHost = DdConsts.DEFAULT_DD_HOST; +let _pHost = DdConsts.DEFAULT_PEP_HOST; +const _cfg = DdCliConfigFileIO.builder().readConfig(false); +if (_cfg) +{ + if (_cfg[DdConsts.PROP_DATADRIVE_HOST]) + _dHost = _cfg[DdConsts.PROP_DATADRIVE_HOST]; + if (_cfg[DdConsts.PROP_PEP_HOST]) + _pHost = _cfg[DdConsts.PROP_PEP_HOST]; +} + + +DdOptions.option( '-d, --dd-host [dd-host]', 'DataDrive middleware host.'); +DdOptions.option( '-p, --pep-host [pep-host]', 'PEP host.'); +DdOptions.option( '-r --reset', `Reset configuration to default values.`); +DdOptions.setCustomHelp(function () { + console.log(''); + console.log(' When no arguments are specified, the command displays the current configuration.'); +}); +DdOptions.parse(process.argv); + + +//Print config nicely +function stringifyDd(map) { + if (map) { + const t = new Table(); + t.cell('DataDrive Host:', map[DdConsts.PROP_DATADRIVE_HOST] || '(undefined)'); + t.cell('PEP Host:', map[DdConsts.PROP_PEP_HOST] || '(undefined)'); + t.newRow(); + return '\n' + t.printTransposed(); + } else{ + return "\nNo configuration available." + } + +} + +function stringifyOcs(map) { + if (map) { + const t = new Table(); + t.cell('OCS Host:', map[DdConsts.PROP_OCS_HOST] || '(undefined)'); + t.cell('OCS API:', map[DdConsts.PROP_OCS_API_DEPLOYMENT] || '(undefined)'); + t.newRow(); + return '\n' + t.printTransposed(); + } else { + return "\nNo configuration available." + } +} + + + +if (DdOptions.program.reset) { + //check for incompatible options + if (DdOptions.program.ddHost || DdOptions.program.pepHost) { + DdUtils.errorAndExit('You cannot specify "--reset" with any other options.'); + } else { + _dHost = DdConsts.DEFAULT_DD_HOST; + _pHost = DdConsts.DEFAULT_PEP_HOST; + } +} else if (!DdOptions.program.ddHost && !DdOptions.program.pepHost ) { + + DdLogger.info('\nDataDrive configuration is:' + stringifyDd(_cfg)); + + //add the OCS config stuff users prolly care about + //let ocsCfg = OcsCfg.getOcsConfig(false); + //DdLogger.info('\nOCS configuration is:' + stringifyOcs(ocsCfg)); + //DdLogger.info( ""); + process.exit(0); +} + +if (DdOptions.program.ddHost && DdOptions.program.ddHost !== true) { + _dHost = DdOptions.program.ddHost; +} + if (DdOptions.program.pepHost && DdOptions.program.pepHost !== true) { + _pHost = DdOptions.program.pepHost; +} + +//Save changes to config file +DdCliConfigFileIO.builder().writeConfig({ datadriveHost : _dHost, pepHost : _pHost}); + +//inform user of updated state +let _updatedCfg = DdCliConfigFileIO.builder().readConfig(false); +if (_updatedCfg) + DdLogger.info('\nThe DataDrive configuration has been changed to:' + stringifyDd(_updatedCfg)); +else + DdUtils.errorAndExit('\nUnable to read updated DataDrive configuration file.'); diff --git a/src/ddrv-publish.js b/src/ddrv-publish.js new file mode 100644 index 0000000..227fd2a --- /dev/null +++ b/src/ddrv-publish.js @@ -0,0 +1,335 @@ +// Create a Datadrive/OCS publish session session by: +// +// 1) Using OCS Client, get the packageId associated with the +// packageName argument passed to us. +// +// 2) Using filesystem sniffer, respond to each new file event by +// pushing file to the Datadrive middleware, awaiting for metadata +// response or error +// +// 3) If Metadata extracted, ptoceed with file upload to Datadrive +// middleware. If error, abort upload. +// +// +// +// Arguments: --packageName packagenameWePublishTo [Required] +// --sourceDir directoryFromWhichFilesWillBePushed [Required] +// --filter wildcard-glob expression [Optional] +// --destRoot S3-path-prefix [Optional] +// --retainPath [Optional] +// --overwrite [Optional] +// What about this one: +// --subdirs [Optional] +// + +//Node library imports + +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const request = require('request'); +const cookie = require('cookie'); +const globToRegExp = require('glob-to-regexp'); + + + + +//OCS library (only need it to translate from packageName to packageId) +const OCS = require('@gov.nasa.jpl.m2020.cs3/ocs-js-client'); + +//local imports +const DdConsts = require('./core/DdConstants.js'); +const DdUtils = require('./core/DdUtils.js'); +const OcsUtils = require('./core/OcsUtils.js'); +const PubConfig = require('./core/DdPubConfig.js'); +const DdListener = require('./core/DdDirectoryListener.js'); +const DdUploader = require('./core/DdUploader.js'); +const DdOptions = require('./core/DdOptions.js'); +const DdLogger = require('./core/DdLogger.js').logger; +const {DataDriveMWServiceSettings} = require('./core/DataDriveMWServiceSettings') + +//-------------------------- + +//This is needed to be able to debug using self-signed certs +//remove for production tho! +//process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; + +//-------------------------- + +DdOptions.version('\n*** '+DdConsts.CLIENT_TITLE+' ***\n\n'); +DdOptions.option('-p, --package-name ', 'The name of the package.'); +DdOptions.option('-s, --source-dir ', 'The source directory.'); +DdOptions.option('-d, --dest-prefix [s3-prefix]', 'Prefix path to be prepended to S3 location', ''); +DdOptions.option('-f, --filter [value]', 'A wildcard expression to filter files', '*'); +DdOptions.option('-r, --retain-path', 'Use the relative path when creating S3 location of file'); +DdOptions.option('-o --overwrite', 'Allows existing files to be overwritten on the server'); +DdOptions.parse(process.argv); + +//------------------------- + +function handleSuccessfulUpload(filepath) { + DdLogger.info("File uploaded: "+filepath); +} + +//--------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------- + +function upload_Callback(filepath, err, response, body) { + + if (err !== null) { // has error + let extractedErrMsg = pubConfig.ddUploader.extractErrorMessage(err); + DdLogger.error(`Error uploading '${filepath}': ${extractedErrMsg}`); + return; + } + + let statusCode = response.statusCode; + + if (statusCode >= 500) + { + DdLogger.error(`Error uploading '${filepath}'. Received server error code (`+statusCode+")"); + if (response.data !== undefined) + DdLogger.printError(response.data); + return; + } + else if (statusCode >= 400) + { + DdLogger.error(`Error uploading '${filepath}'. Received error code (`+statusCode+")"); + if (response.data !== undefined) + DdLogger.printError(response.data); + return; + } + + //let metadata = response.data; + handleSuccessfulUpload(filepath); +}; + +//--------------------------------------------------------------------- + +function handleDirFileError(dirError) { + DdLogger.printError(dirError); +}; + +//--------------------------------------------------------------------- + +function handleDirFileEvent(filepath, isChangeEvent) +{ + //If the event is for a file that passes filter, then get it + if (!pubConfig.satisfiesFilter(filepath)) { + let rejectMsg = "File '"+filepath+"' was skipped because it did not satisfy the filter: " + pubConfig.fileWildcard; + DdLogger.debug(rejectMsg); + return; + } + + let eventType = isChangeEvent ? "Changed" : "New"; + let acceptMsg = eventType +" file event for : " + filepath; + DdLogger.info(acceptMsg); + + let sleepMs = pubConfig.getFileEventTimeout(); + setTimeout(triggerFileUpload, sleepMs, filepath); + +}; + + +//--------------------------------------------------------------------- + +function triggerFileUpload(filepath) +{ + //get the expected OCS path + let ocsPath = pubConfig.getOcsPath(filepath); + + //the uploaded wants a file object (is this the object type Axios expects?? Who knows...) + // let theFile = fs.readFileSync(filepath); + // if (theFile === null) { + // let readErrMsg = "Could not read the following file: ${filepath}"; + // DdLogger.error(readErrMsg); + // return; + // } + + + //function(file, pkg, path, isOverwrite, callback) + if (false) { + pubConfig.ddUploader.verifyMetadata(filepath, pubConfig.packageId, + pubConfig.packageBucket, ocsPath, pubConfig.overwriteEnabled, + extractMetadata_Callback); + } + else{ + pubConfig.ddUploader.autoUpload(filepath, pubConfig.packageId, + pubConfig.packageBucket, + ocsPath, pubConfig.isOverwriteEnabled(), + upload_Callback); + + } + +}; + + +//--------------------------------------------------------------------- + + +function createOcsClient() +{ + + //CREATE OCS CLIENT + let ocsConfig = { + ocsEndpointHost: pubConfig.ocsHost, + ocsApiStage: pubConfig.ocsAPIDeployment + }; + + let ocsClient = new OCS(ocsConfig); + return ocsClient; +} + +//--------------------------------------------------------------------- + +function createDirListener() +{ + let dirListener = new DdListener(pubConfig); + + dirListener.setMessageCallback(handleDirFileEvent); + dirListener.setErrorCallback(handleDirFileError); + + return dirListener; +} + +//--------------------------------------------------------------------- + +function createFileUploader() +{ + let hostUrl = pubConfig.dataDriveHost; + + let fileUploader = new DdUploader(hostUrl, pubConfig.cssoToken); + + return fileUploader; + +} +//--------------------------------------------------------------------- + +function startLocalSubscription() +{ + let _packageId = pubConfig.packageId; + let _packageName = pubConfig.packageName; + + if (DdUtils.isEmptyOrNullString(_packageId)) + { + DdLogger.error("Error: startLocalSubscription: Missing required package id."); + return; + } + if (DdUtils.isEmptyOrNullString(_packageName)) + { + DdLogger.error("Error: startLocalSubscription: Missing required package name."); + return; + } + + //create local directory listener + pubConfig.dirListener = createDirListener(); + if(! pubConfig.dirListener) { + DdLogger.error("Error: Unable to create a directory listener instance."); + return; + } + + //create the file uploader + pubConfig.ddUploader = createFileUploader(); + if(! pubConfig.ddUploader) { + DdLogger.error("Error: Unable to create a file uploaded instance."); + return; + } + + //start the listening session + DdLogger.info("Listening for new files in "+pubConfig.dirListener.getDirectory()+"..."); + DdLogger.info("Will publish to "+_packageName+" ("+_packageId+")..."); + pubConfig.dirListener.startSession(); +} + + +//--------------------------------------------------------------------- + +function initiate_OcsClient() +{ + + //create an OCS client + pubConfig.ocsClient = createOcsClient(); + + //create an OCS utils layer + pubConfig.ocsUtils = OcsUtils.builder(pubConfig.ocsClient, pubConfig.cssoToken) +} + +//--------------------------------------------------------------------- + + +function ddSrvcSettings_Callback(error, ocsHost, ocsStage) +{ + if (error) + { + DdUtils.errorAndExit(error); + } + + pubConfig.setOcsSettings(ocsHost, ocsStage); + initiate_OcsClient() + pubConfig.ocsUtils.translatePackageNameToId(pubConfig.packageName) + .then(pkgDetails => { + xlate_PkgName_PkgId_Callback(err, pkgDetails['packageId'], pkgDetails['packageS3Bucket']) + }).catch(err => { + DdUtils.errorAndExit(err); + }) +} + +//--------------------------------------------------------------------- + +function xlate_PkgName_PkgId_Callback(err,pkgId, pkgBucket) { + + if (err) { + DdLogger.printError(err); + return; + } else if (pkgId != null) { + pubConfig.packageId = pkgId; + pubConfig.packetBucket = pkgBucket; + + if (pkgBucket != null) + { + pubConfig.packageBucket = pkgBucket; + startLocalSubscription(); + } + else + { + DdLogger.error("Package '"+pubConfig.packageName+"' is not configured for file uploads. Aborting."); + return; + } + } +} + + +//--------------------------------------------------------------------- + +function initiate() +{ + //get OCS settings from middleware + let ddService = DataDriveMWServiceSettings.builder(pubConfig.dataDriveHost, pubConfig.cssoToken) + ddService.loadSettings().then(settingResult => { + ddSrvcSettings_Callback(null, ddService.getOcsEndpointHost(), ddService.getOcsApiStage()) + }).catch(err => DdUtils.errorAndExit(err.toString())) +} + +//--------------------------------------------------------------------- + +//------------------------------------------------ +//------------------------------------------------ + +//------------------------------------------------ + +//load initial config/env +const pubConfig = new PubConfig(DdOptions.program); +if (!pubConfig.isConfigured() ) +{ + DdLogger.error('Configuration unsuccessful. Aborting.'); + return; +} + +initiate(); + + +//------------------------------------------------ + diff --git a/src/ddrv-show.js b/src/ddrv-show.js new file mode 100644 index 0000000..e2c17b3 --- /dev/null +++ b/src/ddrv-show.js @@ -0,0 +1,121 @@ +'use strict'; + + +const DdConsts = require('./core/DdConstants.js'); +const DdOptions = require('./core/DdOptions.js'); +const DdConfig = require('./core/DdConfig.js'); +const {DataDriveMWServiceSettings} = require('./core/DataDriveMWServiceSettings') + +const DdUtils = require('./core/DdUtils.js'); +const DdLogger = require('./core/DdLogger.js').logger; + +const Table = require('easy-table'); + + +// load initial config/env +const config = new DdConfig(DdOptions.program); + +/** + * Initialize OCS client + * @returns {Promise} + */ +async function initiate() { + //get OCS settings from middleware + let ddService = DataDriveMWServiceSettings.builder(config.dataDriveHost, config.cssoToken) + try { + await ddService.loadSettings() + } catch (e) { + DdUtils.errorAndExit(e.toString()) + } + config.setOcsSettings(ddService.getOcsEndpointHost(), ddService.getOcsApiStage()) + config.initiate_OcsClient() +} + +/** + * Call OCS to get a list of packages + * @returns {Promise} + */ +async function getPackages() { + try { + return new Promise((resolve, reject) => { + const rqst = { + csso: { + sessionToken: config.cssoToken + } + }; + config.ocsUtils._ocsClient.describeAllPackages(rqst, (err, resp) => { + if (err) { + reject(err); + } + else if (resp.error) { + reject(resp.error); + } + else { + resolve(resp); + } + }) + }); + } catch (error) { + DdUtils.errorAndExit(error); + } +} + +//Print config nicely +/** + * Turns array of JSON information about packages into a table for console log + * @param {Array} data + * @returns {String} + */ +function stringifyPackages(data) { + if (data) { + const t = new Table(); + for (let i = 0; i < data.length; i++) { + t.cell('Name:', data[i][DdConsts.OCS_PACKAGE_NAME] || '(undefined)'); + t.cell('Desc:', data[i][DdConsts.OCS_PACKAGE_DESCRIPTION] || '(undefined)'); + t.newRow(); + } + return '\n' + t.toString(); + } + return ''; +} + +/** + * CLI entrypoint; Checks to see if right arguments and options are set then get the resource + * @returns {Promise} + */ +async function main() { + await initiate(); + // Configure CLI + DdOptions.program.name("ddrv"); + DdOptions.program.usage("show "); + DdOptions.program.on('--help', () => { + console.log(''); + console.log('Examples:'); + console.log(' # List packages in OCS.') + console.log(' ddrv show packages') + }); + // + let resource = undefined; + await new Promise((resolve, reject) => { + DdOptions.program.arguments('').action(async (arg) => { + resource = arg; + }); + DdOptions.program.parse(process.argv); + resolve(); + }); + + if (resource == 'packages') { + let results = await getPackages(); + console.log(stringifyPackages(results.data)); + } + else if (resource === undefined) { + console.log('You must specify the type of resource to show. Ex: packages'); + process.exit(1); + } + else { + DdUtils.errorAndExit('Resource does not exist.') + } + process.exit(0); +} + +main(); diff --git a/src/ddrv-subscribe.js b/src/ddrv-subscribe.js new file mode 100644 index 0000000..50e5d65 --- /dev/null +++ b/src/ddrv-subscribe.js @@ -0,0 +1,369 @@ +// Create a Datadrive/OCS subscription session by: +// +// 1) Using OCS Client, get the packageId associated with the +// packageName argument passed to us. +// +// 2) Using WebSockets, connect to DataDrive middleware layer for +// notifications on newly indexed objects for the packageId. +// +// 3) Using OCS Client, respond to each WS event by querying OCS +// for that file's details, including a downloadable URL. +// +// 4) Use that download URL to perform the actual download +// of the file to this system, into the outputDir. +// +// +// Arguments: --packageName packagenameWeSubscribeTo [Required] +// --outputDir directoryToWhichFilesWillBeSaved [Required] +// --filter wildcard-glob-expression [Optional] +// --retainPath [Optional] +// + +//Node library imports + + +const fs = require('fs'); +//const argv = require('argv-parse'); +const util = require('util'); +const moment = require('moment'); +const {FileMetadata} = require('./core/DdFileMetadata.js'); + +//local imports +const DdConsts = require('./core/DdConstants.js'); +const DdUtils = require('./core/DdUtils.js'); +const {DataDriveWsClient} = require('./core/DdWsClient.js'); +const DdSubConfig = require('./core/DdSubConfig.js'); +const DdOptions = require('./core/DdOptions.js'); +const DdLogger = require('./core/DdLogger.js').logger; +const {DataDriveMWServiceSettings} = require('./core/DataDriveMWServiceSettings') +const {Processor, Queue} = require('./core/DdQueue.js'); +const {QueueEmptyError, MaxProcessSizeError, CannotWriteToLocalFileError} = require('./core/DdError.js'); +const DdPluginHandler = require('./core/DdPluginHandler.js').PluginHandler; +const {EmptyPromise} = require('./core/EmptyPromise') + +const CSSO_RELOAD_ATTEMPT_INTERVAL_MS = 1000 // 1s +//------------------------------------------------ + +class DataDriveSubscriber { + static builder() { + return new DataDriveSubscriber() + } + constructor() { + this.__playbackQueue = new Queue() // queue for playback events + this.__wsQueue = new Queue() // queue for websocket events + this.__playbackProcessor = new Processor(this.__playbackQueue) // processor class processing playback events + this.__wsProcessor = new Processor(this.__wsQueue) // processor class processing ws events + this.__wsProcessorLocked = true // lock to prevent wsProcessor from downloading until "initEventPlayback" function has finished + this.__notifySubscriptionStart = true + + DdOptions.parseSubscriptionOptions(process.argv) // parse command line arguments + this.__subscriptionConfig = new DdSubConfig(DdOptions.program) // load initial config/env + this.__wsClient = null // initialize web socket to null first before initiate() method creates the object + this.__pluginHandler = new DdPluginHandler(this.__subscriptionConfig) // used for plugins + if (! this.__subscriptionConfig.isConfigured()) { + DdLogger.error('Configuration unsuccessful. Aborting.'); + DdOptions.exit(1); // exit the application when configuration is unsuccessful + } + if (!DdUtils.fsChecks(this.__subscriptionConfig.outputDir)) { + DdUtils.errorAndExit(Error('Directory specified does not exist.')); + } + } + + /** + * Using file metadata object and configuration, constructs the final + * output path for the associated file, and checks if file exists + * @param fileMetadata + * @returns {boolean} + */ + + __fileExistsViaMetadata(fileMetadata) + { + let outFilepath = this.__subscriptionConfig.getOutputLocationViaMetadata(fileMetadata); + if (outFilepath == null) + return false; + + return DdUtils.fileExists(outFilepath); + } + + // Gets events from the queue, download, decrement processor count, check if folder exist, lastly update checkpoint file with date of last downloaded item + async processItems() { + /** + * @type {FileMetadata} filemetadata + */ + let fileMetadata = null; + let processor; + if (this.__playbackProcessor.queue.isEmpty() && !this.__wsProcessorLocked) { + processor = this.__wsProcessor; + } + else { + processor = this.__playbackProcessor; + } + + if (this.__notifySubscriptionStart) { + if (this.__playbackProcessor.queue.isEmpty() && !this.__wsProcessorLocked) { + if (this.__subscriptionConfig.playback) { // don't show playback finished message if playback option was not enabled + DdLogger.info('Playback has finished.'); + } + DdLogger.info('Listening for subscriptions...') + this.__notifySubscriptionStart = false; + } + } + + try { + let node = await processor.process(); + let event = node.value.event; + let event_type = node.value.event_type; + let changed_flag = node.value.file_changed; + DdLogger.debug("Decrementing processor size."); + processor.size -= 1; // this is to ensure that only 1 item is processed at a time by the processor + DdLogger.debug("Increment remaining count size."); + + DdLogger.debug("Called getOcsFileMetadata"); + + let url = this.__subscriptionConfig.getOcsUtils().getPermalinkviaPEP(this.__subscriptionConfig.getPepUrl(), event.ocs_url); + DdLogger.info(`Download URL: ${url}`); + event['ocs_download_url'] = url; + fileMetadata = new FileMetadata(); + if (event_type === DdConsts.EVENTTYPE_OCS) { + fileMetadata.unmarshallOCS(event); + } else { + fileMetadata.unmarshallPlayback(event); + } + + //check if options indicate we should skip file if its not considered changed (i.e. OCS metadata update only) + let skip_file = false; + if (this.__subscriptionConfig.skipUnchanged && !changed_flag && this.__fileExistsViaMetadata(fileMetadata)) { + let ocs_name = fileMetadata.getOcsName() + DdLogger.info(`Skipping event for existing file that did not change: ${ocs_name}"`); + skip_file = true; + } + + //Invoke plugin handlers only if file is not skipped + if (!skip_file) { + DdLogger.debug('Invoke "processItem" function for every plugin in the plugin/ folder'); + // This includes the file download plugin + await this.__pluginHandler.callProcessItem(fileMetadata); + } + + //-------------- + + //Still need to update cache/tracking files if file is downloaded or not + + DdLogger.debug("Attempting to create directory.") + const mkdirPromise = EmptyPromise.builder() + fs.mkdir(`${this.__subscriptionConfig.outputDir}/.datadrive`, {recursive: true}, err => { + if (err) { + mkdirPromise.reject(err) + return + } + mkdirPromise.resolve({}) + }) + await mkdirPromise.get() + // write date of file updated to checkpoint file + await DdUtils.writeDateToFile(this.__subscriptionConfig.checkpointPath, fileMetadata.getOcsUpdatedAt()); + + // check if packageName specified and if package name state file does not exist and write package name to it + if (this.__subscriptionConfig.packageName && !fs.existsSync(this.__subscriptionConfig.savedPackageNamePath)) { + await DdUtils.writePackageNameToFile(this.__subscriptionConfig.savedPackageNamePath, this.__subscriptionConfig.packageName); + DdLogger.debug(`${this.__subscriptionConfig.savedPackageNamePath} has been written.`); + } + if (this.__subscriptionConfig.savedSearchName && !fs.existsSync(this.__subscriptionConfig.savedSavedSearchNamePath)) { + await DdUtils.writePackageNameToFile(this.__subscriptionConfig.savedSavedSearchNamePath, this.__subscriptionConfig.savedSearchName); + DdLogger.debug(`${this.__subscriptionConfig.savedSavedSearchNamePath} has been written.`); + } + + //-------------- + } + catch (err) { + if (err instanceof CannotWriteToLocalFileError) { + DdLogger.warn(err.message); + } + else if (!(err instanceof QueueEmptyError) && !(err instanceof MaxProcessSizeError)) { + DdLogger.error(err.message); + DdLogger.debug(err.stack); + } + else { + DdLogger.debug(err.message); + } + processor.size -= 1; + } + } + + /** + * To handle an OCS event that is received via web socket connection to the middleware + * @param {Object} wsOcsObject + * @param {string} wsOcsObject.package_id + * @param {string} wsOcsObject.dataset_id + * @param {string} wsOcsObject.ocs_full_name + * @param {string} wsOcsObject.ocs_url + * @param {string} wsOcsObject.package_dataset_event + * @param {number} wsOcsObject.package_dataset_event_time + * @param {string} wsOcsObject.s3_object_changed ('true' or 'false') + */ + handleWsOcsEvent(wsOcsObject) { + let pkgId = wsOcsObject.package_id; + let datasetId = wsOcsObject.dataset_id; + let eventType = wsOcsObject.package_dataset_event; + let ocs_url = wsOcsObject.ocs_url; + let ocs_full_name = wsOcsObject.ocs_full_name; + let ocs_updated_at = moment(wsOcsObject.package_dataset_event_time).toDate(); + let file_changed = wsOcsObject.hasOwnProperty('s3_object_changed') ? DdUtils.isValueTrue(wsOcsObject.s3_object_changed) : true; + + DdLogger.debug(`Event[${eventType}] Dataset: ${datasetId}; Package: ${pkgId}; Name: ${ocs_full_name}; URL: ${ocs_url}.; Changed: ${file_changed}`); + + if (DdUtils.isEmptyOrNullString(pkgId) || + DdUtils.isEmptyOrNullString(datasetId) || + DdUtils.isEmptyOrNullString(eventType) || + DdUtils.isEmptyOrNullString(ocs_url) || + DdUtils.isEmptyOrNullString(ocs_full_name)) { + DdLogger.error("Message was missing required attributes."); + DdLogger.debug(`${JSON.stringify(wsOcsObject)}`); + //console.error("Message was missing required attributes: "+wsMessage); + return; + } + + // Determine if this is a package event type or saved search event type + if (this.__subscriptionConfig.packageName) { + //make sure event matches our expected package + if (pkgId !== this.__subscriptionConfig.packageId) { + return + } + //If the event is for a file that does not pass filter, reject it + if (! this.__subscriptionConfig.satisfiesFilter(ocs_full_name)) { + let rejectMSg = `File was rejected because it did not satisfy the filter: ${this.__subscriptionConfig.fileWildcard} or ${this.__subscriptionConfig.fileRegex}`; + DdLogger.debug(`${ocs_full_name} ${rejectMSg}`) + return + } + this.__wsQueue.enqueue(datasetId, {"name": ocs_full_name, "date": ocs_updated_at, "event": wsOcsObject, + "event_type": DdConsts.EVENTTYPE_OCS, "file_changed": file_changed}) + return + } + if (this.__subscriptionConfig.savedSearchName) { + // not if saved search name is specified and is a valid saved search message + if (DdUtils.isValidDDSavedSearchMessage(wsOcsObject) === false) { + DdLogger.debug(`Message is not a saved search message: ${JSON.stringify(wsOcsObject)}.`) + return + } + this.__wsQueue.enqueue(datasetId, {"name": ocs_full_name, "date": ocs_updated_at, "event": wsOcsObject, + "event_type": DdConsts.EVENTTYPE_OCS, "file_changed": file_changed}) + return + } + DdLogger.debug(`Package Name or Saved Search Name was not specified, so we are ignore this message as we don't know what to do with it.`); + } + + __createWsClient() { + const wsHost = this.__subscriptionConfig.getDataDriveHost().replace('https', 'wss'); + + let wsConfig = { + wsHost: wsHost, + cssoToken: this.__subscriptionConfig.getCssoToken(), + packageName: this.__subscriptionConfig.packageName, + packageId: this.__subscriptionConfig.packageId, + savedSearchName: this.__subscriptionConfig.savedSearchName, + savedSearchOwner: this.__subscriptionConfig.getUserNameFromCssoToken() + }; + const instance = this + let wsClient = DataDriveWsClient.builder(wsConfig) + wsClient.setMessageCallback(msg => instance.handleWsOcsEvent(msg)) + wsClient.setErrorCallback(errMsg => DdLogger.printError(errMsg)) + wsClient.setFinalConnectionClosedCallback(() => DdOptions.exit(1)) + return wsClient; + } + + async __initEventPlayback() { + if (this.__subscriptionConfig.playback === false) { + this.__wsProcessorLocked = false; + return + } + let filePath = `${this.__subscriptionConfig.outputDir}/.datadrive/checkpoint.txt`; + try { + const checkPointData = await DdUtils.getCheckPointDate(filePath) + let startDate = new Date(checkPointData.toString().trim()); + if (!(startDate instanceof Date) || isNaN(startDate.getTime())) { + throw new TypeError('Bad start date.'); + } + let startTime = startDate.getTime(); + let endTime = Date.now(); + const playBackEventData = await DdUtils.getPlaybackEvents(startTime, endTime, this.__subscriptionConfig); + let events = playBackEventData + DdLogger.debug(JSON.stringify(events)) + events.sort(DdUtils.playbackEventsComparator) + DdLogger.info(`Playback started.`) + DdLogger.info(`${events.length} playback events found since last checkpoint date.`) + + DdLogger.debug(`Events data... ${util.inspect(events, {depth: null})}`) + for (let event of events) { + DdLogger.debug(event); + this.__playbackQueue.enqueue(event.ocs_dataset_id, {"name": event.ocs_full_name, "date": event.ocs_updated_at, + "event": event, "event_type": DdConsts.EVENTTYPE_PLAYBACK, + "file_changed": true}); // Assume all playback files are changed-files + } + } catch (e) { + DdLogger.error(e.message); + DdLogger.debug(e.stack); + DdLogger.error('Failed to initialize event playback.') + } + this.__wsProcessorLocked = false; + } + + async proceedWithSubscriptionAndProcessLoop() { + // final check if configs are valid before starting playback and subscriptions + await this.__subscriptionConfig.validateConfigs(); + await this.__initEventPlayback() + //now we can create a web-socket client and run it + this.__wsClient = this.__createWsClient() + this.__wsClient.startSession() + const instance = this + setInterval(async () => { + let reloaded = instance.__subscriptionConfig.reloadIfSSOTokenAboutToExpire(); + if (reloaded) { + instance.__wsClient.close() + instance.__wsClient = instance.__createWsClient() + instance.__wsClient.startSession() + } + await this.processItems() + + }, CSSO_RELOAD_ATTEMPT_INTERVAL_MS) + } + + async prepareSubscription(ocsHost, ocsStage) { + this.__subscriptionConfig.setOcsSettings(ocsHost, ocsStage); + this.__subscriptionConfig.initiate_OcsClient(); + if (this.__subscriptionConfig.packageName) { + try { + const pkgDetails = await this.__subscriptionConfig.getOcsUtils().translatePackageNameToId(this.__subscriptionConfig.packageName) + if (pkgDetails['packageId'] === null) { + DdUtils.errorAndExit(`cannot find packageId for ${this.__subscriptionConfig.packageName}`) + } + this.__subscriptionConfig.packageId = pkgDetails['packageId'] + await this.proceedWithSubscriptionAndProcessLoop() + } catch (err) { + DdUtils.errorAndExit(err) + } + } + else if (this.__subscriptionConfig.savedSearchName) { + // TODO need to get `owner` of generalized saved search + let response = await DdUtils.getSavedSearch(this.__subscriptionConfig.savedSearchType, this.__subscriptionConfig.savedSearchName, null, this.__subscriptionConfig) + if (DdUtils.validHTTPResponse(response) === false) { + DdUtils.errorAndExit('Saved search specified does not exist.'); + } + await this.proceedWithSubscriptionAndProcessLoop() + } + else { + DdUtils.errorAndExit("Package Name or saved search was not provided or incorrect.") + } + } + + async init() { + const mwSetting = DataDriveMWServiceSettings.builder(this.__subscriptionConfig.getDataDriveHost(), this.__subscriptionConfig.getCssoToken()) + await mwSetting.loadSettings() + await this.prepareSubscription(mwSetting.getOcsEndpointHost(), mwSetting.getOcsApiStage()) + } +} + + +DataDriveSubscriber.builder().init() + .then(_ => {}) + .catch(err => { + DdUtils.errorAndExit(`Error occurred while subscribing. ${err.toString()}`) + }) diff --git a/src/ddrv.js b/src/ddrv.js new file mode 100644 index 0000000..2c258d0 --- /dev/null +++ b/src/ddrv.js @@ -0,0 +1,22 @@ +'use strict'; + +//local imports +const DdConsts = require('./core/DdConstants.js'); +const DdUtils = require('./core/DdUtils.js'); +const DdOptions = require('./core/DdOptions.js'); +DdOptions.version('\n*** '+DdConsts.CLIENT_TITLE+' ***\n\n'); +DdOptions.command('config', 'configure the DataDrive CLI.'); +DdOptions.command('subscribe [parameters]', 'subscribe to an OCS package.'); +DdOptions.command('publish [parameters]', 'publish to an OCS package.'); +DdOptions.command('show ', 'display one or many OCS resources.') + + +DdOptions.parseTopArgs(process.argv); + +// Verify that the command exits. +if (!DdOptions.program.commands.find(function (cmd) { + return (cmd._name === process.argv[2]); +})) { + DdUtils.errorAndExit(`ERROR: Unknown command ${process.argv[2]}`); +} + diff --git a/src/package-lock.json b/src/package-lock.json new file mode 100644 index 0000000..15a094c --- /dev/null +++ b/src/package-lock.json @@ -0,0 +1,10368 @@ +{ + "name": "ddrv_cli", + "version": "1.7.3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "@babel/parser": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", + "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==" + }, + "@babel/types": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz", + "integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + } + } + }, + "@gov.nasa.jpl.m2020.cs3/ocs-js-client": { + "version": "7.6.0", + "resolved": "https://artifactory.jpl.nasa.gov:443/artifactory/api/npm/npm-release-local/@gov.nasa.jpl.m2020.cs3/ocs-js-client/-/@gov.nasa.jpl.m2020.cs3/ocs-js-client-7.6.0.tgz", + "integrity": "sha512-3xQn4W41yK5NK6ckolW48dUob/zycIj2YBKhSmJlT+0GZMiuSnjQzIR8NYnUZM8iN48jmKvRbGwKQJlKY+Ng3Q==", + "requires": { + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "fastq": "^1.13.0", + "http-status-codes": "^2.2.0", + "https-proxy-agent": "^5.0.1", + "moment": "^2.29.4", + "through": "^2.3.8" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.2.tgz", + "integrity": "sha512-wrIBsjA5pl13f0RN4Zx4FNWmU71lv03meGKnqRUoCyan17s4V3WL92f3w3AIuWbNnpcrQyFBU5qMavJoB8d27w==", + "requires": { + "@nodelib/fs.stat": "2.0.2", + "run-parallel": "^1.1.9" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.2.tgz", + "integrity": "sha512-z8+wGWV2dgUhLqrtRYa03yDx4HWMvXKi1z8g3m2JyxAx8F7xk74asqPk5LAETjqDSGLFML/6CDl0+yFunSYicw==" + } + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" + }, + "@nodelib/fs.walk": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.3.tgz", + "integrity": "sha512-l6t8xEhfK9Sa4YO5mIRdau7XSOADfmh3jCr0evNHdY+HNkW6xuQhgMH7D73VV6WpZOagrW0UludvMTiifiwTfA==", + "requires": { + "@nodelib/fs.scandir": "2.1.2", + "fastq": "^1.6.0" + } + }, + "@octokit/endpoint": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.3.5.tgz", + "integrity": "sha512-f8KqzIrnzPLiezDsZZPB+K8v8YSv6aKFl7eOu59O46lmlW4HagWl1U6NWl6LmT8d1w7NsKBI3paVtzcnRGO1gw==", + "dev": true, + "requires": { + "is-plain-object": "^3.0.0", + "universal-user-agent": "^4.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + } + } + }, + "@octokit/request": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.1.0.tgz", + "integrity": "sha512-I15T9PwjFs4tbWyhtFU2Kq7WDPidYMvRB7spmxoQRZfxSmiqullG+Nz+KbSmpkfnlvHwTr1e31R5WReFRKMXjg==", + "dev": true, + "requires": { + "@octokit/endpoint": "^5.1.0", + "@octokit/request-error": "^1.0.1", + "deprecation": "^2.0.0", + "is-plain-object": "^3.0.0", + "node-fetch": "^2.3.0", + "once": "^1.4.0", + "universal-user-agent": "^4.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + } + } + }, + "@octokit/request-error": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.0.4.tgz", + "integrity": "sha512-L4JaJDXn8SGT+5G0uX79rZLv0MNJmfGa4vb4vy1NnpjSnWDLJRy6m90udGwvMmavwsStgbv2QNkPzzTCMmL+ig==", + "dev": true, + "requires": { + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "16.28.9", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.9.tgz", + "integrity": "sha512-IKGnX+Tvzt7XHhs8f4ajqxyJvYAMNX5nWfoJm4CQj8LZToMiaJgutf5KxxpxoC3y5w7JTJpW5rnWnF4TsIvCLA==", + "dev": true, + "requires": { + "@octokit/request": "^5.0.0", + "@octokit/request-error": "^1.0.2", + "atob-lite": "^2.0.0", + "before-after-hook": "^2.0.0", + "btoa-lite": "^1.0.0", + "deprecation": "^2.0.0", + "lodash.get": "^4.4.2", + "lodash.set": "^4.3.2", + "lodash.uniq": "^4.5.0", + "octokit-pagination-methods": "^1.1.0", + "once": "^1.4.0", + "universal-user-agent": "^4.0.0" + } + }, + "@semantic-release/changelog": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-3.0.4.tgz", + "integrity": "sha512-UqEPahcZSW0IKtzOglyjeEZCN99ku6Wb/yH/iOKEBJ7Vkw0/+Fc3VRiGoXTkMfHSFUJk+4UkoQKTlYuwf61C2w==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^8.0.0", + "lodash": "^4.17.4" + } + }, + "@semantic-release/commit-analyzer": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-6.3.0.tgz", + "integrity": "sha512-sh51MVlV8VyrvGIemcvzueDADX/8qGbAgce1F0CtQv8hNKYyhdaJeHzfiM1rNXwCynDmcQj+Yq9rrWt71tBd/Q==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.0", + "debug": "^4.0.0", + "import-from": "^3.0.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "@semantic-release/exec": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@semantic-release/exec/-/exec-3.3.6.tgz", + "integrity": "sha512-Nme7mgDHaoj+mc+hC7HCQB5r6c6f6P0jg/ZntG3AyyO8wPVQOXunbF8Qmhk5+JVlCer0ubPW7BlBXSi6pCbdzw==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "execa": "^1.0.0", + "lodash": "^4.17.4", + "parse-json": "^5.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + } + } + }, + "@semantic-release/git": { + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-7.0.16.tgz", + "integrity": "sha512-Bw/npxTVTeFPnQZmuczWRGRdxqJpWOOFZENx38ykyp42InwDFm4n72bfcCwmP/J4WqkPmMR4p+IracWruz/RUw==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^1.0.0", + "fs-extra": "^8.0.0", + "globby": "^10.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.2.tgz", + "integrity": "sha512-z8+wGWV2dgUhLqrtRYa03yDx4HWMvXKi1z8g3m2JyxAx8F7xk74asqPk5LAETjqDSGLFML/6CDl0+yFunSYicw==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "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" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", + "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.1", + "@nodelib/fs.walk": "^1.2.1", + "glob-parent": "^5.0.0", + "is-glob": "^4.0.1", + "merge2": "^1.2.3", + "micromatch": "^4.0.2" + } + }, + "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" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "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" + } + } + } + }, + "@semantic-release/github": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-5.4.3.tgz", + "integrity": "sha512-nFoG1whDZettsGsMRE64kCFRpGSHxQxiKtUltKw67uYO7Q62049HGcdH7pZh/ipn+Uq2cG4Zef/g1vxVVaK82w==", + "dev": true, + "requires": { + "@octokit/rest": "^16.27.0", + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "bottleneck": "^2.18.1", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "fs-extra": "^8.0.0", + "globby": "^10.0.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", + "issue-parser": "^4.0.0", + "lodash": "^4.17.4", + "mime": "^2.4.3", + "p-filter": "^2.0.0", + "p-retry": "^4.0.0", + "parse-github-url": "^1.0.1", + "url-join": "^4.0.0" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.2.tgz", + "integrity": "sha512-z8+wGWV2dgUhLqrtRYa03yDx4HWMvXKi1z8g3m2JyxAx8F7xk74asqPk5LAETjqDSGLFML/6CDl0+yFunSYicw==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "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" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", + "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.1", + "@nodelib/fs.walk": "^1.2.1", + "glob-parent": "^5.0.0", + "is-glob": "^4.0.1", + "merge2": "^1.2.3", + "micromatch": "^4.0.2" + } + }, + "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" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "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" + } + } + } + }, + "@semantic-release/npm": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-5.1.15.tgz", + "integrity": "sha512-MUUKOOtqsX/aJZJIjiAdw7SkCH+D3De060l1HhTlqrwTB7PzMtXcUMen6Prd1Hv8+gknUFkSWhVmi8tIaGDVnA==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "execa": "^2.0.2", + "fs-extra": "^8.0.0", + "lodash": "^4.17.15", + "nerf-dart": "^1.0.0", + "normalize-url": "^4.0.0", + "npm": "^6.10.3", + "rc": "^1.2.8", + "read-pkg": "^5.0.0", + "registry-auth-token": "^4.0.0" + }, + "dependencies": { + "execa": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/execa/-/execa-2.0.4.tgz", + "integrity": "sha512-VcQfhuGD51vQUQtKIq2fjGDLDbL6N1DTQVpYzxZ7LPIXw3HqTuIz6uxRmpV1qf8i31LHf2kjiaGI+GdHwRgbnQ==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.5", + "get-stream": "^5.0.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^3.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", + "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-key": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz", + "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + } + } + } + }, + "@semantic-release/release-notes-generator": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-7.3.0.tgz", + "integrity": "sha512-6ozBLHM9XZR6Z8PFSKssLtwBYc5l1WOnxj034F8051QOo3TMKDDPKwdj2Niyc+e7ru7tGa3Ftq7nfN0YnD6//A==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-changelog-writer": "^4.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.0", + "debug": "^4.0.0", + "get-stream": "^5.0.0", + "import-from": "^3.0.0", + "into-stream": "^5.0.0", + "lodash": "^4.17.4", + "read-pkg-up": "^6.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-6.0.0.tgz", + "integrity": "sha512-odtTvLl+EXo1eTsMnoUHRmg/XmXdTkwXVxy4VFE9Kp6cCq7b3l7QMdBndND3eAFzrbSAXC/WCUOQQ9rLjifKZw==", + "dev": true, + "requires": { + "find-up": "^4.0.0", + "read-pkg": "^5.1.1", + "type-fest": "^0.5.0" + } + }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + } + } + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", + "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "aggregate-error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.0.tgz", + "integrity": "sha512-yKD9kEoJIR+2IFqhMwayIBgheLYbB3PS2OBhWae1L/ODTd/JF/30cW0bc9TqzRL3k4U41Dieu3BF4I29p8xesA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^3.2.0" + } + }, + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "dependencies": { + "fast-deep-equal": { + "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==" + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + } + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha1-oMoMvCmltz6Dbuvhy/bF4OTrgvk=", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "requires": { + "lodash": "^4.17.11" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "atob-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axios": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", + "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + } + }, + "axios-debug": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/axios-debug/-/axios-debug-0.0.4.tgz", + "integrity": "sha1-Ri+vl++Eoij1K29vdNmWG9z95OI=", + "requires": { + "chalk": "^1.1.3" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "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", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "before-after-hook": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", + "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true + }, + "brace-expansion": { + "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" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "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", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "btoa-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=", + "dev": true + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "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" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "dev": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "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" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + }, + "chokidar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz", + "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "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", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "dev": true, + "requires": { + "colors": "1.0.3" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "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==" + }, + "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==", + "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==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "optional": true + }, + "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=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "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==", + "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=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colornames": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", + "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" + }, + "colorspace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.1.tgz", + "integrity": "sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + }, + "compare-func": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", + "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^3.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "conventional-changelog-angular": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz", + "integrity": "sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "q": "^1.5.1" + } + }, + "conventional-changelog-eslint": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.1.tgz", + "integrity": "sha512-yH3+bYrtvgKxSFChUBQnKNh9/U9kN2JElYBm253VpYs5wXhPHVc9ENcuVGWijh24nnOkei7wEJmnmUzgZ4ok+A==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-writer": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.7.tgz", + "integrity": "sha512-p/wzs9eYaxhFbrmX/mCJNwJuvvHR+j4Fd0SQa2xyAhYed6KBiZ780LvoqUUvsayP4R1DtC27czalGUhKV2oabw==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "conventional-commits-filter": "^2.0.2", + "dateformat": "^3.0.0", + "handlebars": "^4.1.2", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^3.0.0" + }, + "dependencies": { + "conventional-commits-filter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz", + "integrity": "sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "through2": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "dev": true, + "requires": { + "readable-stream": "2 || 3" + } + } + } + }, + "conventional-commits-filter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.1.tgz", + "integrity": "sha512-92OU8pz/977udhBjgPEbg3sbYzIxMDFTlQT97w7KdhR9igNqdJvy8smmedAAgn4tPiqseFloKkrVfbXCVd+E7A==", + "dev": true, + "requires": { + "is-subset": "^0.1.1", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.1.tgz", + "integrity": "sha512-P6U5UOvDeidUJ8ebHVDIoXzI7gMlQ1OF/id6oUvp8cnZvOXMt1n8nYl74Ey9YMn0uVQtxmCtjPQawpsssBWtGg==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.0", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0", + "trim-off-newlines": "^1.0.0" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "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" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "optional": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "diagnostics": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", + "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", + "requires": { + "colorspace": "1.1.x", + "enabled": "1.0.x", + "kuler": "1.0.x" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + } + } + }, + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotenv": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", + "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==" + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "easy-table": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.1.tgz", + "integrity": "sha512-C9Lvm0WFcn2RgxbMnTbXZenMIWcBtkzMr+dWqq/JsVoGFSVUVlPqeOa5LP5kM0I3zoOazFpckOEb2/0LDFfToQ==", + "requires": { + "ansi-regex": "^3.0.0", + "wcwidth": ">=1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "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==" + }, + "enabled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", + "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", + "requires": { + "env-variable": "0.0.x" + } + }, + "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==", + "requires": { + "once": "^1.4.0" + } + }, + "env-ci": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-4.1.1.tgz", + "integrity": "sha512-eTgpkALDeYRGNhYM2fO9LKsWDifoUgKL7hxpPZqFMP2IU7f+r89DtKqCmk3yQB/jxS8CmZTfKnWO5TiIDFs9Hw==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "java-properties": "^1.0.0" + } + }, + "env-variable": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", + "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" + }, + "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" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "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=" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.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" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "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": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "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", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "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==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + }, + "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==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "fast-json-stable-stringify": { + "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=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fast-safe-stringify": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", + "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" + }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "requires": { + "reusify": "^1.0.0" + } + }, + "fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" + }, + "figures": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", + "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "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", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.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==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "find-versions": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.1.0.tgz", + "integrity": "sha512-NCTfNiVzeE/xL+roNDffGuRbrWI6atI18lTJ22vKp7rs2OhYzMK3W1dIdO2TUndH/QMcacM4d1uWwgcZcHK69Q==", + "dev": true, + "requires": { + "array-uniq": "^2.1.0", + "semver-regex": "^2.0.0" + }, + "dependencies": { + "array-uniq": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.1.0.tgz", + "integrity": "sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==", + "dev": true + } + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "requires": { + "is-buffer": "~2.0.3" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==" + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": false, + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true + }, + "aproba": { + "version": "1.2.0", + "resolved": false, + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": false, + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": false, + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "resolved": false, + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true + }, + "debug": { + "version": "4.1.1", + "resolved": false, + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": false, + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "optional": true + }, + "delegates": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "resolved": false, + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "optional": true + }, + "gauge": { + "version": "2.7.4", + "resolved": false, + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": false, + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "optional": 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" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": false, + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": false, + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": false, + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "optional": true + }, + "ini": { + "version": "1.3.5", + "resolved": false, + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": false, + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "optional": true + }, + "minipass": { + "version": "2.3.5", + "resolved": false, + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "resolved": false, + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": false, + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "resolved": false, + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "optional": true + }, + "needle": { + "version": "2.3.0", + "resolved": false, + "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "resolved": false, + "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "resolved": false, + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "resolved": false, + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": false, + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "optional": true + }, + "once": { + "version": "1.4.0", + "resolved": false, + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "optional": true + }, + "osenv": { + "version": "0.1.5", + "resolved": false, + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "optional": true + }, + "rc": { + "version": "1.2.8", + "resolved": false, + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": false, + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": 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" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": false, + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": false, + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": false, + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "optional": true + }, + "sax": { + "version": "1.2.4", + "resolved": false, + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "optional": true + }, + "semver": { + "version": "5.7.0", + "resolved": false, + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": false, + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "optional": true + }, + "string-width": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": false, + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": false, + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "optional": true + }, + "tar": { + "version": "4.4.8", + "resolved": false, + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "optional": true, + "requires": { + "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" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": false, + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "optional": true + }, + "yallist": { + "version": "3.0.3", + "resolved": false, + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "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=", + "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=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "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==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha1-LmpMGxP8AAKCB7p5WnrDFme5/Uo=", + "dev": true, + "requires": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" + }, + "dependencies": { + "split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha1-UuLiIdiMdfmnP5BVbiY/+WdysxQ=", + "dev": true, + "requires": { + "through2": "~2.0.0" + } + } + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + } + } + }, + "graceful-fs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "handlebars": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.2.0.tgz", + "integrity": "sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "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 + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "hook-std": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", + "integrity": "sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "dev": true + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "http-status-codes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", + "integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==" + }, + "https-proxy-agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", + "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "import-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" + }, + "into-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-5.1.0.tgz", + "integrity": "sha512-cbDhb8qlxKMxPBk/QxTtYg1DQ4CwXmadu7quG3B7nrJsgSncEreF2kwWKZFdnjc/lSNNIkFPsjI7SM0Cx/QXPw==", + "dev": true, + "requires": { + "from2": "^2.3.0", + "p-is-promise": "^2.0.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + }, + "is-core-module": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", + "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "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", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "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=" + }, + "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==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "issue-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-4.0.0.tgz", + "integrity": "sha512-1RmmAXHl5+cqTZ9dRr861xWy0Gkc9TWTEklgjKv+nhlB1dY1NmGBV8b20jTWRL5cPGpOIXkz84kEcDBM8Nc0cw==", + "dev": true, + "requires": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + } + }, + "java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true + }, + "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.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "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", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "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==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsonschema": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.4.tgz", + "integrity": "sha512-lz1nOH69GbsVHeVgEdvyavc/33oymY1AZwtePMiMj4HZPMbP5OIKK3zT9INMWjwua/V4Z4yq7wSlBbSG+g4AEw==" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "kuler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", + "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", + "requires": { + "colornames": "^1.1.1" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "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==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=", + "dev": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.set": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", + "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", + "dev": true + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "requires": { + "chalk": "^2.0.1" + }, + "dependencies": { + "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==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "logform": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", + "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "macos-release": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", + "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "dev": true + }, + "marked-terminal": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-3.3.0.tgz", + "integrity": "sha512-+IUQJ5VlZoAFsM5MHNT7g3RHSkA3eETqhRCdXv4niUMAKHQ7lb1yvAcuGPmm4soxhmtX13u4Li6ZToXtvSEH+A==", + "dev": true, + "requires": { + "ansi-escapes": "^3.1.0", + "cardinal": "^2.1.1", + "chalk": "^2.4.1", + "cli-table": "^0.3.1", + "node-emoji": "^1.4.1", + "supports-hyperlinks": "^1.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.4.tgz", + "integrity": "sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "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" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" + }, + "minimatch": { + "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", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "mocha": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", + "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.0", + "yargs-parser": "13.1.1", + "yargs-unparser": "1.6.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multistream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", + "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", + "requires": { + "once": "^1.4.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "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-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" + } + }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=", + "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-abi": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.26.0.tgz", + "integrity": "sha512-ag/Vos/mXXpWLLAYWsAoQdgS+gW7IwvgMLOgqopm/DbzAjazLltzgzpVMsFlgmo9TzG5hGXeaBZx2AI731RIsQ==", + "requires": { + "semver": "^5.4.1" + } + }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "dev": true, + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "dev": true + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "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==" + }, + "normalize-url": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.3.0.tgz", + "integrity": "sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==", + "dev": true + }, + "npm": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.11.3.tgz", + "integrity": "sha512-K2h+MPzZiY39Xf6eHEdECe/LKoJXam4UCflz5kIxoskN3LQFeYs5fqBGT5i4TtM/aBk+86Mcf+jgXs/WuWAutQ==", + "dev": true, + "requires": { + "JSONStream": "^1.3.5", + "abbrev": "~1.1.1", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "aproba": "^2.0.0", + "archy": "~1.0.0", + "bin-links": "^1.1.3", + "bluebird": "^3.5.5", + "byte-size": "^5.0.1", + "cacache": "^12.0.3", + "call-limit": "^1.1.1", + "chownr": "^1.1.2", + "ci-info": "^2.0.0", + "cli-columns": "^3.1.2", + "cli-table3": "^0.5.1", + "cmd-shim": "^3.0.3", + "columnify": "~1.5.4", + "config-chain": "^1.1.12", + "debuglog": "*", + "detect-indent": "~5.0.0", + "detect-newline": "^2.1.0", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "fs-vacuum": "~1.2.10", + "fs-write-stream-atomic": "~1.0.10", + "gentle-fs": "^2.2.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "has-unicode": "~2.0.1", + "hosted-git-info": "^2.8.2", + "iferr": "^1.0.2", + "imurmurhash": "*", + "infer-owner": "^1.0.4", + "inflight": "~1.0.6", + "inherits": "^2.0.4", + "ini": "^1.3.5", + "init-package-json": "^1.10.3", + "is-cidr": "^3.0.0", + "json-parse-better-errors": "^1.0.2", + "lazy-property": "~1.0.0", + "libcipm": "^4.0.3", + "libnpm": "^3.0.1", + "libnpmaccess": "^3.0.2", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "libnpx": "^10.2.0", + "lock-verify": "^2.1.0", + "lockfile": "^1.0.4", + "lodash._baseindexof": "*", + "lodash._baseuniq": "~4.6.0", + "lodash._bindcallback": "*", + "lodash._cacheindexof": "*", + "lodash._createcache": "*", + "lodash._getnative": "*", + "lodash.clonedeep": "~4.5.0", + "lodash.restparam": "*", + "lodash.union": "~4.6.0", + "lodash.uniq": "~4.5.0", + "lodash.without": "~4.4.0", + "lru-cache": "^5.1.1", + "meant": "~1.0.1", + "mississippi": "^3.0.0", + "mkdirp": "~0.5.1", + "move-concurrently": "^1.0.1", + "node-gyp": "^5.0.3", + "nopt": "~4.0.1", + "normalize-package-data": "^2.5.0", + "npm-audit-report": "^1.3.2", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "~3.0.0", + "npm-lifecycle": "^3.1.3", + "npm-package-arg": "^6.1.1", + "npm-packlist": "^1.4.4", + "npm-pick-manifest": "^3.0.2", + "npm-profile": "^4.0.2", + "npm-registry-fetch": "^4.0.0", + "npm-user-validate": "~1.0.0", + "npmlog": "~4.1.2", + "once": "~1.4.0", + "opener": "^1.5.1", + "osenv": "^0.1.5", + "pacote": "^9.5.8", + "path-is-inside": "~1.0.2", + "promise-inflight": "~1.0.1", + "qrcode-terminal": "^0.12.0", + "query-string": "^6.8.2", + "qw": "~1.0.1", + "read": "~1.0.7", + "read-cmd-shim": "^1.0.4", + "read-installed": "~4.0.3", + "read-package-json": "^2.1.0", + "read-package-tree": "^5.3.1", + "readable-stream": "^3.4.0", + "readdir-scoped-modules": "^1.1.0", + "request": "^2.88.0", + "retry": "^0.12.0", + "rimraf": "^2.6.3", + "safe-buffer": "^5.1.2", + "semver": "^5.7.1", + "sha": "^3.0.0", + "slide": "~1.1.6", + "sorted-object": "~2.0.1", + "sorted-union-stream": "~2.1.3", + "ssri": "^6.0.1", + "stringify-package": "^1.0.0", + "tar": "^4.4.10", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "unique-filename": "^1.1.1", + "unpipe": "~1.0.0", + "update-notifier": "^2.5.0", + "uuid": "^3.3.2", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "~3.0.0", + "which": "^1.3.1", + "worker-farm": "^1.7.0", + "write-file-atomic": "^2.4.3" + }, + "dependencies": { + "JSONStream": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "agentkeepalive": { + "version": "3.5.2", + "bundled": true, + "dev": true, + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "ajv": { + "version": "5.5.2", + "bundled": true, + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansi-align": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.0.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "ansistyles": { + "version": "0.1.3", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "asap": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "asn1": { + "version": "0.2.4", + "bundled": true, + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "bundled": true, + "dev": true + }, + "aws4": { + "version": "1.8.0", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bin-links": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cmd-shim": "^3.0.0", + "gentle-fs": "^2.0.1", + "graceful-fs": "^4.1.15", + "write-file-atomic": "^2.3.0" + } + }, + "bluebird": { + "version": "3.5.5", + "bundled": true, + "dev": true + }, + "boxen": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "builtins": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "byline": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "byte-size": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "cacache": { + "version": "12.0.3", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "call-limit": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "chalk": { + "version": "2.4.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chownr": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "cidr-regex": { + "version": "2.0.10", + "bundled": true, + "dev": true, + "requires": { + "ip-regex": "^2.1.0" + } + }, + "cli-boxes": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "cli-columns": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.0.0", + "strip-ansi": "^3.0.1" + } + }, + "cli-table3": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "cmd-shim": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "color-convert": { + "version": "1.9.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "^1.1.1" + } + }, + "color-name": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "colors": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true + }, + "columnify": { + "version": "1.5.4", + "bundled": true, + "dev": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "combined-stream": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "bundled": true, + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "config-chain": { + "version": "1.1.12", + "bundled": true, + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "create-error-class": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "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" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + } + } + }, + "crypto-random-string": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "cyclist": { + "version": "0.2.2", + "bundled": true, + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "debuglog": { + "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 + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true + }, + "defaults": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "detect-indent": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "dezalgo": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "dot-prop": { + "version": "4.2.0", + "bundled": true, + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotenv": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "duplexify": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "editor": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "encoding": { + "version": "0.1.12", + "bundled": true, + "dev": true, + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "env-paths": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "err-code": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "errno": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "es-abstract": { + "version": "1.12.0", + "bundled": true, + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "bundled": true, + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "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": { + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "figgy-pudding": { + "version": "3.5.1", + "bundled": true, + "dev": true + }, + "find-npm-prefix": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "find-up": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flush-write-stream": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true + }, + "form-data": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs-minipass": { + "version": "1.2.6", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs-vacuum": { + "version": "1.2.10", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + }, + "dependencies": { + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "genfun": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "gentle-fs": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.2", + "chownr": "^1.1.2", + "fs-vacuum": "^1.2.10", + "graceful-fs": "^4.1.11", + "iferr": "^0.1.5", + "infer-owner": "^1.0.4", + "mkdirp": "^0.5.1", + "path-is-inside": "^1.0.2", + "read-cmd-shim": "^1.0.1", + "slide": "^1.1.6" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + } + } + }, + "get-caller-file": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.4", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "got": { + "version": "6.7.1", + "bundled": true, + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.2", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "har-validator": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "2.8.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^5.1.1" + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "bundled": true, + "dev": true + }, + "http-proxy-agent": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + } + }, + "http-signature": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "bundled": true, + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "iferr": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-lazy": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "infer-owner": { + "version": "1.0.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.4", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true + }, + "init-package-json": { + "version": "1.10.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.1", + "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^3.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "ip": { + "version": "1.1.5", + "bundled": true, + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "is-ci": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "ci-info": "^1.0.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "bundled": true, + "dev": true + } + } + }, + "is-cidr": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "cidr-regex": "^2.0.10" + } + }, + "is-date-object": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-redirect": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "bundled": true, + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "latest-version": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lazy-property": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "libcipm": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "requires": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "graceful-fs": "^4.1.11", + "ini": "^1.3.5", + "lock-verify": "^2.0.2", + "mkdirp": "^0.5.1", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "pacote": "^9.1.0", + "read-package-json": "^2.0.13", + "rimraf": "^2.6.2", + "worker-farm": "^1.6.0" + } + }, + "libnpm": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.3", + "find-npm-prefix": "^1.0.2", + "libnpmaccess": "^3.0.2", + "libnpmconfig": "^1.2.1", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmpublish": "^1.1.2", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "lock-verify": "^2.0.2", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "npm-profile": "^4.0.2", + "npm-registry-fetch": "^4.0.0", + "npmlog": "^4.1.2", + "pacote": "^9.5.3", + "read-package-json": "^2.0.13", + "stringify-package": "^1.0.0" + } + }, + "libnpmaccess": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "get-stream": "^4.0.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmconfig": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "find-up": "^3.0.0", + "ini": "^1.3.5" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "bundled": true, + "dev": true + } + } + }, + "libnpmhook": { + "version": "5.0.3", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmorg": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmpublish": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "lodash.clonedeep": "^4.5.0", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0", + "semver": "^5.5.1", + "ssri": "^6.0.1" + } + }, + "libnpmsearch": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmteam": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpx": { + "version": "10.2.0", + "bundled": true, + "dev": true, + "requires": { + "dotenv": "^5.0.1", + "npm-package-arg": "^6.0.0", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.0", + "update-notifier": "^2.3.0", + "which": "^1.3.0", + "y18n": "^4.0.0", + "yargs": "^11.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lock-verify": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^6.1.0", + "semver": "^5.4.1" + } + }, + "lockfile": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "signal-exit": "^3.0.2" + } + }, + "lodash._baseindexof": { + "version": "3.1.0", + "bundled": true, + "dev": true + }, + "lodash._baseuniq": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "requires": { + "lodash._createset": "~4.0.0", + "lodash._root": "~3.0.0" + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "lodash._cacheindexof": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "lodash._createcache": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0" + } + }, + "lodash._createset": { + "version": "4.0.3", + "bundled": true, + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "bundled": true, + "dev": true + }, + "lodash._root": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "bundled": true, + "dev": true + }, + "lodash.restparam": { + "version": "3.6.1", + "bundled": true, + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "bundled": true, + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "bundled": true, + "dev": true + }, + "lodash.without": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lowercase-keys": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-fetch-happen": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "agentkeepalive": "^3.4.1", + "cacache": "^12.0.0", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" + } + }, + "meant": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "mem": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "mime-db": { + "version": "1.35.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.19", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "~1.35.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mississippi": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "move-concurrently": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "bundled": true, + "dev": true + }, + "node-fetch-npm": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node-gyp": { + "version": "5.0.3", + "bundled": true, + "dev": true, + "requires": { + "env-paths": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^4.4.8", + "which": "1" + }, + "dependencies": { + "nopt": { + "version": "3.0.6", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true + } + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "bundled": true, + "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" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "bundled": true, + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "npm-audit-report": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "cli-table3": "^0.5.0", + "console-control-strings": "^1.1.0" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, + "npm-cache-filename": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "npm-install-checks": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "npm-lifecycle": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "byline": "^5.0.0", + "graceful-fs": "^4.1.15", + "node-gyp": "^5.0.2", + "resolve-from": "^4.0.0", + "slide": "^1.1.6", + "uid-number": "0.0.6", + "umask": "^1.1.0", + "which": "^1.3.1" + } + }, + "npm-logical-tree": { + "version": "1.2.1", + "bundled": true, + "dev": true + }, + "npm-package-arg": { + "version": "6.1.1", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-packlist": { + "version": "1.4.4", + "bundled": true, + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npm-pick-manifest": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" + } + }, + "npm-profile": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.2 || 2", + "figgy-pudding": "^3.4.1", + "npm-registry-fetch": "^4.0.0" + } + }, + "npm-registry-fetch": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "JSONStream": "^1.3.4", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npm-user-validate": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "bundled": true, + "dev": true + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.1", + "bundled": true, + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "package-json": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "pacote": { + "version": "9.5.8", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cacache": "^12.0.2", + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^3.0.0", + "npm-registry-fetch": "^4.0.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.10", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-retry": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "retry": { + "version": "0.10.1", + "bundled": true, + "dev": true + } + } + }, + "promzard": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "read": "1" + } + }, + "proto-list": { + "version": "1.2.4", + "bundled": true, + "dev": true + }, + "protoduck": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "genfun": "^5.0.0" + } + }, + "prr": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "psl": { + "version": "1.1.29", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "bundled": true, + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true + }, + "qrcode-terminal": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "qs": { + "version": "6.5.2", + "bundled": true, + "dev": true + }, + "query-string": { + "version": "6.8.2", + "bundled": true, + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, + "qw": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true + } + } + }, + "read": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-cmd-shim": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "read-installed": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + } + }, + "read-package-json": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "slash": "^1.0.0" + } + }, + "read-package-tree": { + "version": "5.3.1", + "bundled": true, + "dev": true, + "requires": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "readable-stream": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "registry-auth-token": { + "version": "3.3.2", + "bundled": true, + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "request": { + "version": "2.88.0", + "bundled": true, + "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.0", + "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.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "retry": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-queue": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "sha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "slash": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "slide": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "smart-buffer": { + "version": "4.0.2", + "bundled": true, + "dev": true + }, + "socks": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "4.0.2" + } + }, + "socks-proxy-agent": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } + } + }, + "sorted-object": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "sorted-union-stream": { + "version": "2.1.3", + "bundled": true, + "dev": true, + "requires": { + "from2": "^1.3.0", + "stream-iterate": "^1.1.0" + }, + "dependencies": { + "from2": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~1.1.10" + } + }, + "isarray": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true, + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "split-on-first": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "bundled": true, + "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" + } + }, + "ssri": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stream-each": { + "version": "1.2.2", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-iterate": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-shift": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strict-uri-encode": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "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": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringify-package": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tar": { + "version": "4.4.10", + "bundled": true, + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.5", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true + } + } + }, + "term-size": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "through": { + "version": "2.3.8", + "bundled": true, + "dev": true + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "timed-out": { + "version": "4.0.1", + "bundled": true, + "dev": true + }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "bundled": true, + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "typedarray": { + "version": "0.0.6", + "bundled": true, + "dev": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true + }, + "umask": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "unzip-response": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "bundled": true, + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "url-parse-lax": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "util-extend": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "util-promisify": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "verror": { + "version": "1.10.0", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.2" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "widest-line": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, + "worker-farm": { + "version": "1.7.0", + "bundled": true, + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "xtend": { + "version": "4.0.1", + "bundled": true, + "dev": true + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "11.0.0", + "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" + }, + "dependencies": { + "y18n": { + "version": "3.2.1", + "bundled": true, + "dev": true + } + } + }, + "yargs-parser": { + "version": "9.0.2", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "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=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "octokit-pagination-methods": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", + "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "one-time": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", + "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-name": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", + "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", + "dev": true, + "requires": { + "macos-release": "^2.2.0", + "windows-release": "^3.1.0" + } + }, + "p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "requires": { + "p-map": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "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==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true + }, + "p-retry": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.1.0.tgz", + "integrity": "sha512-oepllyG9gX1qH4Sm20YAKxg1GA7L7puhvGnTfimi31P07zSIj7SDV6YtuAx9nbJF51DES+2CIIRkXs8GKqWJxA==", + "dev": true, + "requires": { + "@types/retry": "^0.12.0", + "retry": "^0.12.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==" + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", + "dev": true + }, + "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" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "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.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "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", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", + "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "dev": true + }, + "pkg": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.1.0.tgz", + "integrity": "sha512-rWTwvLJakQnEVg03s97KNtGkhM3pPfxk7XinjR7H1bToMZQMNpBTwahrAPoFHdQyfn6odI76DP6vX3Br9VubNQ==", + "requires": { + "@babel/parser": "7.13.13", + "@babel/types": "7.13.12", + "chalk": "^4.1.0", + "escodegen": "^2.0.0", + "fs-extra": "^9.1.0", + "globby": "^11.0.3", + "into-stream": "^6.0.0", + "minimist": "^1.2.5", + "multistream": "^4.1.0", + "pkg-fetch": "3.0.4", + "prebuild-install": "6.0.1", + "progress": "^2.0.3", + "resolve": "^1.20.0", + "stream-meter": "^1.0.4", + "tslib": "2.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "into-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "requires": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "pkg-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.0.4.tgz", + "integrity": "sha512-XgMXcco5hy0/Q7OXfQ/FbBnPvS4e7gWB9BCcUWUgaHYo3JretihmJjr62EZWmxAjvodoWLGMZ3E7XHf8Q2LfBg==", + "requires": { + "axios": "^0.21.1", + "chalk": "^4.1.0", + "fs-extra": "^9.1.0", + "progress": "^2.0.3", + "semver": "^7.3.5", + "yargs": "^16.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "follow-redirects": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", + "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==" + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==" + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "prebuild-install": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.1.tgz", + "integrity": "sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==", + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "psl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "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==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "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==" + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "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==" + } + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "dev": true, + "requires": { + "esprima": "~4.0.0" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "registry-auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.0.0.tgz", + "integrity": "sha512-lpQkHxd9UL6tb3k/aHAVfnVtn+Bcs9ob5InuFLLEDqSqeq+AljB8GZW9xY0x7F+xYwEcjKe07nyoxzEYz6yvkw==", + "dev": true, + "requires": { + "rc": "^1.2.8", + "safe-buffer": "^5.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "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" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "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==" + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semantic-release": { + "version": "15.13.24", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-15.13.24.tgz", + "integrity": "sha512-OPshm6HSp+KmZP9dUv1o3MRILDgOeHYWPI+XSpQRERMri7QkaEiIPkZzoNm2d6KDeFDnp03GphQQS4+Zfo+x/Q==", + "dev": true, + "requires": { + "@semantic-release/commit-analyzer": "^6.1.0", + "@semantic-release/error": "^2.2.0", + "@semantic-release/github": "^5.1.0", + "@semantic-release/npm": "^5.0.5", + "@semantic-release/release-notes-generator": "^7.1.2", + "aggregate-error": "^3.0.0", + "cosmiconfig": "^5.0.1", + "debug": "^4.0.0", + "env-ci": "^4.0.0", + "execa": "^1.0.0", + "figures": "^3.0.0", + "find-versions": "^3.0.0", + "get-stream": "^5.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^2.0.0", + "hosted-git-info": "^3.0.0", + "lodash": "^4.17.15", + "marked": "^0.7.0", + "marked-terminal": "^3.2.0", + "p-locate": "^4.0.0", + "p-reduce": "^2.0.0", + "read-pkg-up": "^6.0.0", + "resolve-from": "^5.0.0", + "semver": "^6.0.0", + "signale": "^1.2.1", + "yargs": "^14.0.0" + }, + "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 + }, + "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" + } + }, + "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" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "hosted-git-info": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.0.tgz", + "integrity": "sha512-zYSx1cP4MLsvKtTg8DF/PI6e6FHZ3wcawcTGsrLU2TM+UfD4jmSrn2wdQT16TFbH3lO4PIdjLG0E+cuYDgFD9g==", + "dev": true, + "requires": { + "lru-cache": "^5.1.1" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-6.0.0.tgz", + "integrity": "sha512-odtTvLl+EXo1eTsMnoUHRmg/XmXdTkwXVxy4VFE9Kp6cCq7b3l7QMdBndND3eAFzrbSAXC/WCUOQQ9rLjifKZw==", + "dev": true, + "requires": { + "find-up": "^4.0.0", + "read-pkg": "^5.1.1", + "type-fest": "^0.5.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "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" + } + }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + }, + "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": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.0.0.tgz", + "integrity": "sha512-ssa5JuRjMeZEUjg7bEL99AwpitxU/zWGAGpdj0di41pOEmJti8NR6kyUIJBkR78DTYNPZOU08luUo0GTHuB+ow==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.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.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "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=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "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", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "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 + }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "requires": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "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" + } + } + } + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "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": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha1-Gv2Uc46ZmwNG17n8NzvlXgdXcCk=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "^2.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-meter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", + "integrity": "sha1-Uq+Vql6nYKJJFxZwTb/5D3Ov3R0=", + "requires": { + "readable-stream": "^2.1.4" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "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==", + "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==" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.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 + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "supports-hyperlinks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", + "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", + "dev": true, + "requires": { + "has-flag": "^2.0.0", + "supports-color": "^5.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + } + } + } + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "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=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + }, + "uglify-js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.20.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "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, + "optional": true + } + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "universal-user-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", + "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", + "dev": true, + "requires": { + "os-name": "^3.1.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "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", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "optional": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "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=" + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "windows-release": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", + "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", + "dev": true, + "requires": { + "execa": "^1.0.0" + } + }, + "winston": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", + "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", + "requires": { + "async": "^2.6.1", + "diagnostics": "^1.1.1", + "is-stream": "^1.1.0", + "logform": "^2.1.1", + "one-time": "0.0.4", + "readable-stream": "^3.1.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.3.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "winston-transport": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", + "requires": { + "readable-stream": "^2.3.6", + "triple-beam": "^1.2.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "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==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "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==" + }, + "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==", + "requires": { + "color-convert": "^1.9.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==", + "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==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "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.1" + }, + "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==" + }, + "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==", + "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==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + } + } +} diff --git a/src/package.json b/src/package.json new file mode 100644 index 0000000..1343a6e --- /dev/null +++ b/src/package.json @@ -0,0 +1,144 @@ +{ + "name": "ddrv_cli", + "description": "DataDrive Command Line Interface clients", + "main": "ddrv.js", + "engines": { + "node": "~14.15.0" + }, + "dependencies": { + "@gov.nasa.jpl.m2020.cs3/ocs-js-client": "~7.6.0", + "axios": "~0.18.1", + "axios-debug": "0.0.4", + "bluebird": "^3.5.2", + "chai": "~4.2.0", + "chokidar": "~2.1.5", + "commander": "~2.20.0", + "cookie": "~0.3.1", + "dotenv": "~7.0.0", + "easy-table": "~1.1.1", + "form-data": "~2.5.0", + "fs-extra": "~8.1.0", + "glob-to-regexp": "~0.4.1", + "jsonschema": "~1.2.4", + "lodash": "~4.17.15", + "mocha": "~6.2.0", + "moment": "~2.24.0", + "pkg": "^5.1.0", + "request": "~2.88.2", + "shelljs": "~0.8.3", + "upath": "~1.1.2", + "winston": "~3.2.1", + "ws": "~6.2.1" + }, + "devDependencies": { + "@semantic-release/commit-analyzer": "^6.3.0", + "@semantic-release/exec": "^3.3.6", + "@semantic-release/npm": "^5.1.15", + "@semantic-release/git": "^7.0.16", + "@semantic-release/github": "^5.4.3", + "@semantic-release/release-notes-generator": "^7.3.0", + "conventional-changelog-eslint": "^3.0.1", + "@semantic-release/changelog": "^3.0.4", + "semantic-release": "^15.13.24" + }, + "directories": { + "test": "test" + }, + "bin": { + "ddrv": "ddrv.js" + }, + "pkg": { + "scripts": [ + "ddrv-*.js", + "core/*.js" + ] + }, + "scripts": { + "test": "mocha --exclude test/dd-package-subscribe-test.js --exclude test/dd-checkpoint.js --exclude test/dd-checkpoint.js", + "test-queue": "mocha --grep DdQueue", + "test-util": "mocha --grep DdUtils", + "test-checkpoint": "mocha --grep checkpoint", + "build": "node buildScript.js --build", + "clean": "node buildScript.js --clean", + "package": "node buildScript.js --deploy", + "semantic-release": "npx semantic-release", + "semantic-release-dry-run": "npx semantic-release --dry-run" + }, + "release": { + "branch": "master", + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "angular", + "releaseRules": [ + { + "type": "patch", + "release": "patch" + }, + { + "type": "minor", + "release": "minor" + }, + { + "type": "major", + "release": "major" + } + ] + } + ], + "@semantic-release/release-notes-generator", + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md" + } + ], + [ + "@semantic-release/npm", + { + "npmPublish": false + } + ], + [ + "@semantic-release/exec", + { + "prepareCmd": "npm run package", + "successCmd": "printf ${nextRelease.version} > release.txt" + } + ], + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md", + "package.json", + "package-lock.json" + ], + "message": "chore: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + }, + [ + "@semantic-release/github", + { + "assets": [ + { + "path": "../deployment/dist/ddrv-cli-bundle.zip" + } + ], + "successComment": false, + "failComment": false, + "fileTitle": false, + "label": false + } + ] + ] + }, + "keywords": [ + "datadrive", + "subscription", + "OCS", + "subscribe" + ], + "author": "Nicholas Toole", + "license": "UNLICENSED", + "version": "1.7.3" +} diff --git a/src/plugin_examples/ScriptPlugin.js b/src/plugin_examples/ScriptPlugin.js new file mode 100644 index 0000000..c98f5a8 --- /dev/null +++ b/src/plugin_examples/ScriptPlugin.js @@ -0,0 +1,40 @@ +const path = require('path'); +const util = require('util'); +const exec = util.promisify(require('child_process').exec); +const entrypointDir = path.dirname(require.main.filename); +const { FileMetadata } = require(path.join(entrypointDir, 'core/DdFileMetadata.js')); +const DdLogger = require(path.join(entrypointDir, 'core/DdLogger.js')).logger; +const DdPlugin = require(path.join(entrypointDir, 'core/DdPlugin.js')); + +class ScriptPlugin extends DdPlugin { + constructor(config) { + super(); + this.config = config; + } + + /** + * + * @param {FileMetadata} item + */ + async processItem(item) { + try { + // item is a JSON object and has the following attributes + // ocs_updated_at: DateTime of the event + // ocs_full_name: Full OCS path; includes ocs path and filename + // ocs_dataset_id: Unique ID of the item + // ocs_package_id: Unique ID of the OCS package + // ocs_url: S3 URL where the file resides + // ocs_path: Path in OCS, excludes the file name + // ocs_owner: Owner of the file in OCS, Note: ONLY available if event_type is PLAYBACK + // download_url: Download URL generated by PEP + // event_type: Event type, can be of two types OCS or PLAYBACK + // ocs_name: File name + await exec(`echo "${JSON.stringify(item)}" >> tmp/test.txt`); + } catch (error) { + DdLogger.error(error.stderr); + } + DdLogger.info(`${item.ocs_full_name} was called in ScriptPlugin`); + } +} + +module.exports = ScriptPlugin; \ No newline at end of file diff --git a/src/plugins/FileDownloaderPlugin.js b/src/plugins/FileDownloaderPlugin.js new file mode 100644 index 0000000..eb10910 --- /dev/null +++ b/src/plugins/FileDownloaderPlugin.js @@ -0,0 +1,101 @@ +const fs = require('fs'); +const request = require('request'); +const {FileMetadata} = require('../core/DdFileMetadata.js'); +const DdUtils = require('../core/DdUtils.js'); +const DdLogger = require('../core/DdLogger.js').logger; +const DdPlugin = require('../core/DdPlugin.js'); +const DdSubConfig = require('../core/DdSubConfig.js'); +const {CannotWriteToLocalFileError} = require('../core/DdError.js'); +const {EmptyPromise} = require('../core/EmptyPromise') + +class FileDownloader extends DdPlugin { + /** + * Constructor for FileDownloader + * @param {typeof DdSubConfig} config + */ + constructor(config) { + super(); + this.config = config; + } + + /** + * + * @param {FileMetadata} item + */ + async processItem(item) { + DdLogger.info(`${item['ocs_full_name']} was called in FileDownloader`); + try { + await this.downloadFileFromMetadata(item); + } catch (e) { + DdLogger.error(`failed to download file: error: ${e.toString()}`) + } + } + + /** + * Initiates a file download from extracting the + * OCS-epecific download URL from the OCS file + * metadata. + * + * @param {FileMetadata} ocsFileMetadata + */ + async downloadFileFromMetadata(ocsFileMetadata) { + DdLogger.debug("Called downloadFileFromMetadata"); + if (!ocsFileMetadata) { + throw new Error('downloadFileFromMetadata: empty file metadata') + } + //get the standard OCS metadata we care about + let ocsDownloadUrl = ocsFileMetadata['download_url']; + let ocsLogicalUrl = ocsFileMetadata['ocs_url']; + let ocsPath = ocsFileMetadata['ocs_path']; + let ocsName = ocsFileMetadata['ocs_name']; + let ocsModTimestamp = ocsFileMetadata['ocs_updated_at']; + let filename = ocsName; + let relativePath = this.config.retainPath ? ocsPath : '' + let outFilepath = this.config.getOutputLocation(relativePath, filename); + if (!DdUtils.canWriteToLocalFile(outFilepath, this.config)) { + throw new CannotWriteToLocalFileError(`Overwrite setting not enabled cannot write to ${outFilepath}`) + } + DdLogger.debug("Downloading "+ocsDownloadUrl+" to "+outFilepath); + //subConfig.printDebug("Downloading "+ocsDownloadUrl+" to "+outFilepath); + DdUtils.ensureDirectory(outFilepath); + const file = fs.createWriteStream(outFilepath, { flags: 'w' }); + const downloadRequestPromise = EmptyPromise.builder() + request({ + method: 'GET', + url: ocsDownloadUrl, // Note: This requires PEP in order to generate a download URL + headers: { + Cookie: `ssosession=${this.config.cssoToken}`, + }, + followRedirect: true, + gzip: true, + timeout: 60 * 1000, + time: true, + }) + .on('response', function(resp) { + // resp.pause(); + if (!DdUtils.validHTTPResponse(resp)) { + DdLogger.error("Error occurred when using PEP.") + // throw new Error(`Invalid HTTP response status code from PEP: ${resp.statusCode}`) + downloadRequestPromise.reject(`Invalid HTTP response status code from PEP: ${resp.statusCode}`) + } + }) + .pipe(file) + .on('finish', () => { + DdLogger.info("File downloaded: "+outFilepath); + downloadRequestPromise.resolve() + }) + .on('error', (err) => { + DdLogger.printError(err); + DdLogger.error("Error occurred while downloading file: "+ocsDownloadUrl) + downloadRequestPromise.reject(`download file failed: ${err.toString()}`) + // throw err + }) + // .catch(err => { + // downloadRequestPromise.reject(`download file failed: ${err.toString()}`) + // DdLogger.error(`failed to download file: ${err}`) + // }) + await downloadRequestPromise.get() + } +} + +module.exports = FileDownloader; diff --git a/src/test/dd-checkpoint.js b/src/test/dd-checkpoint.js new file mode 100644 index 0000000..cf40844 --- /dev/null +++ b/src/test/dd-checkpoint.js @@ -0,0 +1,29 @@ +const chai = require('chai'); +const expect = chai.expect; +const assert = chai.assert; +const utils = require('../core/DdUtils'); +const moment = require('moment'); +const fs = require('fs'); + +let filePath = `tmp/checkpoint.txt` +let humanReadableDate = 'Fri Aug 09 2019 15:16:36 GMT-0700 (Pacific Daylight Time)' +describe("checkpoint", () => { + before(() => { + + }); + + after(() => { + fs.unlinkSync(filePath); + }); + + describe("write date to file and read from date file", () => { + it("should take a take a UTC date then write to file a local date", async () => { + let date = new Date(humanReadableDate); + let dateStr = moment(date).format('YYYY-MM-DDTHH:mm:ss.SSSZZ'); + await utils.writeDateToFile(filePath, date); + let dateRead = await utils.getCheckPointDate(filePath); + let dateStrRead = dateRead.toString(); + expect(dateStrRead).to.be.equal(dateStr); + }); + }); +}); \ No newline at end of file diff --git a/src/test/dd-options-and-subconfig.js b/src/test/dd-options-and-subconfig.js new file mode 100644 index 0000000..bef77a9 --- /dev/null +++ b/src/test/dd-options-and-subconfig.js @@ -0,0 +1,185 @@ +const chai = require('chai'); +const expect = chai.expect; +const assert = chai.assert; + +let DdOptions; +let DdSubConfig = require('../core/DdSubConfig.js'); +let DdConsts = require('../core/DdConstants.js'); +const {DdCliConfigFileIO} = require('../core/DdCliConfigFileIO'); +let subConfig; + +describe("DdOptions and DdSubConfig", () => { + before(() => { + DdCliConfigFileIO.builder().setFailOnError(false) + process.env[DdConsts.ENV_PEP_HOST] = 'fakepep.m20-dev.jpl.nasa.gov'; + process.env[DdConsts.ENV_DATADRIVE_HOST] = 'fakeDD-mid.m20-dev.jpl.nasa.gov'; + }); + + beforeEach(() => { + DdOptions = require('../core/DdOptions.js'); + }); + + afterEach(() => { + // Code below is whack... because we want to de-allocate these 3 Singleton classes before testing them again + // You can't do that unless you remove them from the module cache... what... the... f***... makes no sense + // I must be doing something stupid, but at least it works right now... + delete require.cache[require.resolve('../core/DdOptions.js')]; + delete subConfig; + delete require.cache[require.resolve('commander')]; + }); + + describe("Wildcard filter only", () => { + it("should parse options correctly... regex is undefined, wildcard is *", () => { + let argv = [ '/usr/local/Cellar/node/12.9.1/bin/node', + '/Users/jeffliu/mipl/DataDrive-CommandLine/src/ddrv-subscribe.js', + '-o', + 'tmp', + '-p', + 'DataDrive-Dev-Congruent-1', + '-r', + '-P', + '-f', + '*1LLJ01.IMG' + ] + DdOptions.parseSubscriptionOptions(argv); + subConfig = new DdSubConfig(DdOptions.program, false); + expect(subConfig.fileRegex).is.equal(undefined); + expect(subConfig.fileRegexObj).is.equal(undefined); + expect(subConfig.fileWildcard).is.not.equal(undefined); + expect(subConfig.fileWildcard).to.be.not.empty; + expect(subConfig.fileWildcardRegexObj).is.not.equal(undefined); + }); + + it("should accept... NBVOW_H123_1LLJ01.IMG based on wildcard filter", () => { + expect(subConfig.satisfiesFilter('NBVOW_H123_1LLJ01.IMG')).is.true; + }); + it("should accept... /usr/share/bin/NBVOW_H123_1LLJ01.IMG based on wildcard filter", () => { + expect(subConfig.satisfiesFilter('/usr/share/bin/NBVOW_H123_1LLJ01.IMG')).is.true; + }); + it("should NOT accept... NBVOW_H123_1LLJaa01.IMG based on wildcard filter", () => { + expect(subConfig.satisfiesFilter('NBVOW_H123_1LLJaa01.IMG')).is.false; + }); + }); + + describe("Regex filter only", () => { + it("should parse options correctly... regex is defined, wildcard is *", () => { + // Note: the double escape only happens when it shows up in code, when users put this in... + // they put in '.*1LLJ01\.IMG' which when it gets into code, it will become '.*1LLJ01\\.IMG' + let argv = [ '/usr/local/Cellar/node/12.9.1/bin/node', + '/Users/jeffliu/mipl/DataDrive-CommandLine/src/ddrv-subscribe.js', + '-o', + 'tmp', + '-p', + 'DataDrive-Dev-Congruent-1', + '-r', + '-P', + '-x', + '.*1LLJ01\\.IMG' + ] + DdOptions.parseSubscriptionOptions(argv); + subConfig = new DdSubConfig(DdOptions.program, false); + expect(subConfig.fileWildcard).is.equal('*'); + expect(subConfig.fileWildcardRegexObj).is.not.undefined; + expect(subConfig.fileRegex).is.not.equal(undefined); + expect(subConfig.fileRegex).to.be.not.empty; + expect(subConfig.fileRegexObj).is.not.equal(undefined); + }); + + it("should accept... NBVOW_H123_1LLJ01.IMG based on regex filter", () => { + expect(subConfig.satisfiesFilter('NBVOW_H123_1LLJ01.IMG')).is.true; + }); + it("should accept... /usr/share/bin/NBVOW_H123_1LLJ01.IMG based on regex filter", () => { + expect(subConfig.satisfiesFilter('/usr/share/bin/NBVOW_H123_1LLJ01.IMG')).is.true; + }); + it("should NOT accept... NBVOW_H123_1LLJaa01.IMG based on regex filter", () => { + expect(subConfig.satisfiesFilter('NBVOW_H123_1LLJaa01.IMG')).is.false; + }); + it("should NOT accept... /usr/share/bin/jplisawesome3435**.jpg based on regex filter", () => { + expect(subConfig.satisfiesFilter('/usr/share/bin/jplisawesome3435**.jpg')).is.false; + }); + }); + + describe("Regex filter special character test 1", () => { + it("should parse options correctly give... .*\.txt", () => { + // Note: the double escape only happens when it shows up in code, when users put this in... + // they put in '.*\.txt' which when it gets into code, it will become '.*\\.txt' + let argv = [ '/usr/local/Cellar/node/12.9.1/bin/node', + '/Users/jeffliu/mipl/DataDrive-CommandLine/src/ddrv-subscribe.js', + '-o', + 'tmp', + '-p', + 'DataDrive-Dev-Congruent-1', + '-r', + '-P', + '-x', + '.*\\.txt' + ] + DdOptions.parseSubscriptionOptions(argv); + subConfig = new DdSubConfig(DdOptions.program, false); + expect(subConfig.fileRegexObj).is.not.equal(undefined); + }); + + it("should accept... jeff_p1_09-15-2019.txt", () => { + expect(subConfig.satisfiesFilter('jeff_p1_09-15-2019.txt')).is.true; + }); + it("should accept... /usr/share/bin/jeff_p1_09-15-2019.txt", () => { + expect(subConfig.satisfiesFilter('/usr/share/bin/jeff_p1_09-15-2019.txt')).is.true; + }); + it("should NOT accept... jeff_p1_09-15-2019.ttxt should not accept", () => { + expect(subConfig.satisfiesFilter('jeff_p1_09-15-2019.ttxt')).is.false; + }); + }); + + describe("No filter", () => { + it("should parse options correctly... regex is undefined, wildcard is *", () => { + let argv = [ '/usr/local/Cellar/node/12.9.1/bin/node', + '/Users/jeffliu/mipl/DataDrive-CommandLine/src/ddrv-subscribe.js', + '-o', + 'tmp', + '-p', + 'DataDrive-Dev-Congruent-1', + '-r', + '-P' + ] + DdOptions.parseSubscriptionOptions(argv); + subConfig = new DdSubConfig(DdOptions.program, false); + expect(subConfig.fileWildcard).is.equal('*'); + expect(subConfig.fileWildcardRegexObj).is.not.undefined; + expect(subConfig.fileRegex).is.equal(undefined); + expect(subConfig.fileRegexObj).is.equal(undefined); + }); + + it("should accept... NBVOW_H123_1LLJ01.IMG based on no filters", () => { + expect(subConfig.satisfiesFilter('NBVOW_H123_1LLJ01.IMG')).is.true; + }); + it("should accept... /usr/share/bin/NBVOW_H123_1LLJ01.IMG based on no filters", () => { + expect(subConfig.satisfiesFilter('/usr/share/bin/NBVOW_H123_1LLJ01.IMG')).is.true; + }); + it("should NOT accept... NBVOW_H123_1LLJaa01.IMG based on no filters", () => { + expect(subConfig.satisfiesFilter('NBVOW_H123_1LLJaa01.IMG')).is.true; + }); + it("should NOT accept... /usr/share/bin/jplisawesome3435**.jpg based on no filters", () => { + expect(subConfig.satisfiesFilter('/usr/share/bin/jplisawesome3435**.jpg')).is.true; + }); + }); + + describe("Saved search only", () => { + it("should parse options correctly... savedsearchname is defined", () => { + let argv = [ '/usr/local/Cellar/node/12.9.1/bin/node', + '/Users/jeffliu/mipl/DataDrive-CommandLine/src/ddrv-subscribe.js', + '-o', + 'tmp', + '-p', + 'DataDrive-Dev-Congruent-1', + '-r', + '-P', + '-s', + 'jeff-test-saved-search' + ] + DdOptions.parseSubscriptionOptions(argv); + subConfig = new DdSubConfig(DdOptions.program, false); + expect(subConfig.savedSearchName).is.equal('jeff-test-saved-search'); + expect(subConfig.savedSearchType).is.equal('personnel'); + }); + }); +}) diff --git a/src/test/dd-package-subscribe-test.js b/src/test/dd-package-subscribe-test.js new file mode 100644 index 0000000..338113d --- /dev/null +++ b/src/test/dd-package-subscribe-test.js @@ -0,0 +1,91 @@ +const assert = require("assert"); +const chai = require('chai'); +const expect = chai.expect; +const DdConsts = require('../DdConstants.js'); +const {DdCliConfigFileIO} = require('../core/DdCliConfigFileIO') +const OcsCfg = require('../OcsCfg.js') +const OCS = require('@gov.nasa.jpl.m2020.cs3/ocs-js-client'); +const OcsUtils = require('../OcsUtils.js'); +const DdLogger = require('../DdLogger.js').logger +const SsoToken = require('../SsoToken.js'); +const OcsTestUtils = require("./utils/ocs-test-utils.js"); + +const ctxt = {}; + +const init = () => { + const ocsConfig = new OcsCfg() + ctxt.s3Bucket = "testtest"; + ctxt.pkgName = "DataDrive-Dev-1"; + ctxt.file_name = "slowpoke.gif"; + ctxt.dataDriveHost = DdCliConfigFileIO.builder().getDatadriveHost() + ctxt.ocsHost = ocsConfig.getOcsEndpointHost() + ctxt.ocsAPIDeployment = ocsConfig.getOcsApiStage(); +} + +describe("DataDrive-CLI", () => { + let ocs; + let ocsUtils; + + /** + * Setup Tests + */ + before(() => { + init(); + let config = { + ocsEndpointHost: ctxt.ocsHost, + ocsApiStage: ctxt.ocsAPIDeployment + }; + + ocs = OcsTestUtils.getClient(config); + ctxt.cssoToken = ocs.cliGetCSSOTokens(); + ocsUtils = OcsUtils.builder(ocs, ctxt.cssoToken.sessionToken) + }); + + after(() => { + + }); + + describe("csso", () => { + describe("get datadrive env", () => { + it ("should get dataDriveHost", () => { + expect(ctxt.dataDriveHost).to.be.a('string'); + }); + it ("should get ocsHost", () => { + expect(ctxt.ocsHost).to.be.a('string'); + }); + it ("should get ocsAPIDeployment", () => { + expect(ctxt.ocsAPIDeployment).to.be.a('string'); + }); + }); + describe("getToken", () => { + it("should return a csso token saved on the file system", () => { + expect(ctxt.cssoToken).to.be.a('object'); + }); + }); + }); + + describe("ocsUtils", () => { + describe("getOcsFileMetadata", () => { + it("should get file metadta from OCS", (done) => { + packageName = "DataDrive-Dev-1" + ocsObject = { + "package_id": "58269f36-52a9-44d1-9ba2-bdbb84bf5b7c", + "dataset_id": "94bfa83f-c5a1-44bf-a644-1c092177ef3b", + "ocs_full_name": "/data_drive/Slowpoke.gif", + "ocs_url": "s3://m20-dev-ids-datadrive-bucket01/data_drive/uploads/2019-05-17T00:35:43.334Z/98e90c46-ab86-409d-bde3-8ee07e4b848e/Slowpoke.gif", + "package_dataset_event": "OCS object indexed", + "package_dataset_event_time" :1558053358032, + "identity": "m20-dev-ids" + } + ocsUtils.getOcsFileMetadata(packageName, ocsObject.ocs_full_name) + .then(metadata => { + expect(metadata).to.be.a('object'); + expect(ocsObject.ocs_full_name.toLowerCase()).to.include(metadata.ocs_name.toLowerCase()); + done() + }).catch(err => { + expect(err).to.be.a(null) + }) + }); + }); + }); +}); diff --git a/src/test/dd-queue.js b/src/test/dd-queue.js new file mode 100644 index 0000000..aefb239 --- /dev/null +++ b/src/test/dd-queue.js @@ -0,0 +1,69 @@ +const chai = require('chai'); +const expect = chai.expect; +const assert = chai.assert; +const queue = require('../core/DdQueue'); +const Queue = queue.Queue; +const QueueNode = queue.QueueNode; + +let createQueue = (count) => { + let queue = new Queue(); + for (let i = 0; i < count; i++) { + queue.enqueue(i, i); + } + return queue; +} + +describe("DdQueue", () => { + before(() => { + + }); + + after(() => { + + }); + + describe("test 1", () => { + let queue = new Queue() + it("should have length of 4 after enqueuing 4 items", () => { + for (let i = 0; i < 4; i++) { + queue.enqueue(i, i); + } + expect(queue.itemsToList().length).to.equal(4); + }); + it("should have no items after dequeing all items plus some", () => { + for (let i = 0; i < 6; i++) { + queue.dequeue(); + } + expect(queue.itemsToList().length).to.equal(0); + }); + it("should be able to pop node correctly given a key in the middle", () => { + let queue = createQueue(5); + // pop the middle key (2) + let result = queue.pop(2); + expect(result instanceof QueueNode).to.be.true; + expect(result.key).to.be.equal(2); + expect(queue.itemsToList().length).to.equal(4); + }); + it("should be able to pop node correctly given a key in the head", () => { + let queue = createQueue(5); + // pop the head key (0) + let result = queue.pop(0); + expect(result instanceof QueueNode).to.be.true; + expect(result.key).to.be.equal(0); + expect(queue.itemsToList().length).to.equal(4); + let item = queue.dequeue(); + expect(item.key).to.be.equal(1); + item = queue.dequeue(); + expect(item.key).to.be.equal(2); + expect(queue.itemsToList().length).to.equal(2); + }); + it("should be able to pop node correctly given a key in the tail", () => { + let queue = createQueue(5); + // pop the head key (4) + let result = queue.pop(4); + expect(result instanceof QueueNode).to.be.true; + expect(result.key).to.be.equal(4); + expect(queue.itemsToList().length).to.equal(4); + }); + }); +}) \ No newline at end of file diff --git a/src/test/dd-ssoapi.js b/src/test/dd-ssoapi.js new file mode 100644 index 0000000..f40819b --- /dev/null +++ b/src/test/dd-ssoapi.js @@ -0,0 +1,54 @@ +const chai = require('chai'); +const expect = chai.expect; +const assert = chai.assert; +const SsoToken = require('../core/SsoToken'); +const moment = require('moment'); +const fs = require('fs'); + +let ssoToken; + +describe("SsoToken", () => { + before(() => { + ssoToken = new SsoToken(); + }); + + after(() => { + + }); + + describe("loadToken", () => { + it("should correctly load the token and expiration", async () => { + ssoToken.loadToken(sessionPath=`${process.cwd()}/test/ssosession`, expirationPath=`${process.cwd()}/test/expiration`); + expect(ssoToken.getToken()).to.be.not.empty; + expect(ssoToken.getTokenExpiration()).to.be.not.empty; + }); + }); + + describe("isTokenAboutToExpired", () => { + it("should return true because loaded token in loadToken should be about to expire or expired", async () => { + expect(ssoToken.isTokenAboutToExpired()).equals(true); + }); + + it("should throw error as setTokenExpiration should be a string and in seconds (string should be length of 10)", async () => { + let expireDate = new Date(Date.now()); + expireDate.setHours(expireDate.getHours() + 5); + expect(() => {ssoToken.setTokenExpiration(expireDate.getTime().toString())}).to.throw(); + }); + + it("should return false after setting an epoch time that is Date.now plus 5 hours", async () => { + let expireDate = new Date(Date.now()); + expireDate.setHours(expireDate.getHours() + 5); + let time = Math.floor(expireDate.getTime() / 1000); + ssoToken.setTokenExpiration(time.toString()); + expect(ssoToken.isTokenAboutToExpired()).equals(false); + }); + + it("should return true after setting an epoch time that is Date.now plus 30 minutes", async () => { + let expireDate = new Date(Date.now()); + expireDate.setMinutes(expireDate.getMinutes() + 30); + let time = Math.floor(expireDate.getTime() / 1000); + ssoToken.setTokenExpiration(time.toString()); + expect(ssoToken.isTokenAboutToExpired()).equals(true); + }); + }); +}); \ No newline at end of file diff --git a/src/test/dd-utils.js b/src/test/dd-utils.js new file mode 100644 index 0000000..12872b2 --- /dev/null +++ b/src/test/dd-utils.js @@ -0,0 +1,84 @@ +const chai = require('chai'); +const expect = chai.expect; +const assert = chai.assert; +const utils = require('../core/DdUtils'); +const fs = require('fs'); + +describe("DdUtils", () => { + let arr; + before(() => { + arr = [ + { + ocs_updated_at: '2019-04-01T21:31:31Z', + ocs_package_id: '58269f36-52a9-44d1-9ba2-bdbb84bf5b7c', + ocs_owner: 'akassabi' + }, + { + ocs_updated_at: '2019-04-01T22:04:08Z', + ocs_full_name: '/copy/8/DmDj4-jUwAAWMPB (9).jpg', + ocs_dataset_id: '5f972d0e-7b63-477a-90e7-7cc691142555', + ocs_package_id: '58269f36-52a9-44d1-9ba2-bdbb84bf5b7c', + ocs_owner: 'wphyo' + }, + { + ocs_updated_at: '2019-04-01T21:42:54Z', + ocs_full_name: '/copy/2/DmDj4-jUwAAWMPB (9).jpg', + ocs_dataset_id: 'e0c09d6b-25d3-4d31-8b7b-918dd911961b', + ocs_package_id: '58269f36-52a9-44d1-9ba2-bdbb84bf5b7c', + ocs_owner: 'wphyo' + }, + { + ocs_updated_at: '2019-04-01T22:04:28Z', + ocs_full_name: '/copy/16/DmDj4-jUwAAWMPB (9).jpg', + ocs_dataset_id: '19914c0c-eb64-4e62-920f-536ba6b9c2c2', + ocs_package_id: '58269f36-52a9-44d1-9ba2-bdbb84bf5b7c', + ocs_owner: 'wphyo' + }, + { + ocs_updated_at: '2019-04-01T21:35:10Z', + ocs_full_name: '/Air-Temperature-sol-100_2.png', + ocs_dataset_id: 'ee21ad98-937d-4ef8-981c-a0e4e89c832e', + ocs_package_id: '58269f36-52a9-44d1-9ba2-bdbb84bf5b7c', + ocs_owner: 'wphyo' + } + ] + }); + + after(() => { + + }); + + describe("test 1", () => { + it("should sort asc", () => { + arr.sort(utils.playbackEventsComparator); + let i = 0; + let j = 1; + while (j < arr.length) { + assert(arr[i].ocs_updated_at <= arr[j].ocs_updated_at, 'item at i is older than item at j'); + i += 1; + j += 1; + } + }); + }); + + let filePath = "somerandomplace/somefile.txt"; + describe("test canWriteToLocalFile; directory does not exist", () => { + it("should check if folder exists and return true which means there are no conflicts", async () => { + let config = {"overwrite": false} + expect(utils.canWriteToLocalFile(filePath, config)).to.be.true; + }); + }); + + describe("test canWriteToLocalFile; directory exist", () => { + before(() => { + fs.mkdirSync("somerandomplace"); + }); + after(() => { + fs.rmdirSync("somerandomplace"); + }); + it("should check if folder exists and return true", async () => { + let config = {"overwrite": false} + expect(utils.canWriteToLocalFile(filePath, config)).to.be.true; + }); + }); +}) \ No newline at end of file diff --git a/src/test/expiration b/src/test/expiration new file mode 100644 index 0000000..761b834 --- /dev/null +++ b/src/test/expiration @@ -0,0 +1 @@ +1597901337 \ No newline at end of file diff --git a/src/test/ssosession b/src/test/ssosession new file mode 100644 index 0000000..d3012ab --- /dev/null +++ b/src/test/ssosession @@ -0,0 +1 @@ +dev:jeffliu:bb138e95dec5e4c9e2033e736bd75c9c \ No newline at end of file diff --git a/src/test/utils/ocs-test-utils.js b/src/test/utils/ocs-test-utils.js new file mode 100644 index 0000000..77db3a8 --- /dev/null +++ b/src/test/utils/ocs-test-utils.js @@ -0,0 +1,91 @@ +const OCS = require('@gov.nasa.jpl.m2020.cs3/ocs-js-client'); + +let csso; + +const OcsTestUtils = (function() { + const OcsTestUtils = function() {}; + + OcsTestUtils.getClient = function (config = {}) { + ocs = new OCS(config); + return ocs + }; + + OcsTestUtils.createPackage = function (ocs, pkgName, s3Bucket, congruentPaths, cb) { + // Get the list of requried metadata. + ocs.describeRequiredMetadata(OcsTestUtils.toRqst(), function (err, resp) { + OcsTestUtils.processResp(ocs, err, resp, function (err, meta) { + if (err) { + return handleError(cb, err); + } + const _meta = {}; + for (const m of meta) { + _meta[m.tag] = `${m.tag}_val`; + } + const _params = { + packageName: pkgName, + metadata: _meta + }; + if (s3Bucket) _params.s3Bucket = s3Bucket; + if (congruentPaths) _params.congruentPaths = congruentPaths; + ocs.createPackage(OcsTestUtils.toRqst(_params), function (err, resp) { + OcsTestUtils.processResp(ocs, err, resp, function (err, resp) { + if (err) { + return handleError(cb, err); + } + return cb(null, resp); + }); + }); + }); + }); + }; + + OcsTestUtils.toRqst = function (input) { + let _rqst = { + csso: { + sessionToken: csso + }, + input: input + }; + return _rqst; + }; + + OcsTestUtils.processResp = function (ocs, err, resp, cb) { + // Check for errors. + if (err) { + return cb(OcsTestUtils.getFriendlyError(err), null); + } + if (resp.error) { + return cb(resp.error, null); + } + // If no errors, save CSSO creds. + if (resp.csso.authToken) { + if (resp.csso.authToken != csso.authToken) { + // Only save the auth token if it is different. + ocs.cliSaveCSSOAuthToken(resp.csso.authToken); + csso.authToken = resp.csso.authToken; + } + } + cb(null, resp.data); + }; + + const handleError = function (cb, err, msg) { + mlog.error(`ERROR: ${msg}`, err); + if (err instanceof Error) { + cb(err, null); + return; + } else { + let _msg; + if (typeof err === 'object') { + _msg = JSON.stringify(err, null, 2); + } else { + _msg = err; + } + cb(Error(_msg), null); + return; + } + }; + + return OcsTestUtils; +})(); + +module.exports = OcsTestUtils; \ No newline at end of file