diff --git a/README.md b/README.md index b5844bd..6bc7554 100644 --- a/README.md +++ b/README.md @@ -42,18 +42,18 @@ USAGE * [`mesg-cli marketplace:create-offer SID`](#mesg-cli-marketplacecreate-offer-sid) * [`mesg-cli marketplace:publish SERVICE_PATH`](#mesg-cli-marketplacepublish-service_path) * [`mesg-cli marketplace:purchase SERVICE_ID OFFER_ID`](#mesg-cli-marketplacepurchase-service_id-offer_id) -* [`mesg-cli service:delete SERVICE`](#mesg-cli-servicedelete-service) -* [`mesg-cli service:deploy [SERVICE_PATH_OR_URL]`](#mesg-cli-servicedeploy-service_path_or_url) -* [`mesg-cli service:detail SERVICE`](#mesg-cli-servicedetail-service) +* [`mesg-cli service:compile [SERVICE_PATH_OR_URL]`](#mesg-cli-servicecompile-service_path_or_url) +* [`mesg-cli service:create DEFINITION`](#mesg-cli-servicecreate-definition) +* [`mesg-cli service:delete HASH`](#mesg-cli-servicedelete-hash) * [`mesg-cli service:dev [SERVICE_PATH]`](#mesg-cli-servicedev-service_path) * [`mesg-cli service:doc [SERVICE_PATH]`](#mesg-cli-servicedoc-service_path) -* [`mesg-cli service:execute SERVICE TASK`](#mesg-cli-serviceexecute-service-task) +* [`mesg-cli service:execute INSTANCE_HASH TASK`](#mesg-cli-serviceexecute-instance_hash-task) +* [`mesg-cli service:get HASH`](#mesg-cli-serviceget-hash) * [`mesg-cli service:init DIR`](#mesg-cli-serviceinit-dir) * [`mesg-cli service:list`](#mesg-cli-servicelist) -* [`mesg-cli service:logs SERVICE`](#mesg-cli-servicelogs-service) -* [`mesg-cli service:start SERVICE`](#mesg-cli-servicestart-service) -* [`mesg-cli service:stop SERVICE`](#mesg-cli-servicestop-service) -* [`mesg-cli service:validate [SERVICE_PATH]`](#mesg-cli-servicevalidate-service_path) +* [`mesg-cli service:logs INSTANCE_HASH`](#mesg-cli-servicelogs-instance_hash) +* [`mesg-cli service:start SERVICE_HASH`](#mesg-cli-servicestart-service_hash) +* [`mesg-cli service:stop INSTANCE_HASH`](#mesg-cli-servicestop-instance_hash) ## `mesg-cli account:create` @@ -85,10 +85,6 @@ OPTIONS -q, --quiet --passphrase=passphrase (required) Passphrase to unlock your account --silent - -ALIASES - $ mesg-cli account:rm - $ mesg-cli account:destroy ``` _See code: [src/commands/account/delete.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/account/delete.ts)_ @@ -185,11 +181,12 @@ USAGE $ mesg-cli daemon:logs OPTIONS - -h, --help show CLI help + -h, --help show CLI help -q, --quiet - --name=name (required) [default: engine] name of the service running the engine + --[no-]follow Follow logs + --name=name (required) [default: engine] name of the service running the engine --silent - --tail=tail [default: -1] Output specified number of lines at the end of logs + --tail=tail [default: -1] Output specified number of lines at the end of logs ``` _See code: [src/commands/daemon/logs.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/daemon/logs.ts)_ @@ -332,72 +329,64 @@ OPTIONS _See code: [src/commands/marketplace/purchase.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/marketplace/purchase.ts)_ -## `mesg-cli service:delete SERVICE` +## `mesg-cli service:compile [SERVICE_PATH_OR_URL]` -Delete one or many services +Compile a service and upload its source to IPFS ``` USAGE - $ mesg-cli service:delete SERVICE + $ mesg-cli service:compile [SERVICE_PATH_OR_URL] ARGUMENTS - SERVICE Hash or Sid + SERVICE_PATH_OR_URL [default: ./] Path of the service or url to access it OPTIONS -h, --help show CLI help -q, --quiet - --confirm Confirm delete - --keep-data Do not delete services' persistent data --silent - -ALIASES - $ mesg-cli service:rm - $ mesg-cli service:destroy ``` -_See code: [src/commands/service/delete.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/delete.ts)_ +_See code: [src/commands/service/compile.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/compile.ts)_ -## `mesg-cli service:deploy [SERVICE_PATH_OR_URL]` +## `mesg-cli service:create DEFINITION` -Deploy a service +Create a service ``` USAGE - $ mesg-cli service:deploy [SERVICE_PATH_OR_URL] + $ mesg-cli service:create DEFINITION ARGUMENTS - SERVICE_PATH_OR_URL [default: ./] Path of the service or url to access it + DEFINITION Service's definition. Use service:compile first to build service definition OPTIONS - -h, --help show CLI help + -h, --help show CLI help -q, --quiet - --env=FOO=BAR set env defined in mesg.yml (configuration.env) --silent ``` -_See code: [src/commands/service/deploy.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/deploy.ts)_ +_See code: [src/commands/service/create.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/create.ts)_ -## `mesg-cli service:detail SERVICE` +## `mesg-cli service:delete HASH` -Show details of a deployed service +Delete one or many services ``` USAGE - $ mesg-cli service:detail SERVICE - -ARGUMENTS - SERVICE Hash or Sid + $ mesg-cli service:delete HASH OPTIONS -h, --help show CLI help -q, --quiet + --confirm Confirm delete --silent ALIASES - $ mesg-cli service:get + $ mesg-cli service:rm + $ mesg-cli service:destroy ``` -_See code: [src/commands/service/detail.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/detail.ts)_ +_See code: [src/commands/service/delete.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/delete.ts)_ ## `mesg-cli service:dev [SERVICE_PATH]` @@ -411,15 +400,10 @@ ARGUMENTS SERVICE_PATH [default: ./] Path of the service OPTIONS - -d, --dependency=dependency Name of the dependency to show the logs from - -h, --help show CLI help + -h, --help show CLI help -q, --quiet - --env=FOO=BAR set env defined in mesg.yml (configuration.env) - --event=event Filter specific events in the logs - --no-events Remove events from the logs - --no-results Remove results from the logs + --env=FOO=BAR set env defined in mesg.yml (configuration.env) --silent - --task=task Filter specific task results in the logs ``` _See code: [src/commands/service/dev.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/dev.ts)_ @@ -448,31 +432,44 @@ ALIASES _See code: [src/commands/service/doc.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/doc.ts)_ -## `mesg-cli service:execute SERVICE TASK` +## `mesg-cli service:execute INSTANCE_HASH TASK` -describe the command here +Execute a task on a specific service's instance ``` USAGE - $ mesg-cli service:execute SERVICE TASK + $ mesg-cli service:execute INSTANCE_HASH TASK ARGUMENTS - SERVICE Hash or Sid - TASK Task key + INSTANCE_HASH + TASK Task key OPTIONS - -d, --data=FOO=BAR data required to run the task - -h, --help show CLI help - -j, --json=json Path to a JSON file containing the data required to run the task + -d, --data=key=value data required to run the task + -h, --help show CLI help + -j, --json=json Path to a JSON file containing the data required to run the task -q, --quiet --silent - -ALIASES - $ mesg-cli service:exec ``` _See code: [src/commands/service/execute.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/execute.ts)_ +## `mesg-cli service:get HASH` + +Show details of a service + +``` +USAGE + $ mesg-cli service:get HASH + +OPTIONS + -h, --help show CLI help + -q, --quiet + --silent +``` + +_See code: [src/commands/service/get.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/get.ts)_ + ## `mesg-cli service:init DIR` Initialize a service by creating a mesg.yml and Dockerfile in a dedicated directory. @@ -495,7 +492,7 @@ _See code: [src/commands/service/init.ts](https://github.com/mesg-foundation/cli ## `mesg-cli service:list` -List all deployed services +List all instances ``` USAGE @@ -512,92 +509,64 @@ OPTIONS --no-truncate do not truncate output to fit screen --silent --sort=sort property to sort by (prepend '-' for descending) - -ALIASES - $ mesg-cli service:ls ``` _See code: [src/commands/service/list.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/list.ts)_ -## `mesg-cli service:logs SERVICE` +## `mesg-cli service:logs INSTANCE_HASH` Show logs of a service ``` USAGE - $ mesg-cli service:logs SERVICE - -ARGUMENTS - SERVICE Hash or Sid + $ mesg-cli service:logs INSTANCE_HASH OPTIONS - -d, --dependency=dependency Name of the dependency to show the logs from - -h, --help show CLI help + -h, --help show CLI help -q, --quiet - --event=event Filter specific events in the logs - --no-events Remove events from the logs - --no-results Remove results from the logs + --event=event Only display a specific event + --[no-]events Don't display events + --[no-]follow Continuously display logs + --[no-]results Don't display results --silent - --task=task Filter specific task results in the logs + --tail=tail [default: -1] Output only specified number of lines + --task=task Only display a specific task results ``` _See code: [src/commands/service/logs.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/logs.ts)_ -## `mesg-cli service:start SERVICE` +## `mesg-cli service:start SERVICE_HASH` -Start a service +Start a service by creating a new instance ``` USAGE - $ mesg-cli service:start SERVICE - -ARGUMENTS - SERVICE Hash or Sid + $ mesg-cli service:start SERVICE_HASH OPTIONS - -h, --help show CLI help + -h, --help show CLI help -q, --quiet + --env=FOO=BAR set env defined in mesg.yml (configuration.env) --silent ``` _See code: [src/commands/service/start.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/start.ts)_ -## `mesg-cli service:stop SERVICE` +## `mesg-cli service:stop INSTANCE_HASH` -Stop a service +Stop a service by deleting a specific instance ``` USAGE - $ mesg-cli service:stop SERVICE - -ARGUMENTS - SERVICE Hash or Sid - -OPTIONS - -h, --help show CLI help - -q, --quiet - --silent -``` - -_See code: [src/commands/service/stop.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/stop.ts)_ - -## `mesg-cli service:validate [SERVICE_PATH]` - -Validate a service file. Check the yml format and rules. - -``` -USAGE - $ mesg-cli service:validate [SERVICE_PATH] - -ARGUMENTS - SERVICE_PATH [default: ./] Path of the service + $ mesg-cli service:stop INSTANCE_HASH OPTIONS -h, --help show CLI help -q, --quiet - --env=FOO=BAR set env defined in mesg.yml (configuration.env) + --confirm Confirm delete + --delete-data Delete instances' persistent data --silent ``` -_See code: [src/commands/service/validate.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/validate.ts)_ +_See code: [src/commands/service/stop.ts](https://github.com/mesg-foundation/cli/blob/v1.0.4/src/commands/service/stop.ts)_ diff --git a/package-lock.json b/package-lock.json index 4a7c56f..9b6e47e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,14 +14,14 @@ } }, "@babel/generator": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", - "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", "dev": true, "requires": { - "@babel/types": "^7.3.2", + "@babel/types": "^7.4.4", "jsesc": "^2.5.1", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "source-map": "^0.5.0", "trim-right": "^1.0.1" } @@ -47,12 +47,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", - "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.4.4" } }, "@babel/highlight": { @@ -75,47 +75,47 @@ } }, "@babel/parser": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", - "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", "dev": true }, "@babel/template": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", - "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.2.2", - "@babel/types": "^7.2.2" + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" } }, "@babel/traverse": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", - "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", + "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.2.2", + "@babel/generator": "^7.4.4", "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.2.3", - "@babel/types": "^7.2.2", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/types": "^7.4.4", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.10" + "lodash": "^4.17.11" } }, "@babel/types": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", - "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", "dev": true, "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" }, "dependencies": { @@ -634,7 +634,8 @@ "@types/lodash": { "version": "4.14.121", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.121.tgz", - "integrity": "sha512-ORj7IBWj13iYufXt/VXrCNMbUuCTJfhzme5kx9U/UtcIPdJYuvPDUAlHlbNhz/8lKCLy9XGIZnGrqXOtQbPGoQ==" + "integrity": "sha512-ORj7IBWj13iYufXt/VXrCNMbUuCTJfhzme5kx9U/UtcIPdJYuvPDUAlHlbNhz/8lKCLy9XGIZnGrqXOtQbPGoQ==", + "dev": true }, "@types/long": { "version": "4.0.0", @@ -879,6 +880,21 @@ "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, "arg": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", @@ -1300,6 +1316,36 @@ } } }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", @@ -1548,11 +1594,6 @@ } } }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" - }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -1599,6 +1640,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -1638,6 +1685,15 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -1649,6 +1705,37 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -1721,6 +1808,15 @@ "type-detect": "^4.0.0" } }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -1938,6 +2034,12 @@ "is-arrayish": "^0.2.1" } }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -2206,6 +2308,87 @@ } } }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "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" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "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==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -2249,6 +2432,44 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -2381,9 +2602,9 @@ "dev": true }, "globals": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", - "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "globby": { @@ -2975,6 +3196,15 @@ "minimalistic-assert": "^1.0.1" } }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", @@ -3531,24 +3761,125 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, "istanbul-lib-instrument": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", - "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.2.tgz", + "integrity": "sha512-z4PqiCpomGtWj8633oeAdXm1Kn1W++3T8epkZYnwiVgIYIJ0QHszhInYSJTYxebByQH7KVCEAn8R9duzZW2PhQ==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", + "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", "dev": true, "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.3", - "semver": "^5.5.0" + "handlebars": "^4.1.2" } }, "isurl": { @@ -3736,6 +4067,12 @@ "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, "lodash.template": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", @@ -3807,6 +4144,15 @@ "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -3832,45 +4178,67 @@ "safe-buffer": "^5.1.2" } }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "dependencies": { + "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 + }, + "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 + } + } + }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" }, - "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", - "dev": true + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "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 + } + } + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "dev": true }, "mesg-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mesg-js/-/mesg-js-3.0.0.tgz", - "integrity": "sha512-mAqQtLMonpoINjunsmdn2ik4sAygDYEcOoHe8rnAdytbPt9bEP1VeLnK3M7LmqCZZJ+D+0zVpl5ma1sCIaxoeQ==", + "version": "github:mesg-foundation/mesg-js#9b5dd861f939b63562f3265ccafb1c1208efdc78", + "from": "github:mesg-foundation/mesg-js#build/new-api", "requires": { - "@grpc/proto-loader": "^0.3.0", - "clone": "^2.1.2", + "@grpc/proto-loader": "^0.5.1", "grpc": "^1.21.1", "js-yaml": "^3.13.1", "uuid": "^3.3.2" - }, - "dependencies": { - "@grpc/proto-loader": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.3.0.tgz", - "integrity": "sha512-9b8S/V+3W4Gv7G/JKSZ48zApgyYbfIR7mAC9XNnaSWme3zj57MIESu0ELzm9j5oxNIpFG8DgO00iJMIUZ5luqw==", - "requires": { - "@types/lodash": "^4.14.104", - "@types/node": "^9.4.6", - "lodash": "^4.17.5", - "protobufjs": "^6.8.6" - } - }, - "@types/node": { - "version": "9.6.49", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.49.tgz", - "integrity": "sha512-YY0Okyn4QXC4ugJI+Kng5iWjK8A6eIHiQVaGIhJkyn0YL6Iqo0E0tBC8BuhvYcBK87vykBijM5FtMnCqaa5anA==" - } } }, "micromatch": { @@ -4169,6 +4537,12 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==" }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -4241,191 +4615,59 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nyc": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", - "integrity": "sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "requires": { "archy": "^1.0.0", - "arrify": "^1.0.1", - "caching-transform": "^3.0.1", + "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", - "find-cache-dir": "^2.0.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.3", - "istanbul-lib-hook": "^2.0.3", - "istanbul-lib-instrument": "^3.1.0", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.2", - "istanbul-reports": "^2.1.1", - "make-dir": "^1.3.0", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", "rimraf": "^2.6.3", "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", - "test-exclude": "^5.1.0", + "test-exclude": "^5.2.3", "uuid": "^3.3.2", - "yargs": "^12.0.5", - "yargs-parser": "^11.1.1" + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "async": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "caching-transform": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^1.3.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.3.0" - } - }, - "camelcase": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "cliui": { "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "commander": { - "version": "2.17.1", - "bundled": true, - "dev": true, - "optional": true - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "default-require-extensions": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, - "end-of-stream": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "bundled": true, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, - "es6-error": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, "execa": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { "cross-spawn": "^6.0.0", @@ -4435,841 +4677,166 @@ "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "bundled": true, - "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" - } - } - } - }, - "find-cache-dir": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^3.0.0" } }, "find-up": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" - } - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.1.3", - "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" - } - }, - "graceful-fs": { - "version": "4.1.15", - "bundled": true, - "dev": true - }, - "handlebars": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "async": "^2.5.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "has-flag": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "hasha": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-stream": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.7.1", - "bundled": true, - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invert-kv": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-report": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "supports-color": "^6.0.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "rimraf": "^2.6.2", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "istanbul-reports": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "handlebars": "^4.1.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "lcid": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.11", - "bundled": true, - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "bundled": true, - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "bundled": true, - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "mem": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^2.0.0" - } - }, - "merge-source-map": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "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.10", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - } - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "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" - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optimist": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-is-promise": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "2.1.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.0.0", - "bundled": true, - "dev": true - }, - "package-hash": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "bundled": true, - "dev": true - }, - "path-type": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "pump": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "read-pkg": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "release-zalgo": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "resolve": { - "version": "1.10.0", - "bundled": true, - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.6.0", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "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 - }, - "spawn-wrap": { - "version": "1.4.2", - "bundled": true, - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - } - }, - "spdx-correct": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "bundled": true, - "dev": true + } }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, + "get-stream": { + "version": "4.1.0", + "resolved": false, + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "pump": "^3.0.0" } }, - "spdx-license-ids": { - "version": "3.0.3", - "bundled": true, + "invert-kv": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, - "string-width": { - "version": "2.1.1", - "bundled": true, + "lcid": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "invert-kv": "^2.0.0" } }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, + "locate-path": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "test-exclude": { - "version": "5.1.0", - "bundled": true, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { - "arrify": "^1.0.1", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^1.0.1" + "pify": "^4.0.1", + "semver": "^5.6.0" } }, - "uglify-js": { - "version": "3.4.9", - "bundled": true, + "os-locale": { + "version": "3.1.0", + "resolved": false, + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, - "optional": true, "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - } + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, - "uuid": { - "version": "3.3.2", - "bundled": true, - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": 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==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "p-try": "^2.0.0" } }, - "which": { - "version": "1.3.1", - "bundled": true, + "p-locate": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "isexe": "^2.0.0" + "p-limit": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "bundled": true, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "wordwrap": { - "version": "0.0.3", - "bundled": true, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, + "pump": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "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" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "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" + } }, - "write-file-atomic": { - "version": "2.4.2", - "bundled": true, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" } }, "y18n": { "version": "4.0.0", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, "yargs": { - "version": "12.0.5", - "bundled": true, + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" } } } @@ -5358,6 +4925,12 @@ "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", @@ -5376,6 +4949,12 @@ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -5418,6 +4997,18 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", @@ -5621,6 +5212,12 @@ "varint": "^5.0.0" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, "pull-defer": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz", @@ -5734,6 +5331,86 @@ "strict-uri-encode": "^1.0.0" } }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + }, + "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-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + } + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -5772,6 +5449,15 @@ "safe-regex": "^1.1.0" } }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -5784,6 +5470,18 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "resolve": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", @@ -5793,6 +5491,12 @@ "path-parse": "^1.0.6" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -5928,6 +5632,12 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", @@ -6165,6 +5875,20 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "spawn-wrap": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", + "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -6448,6 +6172,18 @@ "xtend": "^4.0.0" } }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + } + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -6892,6 +6628,12 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", @@ -7027,6 +6769,24 @@ } } }, + "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" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, "yn": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.0.tgz", diff --git a/package.json b/package.json index 2771dfd..fd53406 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ }, "bugs": "https://github.com/mesg-foundation/cli/issues", "dependencies": { - "@grpc/proto-loader": "^0.5.1", "@oclif/command": "^1.5.13", "@oclif/config": "^1.13.0", "@oclif/errors": "^1.2.2", @@ -23,7 +22,6 @@ "cli-ux": "^5.2.1", "download-tarball": "^2.0.0", "git-clone": "^0.1.0", - "grpc": "^1.21.1", "handlebars": "^4.1.2", "hosted-git-info": "^2.7.1", "ignore": "^5.1.2", @@ -31,7 +29,7 @@ "ipfs-http-client": "^29.1.1", "is-git-url": "^1.0.0", "js-yaml": "^3.13.1", - "mesg-js": "^3.0.0", + "mesg-js": "github:mesg-foundation/mesg-js#build/new-api", "node-docker-api": "^1.1.22", "rimraf": "^2.6.3", "tar": "^4.4.8", @@ -56,7 +54,7 @@ "chai": "^4.2.0", "globby": "^8.0.2", "mocha": "^5.2.0", - "nyc": "^13.3.0", + "nyc": "^14.1.1", "ts-node": "^8.1.0", "tslint": "^5.16.0", "typescript": "^3.4.5" @@ -110,4 +108,4 @@ "lint": "tslint -p ./ -t stylish --fix" }, "types": "lib/index.d.ts" -} +} \ No newline at end of file diff --git a/src/account-command.ts b/src/account-command.ts index acaea0b..f57164b 100644 --- a/src/account-command.ts +++ b/src/account-command.ts @@ -7,6 +7,8 @@ export abstract class WithoutPassphrase extends Command { static flags = { ...Command.flags } + + static SERVICE_NAME = 'EthWallet' } export abstract class WithPassphrase extends WithoutPassphrase { diff --git a/src/commands/account/create.ts b/src/commands/account/create.ts index fd7ce35..3d66080 100644 --- a/src/commands/account/create.ts +++ b/src/commands/account/create.ts @@ -1,13 +1,16 @@ import {WithPassphrase as Command} from '../../account-command' -import services from '../../services' export default class AccountCreate extends Command { static description = 'Create a new account' async run() { this.spinner.start('Create account') - const {data} = await this.executeAndCaptureError(services.account.id, services.account.tasks.create, { - passphrase: await this.getPassphrase(), + const data = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'create', + inputs: JSON.stringify({ + passphrase: await this.getPassphrase(), + }) }) this.spinner.stop(data.address) return data diff --git a/src/commands/account/delete.ts b/src/commands/account/delete.ts index 9ccda30..647e24d 100644 --- a/src/commands/account/delete.ts +++ b/src/commands/account/delete.ts @@ -1,11 +1,8 @@ import {WithPassphrase as Command} from '../../account-command' -import services from '../../services' export default class AccountDelete extends Command { static description = 'Delete an existing account' - static aliases = ['account:rm', 'account:destroy'] - static args = [{ name: 'ADDRESS', required: true @@ -15,9 +12,13 @@ export default class AccountDelete extends Command { const {args} = this.parse(AccountDelete) this.spinner.start('Delete account') - const {data} = await this.executeAndCaptureError(services.account.id, services.account.tasks.delete, { - passphrase: await this.getPassphrase(), - address: args.ADDRESS, + const data = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'delete', + inputs: JSON.stringify({ + passphrase: await this.getPassphrase(), + address: args.ADDRESS, + }) }) this.spinner.stop(data.address) return data diff --git a/src/commands/account/export.ts b/src/commands/account/export.ts index 66fc4f5..e9cf779 100644 --- a/src/commands/account/export.ts +++ b/src/commands/account/export.ts @@ -1,5 +1,4 @@ import {WithPassphrase as Command} from '../../account-command' -import services from '../../services' export default class AccountExport extends Command { static description = 'Export an existing account' @@ -13,13 +12,14 @@ export default class AccountExport extends Command { const {args} = this.parse(AccountExport) this.spinner.start('Export account') - const {data} = await this.executeAndCaptureError(services.account.id, services.account.tasks.export, { - passphrase: await this.getPassphrase(), - address: args.ADDRESS, + const data = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'export', + inputs: JSON.stringify({ + passphrase: await this.getPassphrase(), + address: args.ADDRESS, + }) }) - if (!data) { - this.error('account not found or passphrase does not match') - } this.spinner.stop() this.styledJSON(data) return data diff --git a/src/commands/account/import-private-key.ts b/src/commands/account/import-private-key.ts index 9ecba1a..f5ea206 100644 --- a/src/commands/account/import-private-key.ts +++ b/src/commands/account/import-private-key.ts @@ -1,5 +1,4 @@ import {WithPassphrase as Command} from '../../account-command' -import services from '../../services' export default class AccountImportPK extends Command { static description = 'Import a account from a private key' @@ -14,9 +13,13 @@ export default class AccountImportPK extends Command { const {args} = this.parse(AccountImportPK) this.spinner.start('Import account') - const {data} = await this.executeAndCaptureError(services.account.id, services.account.tasks.importPK, { - passphrase: await this.getPassphrase(), - privateKey: args.PRIVATE_KEY, + const data = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'importFromPrivateKey', + inputs: JSON.stringify({ + passphrase: await this.getPassphrase(), + privateKey: args.PRIVATE_KEY, + }) }) this.spinner.stop(data.address) return data diff --git a/src/commands/account/import.ts b/src/commands/account/import.ts index 5a8974b..59bfdef 100644 --- a/src/commands/account/import.ts +++ b/src/commands/account/import.ts @@ -1,5 +1,4 @@ import {WithPassphrase as Command} from '../../account-command' -import services from '../../services' export default class AccountImport extends Command { static description = 'Import a account' @@ -14,9 +13,13 @@ export default class AccountImport extends Command { const {args} = this.parse(AccountImport) this.spinner.start('Import account') - const {data} = await this.executeAndCaptureError(services.account.id, services.account.tasks.import, { - passphrase: await this.getPassphrase(), - account: JSON.parse(args.ACCOUNT), + const data = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'import', + inputs: JSON.stringify({ + passphrase: await this.getPassphrase(), + account: JSON.parse(args.ACCOUNT), + }) }) this.spinner.stop(data.address) return data diff --git a/src/commands/account/list.ts b/src/commands/account/list.ts index 8e0961d..0f61516 100644 --- a/src/commands/account/list.ts +++ b/src/commands/account/list.ts @@ -1,7 +1,6 @@ import {cli} from 'cli-ux' import {WithoutPassphrase as Command} from '../../account-command' -import services from '../../services' export default class AccountList extends Command { static description = 'List all existing accounts' @@ -15,7 +14,11 @@ export default class AccountList extends Command { async run() { const {flags} = this.parse(AccountList) - const {data} = await this.executeAndCaptureError(services.account.id, services.account.tasks.list) + const data = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'list', + inputs: JSON.stringify({}) + }) cli.table(data.addresses, { address: {header: 'ADDRESS', get: (x: any) => x}, }, {printLine: this.log, ...flags}) diff --git a/src/commands/daemon/logs.ts b/src/commands/daemon/logs.ts index b3bee3a..6567bc4 100644 --- a/src/commands/daemon/logs.ts +++ b/src/commands/daemon/logs.ts @@ -1,6 +1,7 @@ import {flags} from '@oclif/command' import Command from '../../docker-command' +import {parseLog} from '../../utils/docker' export default class Logs extends Command { static description = 'Show the Engine\'s logs' @@ -10,6 +11,11 @@ export default class Logs extends Command { tail: flags.integer({ description: 'Output specified number of lines at the end of logs', default: -1 + }), + follow: flags.boolean({ + description: 'Follow logs', + allowNo: true, + default: true }) } @@ -23,10 +29,10 @@ export default class Logs extends Command { const logs: any = await service.logs({ stderr: true, stdout: true, - follow: true, + follow: flags.follow, tail: flags.tail && flags.tail >= 0 ? flags.tail : 'all' }) - logs.on('data', (buffer: Buffer) => this.parseLog(buffer).forEach(x => this.log(x))) + logs.on('data', (buffer: Buffer) => parseLog(buffer).forEach(x => this.log(x))) logs.on('error', (error: Error) => { throw error }) diff --git a/src/commands/daemon/start.ts b/src/commands/daemon/start.ts index 96a65fe..3552513 100644 --- a/src/commands/daemon/start.ts +++ b/src/commands/daemon/start.ts @@ -1,7 +1,7 @@ import {flags} from '@oclif/command' import Command from '../../docker-command' -import version from '../../version'; +import version from '../../version' import Status, {ServiceStatus} from './status' diff --git a/src/commands/marketplace/create-offer.ts b/src/commands/marketplace/create-offer.ts index 94d8476..bac2728 100644 --- a/src/commands/marketplace/create-offer.ts +++ b/src/commands/marketplace/create-offer.ts @@ -1,7 +1,6 @@ import {flags} from '@oclif/command' import Command from '../../marketplace-command' -import services from '../../services' export default class MarketplaceCreateOffer extends Command { static description = 'Create a new offer on a service on the MESG Marketplace' @@ -30,14 +29,22 @@ export default class MarketplaceCreateOffer extends Command { const account = await this.getAccount() const passphrase = await this.getPassphrase() this.spinner.start('Creating offer') - const prepareOffer = await this.executeAndCaptureError(services.marketplace.id, services.marketplace.tasks.prepareCreateOffer, { - sid: args.SID, - price: flags.price, - duration: flags.duration, - from: account, + const prepareOffer = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'preparePublishServiceVersion', + inputs: JSON.stringify({ + sid: args.SID, + price: flags.price, + duration: flags.duration, + from: account, + }) }) const signedTx = await this.sign(account, prepareOffer.data, passphrase) - const offer = await this.executeAndCaptureError(services.marketplace.id, services.marketplace.tasks.publishCreateOffer, signedTx) + const offer = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'publishCreateServiceOffer', + inputs: JSON.stringify(signedTx) + }) this.spinner.stop('Offer created') this.styledJSON(offer.data) diff --git a/src/commands/marketplace/publish.ts b/src/commands/marketplace/publish.ts index 5a79d1f..3954027 100644 --- a/src/commands/marketplace/publish.ts +++ b/src/commands/marketplace/publish.ts @@ -3,10 +3,9 @@ import {readdirSync, readFileSync} from 'fs' import {join} from 'path' import Command from '../../marketplace-command' -import {Service, ServiceID} from '../../service-command' -import services from '../../services' -import ServiceDeploy from '../service/deploy' -import ServiceDetail from '../service/detail' +import {createTar} from '../../utils/deployer' +import ServiceCreate from '../service/create' +import ServiceGet from '../service/get' const ipfsClient = require('ipfs-http-client') @@ -29,10 +28,12 @@ export default class MarketplacePublish extends Command { const account = await this.getAccount() this.spinner.start('Deploy service') - const [deployedService] = (await ServiceDeploy.run([path, '--silent'])) as ServiceID[] - this.require(deployedService, 'Deployed service issue') + const deployedService = await ServiceCreate.run([path, '--silent']) + if (!deployedService) { + throw new Error('Deployed service issue') + } - const [service] = (await ServiceDetail.run([deployedService.hash, '--silent'])) as Service[] + const service = await ServiceGet.run([deployedService.hash, '--silent']) this.spinner.status = 'Upload sources' const sources = await this.deploySources(path) @@ -62,10 +63,9 @@ export default class MarketplacePublish extends Command { } async deploySources(path: string): Promise { - const cmd = new ServiceDeploy(this.argv, this.config) const buffer: any[] = [] return new Promise((resolve, reject) => { - cmd.createTar(join(path)) + createTar(join(path)) .on('data', (data: any) => buffer.push(...data)) .once('error', reject) .on('end', async () => resolve(await this.upload(Buffer.from(buffer))) @@ -74,16 +74,24 @@ export default class MarketplacePublish extends Command { } async preparePublishService(service: any, account: string): Promise { - const publishTx = await this.executeAndCaptureError(services.marketplace.id, services.marketplace.tasks.prepareCreateVersion, { - service, - from: account + const publishTx = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'prepareCreateVersion', + inputs: JSON.stringify({ + service, + from: account + }) }) return publishTx.data } async publishService(account: string, serviceTx: any, passphrase: string): Promise { const signedTx = await this.sign(account, serviceTx, passphrase) - const service = await this.executeAndCaptureError(services.marketplace.id, services.marketplace.tasks.publishCreateVersion, signedTx) + const service = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'publishCreateVersion', + inputs: JSON.stringify(signedTx) + }) return service.data } diff --git a/src/commands/marketplace/purchase.ts b/src/commands/marketplace/purchase.ts index 4d85873..63b67a7 100644 --- a/src/commands/marketplace/purchase.ts +++ b/src/commands/marketplace/purchase.ts @@ -1,5 +1,4 @@ import Command from '../../marketplace-command' -import services from '../../services' export default class MarketplacePurchase extends Command { static description = 'Purchase a service on the MESG Marketplace' @@ -23,10 +22,14 @@ export default class MarketplacePurchase extends Command { const account = await this.getAccount() this.spinner.start('Verifying offer') - const preparePurchase = await this.executeAndCaptureError(services.marketplace.id, services.marketplace.tasks.preparePurchase, { - sid: args.SERVICE_ID, - offerIndex: args.OFFER_ID, - from: account, + const preparePurchase = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'preparePurchase', + inputs: JSON.stringify({ + sid: args.SERVICE_ID, + offerIndex: args.OFFER_ID, + from: account, + }) }) this.spinner.stop() const passphrase = await this.getPassphrase() @@ -35,8 +38,12 @@ export default class MarketplacePurchase extends Command { for (const tx of preparePurchase.data.transactions) { signedTxs.push(await this.sign(account, tx, passphrase)) } - const purchase = await this.executeAndCaptureError(services.marketplace.id, services.marketplace.tasks.publishPurchase, { - signedTransactions: signedTxs.map(x => x.signedTransaction) + const purchase = await this.execute({ + instanceHash: await this.engineServiceInstance(Command.SERVICE_NAME), + taskKey: 'publishPurchase', + inputs: JSON.stringify({ + signedTransactions: signedTxs.map(x => x.signedTransaction) + }) }) this.spinner.stop() this.styledJSON(purchase.data) diff --git a/src/commands/service/compile.ts b/src/commands/service/compile.ts index fdb831e..01eda5b 100644 --- a/src/commands/service/compile.ts +++ b/src/commands/service/compile.ts @@ -1,9 +1,12 @@ import {readFileSync} from 'fs' import yaml from 'js-yaml' +import {Service} from 'mesg-js/lib/api' import {join} from 'path' -import deployer from '../../deployer' -import Command, {CompiledDefinition, Parameter} from '../../service-command' +import {WithoutPassphrase} from '../../account-command' +import MarketplaceCommand from '../../marketplace-command' +import Command from '../../root-command' +import deployer from '../../utils/deployer' import MarketplacePublish from '../marketplace/publish' export default class ServiceCompile extends Command { @@ -19,9 +22,7 @@ export default class ServiceCompile extends Command { default: './' }] - static hidden = true - - async run(): Promise { + async run(): Promise { const {args} = this.parse(ServiceCompile) this.spinner.status = 'Download sources' const path = await deployer(await this.processUrl(args.SERVICE_PATH_OR_URL)) @@ -32,9 +33,9 @@ export default class ServiceCompile extends Command { return definition } - parseYml(content: string, source: string): CompiledDefinition { + parseYml(content: string, source: string): Service { const o = yaml.safeLoad(content) - const parseParams = (params: any): Parameter[] => Object.keys(params || {}) + const parseParams = (params: any): any => Object.keys(params || {}) .map((key: string) => { const {name, description, type, repeated, optional, object} = params[key] return {key, name, description, type, repeated, optional, object: parseParams(object || {})} @@ -58,6 +59,31 @@ export default class ServiceCompile extends Command { } } + async getAuthorizedServiceInfo(id: string, versionHash: string): Promise<{ sid: string, source: string, type: string }> { + const {addresses} = await this.execute({ + instanceHash: await this.engineServiceInstance(WithoutPassphrase.SERVICE_NAME), + taskKey: 'list', + inputs: JSON.stringify({}) + }) + if (!addresses.length) { + throw new Error('you have no accounts. please add an authorized account in order to deploy this service') + } + + const {authorized, sid, source, type} = await this.execute({ + instanceHash: await this.engineServiceInstance(MarketplaceCommand.SERVICE_NAME), + taskKey: 'isAuthorized', + inputs: JSON.stringify({ + id, + versionHash, + addresses + }) + }) + if (!authorized) { + throw new Error('you have no authorized accounts. please add an authorized account in order to deploy this service') + } + return {sid, source, type} + } + async processUrl(url: string): Promise { const marketplaceUrl = url.split('mesg://marketplace/service/') if (marketplaceUrl.length === 2) { diff --git a/src/commands/service/create.ts b/src/commands/service/create.ts new file mode 100644 index 0000000..455ad5b --- /dev/null +++ b/src/commands/service/create.ts @@ -0,0 +1,25 @@ +import {ServiceCreateOutputs} from 'mesg-js/lib/api' + +import Command from '../../root-command' + +export default class ServiceCreate extends Command { + static description = 'Create a service' + + static flags = { + ...Command.flags, + } + + static args = [{ + name: 'DEFINITION', + required: true, + description: 'Service\'s definition. Use service:compile first to build service definition' + }] + + async run(): ServiceCreateOutputs { + const {args} = this.parse(ServiceCreate) + this.spinner.start('Create service') + const resp = await this.api.service.create(JSON.parse(args.DEFINITION)) + this.spinner.stop(resp.hash) + return resp + } +} diff --git a/src/commands/service/delete.ts b/src/commands/service/delete.ts index a352c74..6142b4e 100644 --- a/src/commands/service/delete.ts +++ b/src/commands/service/delete.ts @@ -1,7 +1,7 @@ import {flags} from '@oclif/command' import cli from 'cli-ux' -import Command from '../../service-command' +import Command from '../../root-command' export default class ServiceDelete extends Command { static description = 'Delete one or many services' @@ -10,31 +10,23 @@ export default class ServiceDelete extends Command { static flags = { ...Command.flags, - 'keep-data': flags.boolean({description: 'Do not delete services\' persistent data'}), confirm: flags.boolean({description: 'Confirm delete', default: false}) } static strict = false static args = [{ - name: 'SERVICE', + name: 'SERVICE_HASH', required: true, - description: 'Hash or Sid' }] async run(): Promise { const {argv, flags} = this.parse(ServiceDelete) - if (!flags['keep-data']) { - cli.warn('This will delete all data associated to this service') - } if (!flags.confirm && !await cli.confirm('Are you sure?')) return [] this.spinner.start('Delete service') - for (const arg of argv) { - this.spinner.status = arg - await this.unaryCall('DeleteService', { - serviceID: arg, - deleteData: !flags['keep-data'], - }) + for (const hash of argv) { + this.spinner.status = hash + await this.api.service.delete({hash}) } this.spinner.stop() return argv diff --git a/src/commands/service/deploy.ts b/src/commands/service/deploy.ts deleted file mode 100644 index 65bb0f2..0000000 --- a/src/commands/service/deploy.ts +++ /dev/null @@ -1,116 +0,0 @@ -import {flags} from '@oclif/command' -import {existsSync, readdirSync, readFileSync} from 'fs' -import ignore from 'ignore' -import {join} from 'path' -import {Readable, Writable} from 'stream' -import tar from 'tar' - -import deployer from '../../deployer' -import Command, {ServiceID} from '../../service-command' - -export default class ServiceDeploy extends Command { - static description = 'Deploy a service' - - static flags = { - ...Command.flags, - env: flags.string({ - description: 'set env defined in mesg.yml (configuration.env)', - multiple: true, - helpValue: 'FOO=BAR' - }) - } - - static strict = false - - static args = [{ - name: 'SERVICE_PATH_OR_URL', - description: 'Path of the service or url to access it', - default: './' - }] - - async run(): Promise { - const {argv, flags} = this.parse(ServiceDeploy) - - this.spinner.start('Deploy service') - let deployed: ServiceID[] = [] - for (const url of argv) { - this.spinner.status = 'Download sources' - const path = await deployer(await this.processUrl(url)) - - try { - deployed.push(await new Promise((resolve: (value: ServiceID) => void, reject: (reason: Error) => void) => { - const stream = this.mesg.api.DeployService() - stream.on('error', (error: Error) => { - throw error - }) - stream.on('data', (data: any) => this.handleDeploymentResponse(data, resolve, reject)) - this.writeEnv(stream, flags.env) - - this.createTar(path) - .on('end', () => stream.end('')) - .on('error', (error: Error) => { - throw error - }) - .on('data', (chunk: Buffer) => { - if (chunk.length > 0) stream.write({chunk}) - }) - })) - } catch (e) { - this.error(e) - } - } - this.spinner.stop(deployed.map((x: any) => x.sid).join(', ')) - return deployed - } - - createTar(path: string): Readable { - const mesgignore = join(path, '.mesgignore') - const ig = ignore().add([ - '.git', - ...(existsSync(mesgignore) ? readFileSync(mesgignore).toString().split('\n') : []) - ]) - return tar.create({ - cwd: path, - filter: ig.createFilter(), - strict: true, - gzip: true, - portable: true, - }, readdirSync(path)) - .on('error', (error: Error) => { - throw error - }) - } - - writeEnv(stream: Writable, envList: string[]) { - if (!envList || envList.length === 0) return - const env = envList.reduce((prev, item) => { - const [key, value] = item.split('=') - return { - ...prev, - [key]: value - } - }, {}) - stream.write({env}) - } - - handleDeploymentResponse(x: any, resolve: (value: ServiceID) => void, reject: (reason: Error) => void) { - if (x.status) { - this.spinner.status = x.status.message - return - } - return x.service ? resolve(x.service) : reject(x.validationError) - } - - async processUrl(url: string): Promise { - const marketplaceUrl = url.split('mesg://marketplace/service/') - if (marketplaceUrl.length === 2) { - const versionHash = marketplaceUrl[1] - const {type, source} = await this.getAuthorizedServiceInfo('', versionHash) - if (type === 'ipfs') { - return `http://ipfs.app.mesg.com:8080/ipfs/${source}` // tslint:disable-line:no-http-string - } - throw new Error(`unknown protocol '${type}'`) - } - return url - } -} diff --git a/src/commands/service/detail.ts b/src/commands/service/detail.ts deleted file mode 100644 index fa4757c..0000000 --- a/src/commands/service/detail.ts +++ /dev/null @@ -1,30 +0,0 @@ -import Command, {Service} from '../../service-command' - -export default class ServiceDetail extends Command { - static description = 'Show details of a deployed service' - - static aliases = ['service:get'] - - static flags = { - ...Command.flags, - } - - static strict = false - - static args = [{ - name: 'SERVICE', - required: true, - description: 'Hash or Sid' - }] - - async run(): Promise { - const {argv} = this.parse(ServiceDetail) - const services: Service[] = [] - for (const arg of argv) { - const {service} = await this.unaryCall('GetService', {serviceID: arg}) - services.push(service) - } - this.styledJSON(services) - return services - } -} diff --git a/src/commands/service/dev.ts b/src/commands/service/dev.ts index d07d82e..1046a8c 100644 --- a/src/commands/service/dev.ts +++ b/src/commands/service/dev.ts @@ -1,17 +1,19 @@ -import Command, {ServiceID} from '../../service-command' +import Command from '../../root-command' +import ServiceCompile from './compile' +import ServiceCreate from './create' import ServiceDelete from './delete' -import ServiceDeploy from './deploy' -import ServiceLog, {Log} from './logs' +import InstanceLog from './logs' import ServiceStart from './start' +import ServiceStop from './stop' export default class ServiceDev extends Command { static description = 'Run your service in development mode' static flags = { ...Command.flags, - ...ServiceLog.flags, - ...ServiceDeploy.flags + ...ServiceCreate.flags, + ...ServiceStart.flags, } static args = [{ @@ -20,22 +22,19 @@ export default class ServiceDev extends Command { default: './' }] - async run(): Promise { + async run() { const {args, flags} = this.parse(ServiceDev) - const envs = (flags.env || []).reduce((prev, value) => [ - ...prev, - '--env', - value - ], [] as string[]) - const services = (await ServiceDeploy.run([args.SERVICE_PATH, ...envs])) as ServiceID[] - const hashes = services.map(x => x.hash) - await ServiceStart.run(hashes) - const stream = await ServiceLog.run(hashes) + const definition = await ServiceCompile.run([args.SERVICE_PATH, '--silent']) + const service = await ServiceCreate.run([JSON.stringify(definition)]) + const envs = (flags.env || []).reduce((prev, value) => [...prev, '--env', value], [] as string[]) + const instance = await ServiceStart.run([service.hash, ...envs]) + const stream = await InstanceLog.run([instance.hash]) process.on('SIGINT', async () => { try { - await ServiceDelete.run([...hashes, '--keep-data', '--confirm']) + await ServiceStop.run([instance.hash, '--keep-data', '--confirm']) + await ServiceDelete.run([service.hash, '--confirm']) } finally { process.exit(0) } diff --git a/src/commands/service/doc.ts b/src/commands/service/doc.ts index 1abadd8..3b26bb7 100644 --- a/src/commands/service/doc.ts +++ b/src/commands/service/doc.ts @@ -4,7 +4,7 @@ import {compile, registerHelper} from 'handlebars' import {safeLoad} from 'js-yaml' import {join} from 'path' -import Command from '../../service-command' +import Command from '../../root-command' export default class ServiceDoc extends Command { static description = 'Generate the documentation for the service in a README.md file' diff --git a/src/commands/service/execute.ts b/src/commands/service/execute.ts index c89c890..587a7ed 100644 --- a/src/commands/service/execute.ts +++ b/src/commands/service/execute.ts @@ -1,15 +1,13 @@ import {flags} from '@oclif/command' import {readFileSync} from 'fs' +import {ExecutionCreateOutputs} from 'mesg-js/lib/api' -import {ExecutionResult} from '../../root-command' -import Command, {Service, SERVICE_PARAMETER_TYPE} from '../../service-command' +import Command from '../../root-command' -import Detail from './detail' +import ServiceGet from './get' export default class ServiceExecute extends Command { - static description = 'describe the command here' - - static aliases = ['service:exec'] + static description = 'Execute a task on a specific service\'s instance' static flags = { ...Command.flags, @@ -18,39 +16,42 @@ export default class ServiceExecute extends Command { char: 'd', description: 'data required to run the task', multiple: true, - helpValue: 'FOO=BAR' + helpValue: 'key=value' }), } static args = [{ - name: 'SERVICE', + name: 'INSTANCE_HASH', required: true, - description: 'Hash or Sid' }, { name: 'TASK', required: true, description: 'Task key' }] - async run(): Promise { + async run(): ExecutionCreateOutputs { const {args, flags} = this.parse(ServiceExecute) - const service = (await Detail.run([args.SERVICE, '--silent']))[0] as Service + const instance = await this.api.instance.get({hash: args.INSTANCE_HASH}) + const service = await ServiceGet.run([instance.serviceHash, '--silent']) - const task = service.definition.tasks.find((x: any) => x.key === args.TASK) + const task = service.tasks.find((x: any) => x.key === args.TASK) if (!task) { - this.error(`The task ${args.TASK} does not exists in the service ${args.SERVICE}`) - return null + throw new Error(`The task ${args.TASK} does not exists in the instance ${args.INSTANCE_HASH}`) } const inputs = this.convertValue(task.inputs, this.dataFromFlags(flags)) - const result = await this.executeAndCaptureError(service.definition.hash, args.TASK, inputs) - this.log(`Result of task ${args.TASK}`) - this.styledJSON(result.data) + const result = await this.execute({ + inputs: JSON.stringify(inputs), + instanceHash: args.INSTANCE_HASH, + tags: ['CLI'], + taskKey: args.TASK + }) + this.styledJSON(result) return result } - dataFromFlags(flags: {data: string[], json: string | undefined}): any { + dataFromFlags(flags: { data: string[], json: string | undefined }): any { if (flags.json) { return JSON.parse(readFileSync(flags.json).toString()) } @@ -73,7 +74,7 @@ export default class ServiceExecute extends Command { }), {}) } - convert(type: SERVICE_PARAMETER_TYPE, value: string | any): any { + convert(type: 'Object' | 'String' | 'Boolean' | 'Number' | 'Any', value: string | any): any { try { return { Object: (x: string | any) => typeof x === 'string' ? JSON.parse(x) : x, diff --git a/src/commands/service/get.ts b/src/commands/service/get.ts new file mode 100644 index 0000000..b376fe0 --- /dev/null +++ b/src/commands/service/get.ts @@ -0,0 +1,23 @@ +import {ServiceGetOutputs} from 'mesg-js/lib/api' + +import Command from '../../root-command' + +export default class ServiceGet extends Command { + static description = 'Show details of a service' + + static flags = { + ...Command.flags, + } + + static args = [{ + name: 'SERVICE_HASH', + required: true + }] + + async run(): ServiceGetOutputs { + const {args} = this.parse(ServiceGet) + const response = await this.api.service.get({hash: args.SERVICE_HASH}) + this.styledJSON(response) + return response + } +} diff --git a/src/commands/service/init.ts b/src/commands/service/init.ts index 509b3b3..75ef07f 100644 --- a/src/commands/service/init.ts +++ b/src/commands/service/init.ts @@ -4,8 +4,8 @@ import {renameSync} from 'fs' import {prompt} from 'inquirer' import {join} from 'path' -import deployer from '../../deployer' -import Command from '../../service-command' +import Command from '../../root-command' +import deployer from '../../utils/deployer' const templatesURL = 'https://raw.githubusercontent.com/mesg-foundation/awesome/master/templates.json' @@ -54,7 +54,7 @@ export default class ServiceInit extends Command { value: x.name, short: x.name })) - })) as {value: string} + })) as { value: string } const selectedTemplate = templates.find(x => x.name === value) if (!selectedTemplate) { diff --git a/src/commands/service/list.ts b/src/commands/service/list.ts index d61c98f..9ab4ec7 100644 --- a/src/commands/service/list.ts +++ b/src/commands/service/list.ts @@ -1,27 +1,32 @@ import cli from 'cli-ux' +import {Instance} from 'mesg-js/lib/api' -import Command, {Service} from '../../service-command' +import Command from '../../root-command' export default class ServiceList extends Command { - static description = 'List all deployed services' - - static aliases = ['service:ls'] + static description = 'List all instances' static flags = { ...Command.flags, ...cli.table.flags() } - async run(): Promise { + async run(): Promise { const {flags} = this.parse(ServiceList) - const services = (await this.unaryCall('ListServices')).services as Service[] + const {services} = await this.api.service.list({}) + const {instances} = await this.api.instance.list({}) if (!services) return [] cli.table(services, { - hash: {header: 'HASH', get: x => x.definition.hash}, - sid: {header: 'SID', get: x => x.definition.sid}, - name: {header: 'NAME', get: x => x.definition.name}, - status: {header: 'STATUS', get: x => this.status(x.status)} + hash: {header: 'HASH', get: x => x.hash}, + sid: {header: 'SID', get: x => x.sid}, + instances: { + header: 'INSTANCES', + get: x => (instances || []) + .filter(y => y.serviceHash === x.hash) + .map(x => x.hash) + .join('\n') + } }, {printLine: this.log, ...flags}) - return services + return instances } } diff --git a/src/commands/service/logs.ts b/src/commands/service/logs.ts index cd08aa3..b23a470 100644 --- a/src/commands/service/logs.ts +++ b/src/commands/service/logs.ts @@ -1,94 +1,116 @@ import {flags} from '@oclif/command' import chalk from 'chalk' -import {Stream} from 'mesg-js/lib/service' +import {Event, Execution, ExecutionStatus} from 'mesg-js/lib/api' +import {Docker} from 'node-docker-api' -import Command from '../../service-command' +import Command from '../../root-command' +import {parseLog} from '../../utils/docker' export interface Log { dependency: string data: Buffer } -export default class ServiceLog extends Command { +export default class ServiceLogs extends Command { static description = 'Show logs of a service' static flags = { ...Command.flags, - dependency: flags.string({ - char: 'd', - description: 'Name of the dependency to show the logs from', - multiple: true + // dependency: flags.string({ + // char: 'd', + // description: 'Name of the dependency to show the logs from', + // multiple: true + // }), + events: flags.boolean({ + description: 'Don\'t display events', + allowNo: true, + default: true }), - 'no-events': flags.boolean({ - description: 'Remove events from the logs' - }), - 'no-results': flags.boolean({ - description: 'Remove results from the logs' + results: flags.boolean({ + description: 'Don\'t display results', + allowNo: true, + default: true }), event: flags.string({ - description: 'Filter specific events in the logs', - multiple: true + description: 'Only display a specific event' }), task: flags.string({ - description: 'Filter specific task results in the logs', - multiple: true + description: 'Only display a specific task results' + }), + tail: flags.integer({ + description: 'Output only specified number of lines', + default: -1 + }), + follow: flags.boolean({ + description: 'Continuously display logs', + allowNo: true, + default: true }) } static args = [{ - name: 'SERVICE', + name: 'INSTANCE_HASH', required: true, - description: 'Hash or Sid' }] - async run(): Promise> { - const {args, flags} = this.parse(ServiceLog) - const stream = this.mesg.api.ServiceLogs({ - serviceID: args.SERVICE, - dependencies: flags.dependency, - }) as Stream - stream.on('data', response => { - const dependency = response.dependency - this.log(chalk.yellow(dependency + ' | '), response.data.toString().replace('\n', '')) - }) - stream.on('error', (error: Error) => { - throw error + private readonly docker: Docker = new Docker(null) + + async run() { + const {args, flags} = this.parse(ServiceLogs) + + const dockerServices = await this.docker.service.list({ + filters: { + label: [`mesg.hash=${args.INSTANCE_HASH}`] + } }) + for (const service of dockerServices) { + const logs = (await service.logs({ + stderr: true, + stdout: true, + follow: flags.follow, + tail: flags.tail && flags.tail >= 0 ? flags.tail : 'all' + }) as any) + logs + .on('data', (buffer: Buffer) => parseLog(buffer).forEach(x => this.log(x))) + .on('error', (error: Error) => { throw error }) + } - if (!flags['no-results']) { - const tasks = flags.task || [] - this.mesg.api.ListenResult({serviceID: args.SERVICE}) - .on('data', (data: any) => { - if (tasks.length > 0 && !tasks.includes(data.taskKey)) return - this.log(this.formatResult(data)) - }) - .on('error', (error: Error) => { - throw error - }) + if (flags.results) { + this.api.execution.stream({ + filter: { + instanceHash: args.INSTANCE_HASH, + statuses: [ + ExecutionStatus.COMPLETED, + ExecutionStatus.FAILED, + ], + taskKey: flags.task + } + }) + .on('data', data => this.log(this.formatResult(data))) + .on('error', (error: Error) => { throw error }) } - if (!flags['no-events']) { - const events = flags.event || [] - this.mesg.api.ListenEvent({serviceID: args.SERVICE}) - .on('data', (data: any) => { - if (events.length > 0 && !events.includes(data.evenKey)) return - this.log(this.formatEvent(data)) - }) - .on('error', (error: Error) => { - throw error - }) + if (flags.events) { + this.api.event.stream({ + filter: { + instanceHash: args.INSTANCE_HASH, + key: flags.event, + } + }) + .on('data', (data: any) => this.log(this.formatEvent(data))) + .on('error', (error: Error) => { throw error }) } - return stream + // return stream } - formatEvent(event: any) { - return `EVENT[${event.eventKey}]: ` + chalk.gray(event.eventData) + formatEvent(event: Event) { + return `EVENT[${event.key}]: ` + chalk.gray(event.data) } - formatResult(result: any) { - if (result.error) { - return `RESULT[${result.taskKey}]: ` + chalk.red('ERROR:', result.error) + formatResult(execution: Execution) { + if (execution.error) { + return `RESULT[${execution.taskKey}]: ` + chalk.red('ERROR:', execution.error) } - return `RESULT[${result.taskKey}]: ` + chalk.gray(result.outputData) + return `RESULT[${execution.taskKey}]: ` + chalk.gray(execution.outputs || '') } } diff --git a/src/commands/service/newdeploy.ts b/src/commands/service/newdeploy.ts deleted file mode 100644 index 1421a12..0000000 --- a/src/commands/service/newdeploy.ts +++ /dev/null @@ -1,33 +0,0 @@ -import Command from '../../service-command' - -export default class ServiceDeployNew extends Command { - static description = 'Deploy a service' - - static flags = { - ...Command.flags, - } - - static args = [{ - name: 'SERVICE', - required: true, - description: 'Service\'s definition. Use service:compile first to build service definition' - }] - - static hidden = true - - async run(): Promise { - const {args} = this.parse(ServiceDeployNew) - this.spinner.start('Deploy service') - return new Promise((resolve, reject) => { - this.serviceAPI.Create({definition: JSON.parse(args.SERVICE)}, (err: any, resp: any) => { - if (err) { - reject(err) - this.spinner.stop(err) - return - } - this.spinner.stop(`${resp.sid} (${resp.hash})`) - resolve(resp.hash) - }) - }) - } -} diff --git a/src/commands/service/start.ts b/src/commands/service/start.ts index efc69fc..a643c30 100644 --- a/src/commands/service/start.ts +++ b/src/commands/service/start.ts @@ -1,28 +1,33 @@ -import Command from '../../service-command' +import {flags} from '@oclif/command' +import {InstanceCreateOutputs} from 'mesg-js/lib/api' + +import Command from '../../root-command' export default class ServiceStart extends Command { - static description = 'Start a service' + static description = 'Start a service by creating a new instance' static flags = { ...Command.flags, + env: flags.string({ + description: 'set env defined in mesg.yml (configuration.env)', + multiple: true, + helpValue: 'FOO=BAR' + }) } - static strict = false - static args = [{ - name: 'SERVICE', + name: 'SERVICE_HASH', required: true, - description: 'Hash or Sid' }] - async run(): Promise { - const {argv} = this.parse(ServiceStart) + async run(): InstanceCreateOutputs { + const {args, flags} = this.parse(ServiceStart) this.spinner.start('Start service') - for (const arg of argv) { - this.spinner.status = arg - await this.unaryCall('StartService', {serviceID: arg}) - } - this.spinner.stop(argv.join(', ')) - return argv + const instance = await this.api.instance.create({ + serviceHash: args.SERVICE_HASH, + env: flags.env + }) + this.spinner.stop(instance.hash) + return instance } } diff --git a/src/commands/service/stop.ts b/src/commands/service/stop.ts index 3f712e2..572d429 100644 --- a/src/commands/service/stop.ts +++ b/src/commands/service/stop.ts @@ -1,26 +1,37 @@ -import Command from '../../service-command' +import {flags} from '@oclif/command' +import cli from 'cli-ux' + +import Command from '../../root-command' export default class ServiceStop extends Command { - static description = 'Stop a service' + static description = 'Stop a service by deleting a specific instance' static flags = { ...Command.flags, + 'delete-data': flags.boolean({ + description: 'Delete instances\' persistent data', + default: false, + }), + confirm: flags.boolean({description: 'Confirm delete', default: false}) } static strict = false static args = [{ - name: 'SERVICE', + name: 'INSTANCE_HASH', required: true, - description: 'Hash or Sid' }] async run(): Promise { - const {argv} = this.parse(ServiceStop) - this.spinner.start('Stop service') - for (const arg of argv) { - this.spinner.status = arg - await this.unaryCall('StopService', {serviceID: arg}) + const {argv, flags} = this.parse(ServiceStop) + if (flags['delete-data']) { + cli.warn('This will delete all data associated to this instance') + } + if (!flags.confirm && !await cli.confirm('Are you sure?')) return [] + this.spinner.start('Delete instance') + for (const hash of argv) { + this.spinner.status = hash + await this.api.instance.delete({hash, deleteData: flags['delete-data']}) } this.spinner.stop(argv.join(', ')) return argv diff --git a/src/commands/service/validate.ts b/src/commands/service/validate.ts deleted file mode 100644 index 6e0f62d..0000000 --- a/src/commands/service/validate.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Command, {ServiceID} from '../../service-command' - -import ServiceDelete from './delete' -import ServiceDeploy from './deploy' - -export default class ServiceValidate extends Command { - static description = 'Validate a service file. Check the yml format and rules.' - - static flags = { - ...Command.flags, - ...ServiceDeploy.flags - } - - static args = [{ - name: 'SERVICE_PATH', - description: 'Path of the service', - default: './' - }] - - async run() { - const {args, flags} = this.parse(ServiceValidate) - this.spinner.start('Validate service') - const envs = (flags.env || []).reduce((prev, value) => [...prev, '--env', value], [] as string[]) - const services = (await ServiceDeploy.run([args.SERVICE_PATH, ...envs, '--silent'])) as ServiceID[] - const hashes = services.map(x => x.hash) - await ServiceDelete.run([...hashes, '--keep-data', '--confirm', '--silent']) - this.spinner.stop('service is valid') - } -} diff --git a/src/docker-command.ts b/src/docker-command.ts index dd69bc1..d985c66 100644 --- a/src/docker-command.ts +++ b/src/docker-command.ts @@ -132,11 +132,4 @@ export default abstract class extends Command { } }) } - - parseLog(buffer: Buffer): string[] { - return buffer.toString() - .split('\n') - .map(x => x.substring(8)) // Skip the 8 caracters that docker put in front of its logs - .filter(x => x) - } } diff --git a/src/marketplace-command.ts b/src/marketplace-command.ts index db1f894..5ab80fe 100644 --- a/src/marketplace-command.ts +++ b/src/marketplace-command.ts @@ -2,8 +2,8 @@ import {flags} from '@oclif/command' import {cli} from 'cli-ux' import {prompt} from 'inquirer' +import {WithoutPassphrase} from './account-command' import Command from './root-command' -import services from './services' export interface Manifest { version: 1 @@ -32,11 +32,17 @@ export default abstract class MarketplaceCommand extends Command { }) } + static SERVICE_NAME = 'Marketplace' + async sign(account: string, data: any, passphrase: string) { - const res = await this.executeAndCaptureError(services.account.id, services.account.tasks.sign, { - passphrase, - address: account, - transaction: data, + const res = await this.execute({ + instanceHash: await this.engineServiceInstance(WithoutPassphrase.SERVICE_NAME), + taskKey: 'sign', + inputs: JSON.stringify({ + passphrase, + address: account, + transaction: data, + }) }) return res.data } @@ -46,8 +52,14 @@ export default abstract class MarketplaceCommand extends Command { if (flags.account) { return flags.account } - const list = await this.executeAndCaptureError(services.account.id, services.account.tasks.list) - this.require(list.data.addresses.length > 0, 'You need to create an account first.') + const list = await this.execute({ + instanceHash: await this.engineServiceInstance(WithoutPassphrase.SERVICE_NAME), + taskKey: 'list', + inputs: JSON.stringify({}) + }) + if (!list.data.addresses.length) { + throw new Error('You need to create an account first.') + } if (list.data.addresses.length === 1) { return list.data.addresses[0] } @@ -56,7 +68,7 @@ export default abstract class MarketplaceCommand extends Command { name: 'account', message: 'Choose the account to use to publish your service', choices: list.data.addresses - })) as {account: string} + })) as { account: string } return account } diff --git a/src/protobuf/api/service.proto b/src/protobuf/api/service.proto deleted file mode 100644 index 9c44578..0000000 --- a/src/protobuf/api/service.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -import "protobuf/definition/service.proto"; - -package api; - -service ServiceX { - rpc Create (CreateServiceRequest) returns (CreateServiceResponse) {} -} - -message CreateServiceRequest { - definition.Service definition = 1; -} - -message CreateServiceResponse { - string sid = 1; - string hash = 2; -} diff --git a/src/protobuf/definition/service.proto b/src/protobuf/definition/service.proto deleted file mode 100644 index 470b1da..0000000 --- a/src/protobuf/definition/service.proto +++ /dev/null @@ -1,66 +0,0 @@ -syntax = "proto3"; - -package definition; -option go_package = "github.com/mesg-foundation/core/protobuf/definition"; - -// Service represents the service's definition. -message Service { - string hash = 10; // Service's hash. - string sid = 12; // Service's sid. - string name = 1; // Service's name. - string description = 2; // Service's description. - Configuration configuration = 8; // Configurations related to the service - repeated Task tasks = 5; // The list of tasks this service can execute. - repeated Event events = 6; // The list of events this service can emit. - repeated Dependency dependencies = 7; // The container dependencies this service requires. - string repository = 9; // Service's repository url. - string source = 13; // The hash id of service's source code on IPFS. -} - -// Events are emitted by the service whenever the service wants. -message Event { - string key = 4; // Event's key. - string name = 1; // Event's name. - string description = 2; // Event's description. - repeated Parameter data = 3; // List of data of this event. -} - -// Task is a function that requires inputs and returns output. -message Task { - string key = 8; // Task's key. - string name = 1; // Task's name. - string description = 2; // Task's description. - repeated Parameter inputs = 6; // List inputs of this task. - repeated Parameter outputs = 7; // List of tasks outputs. -} - -// Parameter describes the task's inputs, the task's outputs, and the event's data. -message Parameter { - string key = 8; // Parameter's key. - string name = 1; // Parameter's name. - string description = 2; // Parameter's description. - string type = 3; // Parameter's type: `String`, `Number`, `Boolean`, `Object` or `Any`. - bool optional = 4; // Set the parameter as optional. - bool repeated = 9; // Mark a parameter as an array of the defined type - repeated Parameter object = 10; // Optional object structure definition when type is set to `Object` -} - -message Configuration { - repeated string volumes = 1; // List of volumes. - repeated string volumesFrom = 2; // List of volumes mounted from other dependencies. - repeated string ports = 3; // List of ports the container exposes. - repeated string args = 4; // Args to pass to the container. - string command = 5; // Command to run the container. - repeated string env = 6; // Default env vars to apply to service's instance on runtime. -} - -// A dependency is a configuration of an other container that runs separately from the service. -message Dependency { - string key = 8; // Dependency's key. - string image = 1; // Image's name of the container. - repeated string volumes = 2; // List of volumes. - repeated string volumesFrom = 3; // List of volumes mounted from other dependencies. - repeated string ports = 4; // List of ports the container exposes. - repeated string args = 6; // Args to pass to the container. - string command = 5; // Command to run the container. -} diff --git a/src/root-command.ts b/src/root-command.ts index 674085b..f84490f 100644 --- a/src/root-command.ts +++ b/src/root-command.ts @@ -1,24 +1,11 @@ -import * as protoLoader from '@grpc/proto-loader' import {Command, flags} from '@oclif/command' +import {IConfig} from '@oclif/config' import {cli} from 'cli-ux' -import * as grpc from 'grpc' import {application} from 'mesg-js' -import {Application, EventData, Stream} from 'mesg-js/lib/application' -import {checkStreamReady, errNoStatus} from 'mesg-js/lib/util/grpc' -import {join} from 'path' +import createApi, {API, ExecutionCreateInputs, InfoOutputs} from 'mesg-js/lib/api' +import {Application} from 'mesg-js/lib/application' import {format, inspect} from 'util' -type UNARY_METHODS = 'DeleteService' - | 'GetService' - | 'ListServices' - | 'StartService' - | 'StopService' - | 'Info' - -export interface ExecutionResult { - data: any -} - export default abstract class extends Command { static flags = { help: flags.help({char: 'h'}), @@ -26,42 +13,23 @@ export default abstract class extends Command { silent: flags.boolean(), } - private _mesg: Application | null = null - private _serviceAPI: any + public api: API + private readonly _app: Application - get engineEndpoint(): string { + constructor(argv: string[], config: IConfig) { + super(argv, config) + const port = 50052 const host = process.env.DOCKER_HOST ? new URL(process.env.DOCKER_HOST).hostname : 'localhost' - return `${host}:50052` - } - - get mesg() { - if (!this._mesg) { - this._mesg = application({endpoint: this.engineEndpoint}) - } - return this._mesg - } - - get serviceAPI() { - if (!this._serviceAPI) { - this._serviceAPI = this.createClient('ServiceX', 'api', 'service.proto', this.engineEndpoint) - } - return this._serviceAPI - } - - createClient(serviceName: string, dir: string, file: string, endpoint: string) { - const packageDefinition = protoLoader.loadSync(join(__dirname, './protobuf', dir, file), { - includeDirs: [__dirname] - }) - const packageObject = grpc.loadPackageDefinition(packageDefinition) as any - const clientConstructor = packageObject[dir][serviceName] - return new clientConstructor(endpoint, grpc.credentials.createInsecure()) + const endpoint = `${host}:${port}` + this.api = createApi(endpoint) + this._app = application({endpoint}) } get spinner() { const {flags} = this.parse() - const nope = () => {} + const nope = () => { } if (flags.quiet) { return {start: nope, stop: (message?: string) => message ? this.log(message) : null, status: null} } @@ -71,12 +39,6 @@ export default abstract class extends Command { return cli.action } - require(condition: any, errorMessage: string) { - if (!condition) { - throw new Error(errorMessage) - } - } - log(message?: string, ...args: any[]): void { if (this.parse) { const {flags} = this.parse() @@ -94,53 +56,21 @@ export default abstract class extends Command { cli.styledJSON(data) } - async executeAndCaptureError(serviceID: string, taskKey: string, data: object = {}, tags: string[] = []): Promise { - this.debug(`Execute task ${taskKey} from ${serviceID} with ${JSON.stringify(data)}`) - try { - const result = await this.mesg.executeTaskAndWaitResult({ - serviceID, - taskKey, - inputData: JSON.stringify(data), - executionTags: [...tags, 'cli'] - }) - this.debug(`Receiving result of ${result.executionHash}, ${result.taskKey} => ${result.outputData}`) - if (result.error) { - throw new Error(result.error) - } - return { - data: JSON.parse(result.outputData) - } - } catch (e) { - this.error(e.message) - throw new Error(e.message) - } + async execute(request: ExecutionCreateInputs): Promise { + const exec = await this._app.executeTaskAndWaitResult(request) + return JSON.parse(exec.outputs || '') } - async unaryCall(method: UNARY_METHODS, data: object = {}): Promise { - this.debug(`Call MESG Engine API ${method} with ${JSON.stringify(data)}`) - return new Promise((resolve, reject) => this.mesg.api[method](data, (error: Error, res: any) => error - ? reject(error) - : resolve(res))) + async info(): InfoOutputs { + return this.api.core.info() } - listenEvent(serviceID: string, event: string): Stream { - this.debug(`Listening to events ${event} from ${serviceID}`) - const stream = this.mesg.listenEvent({ - eventFilter: event, - serviceID - }) - return stream - .on('error', (err: Error) => { - stream.cancel() - throw err - }) - .on('metadata', metadata => { - const err = checkStreamReady(metadata) - if (err === errNoStatus) return - if (err) { - stream.destroy(err) - return - } - }) + async engineServiceInstance(key: string) { + const info = await this.info() + const service = info.services.find((x: any) => x.key === key) + if (!service) { + throw new Error(`Cannot find service ${key}`) + } + return service.hash } } diff --git a/src/service-command.ts b/src/service-command.ts deleted file mode 100644 index 8421d5a..0000000 --- a/src/service-command.ts +++ /dev/null @@ -1,95 +0,0 @@ -import Command from './root-command' -import services from './services' - -export interface ServiceID { - sid: string - hash: string -} - -export interface Service { - definition: Definition - status: number -} - -export interface CompiledDefinition { - sid: string - name: string - description: string - tasks: Task[] - events: Event[] - dependencies: Dependency[] - configuration: Dependency - repository: string - source: string -} - -export interface Definition extends CompiledDefinition { - hash: string -} - -export interface Task { - key: string - name: string - description: string - inputs: Parameter[] - outputs: Parameter[] -} - -export interface Event { - key: string - name: string - description: string - data: Parameter[] -} - -export interface Dependency { - key: string - image: string - volumes: string[] - volumesFrom: string[] - ports: string[] - command: string - args: string[] - env: string[] -} - -export interface Parameter { - name: string - description: string - type: string - optional: boolean - repeated: boolean - object: Parameter[] -} - -export type SERVICE_PARAMETER_TYPE = 'String' | 'Number' | 'Boolean' | 'Object' | 'Any' - -export interface ServiceInfo { - sid: string - source: string - type: string -} - -export default abstract class extends Command { - static flags = { - ...Command.flags - } - - status(s: number) { - return ['unknown', 'stopped', 'starting', 'partial', 'running'][s] - } - - async getAuthorizedServiceInfo(id: string, versionHash: string): Promise { - const list = await this.executeAndCaptureError(services.account.id, services.account.tasks.list) - const {addresses} = list.data - this.require(addresses.length > 0, 'you have no accounts. please add an authorized account in order to deploy this service') - const res = await this.executeAndCaptureError(services.marketplace.id, services.marketplace.tasks.isAuthorized, { - id, - versionHash, - addresses - }) - const {authorized, sid, source, type} = res.data - this.require(authorized, 'you have no authorized accounts. please add an authorized account in order to deploy this service') - return {sid, source, type} - } -} diff --git a/src/services.ts b/src/services.ts deleted file mode 100644 index f618949..0000000 --- a/src/services.ts +++ /dev/null @@ -1,26 +0,0 @@ -export default { - account: { - id: 'ethwallet', - tasks: { - create: 'create', - delete: 'delete', - export: 'export', - import: 'import', - importPK: 'importFromPrivateKey', - list: 'list', - sign: 'sign', - } - }, - marketplace: { - id: 'marketplace', - tasks: { - prepareCreateVersion: 'preparePublishServiceVersion', - publishCreateVersion: 'publishPublishServiceVersion', - preparePurchase: 'preparePurchase', - publishPurchase: 'publishPurchase', - prepareCreateOffer: 'prepareCreateServiceOffer', - publishCreateOffer: 'publishCreateServiceOffer', - isAuthorized: 'isAuthorized', - } - } -} diff --git a/src/deployer.ts b/src/utils/deployer.ts similarity index 71% rename from src/deployer.ts rename to src/utils/deployer.ts index a6f2bff..ea2f102 100644 --- a/src/deployer.ts +++ b/src/utils/deployer.ts @@ -1,9 +1,12 @@ -import {lstatSync, readdirSync} from 'fs' +import {existsSync, lstatSync, readdirSync, readFileSync} from 'fs' import {fromUrl} from 'hosted-git-info' +import ignore from 'ignore' import isGitUrl from 'is-git-url' import {tmpdir} from 'os' import {join} from 'path' import {sync as rimraf} from 'rimraf' +import {Readable} from 'stream' +import tar from 'tar' import {v4 as uuid} from 'uuid' import {isURL} from 'validator' @@ -45,6 +48,24 @@ const preprocessPath = (path: string): string => { return path } +export const createTar = (path: string): Readable => { + const mesgignore = join(path, '.mesgignore') + const ig = ignore().add([ + '.git', + ...(existsSync(mesgignore) ? readFileSync(mesgignore).toString().split('\n') : []) + ]) + return tar.create({ + cwd: path, + filter: ig.createFilter(), + strict: true, + gzip: true, + portable: true, + }, readdirSync(path)) + .on('error', (error: Error) => { + throw error + }) +} + export default async (pathOrUrl: string): Promise => { if (isGitUrl(pathOrUrl) || isURL(pathOrUrl)) { return preprocessPath(await downloadSrc(pathOrUrl)) diff --git a/src/utils/docker.ts b/src/utils/docker.ts new file mode 100644 index 0000000..45ef5bf --- /dev/null +++ b/src/utils/docker.ts @@ -0,0 +1,6 @@ +export const parseLog = (buffer: Buffer): string[] => { + return buffer.toString() + .split('\n') + .map(x => x.substring(8)) // Skip the 8 characters that docker put in front of its logs + .filter(x => x) +} diff --git a/src/version.ts b/src/version.ts index bbe4bfd..7e3b514 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,3 +1,3 @@ export default { engine: 'v0.10.1' -} \ No newline at end of file +}