diff --git a/.snyk b/.snyk index 0b4505c..9355a89 100644 --- a/.snyk +++ b/.snyk @@ -6,3 +6,5 @@ patch: SNYK-JS-LODASH-567746: - winston > async > lodash: patched: '2020-04-30T17:10:55.970Z' + - '@a2r/telemetry > winston > async > lodash': + patched: '2020-05-04T17:21:45.941Z' diff --git a/index.ts b/index.ts index b80e624..c54fe06 100644 --- a/index.ts +++ b/index.ts @@ -1,10 +1,10 @@ import path from 'path'; import chokidar from 'chokidar'; -import { targetPath, runtimePath } from './settings'; +import { targetPath, proxyPath } from './settings'; import initWatchers from './utils/initWatchers'; import { ensureDir } from './tools/fs'; -import isJest from './tools/isJest'; +import { isJest } from './tools/isJest'; /** * API Watcher process @@ -16,7 +16,7 @@ interface Process { const pendingProcesses: Process[] = []; const serverPath = path.resolve(__dirname, targetPath); -const runtimeDestPath = path.resolve(__dirname, runtimePath); +const proxyDestPath = path.resolve(__dirname, proxyPath); let runningProcess: 'start' | 'stop' = null; @@ -93,7 +93,7 @@ export const restart = start; * Inits API Watcher by ensuring destination path and running start process */ const init = async (): Promise => { - await ensureDir(runtimeDestPath); + await ensureDir(proxyDestPath); await start(); }; diff --git a/model/api.ts b/model/api.ts new file mode 100644 index 0000000..5a6757a --- /dev/null +++ b/model/api.ts @@ -0,0 +1,181 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import ts from 'typescript'; + +/** + * For typescript nodes casting as docs container purposes + */ +export interface JSDocContainer { + /** + * Optional JSDoc array + * @type {ts.JSDoc[]} + * @memberof JSDocContainer + */ + jsDoc?: ts.JSDoc[]; +} + +/** + * Information regarding the return type of a function extracted using AST + */ +export interface ReturnTypeInfo { + /** + * Return identifier + * @type {string} + * @memberof CompilerFileInfo + */ + identifier: string; + /** + * Return type + * @type {string} + * @memberof CompilerFileInfo + */ + type: string; + /** + * Return type + * @type {string} + * @memberof CompilerFileInfo + */ + typeNode: ts.TypeNode | null; +} + +/** + * Model imports information + */ +export interface ModelImport { + /** + * Import clause + */ + clause: ts.ImportClause; + /** + * Path to import from + */ + path: string; + /** + * Related source file + */ + sourceFile?: ts.SourceFile; +} + +/** + * Model imports information + */ +export interface GroupedModelImports { + /** + * Default import + */ + def?: string; + /** + * Named imports + */ + named?: string[]; + /** + * Path to import from + */ + path: string; +} + +/** + * API module info + */ +export interface ModuleInfo { + /** + * Main method node + * @memberof ModuleInfo + */ + mainMethodNode: ts.FunctionDeclaration | ts.ArrowFunction; + /** + * Main method name + * @memberof ModuleInfo + */ + mainMethodName: string; + /** + * Main method parameters nodes + * @type {ts.ParameterDeclaration[]} + * @memberof ModuleInfo + */ + mainMethodParamNodes: ts.ParameterDeclaration[]; + /** + * Main method JSDoc node + * @type {JSDocContainer} + * @memberof ModuleInfo + */ + mainMethodDocs: JSDocContainer; + /** + * Main method return type info + * @type {ReturnTypeInfo} + * @memberof ModuleInfo + */ + mainMethodReturnTypeInfo: Required; + /** + * Module model imports + */ + modelImports: ModelImport[]; + /** + * Keys based on file path (for proxy API object) + */ + keys: string[]; +} + +/** + * API Method in Client API structure + */ +export interface ApiMethod { + /** + * Property key + * @type {string} + * @memberof ApiMethod + */ + key: string; + /** + * Method name + * @type {string} + * @memberof ApiMethod + */ + methodName: string; +} + +/** + * API Namespace in proxy API structure + */ +export interface ApiNamespace { + /** + * Property key + * @type {string} + * @memberof ApiNamespace + */ + key: string; + /** + * Namespaces for property (object sub-objects) + * @type {ApiNamespace[]} + * @memberof ApiNamespace + */ + namespaces: ApiNamespace[]; + /** + * Methods for property (object methods) + * @type {ApiMethod[]} + * @memberof ApiNamespace + */ + methods: ApiMethod[]; +} + +/** + * API module + */ +export interface APIModule { + /** + * Module default export. Must be a `function` and return a `Promise`. Should contain a method to be called from client + * @memberof APIModule + */ + default: (...args: any[]) => Promise; + /** + * Module dispose method. Optional. Will be called when a module is disposed or updated. + * @memberof APIModule + */ + dispose?: () => Promise; +} + +/** + * API levels structure + */ +export interface APIStructure { + [id: string]: APIModule; +} \ No newline at end of file diff --git a/model/sockets.ts b/model/sockets.ts new file mode 100644 index 0000000..b460f72 --- /dev/null +++ b/model/sockets.ts @@ -0,0 +1,76 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import io from 'socket.io'; +import { ParsedUrlQuery } from 'querystring'; + +/** + * Socket basic call + */ +export interface SocketCall { + /** + * Unique ID for socket transmission + * @memberof SocketCall + */ + id: string; +} + +/** + * Socket method call + */ +export interface MethodCall extends SocketCall { + /** + * API Method name corresponding to complete key (like 'users.login') + * @memberof MethodCall + */ + method: string; + /** + * Params for API Method + * @memberof MethodCall + */ + params: any[]; +}; + +/** + * Socket data provider call + */ +export interface DataProviderCall extends SocketCall { + /** + * Page pathname (from Next.js router) + * @memberof DataProviderCall + */ + pathname: string; + /** + * Parsed url query + * @memberof DataProviderCall + */ + query: ParsedUrlQuery; +} + +/** + * Socket standard response + */ +export interface SocketMessage { + /** + * Operation was ok (0) or not (1) + * @memberof SocketMessage + */ + o: number; + /** + * Operation error (if any) + * @memberof SocketMessage + */ + e?: string; + /** + * Operation stack (if error) + * @memberof SocketMessage + */ + s?: string; + /** + * Operation return data + * @memberof SocketMessage + */ + d: any; +}; + +export interface A2RSocket extends io.Socket { + sessionId: string; +}; diff --git a/model/watcher.ts b/model/watcher.ts index 51edd1a..3bd3667 100644 --- a/model/watcher.ts +++ b/model/watcher.ts @@ -46,6 +46,11 @@ export type OnReady = ( targetPath: string, ) => void | Promise; +/** + * On Validation method + */ +export type OnValidation = (serverPath?: string, targetPath?: string) => Promise | void; + /** * Watcher options */ diff --git a/package-lock.json b/package-lock.json index 64a1d8e..7a13c72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "api-watcher", - "version": "0.0.4", + "version": "0.0.5", "lockfileVersion": 1, "requires": true, "dependencies": { "@a2r/telemetry": { - "version": "1.0.30", - "resolved": "https://registry.npmjs.org/@a2r/telemetry/-/telemetry-1.0.30.tgz", - "integrity": "sha512-T6dxal2voNUGkpRoXtyZaoRVGCl8+ADGnNhZRqsLlMQFbkdt2JYR4BSFj0RMdZBenHJPTPKWGHfC+7a2m6S17g==", + "version": "1.0.29", + "resolved": "https://registry.npmjs.org/@a2r/telemetry/-/telemetry-1.0.29.tgz", + "integrity": "sha512-ZLVt4ppk/XG959wo9IczRMRTxeO95+M+87j/Zshlfiry/0baPQQ9HLv7LOd3IIQAL2x89z8EkiMSftJXW9jH2A==", "requires": { "chalk": "^4.0.0", "winston": "^3.2.1" @@ -979,7 +979,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.6.0.tgz", "integrity": "sha512-jtk0gf80v4mFyDqaQNokD8GOPMTXpIUL35ewg6jtmuZw41xt56WF9kqCjiiViSRRRYA0RK+RuiVfmJA5pxvMUQ==", - "dev": true, "requires": { "@snyk/graphlib": "2.1.9-patch", "tslib": "^1.9.3" @@ -989,7 +988,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@snyk/cocoapods-lockfile-parser/-/cocoapods-lockfile-parser-3.2.0.tgz", "integrity": "sha512-DyFqZudOlGXHBOVneLnQnyQ97xZLq+PTF9PhWOmrEzH/tKcLyXhdW/WmDPVNJVyNvogyRZ4cXIj487xy/EeZEw==", - "dev": true, "requires": { "@snyk/dep-graph": "1.18.2", "@snyk/ruby-semver": "^2.0.4", @@ -1003,8 +1001,7 @@ "core-js": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", - "dev": true + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" } } }, @@ -1012,7 +1009,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@snyk/composer-lockfile-parser/-/composer-lockfile-parser-1.4.0.tgz", "integrity": "sha512-ga4YTRjJUuP0Ufr+t1IucwVjEFAv66JSBB/zVHP2zy/jmfA3l3ZjlGQSjsRC6Me9P2Z0esQ83AYNZvmIf9pq2w==", - "dev": true, "requires": { "@snyk/lodash": "^4.17.15-patch" } @@ -1021,7 +1017,6 @@ "version": "3.2.0-rc1", "resolved": "https://registry.npmjs.org/@snyk/configstore/-/configstore-3.2.0-rc1.tgz", "integrity": "sha512-CV3QggFY8BY3u8PdSSlUGLibqbqCG1zJRmGM2DhnhcxQDRRPTGTP//l7vJphOVsUP1Oe23+UQsj7KRWpRUZiqg==", - "dev": true, "requires": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -1035,7 +1030,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, "requires": { "pify": "^3.0.0" } @@ -1043,14 +1037,12 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -1063,7 +1055,6 @@ "version": "1.18.2", "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.18.2.tgz", "integrity": "sha512-v7tIiCH4LmYOSc0xGHKSxSZ2PEDv8zDlYU7ZKSH+1Hk8Qvj3YYEFvtV1iFBHUEQFUen4kQA6lWxlwF8chsNw+w==", - "dev": true, "requires": { "@snyk/graphlib": "2.1.9-patch", "@snyk/lodash": "4.17.15-patch", @@ -1077,22 +1068,19 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@snyk/gemfile": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@snyk/gemfile/-/gemfile-1.2.0.tgz", - "integrity": "sha512-nI7ELxukf7pT4/VraL4iabtNNMz8mUo7EXlqCFld8O5z6mIMLX9llps24iPpaIZOwArkY3FWA+4t+ixyvtTSIA==", - "dev": true + "integrity": "sha512-nI7ELxukf7pT4/VraL4iabtNNMz8mUo7EXlqCFld8O5z6mIMLX9llps24iPpaIZOwArkY3FWA+4t+ixyvtTSIA==" }, "@snyk/graphlib": { "version": "2.1.9-patch", "resolved": "https://registry.npmjs.org/@snyk/graphlib/-/graphlib-2.1.9-patch.tgz", "integrity": "sha512-uFO/pNMm3pN15QB+hVMU7uaQXhsBNwEA8lOET/VDcdOzLptODhXzkJqSHqt0tZlpdAz6/6Uaj8jY00UvPFgFMA==", - "dev": true, "requires": { "@snyk/lodash": "4.17.15-patch" } @@ -1101,7 +1089,6 @@ "version": "6.2.2-patch", "resolved": "https://registry.npmjs.org/@snyk/inquirer/-/inquirer-6.2.2-patch.tgz", "integrity": "sha512-IUq5bHRL0vtVKtfvd4GOccAIaLYHbcertug2UVZzk5+yY6R/CxfYsnFUTho1h4BdkfNdin2tPjE/5jRF4SKSrw==", - "dev": true, "requires": { "@snyk/lodash": "4.17.15-patch", "ansi-escapes": "^3.2.0", @@ -1121,20 +1108,17 @@ "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1143,7 +1127,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1154,7 +1137,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, "requires": { "restore-cursor": "^2.0.0" } @@ -1163,7 +1145,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -1171,14 +1152,12 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } @@ -1186,26 +1165,22 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, "requires": { "mimic-fn": "^1.0.0" } @@ -1214,7 +1189,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -1224,7 +1198,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -1234,7 +1207,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -1245,7 +1217,6 @@ "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" }, @@ -1253,8 +1224,7 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" } } }, @@ -1262,7 +1232,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -1273,7 +1242,6 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.8.0.tgz", "integrity": "sha512-dD7hVdEKMMU9CP0jQLm6Q1+l6506rjW0dqQflJ3QOVohNzptYJtTv9pHKzgRu5+q/fgEc35oYi02A0WIQwSvpw==", - "dev": true, "requires": { "@snyk/graphlib": "2.1.9-patch", "@snyk/lodash": "4.17.15-patch", @@ -1287,19 +1255,24 @@ "source-map-support": "^0.5.7", "temp-dir": "^2.0.0", "tslib": "^1.9.3" + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + } } }, "@snyk/lodash": { "version": "4.17.15-patch", "resolved": "https://registry.npmjs.org/@snyk/lodash/-/lodash-4.17.15-patch.tgz", - "integrity": "sha512-e4+t34bGyjjRnwXwI14hqye9J/nRbG9iwaqTgXWHskm5qC+iK0UrjgYdWXiHJCf3Plbpr+1rpW+4LPzZnCGMhQ==", - "dev": true + "integrity": "sha512-e4+t34bGyjjRnwXwI14hqye9J/nRbG9iwaqTgXWHskm5qC+iK0UrjgYdWXiHJCf3Plbpr+1rpW+4LPzZnCGMhQ==" }, "@snyk/rpm-parser": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@snyk/rpm-parser/-/rpm-parser-1.1.0.tgz", "integrity": "sha512-+DyCagvnpyBjwYTxaPMQGLW4rkpKAw1Jrh8YbZCg7Ix172InBxdve/0zud18Lu2H6xWtDDdMvRDdfl82wlTBvA==", - "dev": true, "requires": { "event-loop-spinner": "1.1.0", "typescript": "3.8.3" @@ -1309,7 +1282,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@snyk/ruby-semver/-/ruby-semver-2.2.0.tgz", "integrity": "sha512-FqUayoVjcyCsQFYPm3DcaCKdFR4xmapUkCGY+bcNBs3jqCUw687PoP9CPQ1Jvtaw5YpfBNl/62jyntsWCeciuA==", - "dev": true, "requires": { "@snyk/lodash": "4.17.15-patch" } @@ -1318,7 +1290,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@snyk/snyk-cocoapods-plugin/-/snyk-cocoapods-plugin-2.2.0.tgz", "integrity": "sha512-Ux7hXKawbk30niGBToGkKqHyKzhT3E7sCl0FNkPkHaaGZwPwhFCDyNFxBd4uGgWiQ+kT+RjtH5ahna+bSP69Yg==", - "dev": true, "requires": { "@snyk/cli-interface": "1.5.0", "@snyk/cocoapods-lockfile-parser": "3.2.0", @@ -1331,7 +1302,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-1.5.0.tgz", "integrity": "sha512-+Qo+IO3YOXWgazlo+CKxOuWFLQQdaNCJ9cSfhFQd687/FuesaIxWdInaAdfpsLScq0c6M1ieZslXgiZELSzxbg==", - "dev": true, "requires": { "tslib": "^1.9.3" } @@ -1342,7 +1312,6 @@ "version": "2.5.1-rc2", "resolved": "https://registry.npmjs.org/@snyk/update-notifier/-/update-notifier-2.5.1-rc2.tgz", "integrity": "sha512-dlled3mfpnAt3cQb5hxkFiqfPCj4Yk0xV8Yl5P8PeVv1pUmO7vI4Ka4Mjs4r6CYM5f9kZhviFPQQcWOIDlMRcw==", - "dev": true, "requires": { "@snyk/configstore": "3.2.0-rc1", "boxen": "^1.3.0", @@ -1360,7 +1329,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1369,24 +1337,16 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -1394,20 +1354,17 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "is-ci": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, "requires": { "ci-info": "^1.5.0" } @@ -1416,7 +1373,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -1427,7 +1383,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/agent-base/-/agent-base-4.2.0.tgz", "integrity": "sha512-8mrhPstU+ZX0Ugya8tl5DsDZ1I5ZwQzbL/8PA0z8Gj0k9nql7nkaMzmPVLj+l/nixWaliXi+EBiLA8bptw3z7Q==", - "dev": true, "requires": { "@types/events": "*", "@types/node": "*" @@ -1497,8 +1452,7 @@ "@types/debug": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", - "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", - "dev": true + "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==" }, "@types/eslint-visitor-keys": { "version": "1.0.0", @@ -1509,8 +1463,7 @@ "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, "@types/glob": { "version": "7.1.1", @@ -1570,8 +1523,7 @@ "@types/js-yaml": { "version": "3.12.3", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.3.tgz", - "integrity": "sha512-otRe77JNNWzoVGLKw8TCspKswRoQToys4tuL6XYVBFxjgeM0RUrx7m3jkaTdxILxeGry3zM8mGYkGXMeQ02guA==", - "dev": true + "integrity": "sha512-otRe77JNNWzoVGLKw8TCspKswRoQToys4tuL6XYVBFxjgeM0RUrx7m3jkaTdxILxeGry3zM8mGYkGXMeQ02guA==" }, "@types/json-schema": { "version": "7.0.4", @@ -1586,10 +1538,9 @@ "dev": true }, "@types/node": { - "version": "13.13.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz", - "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==", - "dev": true + "version": "13.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", + "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -1616,8 +1567,7 @@ "@types/semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", - "dev": true + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" }, "@types/stack-utils": { "version": "1.0.1", @@ -1641,7 +1591,6 @@ "version": "0.4.5", "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.5.tgz", "integrity": "sha512-yohU3zMn0fkhlape1nxXG2bLEGZRc1FeqF80RoHaYXJN7uibaauXfhzhOJr1Xh36sn+/tx21QAOf07b/xYVk1w==", - "dev": true, "requires": { "@types/node": "*" } @@ -1742,8 +1691,7 @@ "@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" }, "abab": { "version": "2.0.3", @@ -1754,8 +1702,16 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } }, "acorn": { "version": "3.3.0", @@ -1792,11 +1748,15 @@ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, "requires": { "es6-promisify": "^5.0.0" } @@ -1839,7 +1799,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", - "dev": true, "requires": { "string-width": "^2.0.0" }, @@ -1847,14 +1806,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -1864,7 +1821,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -1906,8 +1862,7 @@ "ansicolors": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", - "dev": true + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" }, "anymatch": { "version": "3.1.1", @@ -1921,8 +1876,7 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" }, "arg": { "version": "4.1.3", @@ -1934,7 +1888,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -2006,11 +1959,15 @@ "es-abstract": "^1.17.0-next.1" } }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, "asn1": { "version": "0.2.4", @@ -2036,8 +1993,7 @@ "ast-types": { "version": "0.12.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.12.4.tgz", - "integrity": "sha512-ky/YVYCbtVAS8TdMIaTiPFHwEpRB5z1hctepJplTr3UW5q8TDrpIMCILyk8pmLxGtn2KCtC/lSn7zOsaI7nzDw==", - "dev": true + "integrity": "sha512-ky/YVYCbtVAS8TdMIaTiPFHwEpRB5z1hctepJplTr3UW5q8TDrpIMCILyk8pmLxGtn2KCtC/lSn7zOsaI7nzDw==" }, "ast-types-flow": { "version": "0.0.7", @@ -2059,6 +2015,11 @@ "lodash": "^4.17.14" } }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2231,6 +2192,11 @@ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2291,11 +2257,20 @@ } } }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -2306,6 +2281,14 @@ "tweetnacl": "^0.14.3" } }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, "better-docs": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/better-docs/-/better-docs-2.0.1.tgz", @@ -2331,13 +2314,17 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -2348,7 +2335,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, "requires": { "ansi-align": "^2.0.0", "camelcase": "^4.0.0", @@ -2362,14 +2348,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -2377,14 +2361,12 @@ "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -2395,7 +2377,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -2403,20 +2384,17 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -2426,7 +2404,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -2435,7 +2412,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -2510,7 +2486,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -2519,14 +2494,12 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, "cache-base": { "version": "1.0.1", @@ -2545,6 +2518,11 @@ "unset-value": "^1.0.0" } }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2587,8 +2565,7 @@ "capture-stack-trace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", - "dev": true + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==" }, "caseless": { "version": "0.12.0", @@ -2636,8 +2613,7 @@ "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "chokidar": { "version": "3.4.0", @@ -2655,10 +2631,9 @@ } }, "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" }, "class-utils": { "version": "0.3.6", @@ -2695,8 +2670,7 @@ "cli-boxes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" }, "cli-cursor": { "version": "3.1.0", @@ -2710,14 +2684,12 @@ "cli-spinner": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/cli-spinner/-/cli-spinner-0.2.10.tgz", - "integrity": "sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==", - "dev": true + "integrity": "sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==" }, "cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" }, "cliui": { "version": "2.1.0", @@ -2733,14 +2705,12 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collect-v8-coverage": { "version": "1.0.1", @@ -2838,12 +2808,22 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2882,6 +2862,11 @@ "safe-buffer": "~5.1.1" } }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -2922,7 +2907,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, "requires": { "capture-stack-trace": "^1.0.0" } @@ -2931,7 +2915,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -2943,8 +2926,7 @@ "crypto-random-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" }, "cssom": { "version": "0.4.4", @@ -2996,8 +2978,7 @@ "data-uri-to-buffer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", - "dev": true + "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" }, "data-urls": { "version": "1.1.0", @@ -3044,7 +3025,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -3052,8 +3032,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", @@ -3064,14 +3043,12 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "deepmerge": { "version": "4.2.2", @@ -3133,7 +3110,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", - "dev": true, "requires": { "ast-types": "0.x.x", "escodegen": "1.x.x", @@ -3143,8 +3119,7 @@ "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" } } }, @@ -3157,8 +3132,7 @@ "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, "detect-newline": { "version": "3.1.0", @@ -3179,8 +3153,7 @@ "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, "diff-match-patch": { "version": "1.0.4", @@ -3198,7 +3171,6 @@ "version": "0.0.19", "resolved": "https://registry.npmjs.org/dockerfile-ast/-/dockerfile-ast-0.0.19.tgz", "integrity": "sha512-iDRNFeAB2j4rh/Ecc2gh3fjciVifCMsszfCfHlYF5Wv8yybjZLiRDZUBt/pS3xrAz8uWT8fCHLq4pOQMmwCDwA==", - "dev": true, "requires": { "vscode-languageserver-types": "^3.5.0" } @@ -3231,7 +3203,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "dev": true, "requires": { "is-obj": "^2.0.0" } @@ -3240,7 +3211,6 @@ "version": "4.10.0", "resolved": "https://registry.npmjs.org/dotnet-deps-parser/-/dotnet-deps-parser-4.10.0.tgz", "integrity": "sha512-dEO1oTvreaDCtcvhRdOmmAMubyC+MWqVr1c/1Wvasi+NW4NZeB67qGh1taqowUFh+aCXtPw3SP2eExn6aNkhwA==", - "dev": true, "requires": { "@snyk/lodash": "4.17.15-patch", "@types/xml2js": "0.4.5", @@ -3252,8 +3222,7 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "dynamic-dedupe": { "version": "0.3.0", @@ -3277,14 +3246,12 @@ "email-validator": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/email-validator/-/email-validator-2.0.4.tgz", - "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==", - "dev": true + "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==" }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "enabled": { "version": "1.0.2", @@ -3298,11 +3265,68 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } }, + "engine.io": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.1.tgz", + "integrity": "sha512-8MfIfF1/IIfxuc2gv5K+XlFZczw/BpTvqBdl0E2fBLkYQp4miv4LuDTVtYt4yMyaIFLEr4vtaSgV4mjvll8Crw==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "0.3.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" + } + }, + "engine.io-client": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.1.tgz", + "integrity": "sha512-RJNmA+A9Js+8Aoq815xpGAsgWH1VoSYM//2VgIiu9lNOaHFfLpTjH4tOzktBpjIs5lvOfiNY1dwf+NuU6D38Mw==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, "entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", @@ -3356,14 +3380,12 @@ "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, "requires": { "es6-promise": "^4.0.3" } @@ -3371,14 +3393,12 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", - "dev": true, "requires": { "esprima": "^4.0.1", "estraverse": "^4.2.0", @@ -3753,8 +3773,7 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.3.1", @@ -3785,20 +3804,17 @@ "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "event-loop-spinner": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-1.1.0.tgz", "integrity": "sha512-YVFs6dPpZIgH665kKckDktEVvSBccSYJmoZUfhNUdv5d3Xv+Q+SKF4Xis1jolq9aBzuW1ZZhQh/m/zU/TPdDhw==", - "dev": true, "requires": { "tslib": "^1.10.0" } @@ -3810,18 +3826,29 @@ "dev": true }, "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } } }, "exit": { @@ -3921,8 +3948,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", @@ -3949,7 +3975,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -4042,8 +4067,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fast-safe-stringify": { "version": "2.0.7", @@ -4085,8 +4109,7 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "filewatcher": { "version": "3.0.1", @@ -4177,8 +4200,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs.realpath": { "version": "1.0.0", @@ -4195,7 +4217,6 @@ "version": "0.3.10", "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "dev": true, "requires": { "readable-stream": "1.1.x", "xregexp": "2.0.0" @@ -4204,14 +4225,12 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -4222,14 +4241,12 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", - "dev": true + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" } } }, @@ -4264,19 +4281,14 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, "get-uri": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.4.tgz", "integrity": "sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==", - "dev": true, "requires": { "data-uri-to-buffer": "1", "debug": "2", @@ -4290,7 +4302,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -4298,14 +4309,12 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4320,7 +4329,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -4346,7 +4354,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.1.tgz", "integrity": "sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw==", - "dev": true, "requires": { "is-ssh": "^1.3.0", "parse-url": "^5.0.0" @@ -4356,7 +4363,6 @@ "version": "11.1.2", "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.1.2.tgz", "integrity": "sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ==", - "dev": true, "requires": { "git-up": "^4.0.0" } @@ -4386,7 +4392,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", - "dev": true, "requires": { "ini": "^1.3.4" } @@ -4401,7 +4406,6 @@ "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "dev": true, "requires": { "create-error-class": "^3.0.0", "duplexer3": "^0.1.4", @@ -4414,21 +4418,12 @@ "timed-out": "^4.0.0", "unzip-response": "^2.0.1", "url-parse-lax": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } } }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "growly": { "version": "1.3.0", @@ -4461,6 +4456,26 @@ "function-bind": "^1.1.1" } }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4539,8 +4554,7 @@ "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" }, "html-encoding-sniffer": { "version": "1.0.2", @@ -4561,7 +4575,6 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.4", @@ -4574,7 +4587,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, "requires": { "agent-base": "4", "debug": "3.1.0" @@ -4584,7 +4596,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -4592,8 +4603,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -4612,7 +4622,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", - "dev": true, "requires": { "agent-base": "^4.3.0", "debug": "^3.1.0" @@ -4622,7 +4631,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -4639,7 +4647,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -4647,8 +4654,7 @@ "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "ignore": { "version": "4.0.6", @@ -4659,8 +4665,7 @@ "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, "import-fresh": { "version": "3.2.1", @@ -4675,8 +4680,7 @@ "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" }, "import-local": { "version": "3.0.2", @@ -4751,8 +4755,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "indent-string": { "version": "2.1.0", @@ -4763,6 +4766,11 @@ "repeating": "^2.0.0" } }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4780,8 +4788,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { "version": "7.1.0", @@ -4854,14 +4861,12 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "ip-regex": { "version": "2.1.0", @@ -4922,8 +4927,16 @@ "dev": true, "requires": { "ci-info": "^2.0.0" - } - }, + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + } + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -4972,8 +4985,7 @@ "is-docker": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", - "dev": true + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==" }, "is-expression": { "version": "3.0.0", @@ -5013,8 +5025,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-generator-fn": { "version": "2.1.0", @@ -5034,7 +5045,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", - "dev": true, "requires": { "global-dirs": "^0.1.0", "is-path-inside": "^1.0.0" @@ -5043,8 +5053,7 @@ "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" }, "is-number": { "version": "7.0.0", @@ -5054,14 +5063,12 @@ "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, "is-path-inside": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, "requires": { "path-is-inside": "^1.0.1" } @@ -5084,8 +5091,7 @@ "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" }, "is-regex": { "version": "1.0.5", @@ -5099,14 +5105,12 @@ "is-retry-allowed": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" }, "is-ssh": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz", "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==", - "dev": true, "requires": { "protocols": "^1.1.0" } @@ -5163,8 +5167,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -5775,18 +5778,16 @@ "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^15.0.0", "chalk": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "graceful-fs": { @@ -6710,7 +6711,6 @@ "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -6914,7 +6914,6 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.4.0.tgz", "integrity": "sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==", - "dev": true, "requires": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -6926,7 +6925,6 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6941,7 +6939,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6981,7 +6978,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", - "dev": true, "requires": { "package-json": "^4.0.0" } @@ -6996,7 +6992,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, "requires": { "invert-kv": "^1.0.0" } @@ -7017,7 +7012,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -7027,7 +7021,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, "requires": { "immediate": "~3.0.5" } @@ -7077,38 +7070,32 @@ "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" }, "lodash.assignin": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", - "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", - "dev": true + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" }, "lodash.clone": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" }, "lodash.isequal": { "version": "4.5.0", @@ -7125,8 +7112,7 @@ "lodash.set": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true + "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" }, "lodash.sortby": { "version": "4.7.0", @@ -7189,14 +7175,12 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, "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" @@ -7205,8 +7189,7 @@ "macos-release": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", - "dev": true + "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" }, "make-dir": { "version": "3.1.0", @@ -7404,14 +7387,12 @@ "mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { "version": "2.1.27", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dev": true, "requires": { "mime-db": "1.44.0" } @@ -7433,8 +7414,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "mixin-deep": { "version": "1.3.2", @@ -7506,7 +7486,6 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.10.0.tgz", "integrity": "sha512-fKiXMQrpP7CYWJQzKkPPx9hPgmq+YLDyxcG9N8RpiE9FoCkCbzD0NyW0YhE3xn3Aupe7nnDeIx4PFzYehpHT9Q==", - "dev": true, "requires": { "async": "^1.4.0", "ini": "^1.3.0", @@ -7517,26 +7496,22 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -7547,7 +7522,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7556,7 +7530,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7567,7 +7540,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7575,14 +7547,12 @@ "window-size": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -7591,14 +7561,12 @@ "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yargs": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, "requires": { "camelcase": "^2.0.1", "cliui": "^3.0.3", @@ -7615,7 +7583,6 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.1.tgz", "integrity": "sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==", - "dev": true, "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -7626,24 +7593,26 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } } } }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, "netmask": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", - "dev": true + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=" }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-dir": { "version": "0.1.17", @@ -7699,14 +7668,12 @@ "normalize-url": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, "requires": { "path-key": "^2.0.0" } @@ -7714,8 +7681,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nwsapi": { "version": "2.2.0", @@ -7735,6 +7701,11 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -7769,8 +7740,7 @@ "object-hash": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", - "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", - "dev": true + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" }, "object-inspect": { "version": "1.7.0", @@ -7876,7 +7846,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/open/-/open-7.0.3.tgz", "integrity": "sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA==", - "dev": true, "requires": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -7886,7 +7855,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, "requires": { "is-docker": "^2.0.0" } @@ -7897,7 +7865,6 @@ "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -7911,7 +7878,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, "requires": { "lcid": "^1.0.0" } @@ -7920,7 +7886,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "dev": true, "requires": { "macos-release": "^2.2.0", "windows-release": "^3.1.0" @@ -7929,8 +7894,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "p-each-series": { "version": "2.1.0", @@ -7941,8 +7905,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { "version": "1.3.0", @@ -7965,8 +7928,7 @@ "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" }, "p-try": { "version": "1.0.0", @@ -7978,7 +7940,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz", "integrity": "sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ==", - "dev": true, "requires": { "agent-base": "^4.2.0", "debug": "^4.1.1", @@ -7994,7 +7955,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", - "dev": true, "requires": { "co": "^4.6.0", "degenerator": "^1.0.4", @@ -8007,7 +7967,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", - "dev": true, "requires": { "got": "^6.7.1", "registry-auth-token": "^3.0.1", @@ -8018,8 +7977,7 @@ "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "parent-module": { "version": "1.0.1", @@ -8043,7 +8001,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.1.tgz", "integrity": "sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA==", - "dev": true, "requires": { "is-ssh": "^1.3.0", "protocols": "^1.4.0" @@ -8053,7 +8010,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.1.tgz", "integrity": "sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg==", - "dev": true, "requires": { "is-ssh": "^1.3.0", "normalize-url": "^3.3.0", @@ -8067,6 +8023,22 @@ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", "dev": true }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -8087,14 +8059,12 @@ "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.6", @@ -8176,20 +8146,17 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" }, "pretty-format": { "version": "25.3.0", @@ -8217,14 +8184,12 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, "requires": { "asap": "~2.0.3" } @@ -8253,14 +8218,12 @@ "protocols": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz", - "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==", - "dev": true + "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==" }, "proxy-agent": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.1.1.tgz", "integrity": "sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw==", - "dev": true, "requires": { "agent-base": "^4.2.0", "debug": "4", @@ -8276,7 +8239,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "requires": { "yallist": "^3.0.2" } @@ -8284,22 +8246,19 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.8.0", @@ -8437,7 +8396,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -8459,7 +8417,6 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", - "dev": true, "requires": { "bytes": "3.1.0", "http-errors": "1.7.3", @@ -8471,7 +8428,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -8623,7 +8579,6 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", - "dev": true, "requires": { "rc": "^1.1.6", "safe-buffer": "^5.0.1" @@ -8633,7 +8588,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, "requires": { "rc": "^1.0.1" } @@ -8838,14 +8792,12 @@ "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, "rxjs": { "version": "6.5.5", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", - "dev": true, "requires": { "tslib": "^1.9.0" } @@ -8867,8 +8819,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sane": { "version": "4.1.0", @@ -8926,6 +8877,21 @@ } } }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -8949,6 +8915,15 @@ } } }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -9014,8 +8989,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "saxes": { "version": "3.1.11", @@ -9029,20 +9003,17 @@ "secure-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/secure-keys/-/secure-keys-1.0.0.tgz", - "integrity": "sha1-8MgtmKOxOah3aogIBQuCRDEIf8o=", - "dev": true + "integrity": "sha1-8MgtmKOxOah3aogIBQuCRDEIf8o=" }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "semver-diff": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true, "requires": { "semver": "^5.0.3" } @@ -9056,8 +9027,7 @@ "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" }, "set-value": { "version": "2.0.1", @@ -9085,14 +9055,12 @@ "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -9100,8 +9068,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "shellwords": { "version": "0.1.1", @@ -9122,8 +9089,7 @@ "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "simple-swizzle": { "version": "0.2.2", @@ -9192,8 +9158,7 @@ "smart-buffer": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", - "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", - "dev": true + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==" }, "snapdragon": { "version": "0.8.2", @@ -9324,10 +9289,9 @@ } }, "snyk": { - "version": "1.317.0", - "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.317.0.tgz", - "integrity": "sha512-zNUvvT50Ii5TpHEo9YmDo+j5tqO1b8jXQK9XygfgiuXPRUwxf6PMSqDM5hKkfzuBhaBYZ4IbZWQFQPbMkprj0w==", - "dev": true, + "version": "1.319.0", + "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.319.0.tgz", + "integrity": "sha512-tOFkZuJYPxzT50joiHd/bxdfsWd/cqFZcfEj6VxRJ28wYBC7imzodp4m8cC6Rcox4++2WEm6ZHNlPLyYjmfPOg==", "requires": { "@snyk/cli-interface": "2.6.0", "@snyk/configstore": "^3.2.0-rc1", @@ -9381,20 +9345,17 @@ "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -9403,7 +9364,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -9414,7 +9374,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -9422,14 +9381,12 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -9437,20 +9394,17 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "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", @@ -9461,7 +9415,6 @@ "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" } @@ -9470,7 +9423,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -9479,7 +9431,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -9492,7 +9443,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/snyk-config/-/snyk-config-3.1.0.tgz", "integrity": "sha512-3UlyogA67/9WOssJ7s4d7gqWQRWyO/LbgdBBNMhhmFDKa7eTUSW+A782CVHgyDSJZ2kNANcMWwMiOL+h3p6zQg==", - "dev": true, "requires": { "@snyk/lodash": "4.17.15-patch", "debug": "^4.1.1", @@ -9503,7 +9453,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.1.0.tgz", "integrity": "sha512-ggGTiiCuwLYGdlGW/UBuUXJ7omliH0EnbpLfdlTBoRKvmvgoUo1l4Menk18R1ZVXgcXTwwGK9jmuUpPH+X0VNw==", - "dev": true, "requires": { "@snyk/rpm-parser": "^1.1.0", "debug": "^4.1.1", @@ -9517,8 +9466,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -9526,7 +9474,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/snyk-go-parser/-/snyk-go-parser-1.4.0.tgz", "integrity": "sha512-zcLA8u/WreycCjFKBblYfxszg7Fmnemuu9Ug/CE/jqF0yBXsI5DCWMteUvFkoa8DRntfGTlgf98TRl2aTSc2MQ==", - "dev": true, "requires": { "toml": "^3.0.0", "tslib": "^1.10.0" @@ -9536,7 +9483,6 @@ "version": "1.14.0", "resolved": "https://registry.npmjs.org/snyk-go-plugin/-/snyk-go-plugin-1.14.0.tgz", "integrity": "sha512-9L+76De8F6yXWb+O3DA8QUi7+eDF2mOzCOveEPUJGkqWIDmurIiFcVxHJoj0EStjcxb3dX367KKlDlfFx+HiyA==", - "dev": true, "requires": { "@snyk/graphlib": "2.1.9-patch", "debug": "^4.1.1", @@ -9549,7 +9495,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -9558,7 +9503,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", - "dev": true, "requires": { "rimraf": "^2.6.3" } @@ -9569,7 +9513,6 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/snyk-gradle-plugin/-/snyk-gradle-plugin-3.2.5.tgz", "integrity": "sha512-XxPi/B16dGkV1USoyFbpn6LlSJ9SUC6Y6z/4lWuF4spLnKtWwpEb1bwTdBFsxnkUfqzIRtPr0+wcxxXvv9Rvcw==", - "dev": true, "requires": { "@snyk/cli-interface": "2.3.0", "@types/debug": "^4.1.4", @@ -9583,7 +9526,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.3.0.tgz", "integrity": "sha512-ecbylK5Ol2ySb/WbfPj0s0GuLQR+KWKFzUgVaoNHaSoN6371qRWwf2uVr+hPUP4gXqCai21Ug/RDArfOhlPwrQ==", - "dev": true, "requires": { "tslib": "^1.9.3" } @@ -9592,7 +9534,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -9601,7 +9542,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -9612,7 +9552,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -9620,20 +9559,17 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -9644,7 +9580,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/snyk-module/-/snyk-module-1.9.1.tgz", "integrity": "sha512-A+CCyBSa4IKok5uEhqT+hV/35RO6APFNLqk9DRRHg7xW2/j//nPX8wTSZUPF8QeRNEk/sX+6df7M1y6PBHGSHA==", - "dev": true, "requires": { "debug": "^3.1.0", "hosted-git-info": "^2.7.1" @@ -9654,7 +9589,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -9665,7 +9599,6 @@ "version": "2.15.0", "resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.15.0.tgz", "integrity": "sha512-24HWz27Hc5sw+iHtxtQFy0kltjyFZXJ3vfsPA0TTZAL0tOJXInIuZpWD6njC0Y3/sn9CH5kS2KM8GAM7FyKVig==", - "dev": true, "requires": { "@snyk/cli-interface": "2.5.0", "@snyk/java-call-graph-builder": "1.8.0", @@ -9679,7 +9612,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.5.0.tgz", "integrity": "sha512-XMc2SCFH4RBSncZgoPb+BBlNq0NYpEpCzptKi69qyMpBy0VsRqIQqddedaazMCU1xEpXTytq6KMYpzUafZzp5Q==", - "dev": true, "requires": { "tslib": "^1.9.3" } @@ -9688,7 +9620,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -9697,7 +9628,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", - "dev": true, "requires": { "rimraf": "^2.6.3" } @@ -9708,7 +9638,6 @@ "version": "1.22.0", "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.22.0.tgz", "integrity": "sha512-l6jLoJxqcIIkQopSdQuAstXdMw5AIgLu+uGc5CYpHyw8fYqOwna8rawwofNeGuwJAAv4nEiNiexeYaR88OCq6Q==", - "dev": true, "requires": { "@snyk/graphlib": "2.1.9-patch", "@snyk/lodash": "^4.17.15-patch", @@ -9725,7 +9654,6 @@ "version": "1.17.0", "resolved": "https://registry.npmjs.org/snyk-nuget-plugin/-/snyk-nuget-plugin-1.17.0.tgz", "integrity": "sha512-t7iZ87LBhCK6P2/mJsQh7Dmk3J9zd+IHL4yoSK95Iyk/gP8r++DZijoRHEXy8BlS+eOtSAj1vgCYvv2eAmG28w==", - "dev": true, "requires": { "@snyk/lodash": "4.17.15-patch", "debug": "^3.1.0", @@ -9739,14 +9667,12 @@ "core-js": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", - "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=", - "dev": true + "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=" }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -9754,14 +9680,12 @@ "es6-promise": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", - "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", - "dev": true + "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" }, "jszip": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", - "dev": true, "requires": { "core-js": "~2.3.0", "es6-promise": "~3.0.2", @@ -9774,7 +9698,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", - "dev": true, "requires": { "immediate": "~3.0.5" } @@ -9782,14 +9705,12 @@ "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "readable-stream": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -9802,8 +9723,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" } } }, @@ -9811,7 +9731,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/snyk-paket-parser/-/snyk-paket-parser-1.6.0.tgz", "integrity": "sha512-6htFynjBe/nakclEHUZ1A3j5Eu32/0pNve5Qm4MFn3YQmJgj7UcAO8hdyK3QfzEY29/kAv/rkJQg+SKshn+N9Q==", - "dev": true, "requires": { "tslib": "^1.9.3" } @@ -9820,7 +9739,6 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/snyk-php-plugin/-/snyk-php-plugin-1.9.0.tgz", "integrity": "sha512-uORrEoC47dw0ITZYu5vKqQtmXnbbQs+ZkWeo5bRHGdf10W8e4rNr1S1R4bReiLrSbSisYhVHeFMkdOAiLIPJVQ==", - "dev": true, "requires": { "@snyk/cli-interface": "2.3.2", "@snyk/composer-lockfile-parser": "1.4.0", @@ -9831,7 +9749,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.3.2.tgz", "integrity": "sha512-jmZyxVHqzYU1GfdnWCGdd68WY/lAzpPVyqalHazPj4tFJehrSfEFc82RMTYAMgXEJuvFRFIwhsvXh3sWUhIQmg==", - "dev": true, "requires": { "tslib": "^1.9.3" } @@ -9842,7 +9759,6 @@ "version": "1.13.5", "resolved": "https://registry.npmjs.org/snyk-policy/-/snyk-policy-1.13.5.tgz", "integrity": "sha512-KI6GHt+Oj4fYKiCp7duhseUj5YhyL/zJOrrJg0u6r59Ux9w8gmkUYT92FHW27ihwuT6IPzdGNEuy06Yv2C9WaQ==", - "dev": true, "requires": { "debug": "^3.1.0", "email-validator": "^2.0.4", @@ -9859,7 +9775,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -9867,8 +9782,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -9876,7 +9790,6 @@ "version": "1.17.0", "resolved": "https://registry.npmjs.org/snyk-python-plugin/-/snyk-python-plugin-1.17.0.tgz", "integrity": "sha512-EKdVOUlvhiVpXA5TeW8vyxYVqbITAfT+2AbL2ZRiiUNLP5ae+WiNYaPy7aB5HAS9IKBKih+IH8Ag65Xu1IYSYA==", - "dev": true, "requires": { "@snyk/cli-interface": "^2.0.3", "tmp": "0.0.33" @@ -9886,7 +9799,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/snyk-resolve/-/snyk-resolve-1.0.1.tgz", "integrity": "sha512-7+i+LLhtBo1Pkth01xv+RYJU8a67zmJ8WFFPvSxyCjdlKIcsps4hPQFebhz+0gC5rMemlaeIV6cqwqUf9PEDpw==", - "dev": true, "requires": { "debug": "^3.1.0", "then-fs": "^2.0.0" @@ -9896,7 +9808,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -9907,7 +9818,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/snyk-resolve-deps/-/snyk-resolve-deps-4.4.0.tgz", "integrity": "sha512-aFPtN8WLqIk4E1ulMyzvV5reY1Iksz+3oPnUVib1jKdyTHymmOIYF7z8QZ4UUr52UsgmrD9EA/dq7jpytwFoOQ==", - "dev": true, "requires": { "@types/node": "^6.14.4", "@types/semver": "^5.5.0", @@ -9931,14 +9841,12 @@ "@types/node": { "version": "6.14.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.10.tgz", - "integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA==", - "dev": true + "integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA==" }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -9946,8 +9854,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -9955,7 +9862,6 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/snyk-sbt-plugin/-/snyk-sbt-plugin-2.11.0.tgz", "integrity": "sha512-wUqHLAa3MzV6sVO+05MnV+lwc+T6o87FZZaY+43tQPytBI2Wq23O3j4POREM4fa2iFfiQJoEYD6c7xmhiEUsSA==", - "dev": true, "requires": { "debug": "^4.1.1", "semver": "^6.1.2", @@ -9968,7 +9874,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -9976,14 +9881,12 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "tmp": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", - "dev": true, "requires": { "rimraf": "^2.6.3" } @@ -9994,7 +9897,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/snyk-tree/-/snyk-tree-1.0.0.tgz", "integrity": "sha1-D7cxdtvzLngvGRAClBYESPkRHMg=", - "dev": true, "requires": { "archy": "^1.0.0" } @@ -10003,7 +9905,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/snyk-try-require/-/snyk-try-require-1.3.1.tgz", "integrity": "sha1-bgJvkuZK9/zM6h7lPVJIQeQYohI=", - "dev": true, "requires": { "debug": "^3.1.0", "lodash.clonedeep": "^4.3.0", @@ -10015,18 +9916,114 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } } } }, + "socket.io": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.4.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" + } + }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + }, + "socket.io-client": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + } + } + }, + "socket.io-parser": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz", + "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, "socks": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", - "dev": true, "requires": { "ip": "1.1.5", "smart-buffer": "^4.1.0" @@ -10036,7 +10033,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", - "dev": true, "requires": { "agent-base": "~4.2.1", "socks": "~2.3.2" @@ -10046,7 +10042,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, "requires": { "es6-promisify": "^5.0.0" } @@ -10056,8 +10051,7 @@ "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 + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { "version": "0.5.3", @@ -10076,7 +10070,6 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -10132,8 +10125,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", @@ -10187,8 +10179,7 @@ "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "stealthy-require": { "version": "1.1.1", @@ -10346,8 +10337,7 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-final-newline": { "version": "2.0.0", @@ -10375,8 +10365,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { "version": "7.1.0", @@ -10452,7 +10441,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, "requires": { "bl": "^4.0.1", "end-of-stream": "^1.4.1", @@ -10464,14 +10452,12 @@ "temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" }, "tempfile": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=", - "dev": true, "requires": { "temp-dir": "^1.0.0", "uuid": "^3.0.1" @@ -10480,8 +10466,7 @@ "temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", - "dev": true + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=" } } }, @@ -10489,43 +10474,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "dev": true, "requires": { "execa": "^0.7.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } } }, "terminal-link": { @@ -10564,7 +10514,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/then-fs/-/then-fs-2.0.0.tgz", "integrity": "sha1-cveS3Z0xcFqRrhnr/Piz+WjIHaI=", - "dev": true, "requires": { "promise": ">=3.2 <8" } @@ -10578,26 +10527,22 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "thunkify": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", - "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", - "dev": true + "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=" }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "requires": { "os-tmpdir": "~1.0.2" } @@ -10608,6 +10553,11 @@ "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", "dev": true }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -10657,8 +10607,7 @@ "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "token-stream": { "version": "0.0.1", @@ -10669,8 +10618,7 @@ "toml": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "dev": true + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" }, "tough-cookie": { "version": "3.0.1", @@ -10695,8 +10643,7 @@ "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" }, "trim-newlines": { "version": "1.0.0", @@ -10850,8 +10797,7 @@ "tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" }, "tsutils": { "version": "3.17.1", @@ -10881,7 +10827,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "~1.1.2" } @@ -10966,7 +10911,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "dev": true, "requires": { "crypto-random-string": "^1.0.0" } @@ -10974,8 +10918,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "unset-value": { "version": "1.0.0", @@ -11020,8 +10963,7 @@ "unzip-response": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" }, "uri-js": { "version": "4.2.2", @@ -11042,7 +10984,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, "requires": { "prepend-http": "^1.0.1" } @@ -11061,8 +11002,7 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "v8-compile-cache": { "version": "2.1.0", @@ -11119,8 +11059,7 @@ "vscode-languageserver-types": { "version": "3.15.1", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==", - "dev": true + "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" }, "vue-docgen-api": { "version": "3.26.0", @@ -11230,7 +11169,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -11245,7 +11183,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", - "dev": true, "requires": { "string-width": "^2.1.1" }, @@ -11253,14 +11190,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -11270,7 +11205,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -11287,9 +11221,32 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz", "integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==", - "dev": true, "requires": { "execa": "^1.0.0" + }, + "dependencies": { + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } } }, "winston": { @@ -11354,8 +11311,7 @@ "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, "wordwrap": { "version": "0.0.2", @@ -11403,14 +11359,12 @@ "ws": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.5.tgz", - "integrity": "sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA==", - "dev": true + "integrity": "sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA==" }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", - "dev": true + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" }, "xml-name-validator": { "version": "3.0.0", @@ -11422,7 +11376,6 @@ "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, "requires": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -11431,8 +11384,7 @@ "xmlbuilder": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" }, "xmlchars": { "version": "2.2.0", @@ -11446,6 +11398,11 @@ "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", "dev": true }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, "xregexp": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", @@ -11470,8 +11427,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { "version": "3.10.0", @@ -11503,6 +11459,11 @@ "decamelize": "^1.2.0" } }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 06dcd7f..5aafd7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "api-watcher", - "version": "0.0.5", + "version": "0.1.0", "description": "API Watcher", "engines": { "node": ">=12" @@ -38,21 +38,23 @@ "license": "ISC", "homepage": "https://a2r.com/", "dependencies": { - "@a2r/telemetry": "^1.0.30", + "@a2r/telemetry": "^1.0.29", "chalk": "^4.0.0", "chokidar": "^3.4.0", "rimraf": "^3.0.2", + "snyk": "^1.319.0", + "socket.io": "^2.3.0", "typescript": "^3.5.3", "winston": "^3.2.1", "winston-transport": "^4.3.0" }, "devDependencies": { "@types/jest": "^25.1.1", - "@types/node": "^13.13.4", + "@types/node": "^13.13.5", "@types/rimraf": "^3.0.0", "@typescript-eslint/eslint-plugin": "^2.31.0", "@typescript-eslint/parser": "^2.31.0", - "babel-jest": "^25.5.1", + "babel-jest": "^25.4.0", "better-docs": "^2.0.1", "coveralls": "^3.0.11", "eslint": "^6.8.0", @@ -61,9 +63,8 @@ "eslint-plugin-import": "^2.18.2", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-react": "^7.14.2", - "jest": "^25.5.4", + "jest": "^25.4.0", "jsdoc": "^3.6.3", - "snyk": "^1.316.1", "ts-jest": "^25.4.0", "ts-node-dev": "^1.0.0-pre.40", "wait-for-expect": "^3.0.2" diff --git a/settings/index.ts b/settings/index.ts index dec3a2c..23ca7d0 100644 --- a/settings/index.ts +++ b/settings/index.ts @@ -1,7 +1,9 @@ +import path from 'path'; + /** * Default target path for watchers, should contain `api` and `model` folders */ -export const targetPath = './server'; +export const targetPath = 'server'; /** * Default api path inside main target path @@ -14,6 +16,31 @@ export const apiPath = 'api'; export const modelPath = 'model'; /** - * Default runtime target path, where watcher will copy api files once validated + * Default proxy target path, where watcher will generate proxy for API and Model + */ +export const proxyPath = '.a2r/proxy'; + +/** + * Default socket path + */ +export const socketPath = '/ws'; + +/** + * Default socket port + */ +export const socketPort = 4000; + +/** + * Default API source path + */ +export const defaultApiSourcePath = path.resolve(process.cwd(), targetPath, apiPath); + +/** + * Default Model source path + */ +export const defaultModelSourcePath = path.resolve(process.cwd(), targetPath, apiPath); + +/** + * Default proxy target path */ -export const runtimePath = './.a2r/runtime'; \ No newline at end of file +export const defaultProxyTargetPath = path.resolve(process.cwd(), proxyPath, apiPath); diff --git a/test/mocks/.a2r/api-proxy/api/index.ts b/test/mocks/.a2r/api-proxy/api/index.ts new file mode 100644 index 0000000..e3aedb6 --- /dev/null +++ b/test/mocks/.a2r/api-proxy/api/index.ts @@ -0,0 +1,63 @@ +import generateId from 'shortid'; + +import socket, { MethodCall, SocketMessage } from './socket'; +import isClient from './isClient'; + +import Info, { Data, Source } from '../model/data'; + +const methodWrapper = (method: string, ...args: any[]): Promise => { + console.log('methodWrapper', method, [...args]); + if (!isClient()) { + console.log('on server side, executing api method directly'); + // try { + // const apiModule = getModule(method); + // return apiModule.default(...args); + // } catch (ex) { + // console.log('Error loading API module at server', ex.message, ex.stack); + // } + } + return new Promise((resolve, reject): void => { + console.log('socket connected?', socket && socket.connected); + if (socket) { + if (socket.disconnected) { + console.log('socket disconnected, connecting'); + socket.connect(); + } + const id = generateId(); + console.log('id', id); + socket.on(id, (res: SocketMessage): void => { + socket.off(id); + if (res.o) { + resolve(res.d); + } else { + const error = new Error(res.e); + error.stack = res.s; + reject(error); + } + }); + + const call: MethodCall = { + method, + id, + params: args, + }; + + console.log('before emit, call:', call); + socket.emit('*', call); + } else { + console.error('No client socket available!'); + reject(new Error('No client socket available!')); + } + }); +}; + +/** + * Method documentation + */ +const method = (src: Source, data: Data = { info: 'default text' }): Promise => methodWrapper('basic', src, data); + +const api = { + basic: method, +}; + +export default api; diff --git a/test/mocks/.a2r/api-proxy/api/isClient.ts b/test/mocks/.a2r/api-proxy/api/isClient.ts new file mode 100644 index 0000000..92c9678 --- /dev/null +++ b/test/mocks/.a2r/api-proxy/api/isClient.ts @@ -0,0 +1,21 @@ +let forceServerSimulation = false; + +/** + * Allows you to disable client detection + * @param {boolean} value True to force Server Side Simulation + */ +export const setForceServerSimulation = (value: boolean): void => { + forceServerSimulation = value; +}; + +/** + * Checks if the script is running on the client side + */ +const isClient = (): boolean => { + if (forceServerSimulation) { + return false; + } + return typeof window === 'object'; +}; + +export default isClient; \ No newline at end of file diff --git a/test/mocks/.a2r/api-proxy/api/socket.ts b/test/mocks/.a2r/api-proxy/api/socket.ts new file mode 100644 index 0000000..fa7eca9 --- /dev/null +++ b/test/mocks/.a2r/api-proxy/api/socket.ts @@ -0,0 +1,64 @@ +import io from "socket.io-client"; + +import isClient from './isClient'; + +/** + * Socket basic call + */ +export interface SocketCall { + /** + * Unique ID for socket transmission + * @type {string} + * @memberof MethodCall + */ + id: string; +} + +/** + * Socket method call + */ +export interface MethodCall extends SocketCall { + /** + * API Method name corresponding to complete key (like 'users.login') + * @memberof MethodCall + */ + method: string; + /** + * Params for API Method + * @memberof MethodCall + */ + params: any[]; +}; + +/** + * Socket standard response + */ +export interface SocketMessage { + /** + * Operation was ok (0) or not (1) + * @memberof SocketMessage + */ + o: number; + /** + * Operation error (if any) + * @memberof SocketMessage + */ + e?: string; + /** + * Operation stack (if error) + * @memberof SocketMessage + */ + s?: string; + /** + * Operation return data + * @memberof SocketMessage + */ + d: any; +}; + +const socket = io('http://localhost:4000', { + autoConnect: isClient(), + path: '/ws', +}); + +export default socket; \ No newline at end of file diff --git a/test/mocks/.a2r/model-imports/api/index.ts b/test/mocks/.a2r/model-imports/api/index.ts new file mode 100644 index 0000000..f2f98f4 --- /dev/null +++ b/test/mocks/.a2r/model-imports/api/index.ts @@ -0,0 +1,80 @@ +import generateId from 'shortid'; + +import socket, { MethodCall, SocketMessage } from './socket'; +import isClient from './isClient'; + +import { Data } from '../model/data'; +import Data2, { Blas, Juan } from '../model/data2'; +import Data3 from '../model/data3'; + +const methodWrapper = (method: string, ...args: any[]): Promise => { + console.log('methodWrapper', method, [...args]); + if (!isClient()) { + console.log('on server side, executing api method directly'); + // try { + // const apiModule = getModule(method); + // return apiModule.default(...args); + // } catch (ex) { + // console.log('Error loading API module at server', ex.message, ex.stack); + // } + } + return new Promise((resolve, reject): void => { + console.log('socket connected?', socket && socket.connected); + if (socket) { + if (socket.disconnected) { + console.log('socket disconnected, connecting'); + socket.connect(); + } + const id = generateId(); + console.log('id', id); + socket.on(id, (res: SocketMessage): void => { + socket.off(id); + if (res.o) { + resolve(res.d); + } else { + const error = new Error(res.e); + error.stack = res.s; + reject(error); + } + }); + + const call: MethodCall = { + method, + id, + params: args, + }; + + console.log('before emit, call:', call); + socket.emit('*', call); + } else { + console.error('No client socket available!'); + reject(new Error('No client socket available!')); + } + }); +}; + +/** + * Gets data from server + * @returns {Promise} + */ +const getData = (data: Data2, blas: Blas): Promise => methodWrapper('modelImports2', data, blas); + +/** + * Gets data from server + * @returns {Promise} + */ +const getData2 = (): Promise => methodWrapper('modelImports3'); + +/** + * Gets data from server + * @returns {Promise} + */ +const getData3 = (data: Data2, juan: Juan): Promise => methodWrapper('modelImports', data, juan); + +const api = { + modelImports2: getData, + modelImports3: getData2, + modelImports: getData3, +}; + +export default api; diff --git a/test/mocks/.a2r/model-imports/api/isClient.ts b/test/mocks/.a2r/model-imports/api/isClient.ts new file mode 100644 index 0000000..92c9678 --- /dev/null +++ b/test/mocks/.a2r/model-imports/api/isClient.ts @@ -0,0 +1,21 @@ +let forceServerSimulation = false; + +/** + * Allows you to disable client detection + * @param {boolean} value True to force Server Side Simulation + */ +export const setForceServerSimulation = (value: boolean): void => { + forceServerSimulation = value; +}; + +/** + * Checks if the script is running on the client side + */ +const isClient = (): boolean => { + if (forceServerSimulation) { + return false; + } + return typeof window === 'object'; +}; + +export default isClient; \ No newline at end of file diff --git a/test/mocks/.a2r/model-imports/api/socket.ts b/test/mocks/.a2r/model-imports/api/socket.ts new file mode 100644 index 0000000..fa7eca9 --- /dev/null +++ b/test/mocks/.a2r/model-imports/api/socket.ts @@ -0,0 +1,64 @@ +import io from "socket.io-client"; + +import isClient from './isClient'; + +/** + * Socket basic call + */ +export interface SocketCall { + /** + * Unique ID for socket transmission + * @type {string} + * @memberof MethodCall + */ + id: string; +} + +/** + * Socket method call + */ +export interface MethodCall extends SocketCall { + /** + * API Method name corresponding to complete key (like 'users.login') + * @memberof MethodCall + */ + method: string; + /** + * Params for API Method + * @memberof MethodCall + */ + params: any[]; +}; + +/** + * Socket standard response + */ +export interface SocketMessage { + /** + * Operation was ok (0) or not (1) + * @memberof SocketMessage + */ + o: number; + /** + * Operation error (if any) + * @memberof SocketMessage + */ + e?: string; + /** + * Operation stack (if error) + * @memberof SocketMessage + */ + s?: string; + /** + * Operation return data + * @memberof SocketMessage + */ + d: any; +}; + +const socket = io('http://localhost:4000', { + autoConnect: isClient(), + path: '/ws', +}); + +export default socket; \ No newline at end of file diff --git a/test/mocks/.a2r/proxy/api/index.ts b/test/mocks/.a2r/proxy/api/index.ts new file mode 100644 index 0000000..ec6dcea --- /dev/null +++ b/test/mocks/.a2r/proxy/api/index.ts @@ -0,0 +1,55 @@ +import generateId from 'shortid'; + +import socket, { MethodCall, SocketMessage } from './socket'; +import isClient from './isClient'; + +const methodWrapper = (method: string, ...args: any[]): Promise => { + console.log('methodWrapper', method, [...args]); + if (!isClient()) { + console.log('on server side, executing api method directly'); + // try { + // const apiModule = getModule(method); + // return apiModule.default(...args); + // } catch (ex) { + // console.log('Error loading API module at server', ex.message, ex.stack); + // } + } + return new Promise((resolve, reject): void => { + console.log('socket connected?', socket && socket.connected); + if (socket) { + if (socket.disconnected) { + console.log('socket disconnected, connecting'); + socket.connect(); + } + const id = generateId(); + console.log('id', id); + socket.on(id, (res: SocketMessage): void => { + socket.off(id); + if (res.o) { + resolve(res.d); + } else { + const error = new Error(res.e); + error.stack = res.s; + reject(error); + } + }); + + const call: MethodCall = { + method, + id, + params: args, + }; + + console.log('before emit, call:', call); + socket.emit('*', call); + } else { + console.error('No client socket available!'); + reject(new Error('No client socket available!')); + } + }); +}; + +const api = { +}; + +export default api; diff --git a/test/mocks/.a2r/proxy/api/isClient.ts b/test/mocks/.a2r/proxy/api/isClient.ts new file mode 100644 index 0000000..92c9678 --- /dev/null +++ b/test/mocks/.a2r/proxy/api/isClient.ts @@ -0,0 +1,21 @@ +let forceServerSimulation = false; + +/** + * Allows you to disable client detection + * @param {boolean} value True to force Server Side Simulation + */ +export const setForceServerSimulation = (value: boolean): void => { + forceServerSimulation = value; +}; + +/** + * Checks if the script is running on the client side + */ +const isClient = (): boolean => { + if (forceServerSimulation) { + return false; + } + return typeof window === 'object'; +}; + +export default isClient; \ No newline at end of file diff --git a/test/mocks/.a2r/proxy/api/socket.ts b/test/mocks/.a2r/proxy/api/socket.ts new file mode 100644 index 0000000..fa7eca9 --- /dev/null +++ b/test/mocks/.a2r/proxy/api/socket.ts @@ -0,0 +1,64 @@ +import io from "socket.io-client"; + +import isClient from './isClient'; + +/** + * Socket basic call + */ +export interface SocketCall { + /** + * Unique ID for socket transmission + * @type {string} + * @memberof MethodCall + */ + id: string; +} + +/** + * Socket method call + */ +export interface MethodCall extends SocketCall { + /** + * API Method name corresponding to complete key (like 'users.login') + * @memberof MethodCall + */ + method: string; + /** + * Params for API Method + * @memberof MethodCall + */ + params: any[]; +}; + +/** + * Socket standard response + */ +export interface SocketMessage { + /** + * Operation was ok (0) or not (1) + * @memberof SocketMessage + */ + o: number; + /** + * Operation error (if any) + * @memberof SocketMessage + */ + e?: string; + /** + * Operation stack (if error) + * @memberof SocketMessage + */ + s?: string; + /** + * Operation return data + * @memberof SocketMessage + */ + d: any; +}; + +const socket = io('http://localhost:4000', { + autoConnect: isClient(), + path: '/ws', +}); + +export default socket; \ No newline at end of file diff --git a/test/mocks/.a2r/proxy/model/ok.ts b/test/mocks/.a2r/proxy/model/ok.ts new file mode 100644 index 0000000..29e017d --- /dev/null +++ b/test/mocks/.a2r/proxy/model/ok.ts @@ -0,0 +1,4 @@ + +export interface Data { + info: string; +} diff --git a/test/mocks/server/init-ok/api/ok.ts b/test/mocks/server/init-ok/api/ok.ts new file mode 100644 index 0000000..98b1a78 --- /dev/null +++ b/test/mocks/server/init-ok/api/ok.ts @@ -0,0 +1,12 @@ +import { Data } from '../model/ok'; + +/** + * Method documentation + */ +const method = async (): Promise => { + return { + info: 'info', + }; +}; + +export default method; diff --git a/test/mocks/server/init-ok/model/ok.ts b/test/mocks/server/init-ok/model/ok.ts new file mode 100644 index 0000000..29e017d --- /dev/null +++ b/test/mocks/server/init-ok/model/ok.ts @@ -0,0 +1,4 @@ + +export interface Data { + info: string; +} diff --git a/test/mocks/server/model-imports/api/model-imports-2.ts b/test/mocks/server/model-imports/api/model-imports-2.ts new file mode 100644 index 0000000..4281ecd --- /dev/null +++ b/test/mocks/server/model-imports/api/model-imports-2.ts @@ -0,0 +1,15 @@ +import { Data } from '../model/data'; +import Data2, { Blas } from '../model/data2'; + +/** + * Gets data from server + * @returns {Promise} + */ +const getData = async (data: Data2, blas: Blas): Promise => { + console.log('data server method!', data, blas); + return { + info: 'Data from API', + }; +}; + +export default getData; \ No newline at end of file diff --git a/test/mocks/server/model-imports/api/model-imports-3.ts b/test/mocks/server/model-imports/api/model-imports-3.ts new file mode 100644 index 0000000..7ce9501 --- /dev/null +++ b/test/mocks/server/model-imports/api/model-imports-3.ts @@ -0,0 +1,13 @@ +import Data3 from '../model/data3'; + +/** + * Gets data from server + * @returns {Promise} + */ +const getData = async (): Promise => { + return { + info: 'Data from API', + }; +}; + +export default getData; \ No newline at end of file diff --git a/test/mocks/server/model-imports/api/model-imports.ts b/test/mocks/server/model-imports/api/model-imports.ts new file mode 100644 index 0000000..008b620 --- /dev/null +++ b/test/mocks/server/model-imports/api/model-imports.ts @@ -0,0 +1,15 @@ +import { Data } from '../model/data'; +import Data2, { Juan } from '../model/data2'; + +/** + * Gets data from server + * @returns {Promise} + */ +const getData = async (data: Data2, juan: Juan): Promise => { + console.log('data server method!', data, juan); + return { + info: 'Data from API', + }; +}; + +export default getData; \ No newline at end of file diff --git a/test/mocks/server/model-imports/model/data.ts b/test/mocks/server/model-imports/model/data.ts new file mode 100644 index 0000000..3e44c6e --- /dev/null +++ b/test/mocks/server/model-imports/model/data.ts @@ -0,0 +1,3 @@ +export interface Data { + info: string; +} \ No newline at end of file diff --git a/test/mocks/server/model-imports/model/data2.ts b/test/mocks/server/model-imports/model/data2.ts new file mode 100644 index 0000000..b84f2ea --- /dev/null +++ b/test/mocks/server/model-imports/model/data2.ts @@ -0,0 +1,11 @@ +export interface Blas { + info: string; +} + +export interface Juan { + info: string; +} + +export default interface Data2 { + info: string; +} \ No newline at end of file diff --git a/test/mocks/server/model-imports/model/data3.ts b/test/mocks/server/model-imports/model/data3.ts new file mode 100644 index 0000000..a76418c --- /dev/null +++ b/test/mocks/server/model-imports/model/data3.ts @@ -0,0 +1,3 @@ +export default interface Data3 { + info: string; +} \ No newline at end of file diff --git a/test/mocks/server/model-validation/data1.ts b/test/mocks/server/model-validation/data1.ts new file mode 100644 index 0000000..3e44c6e --- /dev/null +++ b/test/mocks/server/model-validation/data1.ts @@ -0,0 +1,3 @@ +export interface Data { + info: string; +} \ No newline at end of file diff --git a/test/mocks/server/model-validation/data2.ts b/test/mocks/server/model-validation/data2.ts new file mode 100644 index 0000000..3e44c6e --- /dev/null +++ b/test/mocks/server/model-validation/data2.ts @@ -0,0 +1,3 @@ +export interface Data { + info: string; +} \ No newline at end of file diff --git a/test/mocks/server/model-validation/empty.ts b/test/mocks/server/model-validation/empty.ts new file mode 100644 index 0000000..e69de29 diff --git a/test/mocks/server/module-info/api/basic.ts b/test/mocks/server/module-info/api/basic.ts new file mode 100644 index 0000000..7a6ae6e --- /dev/null +++ b/test/mocks/server/module-info/api/basic.ts @@ -0,0 +1,15 @@ +import Info, { Data, Source } from '../model/data'; + +/** + * Method documentation + */ +const method = async ( + src: Source, + data: Data = { info: 'default text' }, +): Promise => { + return { + info: `${src.info} ${data.info}`, + }; +}; + +export default method; diff --git a/test/mocks/server/module-info/model/data.ts b/test/mocks/server/module-info/model/data.ts new file mode 100644 index 0000000..9540898 --- /dev/null +++ b/test/mocks/server/module-info/model/data.ts @@ -0,0 +1,12 @@ + +export interface Data { + info: string; +} + +export interface Source { + info: string; +} + +export default interface Info { + info: string; +} diff --git a/test/mocks/.a2r/runtime/model/documented.ts b/test/mocks/server/no-return/no-return.ts similarity index 57% rename from test/mocks/.a2r/runtime/model/documented.ts rename to test/mocks/server/no-return/no-return.ts index 4d67a4e..a91c40e 100644 --- a/test/mocks/.a2r/runtime/model/documented.ts +++ b/test/mocks/server/no-return/no-return.ts @@ -1,8 +1,8 @@ /** * Method documentation */ -const method = (): void => { - // Do stuff +const method = () => { + return 'hello'; }; export default method; diff --git a/test/mocks/server/stress-validator/folder/file-0.ts b/test/mocks/server/stress-validator/folder/file-0.ts new file mode 100644 index 0000000..b5f02fc --- /dev/null +++ b/test/mocks/server/stress-validator/folder/file-0.ts @@ -0,0 +1 @@ +// test file \ No newline at end of file diff --git a/test/mocks/server/stress-validator/folder/file-1.ts b/test/mocks/server/stress-validator/folder/file-1.ts new file mode 100644 index 0000000..b5f02fc --- /dev/null +++ b/test/mocks/server/stress-validator/folder/file-1.ts @@ -0,0 +1 @@ +// test file \ No newline at end of file diff --git a/test/mocks/server/stress-validator/folder/file-2.ts b/test/mocks/server/stress-validator/folder/file-2.ts new file mode 100644 index 0000000..b5f02fc --- /dev/null +++ b/test/mocks/server/stress-validator/folder/file-2.ts @@ -0,0 +1 @@ +// test file \ No newline at end of file diff --git a/test/mocks/server/stress-validator/folder/file-3.ts b/test/mocks/server/stress-validator/folder/file-3.ts new file mode 100644 index 0000000..b5f02fc --- /dev/null +++ b/test/mocks/server/stress-validator/folder/file-3.ts @@ -0,0 +1 @@ +// test file \ No newline at end of file diff --git a/test/mocks/server/stress-validator/folder/file-4.ts b/test/mocks/server/stress-validator/folder/file-4.ts new file mode 100644 index 0000000..b5f02fc --- /dev/null +++ b/test/mocks/server/stress-validator/folder/file-4.ts @@ -0,0 +1 @@ +// test file \ No newline at end of file diff --git a/test/mocks/server/stress-validator/folder/file.ts b/test/mocks/server/stress-validator/folder/file.ts new file mode 100644 index 0000000..b5f02fc --- /dev/null +++ b/test/mocks/server/stress-validator/folder/file.ts @@ -0,0 +1 @@ +// test file \ No newline at end of file diff --git a/test/mocks/server/stress-validator/folder/last-file.ts b/test/mocks/server/stress-validator/folder/last-file.ts new file mode 100644 index 0000000..b5f02fc --- /dev/null +++ b/test/mocks/server/stress-validator/folder/last-file.ts @@ -0,0 +1 @@ +// test file \ No newline at end of file diff --git a/test/mocks/.a2r/runtime/api/documented.ts b/test/mocks/server/validation-fail/undocumented.ts similarity index 68% rename from test/mocks/.a2r/runtime/api/documented.ts rename to test/mocks/server/validation-fail/undocumented.ts index 4d67a4e..cf5278d 100644 --- a/test/mocks/.a2r/runtime/api/documented.ts +++ b/test/mocks/server/validation-fail/undocumented.ts @@ -1,6 +1,3 @@ -/** - * Method documentation - */ const method = (): void => { // Do stuff }; diff --git a/test/mocks/working-server/api/documented.ts b/test/mocks/working-server/api/documented.ts deleted file mode 100644 index 4d67a4e..0000000 --- a/test/mocks/working-server/api/documented.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Method documentation - */ -const method = (): void => { - // Do stuff -}; - -export default method; diff --git a/test/mocks/working-server/model/documented.ts b/test/mocks/working-server/model/documented.ts deleted file mode 100644 index 4d67a4e..0000000 --- a/test/mocks/working-server/model/documented.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Method documentation - */ -const method = (): void => { - // Do stuff -}; - -export default method; diff --git a/test/tests/api/apiObject.ts b/test/tests/api/apiObject.ts new file mode 100644 index 0000000..a0b322e --- /dev/null +++ b/test/tests/api/apiObject.ts @@ -0,0 +1,51 @@ +import { ApiNamespace } from '../../../model/api'; + +import updateApiObject from '../../../utils/updateApiObject'; +import getApiObject from '../../../utils/getApiObject'; + +const expectedString = `const api = { + data: { + users: { + list, + add, + }, + items: { + list: listItems, + add, + }, + }, + whatever: { + import, + export, + }, + ping, +};` + +/** + * Method `updateApiObject` should build API object properly and `getApiObject` should return proper string representation + */ +test('Update API object and get string representation', () => { + let apiObject: ApiNamespace = { + key: 'api', + namespaces: [], + methods: [], + }; + apiObject = updateApiObject(apiObject, ['data', 'users', 'list'], 'list'); + apiObject = updateApiObject(apiObject, ['data', 'users', 'add'], 'add'); + apiObject = updateApiObject(apiObject, ['data', 'items', 'list'], 'listItems'); + apiObject = updateApiObject(apiObject, ['data', 'items', 'add'], 'add'); + apiObject = updateApiObject(apiObject, ['whatever', 'import'], 'import'); + apiObject = updateApiObject(apiObject, ['whatever', 'export'], 'export'); + apiObject = updateApiObject(apiObject, ['ping'], 'ping'); + expect(apiObject.key).toBe('api'); + expect(apiObject.namespaces.length).toBe(2); + expect(apiObject.methods.length).toBe(1); + const dataNamespace = apiObject.namespaces.find(n => n.key === 'data'); + expect(dataNamespace).toBeTruthy(); + const usersNamespace = dataNamespace.namespaces.find(n => n.key === 'users'); + expect(usersNamespace).toBeTruthy(); + const addUserMethod = usersNamespace.methods.find(m => m.key === 'add'); + expect(addUserMethod).toBeTruthy(); + const stringApiObject = getApiObject(apiObject); + expect(stringApiObject).toBe(expectedString); +}); \ No newline at end of file diff --git a/test/tests/api/apiProxy.ts b/test/tests/api/apiProxy.ts new file mode 100644 index 0000000..8286be5 --- /dev/null +++ b/test/tests/api/apiProxy.ts @@ -0,0 +1,32 @@ +import path from 'path'; +import waitForExpect from 'wait-for-expect'; + +import { build } from '../../../utils/apiProxy'; +import { emptyFolder, exists } from '../../../tools/fs'; + +const apiSourcePath = path.resolve(__dirname, '../../mocks/server/module-info/api'); +const proxyTargetPath = path.resolve(__dirname, '../../mocks/.a2r/api-proxy/api'); +const apiProxyIndexPath = path.resolve(proxyTargetPath, 'index.ts'); +const socketProxyPath = path.resolve(proxyTargetPath, 'socket.ts'); + +beforeAll(async (): Promise => { + await emptyFolder(proxyTargetPath); +}); + +/** + * API Proxy should build expected content + */ +test('API Proxy build', async (): Promise => { + await build(apiSourcePath, proxyTargetPath); + await waitForExpect(async (): Promise => { + expect(await exists(socketProxyPath)).toBe(true); + expect(await exists(apiProxyIndexPath)).toBe(true); + }); +}); + +/** + * API Proxy should build from default paths when not specific paths are provided + */ +test('API Proxy build with default paths', async (): Promise => { + await build(); +}); diff --git a/test/tests/api/getModuleInfo.ts b/test/tests/api/getModuleInfo.ts new file mode 100644 index 0000000..40c8ee7 --- /dev/null +++ b/test/tests/api/getModuleInfo.ts @@ -0,0 +1,23 @@ +import path from 'path'; + +import getModuleInfo from '../../../utils/getModuleInfo'; + +const apiSourcePath = path.resolve(__dirname, '../../mocks/server/module-info/api'); +const filePath = path.resolve(apiSourcePath, 'basic.ts'); + +/** + * Module info should contain expected data + */ +test('Module info', async (): Promise => { + const moduleInfo = await getModuleInfo(filePath, apiSourcePath); + expect(moduleInfo).not.toBe(undefined); + expect(moduleInfo.mainMethodName).toBe('method'); + expect(moduleInfo.keys).toEqual(['basic']); + expect(moduleInfo.modelImports.length).toBe(1); + expect(moduleInfo.mainMethodDocs).not.toBe(undefined); + expect(moduleInfo.mainMethodNode).not.toBe(undefined); + expect(moduleInfo.mainMethodParamNodes.length).toBe(2); + expect(moduleInfo.mainMethodReturnTypeInfo).not.toBe(undefined); + expect(moduleInfo.mainMethodReturnTypeInfo.identifier).toBe('Promise'); + expect(moduleInfo.mainMethodReturnTypeInfo.type).toBe('Info'); +}); \ No newline at end of file diff --git a/test/tests/api/getProxyMethod.ts b/test/tests/api/getProxyMethod.ts new file mode 100644 index 0000000..0df7527 --- /dev/null +++ b/test/tests/api/getProxyMethod.ts @@ -0,0 +1,32 @@ +import path from 'path'; + +import getModuleInfo from '../../../utils/getModuleInfo'; +import getProxyMethod from '../../../utils/getProxyMethod'; + +const apiSourcePath = path.resolve( + __dirname, + '../../mocks/server/module-info/api', +); +const filePath = path.resolve(apiSourcePath, 'basic.ts'); + +const expected = `const method = (src: Source, data: Data = { info: 'default text' }): Promise => methodWrapper('basic', src, data);`; + +/** + * Proxy method should be build as expected + */ +test('Basic proxy method', async (): Promise => { + const { + keys, + mainMethodName, + mainMethodParamNodes, + mainMethodReturnTypeInfo, + } = await getModuleInfo(filePath, apiSourcePath); + + const method = getProxyMethod( + keys.join('.'), + mainMethodName, + mainMethodParamNodes, + mainMethodReturnTypeInfo, + ); + expect(method).toBe(expected); +}); diff --git a/test/tests/api/modelImports.ts b/test/tests/api/modelImports.ts new file mode 100644 index 0000000..76a4a84 --- /dev/null +++ b/test/tests/api/modelImports.ts @@ -0,0 +1,25 @@ +import path from 'path'; +import waitForExpect from 'wait-for-expect'; + +import { build } from '../../../utils/apiProxy'; +import { emptyFolder, exists } from '../../../tools/fs'; + +const apiSourcePath = path.resolve(__dirname, '../../mocks/server/model-imports/api'); +const proxyTargetPath = path.resolve(__dirname, '../../mocks/.a2r/model-imports/api'); +const apiProxyIndexPath = path.resolve(proxyTargetPath, 'index.ts'); +const socketProxyPath = path.resolve(proxyTargetPath, 'socket.ts'); + +beforeAll(async (): Promise => { + await emptyFolder(proxyTargetPath); +}); + +/** + * Model imports should work properly with just default import, with just named imports and with both combined + */ +test('API Proxy build covering different model imports types', async (): Promise => { + await build(apiSourcePath, proxyTargetPath); + await waitForExpect(async (): Promise => { + expect(await exists(socketProxyPath)).toBe(true); + expect(await exists(apiProxyIndexPath)).toBe(true); + }); +}); \ No newline at end of file diff --git a/test/tests/basic/capitalize.ts b/test/tests/basic/capitalize.ts new file mode 100644 index 0000000..96a1a54 --- /dev/null +++ b/test/tests/basic/capitalize.ts @@ -0,0 +1,5 @@ +import capitalize from '../../../tools/capitalize'; + +test('Capitalize', (): void => { + expect(capitalize('hello')).toBe('Hello'); +}) \ No newline at end of file diff --git a/test/tests/basic/cleanText.ts b/test/tests/basic/cleanText.ts new file mode 100644 index 0000000..a80deaa --- /dev/null +++ b/test/tests/basic/cleanText.ts @@ -0,0 +1,19 @@ +import cleanText from '../../../tools/cleanText'; + +/** + * Clean text method should work as expected + */ +test('Clean text', (): void => { + expect(cleanText('Adiós')).toBe('Adios'); + expect(cleanText('Adiós', true)).toBe('adios'); + expect(cleanText('Adiós?', false, true)).toBe('Adios'); + expect(cleanText('Adiós?', true, true)).toBe('adios'); + expect(cleanText('Hello Adiós', false, false, true)).toBe('HelloAdios'); + expect(cleanText('Hello Adiós', true, false, true)).toBe('helloadios'); + expect(cleanText('Hello? Adiós', true, false, true)).toBe('hello?adios'); + expect(cleanText('Hello? Adiós', true, true, true)).toBe('helloadios'); + expect(cleanText('Hello? Adiós', false, true, true, true)).toBe('helloAdios'); + expect(cleanText('Hello? Adiós', true, true, true, false, '', '-')).toBe('hello-adios'); + expect(cleanText('')).toBe(''); + expect(cleanText('€')).toBe('€'); +}); \ No newline at end of file diff --git a/test/tests/basic/isClient.ts b/test/tests/basic/isClient.ts new file mode 100644 index 0000000..9ae61a1 --- /dev/null +++ b/test/tests/basic/isClient.ts @@ -0,0 +1,11 @@ +import isClient, { setForceServerSimulation } from '../../../tools/isClient'; + +/** + * Method `isClient` should return `true` at startup and then `false` after being forced + */ +test('Method isClient basic flow', (): void => { + expect(isClient()).toBe(true); + setForceServerSimulation(true); + expect(isClient()).toBe(false); + setForceServerSimulation(false); +}); diff --git a/test/tests/basic/isJest.ts b/test/tests/basic/isJest.ts index 65fe78e..873ce31 100644 --- a/test/tests/basic/isJest.ts +++ b/test/tests/basic/isJest.ts @@ -1,17 +1,11 @@ -import isJest, { setForceDisableJestDetection } from '../../../tools/isJest'; +import { isJest, setForceDisableJestDetection } from '../../../tools/isJest'; /** - * Method `isJest` should return true + * Method `isJest` should return `true` at startup and then `false` after being forced */ -test('Method isJest should return true', async () => { +test('Method isJest basic flow', (): void => { expect(isJest()).toBe(true); -}); - -/** - * After using `setForceDisableJestDetection` method `isJset` should return `false` - */ -test('Method isJest should return false after using setForceDisableJestDetection', async () => { setForceDisableJestDetection(true); expect(isJest()).toBe(false); setForceDisableJestDetection(false); -}); \ No newline at end of file +}); diff --git a/test/tests/basic/jest-init.ts b/test/tests/basic/jest-init.ts index 2a53a5a..be92c8b 100644 --- a/test/tests/basic/jest-init.ts +++ b/test/tests/basic/jest-init.ts @@ -8,6 +8,7 @@ test('Should init when jest forced disabled', async (): Promise => { await waitForExpect(async (): Promise => { expect(index.activeWatchers.length).toBe(2); }); + setForceDisableJestDetection(false); await index.stop(); expect(index.activeWatchers.length).toBe(0); }); \ No newline at end of file diff --git a/test/tests/sockets/methodWrapper.ts b/test/tests/sockets/methodWrapper.ts new file mode 100644 index 0000000..f019acd --- /dev/null +++ b/test/tests/sockets/methodWrapper.ts @@ -0,0 +1,52 @@ +import getMethodWrapper from '../../../utils/getMethodWrapper'; + +const expected = `const methodWrapper = (method: string, ...args: any[]): Promise => { + console.log('methodWrapper', method, [...args]); + if (!isClient()) { + console.log('on server side, executing api method directly'); + // try { + // const apiModule = getModule(method); + // return apiModule.default(...args); + // } catch (ex) { + // console.log('Error loading API module at server', ex.message, ex.stack); + // } + } + return new Promise((resolve, reject): void => { + console.log('socket connected?', socket && socket.connected); + if (socket) { + if (socket.disconnected) { + console.log('socket disconnected, connecting'); + socket.connect(); + } + const id = generateId(); + console.log('id', id); + socket.on(id, (res: SocketMessage): void => { + socket.off(id); + if (res.o) { + resolve(res.d); + } else { + const error = new Error(res.e); + error.stack = res.s; + reject(error); + } + }); + + const call: MethodCall = { + method, + id, + params: args, + }; + + console.log('before emit, call:', call); + socket.emit('*', call); + } else { + console.error('No client socket available!'); + reject(new Error('No client socket available!')); + } + }); +};`; + +test('Method wrapper should build method processing requests', (): void => { + const methodWrapper = getMethodWrapper(); + expect(methodWrapper).toBe(expected); +}) \ No newline at end of file diff --git a/test/tests/sockets/socketProvider.ts b/test/tests/sockets/socketProvider.ts new file mode 100644 index 0000000..7af5e75 --- /dev/null +++ b/test/tests/sockets/socketProvider.ts @@ -0,0 +1,77 @@ +import getSocketProvider from '../../../utils/getSocketProvider'; + +import { socketPort, socketPath } from '../../../settings'; + +/** + * Socket provider should return expected content + */ +test('Socket provider should build interfaces and client socket', (): void => { + const url = `http://localhost:${socketPort}`; + const expected = `import io from "socket.io-client"; + +import isClient from './isClient'; + +/** + * Socket basic call + */ +export interface SocketCall { + /** + * Unique ID for socket transmission + * @type {string} + * @memberof MethodCall + */ + id: string; +} + +/** + * Socket method call + */ +export interface MethodCall extends SocketCall { + /** + * API Method name corresponding to complete key (like 'users.login') + * @memberof MethodCall + */ + method: string; + /** + * Params for API Method + * @memberof MethodCall + */ + params: any[]; +}; + +/** + * Socket standard response + */ +export interface SocketMessage { + /** + * Operation was ok (0) or not (1) + * @memberof SocketMessage + */ + o: number; + /** + * Operation error (if any) + * @memberof SocketMessage + */ + e?: string; + /** + * Operation stack (if error) + * @memberof SocketMessage + */ + s?: string; + /** + * Operation return data + * @memberof SocketMessage + */ + d: any; +}; + +const socket = io('${url}', { + autoConnect: isClient(), + path: '${socketPath}', +}); + +export default socket;` + + const socketProvider = getSocketProvider(); + expect(socketProvider).toBe(expected); +}); \ No newline at end of file diff --git a/test/tests/ts/getExportsIdentifiersFromNodes.ts b/test/tests/ts/getExportsIdentifiersFromNodes.ts new file mode 100644 index 0000000..1ea0ae1 --- /dev/null +++ b/test/tests/ts/getExportsIdentifiersFromNodes.ts @@ -0,0 +1,18 @@ +import ts from 'typescript'; +import path from 'path'; + +import getExportsIdentifiersFromNodes from '../../../utils/getExportsIdentifiersFromNodes'; +import { readFile } from '../../../tools/fs'; + +const modelSourcePath = path.resolve(__dirname, '../../mocks/server/model-imports/model'); + +test('Get exports identifiers', async (): Promise => { + const filePath = path.resolve(modelSourcePath, 'data.ts'); + const content = await readFile(filePath, 'utf8'); + const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true); + const fileNodes = sourceFile.getChildren(); + const identifiers = getExportsIdentifiersFromNodes(fileNodes); + console.log(identifiers); + expect(identifiers.length).toBe(1); + expect(identifiers).toContain('Data'); +}); \ No newline at end of file diff --git a/test/tests/watcher/getFunctionDocContainer.ts b/test/tests/ts/getFunctionDocContainer.ts similarity index 100% rename from test/tests/watcher/getFunctionDocContainer.ts rename to test/tests/ts/getFunctionDocContainer.ts diff --git a/test/tests/watcher/getFunctionName.ts b/test/tests/ts/getFunctionName.ts similarity index 100% rename from test/tests/watcher/getFunctionName.ts rename to test/tests/ts/getFunctionName.ts diff --git a/test/tests/ts/getFunctionReturnTypeInfo.ts b/test/tests/ts/getFunctionReturnTypeInfo.ts new file mode 100644 index 0000000..7e9b319 --- /dev/null +++ b/test/tests/ts/getFunctionReturnTypeInfo.ts @@ -0,0 +1,30 @@ +import ts from 'typescript'; +import path from 'path'; + +import getFunctionReturnTypeInfo from '../../../utils/getFunctionReturnTypeInfo'; +import getMainMethodName from '../../../utils/getMainMethodName'; +import getMainMethodNode from '../../../utils/getMainMethodNode'; +import { readFile } from '../../../tools/fs'; + +const filePath = path.resolve(__dirname, '../../mocks/server/no-return/no-return.ts'); + +test('Get function return type info should return null if no return is defined', async () => { + const content = await readFile(filePath, 'utf8'); + const mainMethodParamNodes: ts.ParameterDeclaration[] = []; + const sourceFile = ts.createSourceFile( + filePath, + content, + ts.ScriptTarget.Latest, + true, + ); + const fileNodes = sourceFile.getChildren(); + const mainMethodName = getMainMethodName(fileNodes); + const mainMethodNode = getMainMethodNode(fileNodes, mainMethodName); + mainMethodNode.forEachChild((child): void => { + if (ts.isParameter(child)) { + mainMethodParamNodes.push(child); + } + }); + const mainMethodReturnTypeInfo = getFunctionReturnTypeInfo(mainMethodNode); + expect(mainMethodReturnTypeInfo).toBe(null); +}); \ No newline at end of file diff --git a/test/tests/watcher/getMainMethodName.ts b/test/tests/ts/getMainMethodName.ts similarity index 100% rename from test/tests/watcher/getMainMethodName.ts rename to test/tests/ts/getMainMethodName.ts diff --git a/test/tests/watcher/getMainMethodNode.ts b/test/tests/ts/getMainMethodNode.ts similarity index 100% rename from test/tests/watcher/getMainMethodNode.ts rename to test/tests/ts/getMainMethodNode.ts diff --git a/test/tests/ts/getModelImports.ts b/test/tests/ts/getModelImports.ts new file mode 100644 index 0000000..468ab29 --- /dev/null +++ b/test/tests/ts/getModelImports.ts @@ -0,0 +1,56 @@ +import ts from 'typescript'; +import path from 'path'; + +import { readFile, getFilesRecursively } from '../../../tools/fs'; +import getModelImports from '../../../utils/getModelImports'; +import getGroupedModelImports from '../../../utils/getGroupedModelImports'; +import { ModelImport } from '../../../model/api'; + +const mainPath = path.resolve(__dirname, '../../mocks/server/model-imports'); + +/** + * Method should return proper information about model imports on file + */ +test('Get model imports', async (): Promise => { + const filePath = path.resolve(mainPath, 'api', 'model-imports.ts'); + const content = await readFile(filePath, 'utf8'); + const sourceFile = ts.createSourceFile( + filePath, + content, + ts.ScriptTarget.Latest, + false, + ts.ScriptKind.TS, + ); + + const children = sourceFile.getChildren(sourceFile); + + const imports = getModelImports(children, sourceFile); + expect(imports.length).toBe(2); +}); + +/** + * Should group model imports from same path + */ +test('Group model imports from same path', async (): Promise => { + const apiPath = path.resolve(mainPath, 'api'); + const files = await getFilesRecursively(apiPath, ['.ts']); + const fileImports = await Promise.all(files.map(async (filePath): Promise => { + const content = await readFile(filePath, 'utf8'); + const sourceFile = ts.createSourceFile( + filePath, + content, + ts.ScriptTarget.Latest, + false, + ts.ScriptKind.TS, + ); + + const children = sourceFile.getChildren(sourceFile); + + return getModelImports(children, sourceFile); + })); + + const imports = fileImports.reduce((t, i) => [...t, ...i], []); + expect(imports.length).toBe(5); + const groupedImports = getGroupedModelImports(imports); + expect(groupedImports.length).toBe(3); +}); \ No newline at end of file diff --git a/test/tests/watcher/apiFileValidation.ts b/test/tests/validations/apiFileValidation.ts similarity index 92% rename from test/tests/watcher/apiFileValidation.ts rename to test/tests/validations/apiFileValidation.ts index beb1fa1..9fbb3d6 100644 --- a/test/tests/watcher/apiFileValidation.ts +++ b/test/tests/validations/apiFileValidation.ts @@ -7,7 +7,7 @@ const apiPath = path.resolve(__dirname, '../../mocks/server/api'); /** * An empty file shouldn't pass validation */ -test(`Empty fail shouldn't pass validation`, async (): Promise => { +test(`Empty API file shouldn't pass validation`, async (): Promise => { const emptyFile = path.resolve(apiPath, 'empty.ts'); const validate = await apiFileValidation(emptyFile); expect(validate).toBe(false); diff --git a/test/tests/validations/modelFileValidation.ts b/test/tests/validations/modelFileValidation.ts new file mode 100644 index 0000000..21a751c --- /dev/null +++ b/test/tests/validations/modelFileValidation.ts @@ -0,0 +1,24 @@ +import path from 'path'; + +import modelFileValidation from '../../../utils/modelFileValidation'; + +const modelPath = path.resolve(__dirname, '../../mocks/server/model-validation'); + +/** + * An empty model file shouldn't pass validation + */ +test(`Empty model file shouldn't pass validation`, async (): Promise => { + const emptyFile = path.resolve(modelPath, 'empty.ts'); + expect(await modelFileValidation(emptyFile)).toBe(false); +}); + +/** + * Model validation shouldn't allow duplicated keys + */ +test('Not allowing duplicated model keys', async (): Promise => { + const data1Path = path.resolve(modelPath, 'data1.ts'); + expect(await modelFileValidation(data1Path)).toBe(true); + const data2Path = path.resolve(modelPath, 'data2.ts'); + expect(await modelFileValidation(data2Path)).toBe(false); +}); + diff --git a/test/tests/validations/stressValidator.ts b/test/tests/validations/stressValidator.ts new file mode 100644 index 0000000..f0cc3e0 --- /dev/null +++ b/test/tests/validations/stressValidator.ts @@ -0,0 +1,98 @@ +import path from 'path'; +import waitForExpect from 'wait-for-expect'; + +import { WatcherOptions, OnReady } from '../../../model/watcher'; + +import onError from '../../../utils/onError'; +import Validator from '../../../utils/runtimeValidator'; +import watchFolder from '../../../utils/watchFolder'; +import fileValidation from '../../../utils/modelFileValidation'; +import { mkDir, emptyFolder, exists, writeFile } from '../../../tools/fs'; + +const serverPath = path.resolve( + __dirname, + '../../mocks/server/stress-validator', +); + +beforeAll(async () => { + await emptyFolder(serverPath); +}); + +const writeSeveralFiles = async ( + filePath: string, + nFiles = 5, +): Promise => { + const files = new Array(nFiles) + .fill(null) + .map((_val, i) => path.resolve(filePath, `file-${i}.ts`)); + await Promise.all(files.map(file => writeFile(file, '// test file'))); +}; + +/** + * Validator should process several files. Method `processQueue` should be called when already processing and `filesToProcess` array should be filtered when adding new files + */ +test('Stress validator by writing several files at once', async (): Promise< + void +> => { + const onValidation = (): void => { + // Empty validation handler for testing purposes + }; + let onEvent: ( + eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', + eventPath: string, + ) => void = null; + const onReady: OnReady = async (watcher, targetPath): Promise => { + const validator = new Validator(fileValidation, onValidation, targetPath); + onEvent = jest.fn((eventName, eventPath): void => { + validator.addFileToQueue({ targetPath: eventPath, type: eventName }); + }); + watcher.on('all', onEvent); + }; + const jestOnReady = jest.fn(onReady); + const watcherOptions: WatcherOptions = { + onError, + onReady: jestOnReady, + targetPath: serverPath, + }; + + const watcher = await watchFolder(watcherOptions); + await waitForExpect( + async (): Promise => { + expect(jestOnReady).toHaveBeenCalled(); + }, + ); + + const folderPath = path.resolve(serverPath, 'folder'); + await mkDir(folderPath); + await waitForExpect( + async (): Promise => { + expect(await exists(folderPath)).toBe(true); + }, + ); + + const filePath = path.resolve(folderPath, 'file.ts'); + await writeFile(filePath, '// test file'); + await waitForExpect( + async (): Promise => { + expect(await exists(filePath)).toBe(true); + expect(onEvent).toHaveBeenCalledWith('add', filePath); + }, + ); + + const lastFilePath = path.resolve(folderPath, 'last-file.ts'); + setTimeout(async function writeFiles(): Promise { + await writeSeveralFiles(folderPath); + setTimeout(async function writeLastFile(): Promise { + await writeFile(lastFilePath, '// test file'); + }, 2000); + }, 2000); + + await waitForExpect( + async (): Promise => { + expect(await exists(lastFilePath)).toBe(true); + expect(onEvent).toHaveBeenCalledWith('add', lastFilePath); + }, + ); + + await watcher.close(); +}); diff --git a/test/tests/validations/validationFail.ts b/test/tests/validations/validationFail.ts new file mode 100644 index 0000000..4a73b9e --- /dev/null +++ b/test/tests/validations/validationFail.ts @@ -0,0 +1,41 @@ +import path from 'path'; +import waitForExpect from 'wait-for-expect'; + +import { WatcherOptions, OnReady } from '../../../model/watcher'; + +import onError from '../../../utils/onError'; +import Validator from '../../../utils/runtimeValidator'; +import watchFolder from '../../../utils/watchFolder'; +import fileValidation from '../../../utils/apiFileValidation'; + +const serverPath = path.resolve(__dirname, '../../mocks/server/validation-fail'); + +/** + * When validator processes a not validating file, it should be added to `failingFiles` map + */ +test('Failing file should be processed properly', async (): Promise => { + const onValidation = (): void => { + // Empty validation handler for testing purposes + }; + let validator: Validator = null; + const onReady: OnReady = async (watcher, targetPath): Promise => { + validator = new Validator(fileValidation, onValidation, targetPath); + const onEvent = jest.fn((eventName, eventPath): void => { + validator.addFileToQueue({ targetPath: eventPath, type: eventName }); + }); + watcher.on('all', onEvent); + }; + const watcherOptions: WatcherOptions = { + onError, + onReady, + targetPath: serverPath, + }; + const watcher = await watchFolder(watcherOptions); + + await waitForExpect(async (): Promise => { + expect(validator).not.toBe(null); + expect(validator.failingFiles.size).toBe(1); + }); + + await watcher.close(); +}); \ No newline at end of file diff --git a/test/tests/validations/validator.ts b/test/tests/validations/validator.ts new file mode 100644 index 0000000..61acd8c --- /dev/null +++ b/test/tests/validations/validator.ts @@ -0,0 +1,106 @@ +import path from 'path'; +import waitForExpect from 'wait-for-expect'; + +import { WatcherOptions, OnReady } from '../../../model/watcher'; + +import onError from '../../../utils/onError'; +import Validator from '../../../utils/runtimeValidator'; +import watchFolder from '../../../utils/watchFolder'; +import fileValidation from '../../../utils/modelFileValidation'; +import { + mkDir, + emptyFolder, + exists, + writeFile, + unlink, + rmDir, +} from '../../../tools/fs'; + +const serverPath = path.resolve(__dirname, '../../mocks/server/validator'); + +beforeAll(async () => { + await emptyFolder(serverPath); +}); + +/** + * Validator should handle basic event types properly + */ +test('Basic validator flow', async (): Promise => { + const onValidation = (): void => { + // Empty validation handler for testing purposes + }; + let onEvent: ( + eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', + eventPath: string, + ) => void = null; + const onReady: OnReady = async (watcher, targetPath): Promise => { + const validator = new Validator(fileValidation, onValidation, targetPath); + onEvent = jest.fn((eventName, eventPath): void => { + validator.addFileToQueue({ targetPath: eventPath, type: eventName }); + }); + watcher.on('all', onEvent); + }; + const jestOnReady = jest.fn(onReady); + const watcherOptions: WatcherOptions = { + onError, + onReady: jestOnReady, + targetPath: serverPath, + }; + + const watcher = await watchFolder(watcherOptions); + await waitForExpect( + async (): Promise => { + expect(jestOnReady).toHaveBeenCalled(); + }, + ); + + const folderPath = path.resolve(serverPath, 'folder'); + await mkDir(folderPath); + await waitForExpect( + async (): Promise => { + expect(await exists(folderPath)).toBe(true); + }, + ); + + const filePath = path.resolve(folderPath, 'file.ts'); + await writeFile(filePath, '// test file'); + await waitForExpect( + async (): Promise => { + expect(await exists(filePath)).toBe(true); + expect(onEvent).toHaveBeenCalledWith( + 'add', + filePath, + ); + }, + ); + + await writeFile(filePath, '// test file changed'); + await waitForExpect(async (): Promise => { + expect(onEvent).toHaveBeenCalledWith( + 'change', + filePath, + ); + }); + + await unlink(filePath); + await waitForExpect( + async (): Promise => { + expect(await exists(filePath)).toBe(false); + expect(onEvent).toHaveBeenCalledWith( + 'unlink', + filePath, + ); + }, + ); + + await rmDir(folderPath); + await waitForExpect(async (): Promise => { + expect(await exists(folderPath)).toBe(false); + expect(onEvent).toHaveBeenCalledWith( + 'unlinkDir', + folderPath, + ); + }); + + await watcher.close(); +}); diff --git a/test/tests/watcher/initWatchers.ts b/test/tests/watcher/initWatchers.ts index a2f882f..86169ed 100644 --- a/test/tests/watcher/initWatchers.ts +++ b/test/tests/watcher/initWatchers.ts @@ -1,52 +1,109 @@ import path from 'path'; import waitForExpect from 'wait-for-expect'; -import { runtimePath, apiPath, modelPath } from '../../../settings'; +import { apiPath, modelPath, proxyPath } from '../../../settings'; +import { emptyFolder, ensureDir, writeFile, exists } from '../../../tools/fs'; import initWatchers from '../../../utils/initWatchers'; -import { exists, rimraf } from '../../../tools/fs'; +import { setForceDisableJestDetection } from '../../../tools/isJest'; +const serverPath = path.resolve(__dirname, '../../mocks/server/init-ok'); +const serverApiPath = path.resolve(serverPath, apiPath); +const serverModelPath = path.resolve(serverPath, modelPath); const mainPath = path.resolve(__dirname, '../../mocks'); +beforeEach(async (): Promise => { + await emptyFolder(serverPath); + await ensureDir(serverApiPath); + await ensureDir(serverModelPath); +}); + +const apiFileContent = `import { Data } from '../model/ok'; + +/** + * Method documentation + */ +const method = async (): Promise => { + return { + info: 'info', + }; +}; + +export default method; +`; + +const modeFileContent = ` +export interface Data { + info: string; +} +`; + /** * Unexisting server path will throw exception */ -test('Unexisting server path will throw exception', (): Promise => { +test('Unexisting server path will throw exception', async (): Promise => { const wrongPath = '/wrong/path/to/server'; - expect.assertions(1); - return expect(initWatchers(wrongPath, wrongPath)).rejects.toBeInstanceOf( - Error, - ); + await waitForExpect(async (): Promise => { + expect(initWatchers(wrongPath, wrongPath)).rejects.toBeInstanceOf(Error); + }); }); /** - * Server path must exist and watcher should process existing files + * Should work with existing server path and process files when added */ -test(`Watchers should work for existing server path and process existing files when starting`, async (): Promise< - void -> => { - const workingPath = path.resolve(mainPath, 'working-server'); - const runtimeDestPath = path.resolve(mainPath, runtimePath); - const expectedApiFilePath = path.resolve( - runtimeDestPath, - apiPath, - 'documented.ts', - ); - const expectedModelFilePath = path.resolve( - runtimeDestPath, - modelPath, - 'documented.ts', - ); - await rimraf(runtimeDestPath); - const watchers = await initWatchers(workingPath, mainPath); - await waitForExpect( - async (): Promise => { - expect(await exists(expectedApiFilePath)).toBe(true); - expect(await exists(expectedModelFilePath)).toBe(true); - }, - ); - await Promise.all( - watchers.map(async watcher => { - await watcher.close(); - }), - ); +test('Basic watchers flow', async (): Promise => { + const watchers = await initWatchers(serverPath, mainPath); + const handler = jest.fn((): void => { + // Empty function to check event handler + }); + watchers.forEach((watcher): void => { + watcher.on('all', handler); + }); + const fileName = 'ok.ts'; + const serverApiFilePath = path.resolve(serverApiPath, fileName); + const serverModelFilePath = path.resolve(serverModelPath, fileName); + await writeFile(serverApiFilePath, apiFileContent); + await writeFile(serverModelFilePath, modeFileContent); + await waitForExpect(async (): Promise => { + expect(await exists(serverApiFilePath)).toBe(true); + expect(await exists(serverModelFilePath)).toBe(true); + expect(handler).toHaveBeenCalledWith( + 'add', + serverApiFilePath, + ); + expect(handler).toHaveBeenCalledWith( + 'add', + serverModelFilePath, + ); + }); + + await Promise.all(watchers.map(w => w.close())); }); + + +/** + * When disabling jest, watchers should process files when added + */ +test('Complete watchers flow', async (): Promise => { + setForceDisableJestDetection(true); + const watchers = await initWatchers(serverPath, mainPath); + const fileName = 'ok.ts'; + const serverApiFilePath = path.resolve(serverApiPath, fileName); + const serverModelFilePath = path.resolve(serverModelPath, fileName); + await writeFile(serverApiFilePath, apiFileContent); + await writeFile(serverModelFilePath, modeFileContent); + await waitForExpect(async (): Promise => { + expect(await exists(serverApiFilePath)).toBe(true); + expect(await exists(serverModelFilePath)).toBe(true); + }); + + const proxyIndexPath = path.resolve(mainPath, proxyPath, 'api', 'index.ts'); + const modelResultingPath = path.resolve(mainPath, proxyPath, 'model', fileName); + + await waitForExpect(async (): Promise => { + expect(await exists(proxyIndexPath)).toBe(true); + expect(await exists(modelResultingPath)).toBe(true); + }); + + setForceDisableJestDetection(false); + await Promise.all(watchers.map(w => w.close())); +}, 10000); diff --git a/test/tests/watcher/watcherAddEventHandler.ts b/test/tests/watcher/watcherAddEventHandler.ts deleted file mode 100644 index 8215ecc..0000000 --- a/test/tests/watcher/watcherAddEventHandler.ts +++ /dev/null @@ -1,69 +0,0 @@ -import path from 'path'; -import waitForExpect from 'wait-for-expect'; - -import { apiPath } from '../../../settings'; -import onError from '../../../utils/onError'; -import watchFolder from '../../../utils/watchFolder'; -import getOnApiWatcherReady from '../../../utils/getOnApiWatcherReady'; -import { exists, rimraf, emptyFolder, writeFile } from '../../../tools/fs'; - -const runtimePath = '.a2r-add/runtime'; - -const mainPath = path.resolve(__dirname, '../../mocks'); -const targetPath = path.resolve(__dirname, '../../mocks/server/right'); -const fileName = 'documented.ts'; -const documentedFilePath = path.resolve(targetPath, fileName); -const runtimeDestPath = path.resolve(mainPath, runtimePath); -const runtimeApiDestPath = path.resolve(runtimeDestPath, apiPath); -const expectedApiFilePath = path.resolve(runtimeApiDestPath, fileName); - -const validatedFileContent = `/** - * Method documentation - */ -const method = (): void => { - // Do stuff -}; - -export default method;`; - -beforeAll(async (): Promise => { - await emptyFolder(targetPath); - await emptyFolder(runtimeApiDestPath); -}); - -/** - * Once watcher is ready and a new file is added, it should be processed - */ -test(`Watcher should process a file when added`, async (): Promise< - void -> => { - await rimraf(runtimeDestPath); - const onApiWatcherReady = getOnApiWatcherReady(runtimeApiDestPath); - const jestOnReady = jest.fn(onApiWatcherReady); - const watcher = await watchFolder({ - onError, - targetPath, - onReady: jestOnReady, - }); - await waitForExpect( - async (): Promise => { - expect(jestOnReady).toHaveBeenCalled(); - }, - ); - setTimeout(async (): Promise => { - await writeFile(documentedFilePath, validatedFileContent); - }, 1000); - await waitForExpect( - async (): Promise => { - expect(await exists(documentedFilePath)).toBe(true); - expect(await exists(expectedApiFilePath)).toBe(true); - }, - ); - await watcher.close(); -}); - -afterAll(async (): Promise => { - await emptyFolder(targetPath); - await emptyFolder(runtimeApiDestPath); -}); - diff --git a/test/tests/watcher/watcherStress.ts b/test/tests/watcher/watcherStress.ts deleted file mode 100644 index 03176bc..0000000 --- a/test/tests/watcher/watcherStress.ts +++ /dev/null @@ -1,105 +0,0 @@ -import path from 'path'; -import waitForExpect from 'wait-for-expect'; - -import { apiPath } from '../../../settings'; -import { emptyFolder, writeFile, exists, rimraf } from '../../../tools/fs'; -import getOnApiWatcherReady from '../../../utils/getOnApiWatcherReady'; -import watchFolder from '../../../utils/watchFolder'; -import onError from '../../../utils/onError'; - -const runtimePath = '.a2r-stress/runtime'; - -const targetPath = path.resolve(__dirname, '../../mocks/server/stressing-api'); -const mainPath = path.resolve(__dirname, '../../mocks'); -const runtimeDestPath = path.resolve(mainPath, runtimePath, apiPath); - -const lastFileName = 'validated-final.ts'; -const lastFilePath = path.resolve(targetPath, lastFileName); -const lastFileDestPath = path.resolve(mainPath, runtimePath, apiPath, lastFileName); - -const validatedFileContent = `/** - * Method documentation - */ -const method = (): void => { - // Do stuff -}; - -export default method;`; - -beforeAll( - async (): Promise => { - await emptyFolder(targetPath); - await emptyFolder(runtimeDestPath); - }, -); - -const writeAndChangeFiles = async (nFiles = 5): Promise => { - const files = new Array(nFiles) - .fill(null) - .map((_val, i) => path.resolve(targetPath, `validated-${i}.ts`)); - await Promise.all( - files.map((file) => - writeFile( - file, - `${validatedFileContent}${Math.random() < 0.5 ? '\n' : '\n\n'}`, - ), - ), - ); -}; - -/** - * Basic API Watcher should work - */ -test(`API should work fine with multiple file changes`, async (): Promise< - void -> => { - await rimraf(runtimeDestPath); - const onApiWatcherReady = getOnApiWatcherReady(runtimeDestPath); - const jestOnReady = jest.fn(onApiWatcherReady); - const nFiles = 5; - const files = new Array(nFiles) - .fill(null) - .map((_val, i) => path.resolve(targetPath, `validated-${i}.ts`)); - - const watcher = await watchFolder({ - onError, - targetPath, - onReady: jestOnReady, - }); - await waitForExpect( - async (): Promise => { - expect(jestOnReady).toHaveBeenCalled(); - }, - ); - await Promise.all(files.map((file) => writeFile(file, validatedFileContent))); - await Promise.all( - files.map((file) => - waitForExpect( - async (): Promise => { - expect(await exists(file)).toBe(true); - }, - ), - ), - ); - setTimeout(async function writeFiles(): Promise { - await writeAndChangeFiles(nFiles); - setTimeout(async function closeWatcher(): Promise { - writeFile(lastFilePath, validatedFileContent) - }, 2000); - }, 2000); - await waitForExpect( - async (): Promise => { - expect(await exists(lastFilePath)).toBe(true); - expect(await exists(lastFileDestPath)).toBe(true); - }, - 15000, - ); - await watcher.close(); -}, 25000); - -afterAll( - async (): Promise => { - await emptyFolder(targetPath); - await emptyFolder(runtimeDestPath); - }, -); diff --git a/test/tests/watcher/watcherUnlinkEventHandler.ts b/test/tests/watcher/watcherUnlinkEventHandler.ts deleted file mode 100644 index 06b297b..0000000 --- a/test/tests/watcher/watcherUnlinkEventHandler.ts +++ /dev/null @@ -1,77 +0,0 @@ -import path from 'path'; -import waitForExpect from 'wait-for-expect'; - -import { apiPath } from '../../../settings'; -import onError from '../../../utils/onError'; -import watchFolder from '../../../utils/watchFolder'; -import getOnApiWatcherReady from '../../../utils/getOnApiWatcherReady'; -import { exists, rimraf, emptyFolder, writeFile, unlink, ensureDir } from '../../../tools/fs'; - -const runtimePath = '.a2r-unlink/runtime'; - -const mainPath = path.resolve(__dirname, '../../mocks'); -const targetPath = path.resolve(__dirname, '../../mocks/server/unlink-api'); -const subFolderPath = path.resolve(targetPath, 'folder'); -const fileName = 'unlink-documented.ts'; -const documentedFilePath = path.resolve(targetPath, fileName); -const subFolderDocumentedFilePath = path.resolve(subFolderPath, fileName); -const runtimeDestPath = path.resolve(mainPath, runtimePath); -const runtimeApiDestPath = path.resolve(runtimeDestPath, apiPath); -const expectedApiFilePath = path.resolve(runtimeApiDestPath, fileName); -const expectedApiSubFolderFilePath = path.resolve(runtimeApiDestPath, 'folder', fileName); - -const validatedFileContent = `/** - * Method documentation - */ -const method = (): void => { - // Do stuff -}; - -export default method;`; - -beforeAll(async (): Promise => { - await emptyFolder(targetPath); - await emptyFolder(runtimeApiDestPath); -}); - -/** - * Basic API Watcher unlink flow should cover unlink and unlinkDir event types - */ -test(`Basic API Watcher unlink flow`, async (): Promise => { - await rimraf(runtimeDestPath); - const onApiWatcherReady = getOnApiWatcherReady(runtimeApiDestPath); - const jestOnReady = jest.fn(onApiWatcherReady); - await writeFile(documentedFilePath, validatedFileContent); - await ensureDir(subFolderPath); - await writeFile(subFolderDocumentedFilePath, validatedFileContent); - const watcher = await watchFolder({ - onError, - targetPath, - onReady: jestOnReady, - }); - await waitForExpect( - async (): Promise => { - expect(jestOnReady).toHaveBeenCalled(); - expect(await exists(expectedApiFilePath)).toBe(true); - expect(await exists(expectedApiSubFolderFilePath)).toBe(true); - }, - ); - setTimeout(async (): Promise => { - await unlink(documentedFilePath); - await rimraf(subFolderPath); - }, 1000); - await waitForExpect( - async (): Promise => { - expect(await exists(documentedFilePath)).toBe(false); - expect(await exists(subFolderPath)).toBe(false); - expect(await exists(expectedApiFilePath)).toBe(false); - expect(await exists(expectedApiSubFolderFilePath)).toBe(false); - }, - ); - await watcher.close(); -}); - -afterAll(async (): Promise => { - await emptyFolder(targetPath); - await emptyFolder(runtimeApiDestPath); -}); diff --git a/tools/capitalize.ts b/tools/capitalize.ts new file mode 100644 index 0000000..787dd57 --- /dev/null +++ b/tools/capitalize.ts @@ -0,0 +1,7 @@ +/** + * Capitalizes string + * @param src Source string + */ +const capitalize = (src: string): string => `${src.charAt(0).toUpperCase()}${src.slice(1)}`; + +export default capitalize; diff --git a/tools/cleanText.ts b/tools/cleanText.ts new file mode 100644 index 0000000..2186344 --- /dev/null +++ b/tools/cleanText.ts @@ -0,0 +1,319 @@ +/* eslint-disable no-control-regex */ +import capitalize from './capitalize'; + +const defaultDiacriticsRemovalMap = [ + { + base: 'A', + letters: + '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F', + }, + { base: 'AA', letters: '\uA732' }, + { base: 'AE', letters: '\u00C6\u01FC\u01E2' }, + { base: 'AO', letters: '\uA734' }, + { base: 'AU', letters: '\uA736' }, + { base: 'AV', letters: '\uA738\uA73A' }, + { base: 'AY', letters: '\uA73C' }, + { + base: 'B', + letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181', + }, + { + base: 'C', + letters: + '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E', + }, + { + base: 'D', + letters: + '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779', + }, + { base: 'DZ', letters: '\u01F1\u01C4' }, + { base: 'Dz', letters: '\u01F2\u01C5' }, + { + base: 'E', + letters: + '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E', + }, + { base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' }, + { + base: 'G', + letters: + '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E', + }, + { + base: 'H', + letters: + '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D', + }, + { + base: 'I', + letters: + '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197', + }, + { base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' }, + { + base: 'K', + letters: + '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2', + }, + { + base: 'L', + letters: + '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780', + }, + { base: 'LJ', letters: '\u01C7' }, + { base: 'Lj', letters: '\u01C8' }, + { base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' }, + { + base: 'N', + letters: + '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4', + }, + { base: 'NJ', letters: '\u01CA' }, + { base: 'Nj', letters: '\u01CB' }, + { + base: 'O', + letters: + '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C', + }, + { base: 'OI', letters: '\u01A2' }, + { base: 'OO', letters: '\uA74E' }, + { base: 'OU', letters: '\u0222' }, + { base: 'OE', letters: '\u008C\u0152' }, + { base: 'oe', letters: '\u009C\u0153' }, + { + base: 'P', + letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754', + }, + { base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' }, + { + base: 'R', + letters: + '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782', + }, + { + base: 'S', + letters: + '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784', + }, + { + base: 'T', + letters: + '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786', + }, + { base: 'TZ', letters: '\uA728' }, + { + base: 'U', + letters: + '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244', + }, + { base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' }, + { base: 'VY', letters: '\uA760' }, + { + base: 'W', + letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72', + }, + { base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' }, + { + base: 'Y', + letters: + '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE', + }, + { + base: 'Z', + letters: + '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762', + }, + { + base: 'a', + letters: + '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250', + }, + { base: 'aa', letters: '\uA733' }, + { base: 'ae', letters: '\u00E6\u01FD\u01E3' }, + { base: 'ao', letters: '\uA735' }, + { base: 'au', letters: '\uA737' }, + { base: 'av', letters: '\uA739\uA73B' }, + { base: 'ay', letters: '\uA73D' }, + { + base: 'b', + letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253', + }, + { + base: 'c', + letters: + '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184', + }, + { + base: 'd', + letters: + '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A', + }, + { base: 'dz', letters: '\u01F3\u01C6' }, + { + base: 'e', + letters: + '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD', + }, + { base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' }, + { + base: 'g', + letters: + '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F', + }, + { + base: 'h', + letters: + '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265', + }, + { base: 'hv', letters: '\u0195' }, + { + base: 'i', + letters: + '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131', + }, + { base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' }, + { + base: 'k', + letters: + '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3', + }, + { + base: 'l', + letters: + '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747', + }, + { base: 'lj', letters: '\u01C9' }, + { base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' }, + { + base: 'n', + letters: + '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5', + }, + { base: 'nj', letters: '\u01CC' }, + { + base: 'o', + letters: + '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275', + }, + { base: 'oi', letters: '\u01A3' }, + { base: 'ou', letters: '\u0223' }, + { base: 'oo', letters: '\uA74F' }, + { + base: 'p', + letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755', + }, + { base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' }, + { + base: 'r', + letters: + '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783', + }, + { + base: 's', + letters: + '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B', + }, + { + base: 't', + letters: + '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787', + }, + { base: 'tz', letters: '\uA729' }, + { + base: 'u', + letters: + '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289', + }, + { base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' }, + { base: 'vy', letters: '\uA761' }, + { + base: 'w', + letters: + '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73', + }, + { base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' }, + { + base: 'y', + letters: + '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF', + }, + { + base: 'z', + letters: + '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763', + }, +]; + +const diacriticsMap = {}; +for (let i = 0, l = defaultDiacriticsRemovalMap.length; i < l; i++) { + const letters = defaultDiacriticsRemovalMap[i].letters.split(''); + for (let j = 0, k = letters.length; j < k; j++) { + diacriticsMap[letters[j]] = defaultDiacriticsRemovalMap[i].base; + } +} + +/** + * Clean text + * @param {string} str Source string to clean + * @param {boolean} toLower Transform to lower + * @param {boolean} removeNonAlphanumeric Remove any non-alphanumeric or non-space character + * @param {boolean} removeSpaces Remove spaces + * @param {boolean} turnToCamelCase Turn string to camel case + * @param {string} camelCaseSeparator Separator for camel case conversion + * @param {string} spaceSubstitute If provided, will be used to replace spaces + */ +const cleanText = ( + str: string, + toLower = false, + removeNonAlphanumeric = false, + removeSpaces = false, + turnToCamelCase = false, + camelCaseSeparator = ' ', + spaceSubstitute = '', +): string => { + let res = (str || '').trim(); + + res = res + .replace(/[\u00AD\u002D\u2011]+/g, '-') + .replace(/­/g, '') + .replace(/ /g, ' ') + .replace(/Á/g, 'a') + .replace(/á/g, 'a') + .replace(/É/g, 'e') + .replace(/é/g, 'e') + .replace(/Í/g, 'i') + .replace(/í/g, 'i') + .replace(/Ó/g, 'o') + .replace(/ó/g, 'o') + .replace(/Ú/g, 'u') + .replace(/ú/g, 'u') + .replace(/[^\u0000-\u007E]/g, a => diacriticsMap[a] || a); + + if (removeNonAlphanumeric) { + res = res.replace(/[^0-9a-zA-Z\-\s]/g, ''); + } + + res = res.replace(/\s{2,}/g, ' '); + + if (turnToCamelCase) { + res = res + .split(camelCaseSeparator) + .map((s, i) => (i ? s && capitalize(s) : s && s.toLowerCase())) + .join(''); + } + + if (removeSpaces) { + res = res.replace(/\s/g, spaceSubstitute); + if (spaceSubstitute) { + res = res.replace( + new RegExp(`${spaceSubstitute}+`, 'g'), + spaceSubstitute, + ); + } + } + + return toLower ? res.toLowerCase() : res; +}; + +export default cleanText; diff --git a/tools/fs.ts b/tools/fs.ts index cfe6a49..dc6aa75 100644 --- a/tools/fs.ts +++ b/tools/fs.ts @@ -113,15 +113,32 @@ export const ensureDir = async ( * Gets files recursively * @param folderPath Path to get files from */ -export const getFilesRecursively = async (folderPath: string): Promise => { - const contents = await readDir(folderPath, { encoding: 'utf8', withFileTypes: true }); - const files = await Promise.all(contents.map(async (content): Promise => { - if (content.isDirectory()) { - const folderFiles = await getFilesRecursively(path.resolve(folderPath, content.name)); - return folderFiles; - } - return [path.resolve(folderPath, content.name)]; - })); +export const getFilesRecursively = async ( + folderPath: string, + extName?: string[], +): Promise => { + const contents = await readDir(folderPath, { + encoding: 'utf8', + withFileTypes: true, + }); + const files = await Promise.all( + contents.map( + async (content): Promise => { + if (content.isDirectory()) { + const folderFiles = await getFilesRecursively( + path.resolve(folderPath, content.name), + extName, + ); + return folderFiles; + } + const ext = path.extname(content.name); + if (!extName || !extName.length || extName.indexOf(ext) !== -1) { + return [path.resolve(folderPath, content.name)]; + } + return []; + }, + ), + ); return files.reduce((t, f) => [...t, ...f], []); }; diff --git a/tools/isClient.ts b/tools/isClient.ts new file mode 100644 index 0000000..92c9678 --- /dev/null +++ b/tools/isClient.ts @@ -0,0 +1,21 @@ +let forceServerSimulation = false; + +/** + * Allows you to disable client detection + * @param {boolean} value True to force Server Side Simulation + */ +export const setForceServerSimulation = (value: boolean): void => { + forceServerSimulation = value; +}; + +/** + * Checks if the script is running on the client side + */ +const isClient = (): boolean => { + if (forceServerSimulation) { + return false; + } + return typeof window === 'object'; +}; + +export default isClient; \ No newline at end of file diff --git a/tools/isJest.ts b/tools/isJest.ts index 00887bf..f7df286 100644 --- a/tools/isJest.ts +++ b/tools/isJest.ts @@ -11,11 +11,9 @@ export const setForceDisableJestDetection = (value: boolean): void => { /** * Checks if the script is running using Jest test engine */ -const isJest = (): boolean => { +export const isJest = (): boolean => { if (forceDisableJestDetection) { return false; } return typeof jest !== 'undefined'; }; - -export default isJest; \ No newline at end of file diff --git a/utils/apiProxy.ts b/utils/apiProxy.ts new file mode 100644 index 0000000..d4d77bc --- /dev/null +++ b/utils/apiProxy.ts @@ -0,0 +1,146 @@ +import ts from 'typescript'; +import path from 'path'; +import { out } from '@a2r/telemetry'; + +import { + APIStructure, + ModuleInfo, + ApiNamespace, + GroupedModelImports, +} from '../model/api'; + +import { defaultApiSourcePath, defaultProxyTargetPath } from '../settings'; +import { getFilesRecursively, writeFile, copyFile } from '../tools/fs'; +import getModuleInfo from './getModuleInfo'; +import getGroupedModelImports from './getGroupedModelImports'; +import getProxyMethod from './getProxyMethod'; +import updateApiObject from './updateApiObject'; +import getApiObjectText from './getApiObject'; +import getMethodWrapper from './getMethodWrapper'; +import getSocketProvider from './getSocketProvider'; + +export const api: APIStructure = {}; + +const isClientInternalPath = path.resolve(__dirname, '../tools/isClient.ts'); + +/** + * Gets external needed imports + */ +const getExternalImports = (): string => + [`import generateId from 'shortid';`].join('\n'); + +/** + * Gets internal needed imports + */ +const getInternalImports = (): string => + [ + `import socket, { MethodCall, SocketMessage } from './socket';`, + `import isClient from './isClient';`, + ].join('\n'); + +/** + * Gets model imports text + * @param groupedModelImports Grouped model imports (by path) + */ +const getInternalModelImports = ( + groupedModelImports: GroupedModelImports[], +): string => + groupedModelImports + .map( + ({ def, named, path: fromPath }) => + `import ${def ? `${def}${named && named.length ? ', ' : ''}` : ''}${ + named && named.length ? `{ ${named.join(', ')} }` : '' + } from ${fromPath};`, + ) + .join('\n'); + +/** + * Gets docs text + * @param jsDoc `jsDoc` property from `JSDocContainer` + */ +const getDocs = (jsDoc: ts.JSDoc[]): string => { + return jsDoc[0].getFullText(); +}; + +const getValidMethodName = ( + methodName: string, + existing: { [key: string]: boolean }, +): string => { + let res = methodName; + let i = 2; + while (existing[res]) { + res = `${methodName}${i}`; + i++; + } + return res; +}; + +/** + * Build API proxy and needed files + * @param apiSourcePath API source path + * @param proxyTargetPath Proxy target path, where generated files will be written + */ +export const build = async ( + apiSourcePath = defaultApiSourcePath, + proxyTargetPath = defaultProxyTargetPath, +): Promise => { + const proxyIndexPath = path.resolve(proxyTargetPath, 'index.ts'); + const socketFilePath = path.resolve(proxyTargetPath, 'socket.ts'); + const isClientFilePath = path.resolve(proxyTargetPath, 'isClient.ts'); + const files = await getFilesRecursively(apiSourcePath, ['.ts']); + + const modulesInfo: ModuleInfo[] = await Promise.all( + files.map(file => getModuleInfo(file, apiSourcePath)), + ); + + let apiObject: ApiNamespace = { + key: 'api', + namespaces: [], + methods: [], + }; + + const imports = []; + const methods = []; + const methodsNames: { [key: string]: boolean } = {}; + + for (let i = 0, l = modulesInfo.length; i < l; i++) { + const { + mainMethodDocs, + mainMethodName, + mainMethodParamNodes, + mainMethodReturnTypeInfo, + modelImports, + keys, + } = modulesInfo[i]; + const doc = getDocs(mainMethodDocs.jsDoc as ts.JSDoc[]); + const methodName = getValidMethodName(mainMethodName, methodsNames); + methodsNames[methodName] = true; + const method = getProxyMethod( + keys.join('.'), + methodName, + mainMethodParamNodes, + mainMethodReturnTypeInfo, + ); + imports.push(...modelImports); + methods.push([doc, method].join('\n')); + apiObject = updateApiObject(apiObject, keys, methodName); + } + + const groupedImports = getGroupedModelImports(imports); + + await writeFile(socketFilePath, getSocketProvider()); + await copyFile(isClientInternalPath, isClientFilePath); + await writeFile( + proxyIndexPath, + [ + getExternalImports(), + getInternalImports(), + getInternalModelImports(groupedImports), + getMethodWrapper(), + ...methods, + getApiObjectText(apiObject), + 'export default api;\n', + ].filter(s => !!s).join('\n\n'), + ); + out.verbose('API Proxy built'); +}; diff --git a/utils/getApiObject.ts b/utils/getApiObject.ts new file mode 100644 index 0000000..f91947a --- /dev/null +++ b/utils/getApiObject.ts @@ -0,0 +1,32 @@ +import { ApiNamespace } from '../model/api'; + +const getApiObjectText = (namespace: ApiNamespace, level = 0): string => { + const { key, methods, namespaces } = namespace; + const lines: string[] = [ + `${Array(level * 2) + .fill(' ') + .join('')}${!level ? 'const ' : ''}${key}${!level ? ' =' : ':'} {`, + ]; + if (namespaces.length) { + lines.push(...namespaces.map(n => getApiObjectText(n, level + 1))); + } + if (methods.length) { + lines.push( + ...methods.map((m): string => { + return `${Array((level + 1) * 2) + .fill(' ') + .join('')}${ + m.key === m.methodName ? m.key : `${m.key}: ${m.methodName}` + },`; + }), + ); + } + lines.push( + `${Array(level * 2) + .fill(' ') + .join('')}}${level ? ',' : ';'}`, + ); + return lines.join('\n'); +}; + +export default getApiObjectText; diff --git a/utils/getExportsIdentifiersFromNodes.ts b/utils/getExportsIdentifiersFromNodes.ts new file mode 100644 index 0000000..d6fec85 --- /dev/null +++ b/utils/getExportsIdentifiersFromNodes.ts @@ -0,0 +1,36 @@ +import ts from 'typescript'; + +const getIdentifier = (nodes: ts.Node[]): string => { + let res = ''; + for (let i = 0, l = nodes.length; i < l && !res; i += 1) { + const node = nodes[i]; + if (ts.isIdentifier(node)) { + res = node.getText().trim(); + } + } + return res; +}; + +const getExportsIdentifiersFromNodes = ( + nodes: ts.Node[], + keys: string[] = new Array(), +): string[] => { + const res = [...keys]; + for (let i = 0, l = nodes.length; i < l; i += 1) { + const node = nodes[i]; + const children = node.getChildren(); + if ( + ts.isInterfaceDeclaration(node) || + ts.isEnumDeclaration(node) || + ts.isTypeAliasDeclaration(node) + ) { + const identifier = getIdentifier(children); + res.push(identifier); + } else if (children.length) { + res.push(...getExportsIdentifiersFromNodes(children)); + } + } + return res; +}; + +export default getExportsIdentifiersFromNodes; diff --git a/utils/getFunctionReturnTypeInfo.ts b/utils/getFunctionReturnTypeInfo.ts new file mode 100644 index 0000000..e381daa --- /dev/null +++ b/utils/getFunctionReturnTypeInfo.ts @@ -0,0 +1,50 @@ +import ts from 'typescript'; +import { out } from '@a2r/telemetry'; + +import { ReturnTypeInfo } from '../model/api'; + +const getTypeReference = ( + node: ts.Node, +): ts.TypeReferenceNode | null => { + let typeReference: ts.TypeReferenceNode | null = null; + const children = node.getChildren(); + for (let i = 0, l = children.length; i < l && !typeReference; i += 1) { + const child = children[i]; + if (ts.isTypeReferenceNode(child)) { + typeReference = child; + } + } + return typeReference; +}; + +const getFunctionReturnTypeInfo = ( + node: ts.FunctionDeclaration | ts.ArrowFunction, +): ReturnTypeInfo | null => { + let returnTypeInfo: ReturnTypeInfo | null = null; + const typeReference = getTypeReference(node); + if (typeReference) { + const children = typeReference.getChildren(); + let identifier = ''; + let type = ''; + let typeNode: ts.TypeNode | null = null; + for (let i = 0, l = children.length; i < l; i += 1) { + const child = children[i]; + if (ts.isIdentifier(child)) { + identifier = child.getText().trim(); + } else if (child.kind === ts.SyntaxKind.SyntaxList) { + typeNode = child.getChildAt(0) as ts.TypeNode; + type = typeNode.getText().trim(); + } + } + returnTypeInfo = { + identifier, + type, + typeNode, + }; + } else { + out.error(`No return type provided for method:\n${node.getFullText()}`); + } + return returnTypeInfo; +}; + +export default getFunctionReturnTypeInfo; diff --git a/utils/getGroupedModelImports.ts b/utils/getGroupedModelImports.ts new file mode 100644 index 0000000..4d0e040 --- /dev/null +++ b/utils/getGroupedModelImports.ts @@ -0,0 +1,52 @@ +import ts from 'typescript'; + +import { ModelImport, GroupedModelImports } from '../model/api'; + +const getNamedImports = (nodes: ts.Node[], sourceFile?: ts.SourceFile): string[] => { + const res: string[] = []; + for (let i = 0, l = nodes.length; i < l; i++) { + const node = nodes[i]; + if (ts.isIdentifier(node)) { + res.push(node.getFullText(sourceFile).trim()); + } else { + const children = node.getChildren(sourceFile); + if (children.length) { + res.push(...getNamedImports(children, sourceFile)); + } + } + } + return res; +}; + +const getGroupedModelImports = (imports: ModelImport[]): GroupedModelImports[] => { + const res: GroupedModelImports[] = []; + for (let i = 0, l = imports.length; i < l; i++) { + const { clause, path, sourceFile } = imports[i]; + const pathForProxy = path.replace(/([./]+)\/model/, '../model'); + let grouped = res.find(g => g.path === pathForProxy); + if (!grouped) { + grouped = { + path: pathForProxy, + }; + res.push(grouped); + } + const children = clause.getChildren(sourceFile); + for (let j = 0, k = children.length; j < k; j++) { + const child = children[j]; + if (ts.isIdentifier(child)) { + grouped.def = child.getFullText(sourceFile); + } + if (ts.isNamedImports(child)) { + grouped.named = Array.from( + new Set([ + ...(grouped.named || []), + ...getNamedImports(child.getChildren(sourceFile), sourceFile), + ]), + ); + } + } + } + return res; +}; + +export default getGroupedModelImports; diff --git a/utils/getMethodWrapper.ts b/utils/getMethodWrapper.ts new file mode 100644 index 0000000..32d8519 --- /dev/null +++ b/utils/getMethodWrapper.ts @@ -0,0 +1,49 @@ +const getMethodWrapper = (): string => { + return `const methodWrapper = (method: string, ...args: any[]): Promise => { + console.log('methodWrapper', method, [...args]); + if (!isClient()) { + console.log('on server side, executing api method directly'); + // try { + // const apiModule = getModule(method); + // return apiModule.default(...args); + // } catch (ex) { + // console.log('Error loading API module at server', ex.message, ex.stack); + // } + } + return new Promise((resolve, reject): void => { + console.log('socket connected?', socket && socket.connected); + if (socket) { + if (socket.disconnected) { + console.log('socket disconnected, connecting'); + socket.connect(); + } + const id = generateId(); + console.log('id', id); + socket.on(id, (res: SocketMessage): void => { + socket.off(id); + if (res.o) { + resolve(res.d); + } else { + const error = new Error(res.e); + error.stack = res.s; + reject(error); + } + }); + + const call: MethodCall = { + method, + id, + params: args, + }; + + console.log('before emit, call:', call); + socket.emit('*', call); + } else { + console.error('No client socket available!'); + reject(new Error('No client socket available!')); + } + }); +};`; +}; + +export default getMethodWrapper; diff --git a/utils/getModelImports.ts b/utils/getModelImports.ts new file mode 100644 index 0000000..a5c1206 --- /dev/null +++ b/utils/getModelImports.ts @@ -0,0 +1,30 @@ +import ts from 'typescript'; + +import { ModelImport } from '../model/api'; + +const getModelImports = (fileNodes: ts.Node[], sourceFile?: ts.SourceFile): ModelImport[] => { + const res: ModelImport[] = []; + for (let i = 0, l = fileNodes.length; i < l; i++) { + const node = fileNodes[i]; + const children = node.getChildren(sourceFile); + if (ts.isImportDeclaration(node)) { + let clause: ts.ImportClause = null; + let path: string = null; + for (let j = 0, k = children.length; j < k && (!clause || !path); j++) { + const child = children[j]; + if (ts.isImportClause(child)) { + clause = child; + } + if (ts.isStringLiteral(child)) { + path = child.getFullText(sourceFile); + } + } + res.push({ clause, path, sourceFile }); + } else if (children.length) { + res.push(...getModelImports(children, sourceFile)); + } + } + return res; +}; + +export default getModelImports; diff --git a/utils/getModuleInfo.ts b/utils/getModuleInfo.ts new file mode 100644 index 0000000..ad805fe --- /dev/null +++ b/utils/getModuleInfo.ts @@ -0,0 +1,55 @@ +import ts from 'typescript'; +import path from 'path'; + +import { ModuleInfo } from '../model/api'; + +import { readFile } from '../tools/fs'; +import cleanText from '../tools/cleanText'; +import getMainMethodName from './getMainMethodName'; +import getMainMethodNode from './getMainMethodNode'; +import getFunctionDocContainer from './getFunctionDocContainer'; +import getFunctionReturnTypeInfo from './getFunctionReturnTypeInfo'; +import getModelImports from './getModelImports'; + +/** + * Gets module info from a file + * @param filePath Module file path + * @param apiSourcePath API source path (used for relative path) + */ +const getModuleInfo = async (filePath: string, apiSourcePath: string): Promise => { + const content = await readFile(filePath, 'utf8'); + const mainMethodParamNodes: ts.ParameterDeclaration[] = []; + const sourceFile = ts.createSourceFile( + filePath, + content, + ts.ScriptTarget.Latest, + true, + ); + const fileNodes = sourceFile.getChildren(); + const mainMethodName = getMainMethodName(fileNodes); + const mainMethodNode = getMainMethodNode(fileNodes, mainMethodName); + mainMethodNode.forEachChild((child): void => { + if (ts.isParameter(child)) { + mainMethodParamNodes.push(child); + } + }); + const mainMethodDocs = getFunctionDocContainer(mainMethodNode); + const mainMethodReturnTypeInfo = getFunctionReturnTypeInfo(mainMethodNode); + const modelImports = getModelImports(fileNodes, sourceFile); + const keys = path + .relative(apiSourcePath, filePath) + .replace(/\.ts$/, '') + .split(path.sep) + .map(s => cleanText(s, false, true, true, true, '-')); + return { + mainMethodDocs, + mainMethodName, + mainMethodNode, + mainMethodParamNodes, + mainMethodReturnTypeInfo, + modelImports, + keys, + }; +}; + +export default getModuleInfo; diff --git a/utils/getOnApiWatcherReady.ts b/utils/getOnApiWatcherReady.ts deleted file mode 100644 index c105c39..0000000 --- a/utils/getOnApiWatcherReady.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { OnReady } from '../model/watcher'; - -import Validator from './runtimeValidator'; -import apiFileValidation from './apiFileValidation'; -import { copyContents, emptyFolder } from '../tools/fs'; - -const getOnApiWatcherReady = (apiRuntimePath: string): OnReady => async ( - watcher, - targetPath, -): Promise => { - const validator = new Validator( - targetPath, - apiFileValidation, - async (): Promise => { - await emptyFolder(apiRuntimePath); - await copyContents(targetPath, apiRuntimePath); - // Generate proxy - }, - ); - watcher.on('all', (eventName, eventPath): void => { - validator.addFileToQueue({ targetPath: eventPath, type: eventName }); - }); -}; - -export default getOnApiWatcherReady; diff --git a/utils/getProxyMethod.ts b/utils/getProxyMethod.ts new file mode 100644 index 0000000..1a7f264 --- /dev/null +++ b/utils/getProxyMethod.ts @@ -0,0 +1,27 @@ +import ts from 'typescript'; + +import { ReturnTypeInfo } from '../model/api'; + +const getProxyMethod = ( + key: string, + methodName: string, + paramNodes: ts.ParameterDeclaration[], + returnTypeInfo: ReturnTypeInfo, +): string => { + return `const ${methodName} = (${paramNodes + .map(n => n.getFullText().trim()) + .join(', ')}): Promise<${returnTypeInfo.type}> => methodWrapper('${key}'${ + paramNodes.length + ? `, ${paramNodes + .map(n => + n + .getChildAt(0) + .getFullText() + .trim(), + ) + .join(', ')}` + : '' + });`; +}; + +export default getProxyMethod; diff --git a/utils/getSocketProvider.ts b/utils/getSocketProvider.ts new file mode 100644 index 0000000..a5a0e61 --- /dev/null +++ b/utils/getSocketProvider.ts @@ -0,0 +1,72 @@ +import { socketPath, socketPort } from '../settings'; + +const getSocketProvider = (port = socketPort): string => { + const url = `http://localhost:${port}`; + + return `import io from "socket.io-client"; + +import isClient from './isClient'; + +/** + * Socket basic call + */ +export interface SocketCall { + /** + * Unique ID for socket transmission + * @type {string} + * @memberof MethodCall + */ + id: string; +} + +/** + * Socket method call + */ +export interface MethodCall extends SocketCall { + /** + * API Method name corresponding to complete key (like 'users.login') + * @memberof MethodCall + */ + method: string; + /** + * Params for API Method + * @memberof MethodCall + */ + params: any[]; +}; + +/** + * Socket standard response + */ +export interface SocketMessage { + /** + * Operation was ok (0) or not (1) + * @memberof SocketMessage + */ + o: number; + /** + * Operation error (if any) + * @memberof SocketMessage + */ + e?: string; + /** + * Operation stack (if error) + * @memberof SocketMessage + */ + s?: string; + /** + * Operation return data + * @memberof SocketMessage + */ + d: any; +}; + +const socket = io('${url}', { + autoConnect: isClient(), + path: '${socketPath}', +}); + +export default socket;`; +}; + +export default getSocketProvider; \ No newline at end of file diff --git a/utils/initWatchers.ts b/utils/initWatchers.ts index 836ff58..52ee1ae 100644 --- a/utils/initWatchers.ts +++ b/utils/initWatchers.ts @@ -1,13 +1,19 @@ import path from 'path'; import chokidar from 'chokidar'; +import { out } from '@a2r/telemetry'; -import { WatcherOptions } from '../model/watcher'; +import { WatcherOptions, OnReady } from '../model/watcher'; -import { apiPath, modelPath, runtimePath } from '../settings'; +import { apiPath, modelPath, proxyPath } from '../settings'; import { exists, emptyFolder } from '../tools/fs'; +import { fullPath } from '../tools/colors'; import watchFolder from './watchFolder'; import onError from './onError'; -import getOnApiWatcherReady from './getOnApiWatcherReady'; +import Validator from './runtimeValidator'; +import apiFileValidation from './apiFileValidation'; +import onApiValidation from './onApiValidation'; +import modelFileValidation from './modelFileValidation'; +import onModelValidation from './onModelValidation'; /** * Starts watchers @@ -22,24 +28,54 @@ const initWatchers = async ( throw new Error(`Provided server path doesn't exist`); } - const apiTargetPath = path.resolve(serverPath, apiPath); - const apiRuntimePath = path.resolve(mainPath, runtimePath, apiPath); - await emptyFolder(apiRuntimePath); - const onApiWatcherReady = getOnApiWatcherReady(apiRuntimePath); + const proxyTargetPath = path.resolve(mainPath, proxyPath); + + const apiSourcePath = path.resolve(serverPath, apiPath); + const apiProxyPath = path.resolve(proxyTargetPath, apiPath); + await emptyFolder(apiProxyPath); + const onApiWatcherReady: OnReady = async ( + watcher, + targetPath, + ): Promise => { + out.verbose(`API proxy path: ${fullPath(apiProxyPath)}`); + const validator = new Validator( + apiFileValidation, + onApiValidation, + targetPath, + apiProxyPath, + ); + watcher.on('all', (eventName, eventPath): void => { + validator.addFileToQueue({ targetPath: eventPath, type: eventName }); + }); + }; const apiWatcherOptions: WatcherOptions = { onError, - targetPath: apiTargetPath, + targetPath: apiSourcePath, onReady: onApiWatcherReady, }; const apiWatcher = await watchFolder(apiWatcherOptions); - const modelTargetPath = path.resolve(serverPath, modelPath); - const modelRuntimePath = path.resolve(mainPath, runtimePath, modelPath); - await emptyFolder(modelRuntimePath); - const onModelWatcherReady = getOnApiWatcherReady(modelRuntimePath); + const modelSourcePath = path.resolve(serverPath, modelPath); + const modelProxyPath = path.resolve(proxyTargetPath, modelPath); + await emptyFolder(modelProxyPath); + const onModelWatcherReady: OnReady = async ( + watcher, + targetPath, + ): Promise => { + out.verbose(`Model proxy path: ${fullPath(modelProxyPath)}`); + const validator = new Validator( + modelFileValidation, + onModelValidation, + targetPath, + modelProxyPath, + ); + watcher.on('all', (eventName, eventPath): void => { + validator.addFileToQueue({ targetPath: eventPath, type: eventName }); + }); + }; const modelWatcherOptions: WatcherOptions = { onError, - targetPath: modelTargetPath, + targetPath: modelSourcePath, onReady: onModelWatcherReady, }; const modelWatcher = await watchFolder(modelWatcherOptions); diff --git a/utils/modelFileValidation.ts b/utils/modelFileValidation.ts new file mode 100644 index 0000000..d6263ad --- /dev/null +++ b/utils/modelFileValidation.ts @@ -0,0 +1,39 @@ +import ts from 'typescript'; +import { out } from '@a2r/telemetry'; +import chalk from 'chalk'; + +import { readFile } from '../tools/fs'; +import { fullPath } from '../tools/colors'; +import getExportsIdentifiersFromNodes from './getExportsIdentifiersFromNodes'; + +const modelKeys = new Map(); + +const fileValidation = async (filePath: string): Promise => { + const content = await readFile(filePath, 'utf8'); + if (content) { + const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true); + const fileNodes = sourceFile.getChildren(); + const identifiers = getExportsIdentifiersFromNodes(fileNodes); + let validated = true; + for (let i = 0, l = identifiers.length; i < l && validated; i += 1) { + const identifier = identifiers[i]; + const keyPath = modelKeys.get(identifier); + if (keyPath && keyPath !== filePath) { + validated = false; + out.error(`There is already a type, interface or enum called ${chalk.bold( + identifier, + )} on file ${fullPath(keyPath)}`); + } + } + if (validated) { + identifiers.forEach((k) => { + modelKeys.set(k, filePath); + }); + } + return validated; + } + out.error(`File ${fullPath(filePath)} is empty`); + return false; +}; + +export default fileValidation; diff --git a/utils/onApiValidation.ts b/utils/onApiValidation.ts new file mode 100644 index 0000000..5198fcc --- /dev/null +++ b/utils/onApiValidation.ts @@ -0,0 +1,19 @@ +import { build } from './apiProxy'; +import { isJest } from '../tools/isJest'; + +import { OnValidation } from '../model/watcher'; + +/** + * Method executed when API is validated after changes are processed + */ +const onApiValidation: OnValidation = async ( + serverPath, + targetPath, +): Promise => { + if (!isJest()) { + // TODO: Call to main A2R instance to restart API Runtime + await build(serverPath, targetPath); + } +}; + +export default onApiValidation; diff --git a/utils/onModelValidation.ts b/utils/onModelValidation.ts new file mode 100644 index 0000000..672390e --- /dev/null +++ b/utils/onModelValidation.ts @@ -0,0 +1,20 @@ +import { OnValidation } from '../model/watcher'; + +import { copyContents, emptyFolder } from '../tools/fs'; +import { isJest } from '../tools/isJest'; + +/** + * Method executed when API is validated after changes are processed + */ +const onModelValidation: OnValidation = async ( + serverPath: string, + targetPath: string, +): Promise => { + if (!isJest()) { + // TODO: Call to main A2R instance to restart API Runtime + await emptyFolder(targetPath); + await copyContents(serverPath, targetPath); + } +}; + +export default onModelValidation; diff --git a/utils/runtimeValidator.ts b/utils/runtimeValidator.ts index d95eefc..6e560ba 100644 --- a/utils/runtimeValidator.ts +++ b/utils/runtimeValidator.ts @@ -1,6 +1,6 @@ import { out } from '@a2r/telemetry'; -import { ProcessInfo } from '../model/watcher'; +import { ProcessInfo, OnValidation } from '../model/watcher'; import { getFilesRecursively } from '../tools/fs'; @@ -9,17 +9,20 @@ import { getFilesRecursively } from '../tools/fs'; */ class RuntimeValidator { constructor( - targetPath: string, fileValidator: (filePath: string) => Promise, - onSuccess: () => Promise, + onValidation: OnValidation, + sourcePath: string, + targetPath?: string, ) { this.filesToProcess = new Array(); this.failingFiles = new Map(); this.validator = fileValidator; - this.onSuccess = onSuccess; + this.onValidation = onValidation; + this.sourcePath = sourcePath; + this.targetPath = targetPath; this.processing = true; - getFilesRecursively(targetPath).then((files) => { + getFilesRecursively(sourcePath, ['.ts']).then((files) => { this.filesToProcess.push(...files); this.processing = false; this.processQueue(); @@ -34,7 +37,7 @@ class RuntimeValidator { /** * Function to be executed if there are no failing files after all files are processed */ - private onSuccess: () => Promise; + private onValidation: OnValidation; /** * Indicates whether the validator is processing a file or not @@ -49,7 +52,17 @@ class RuntimeValidator { /** * Files that didn't pass validation */ - private failingFiles: Map; + public failingFiles: Map; + + /** + * Source path + */ + public sourcePath: string; + + /** + * Target path + */ + public targetPath?: string; /** * Processes pending files (from `filesToProcess`) @@ -70,10 +83,10 @@ class RuntimeValidator { this.processing = false; await this.processQueue(); } else { - this.processing = false; if (!this.failingFiles.size) { - await this.onSuccess(); + await this.onValidation(this.sourcePath, this.targetPath); } + this.processing = false; } } } diff --git a/utils/updateApiObject.ts b/utils/updateApiObject.ts new file mode 100644 index 0000000..56b73a7 --- /dev/null +++ b/utils/updateApiObject.ts @@ -0,0 +1,34 @@ +import { ApiNamespace } from '../model/api'; + +const updateApiObject = ( + structure: ApiNamespace, + keys: string[], + methodName: string, +): ApiNamespace => { + const newApiObject: ApiNamespace = { ...structure }; + const lastIndex = keys.length - 1; + return keys.reduce( + (t: ApiNamespace, key: string, i: number): ApiNamespace => { + if (i === lastIndex) { + t.methods.push({ + key, + methodName, + }); + return newApiObject; + } + let namespace = t.namespaces.find((n): boolean => n.key === key); + if (!namespace) { + namespace = { + key, + namespaces: [], + methods: [], + }; + t.namespaces.push(namespace); + } + return namespace; + }, + newApiObject, + ); +}; + +export default updateApiObject; diff --git a/utils/watchFolder.ts b/utils/watchFolder.ts index 2d6b521..9792dc8 100644 --- a/utils/watchFolder.ts +++ b/utils/watchFolder.ts @@ -9,26 +9,30 @@ import { WatcherOptions } from '../model/watcher'; * * @param {WatcherOptions} watcherOptions watcher options */ -const watchFolder = async (watcherOptions: WatcherOptions): Promise => - new Promise( - (resolve, reject): void => { - const { targetPath, onReady, onError, options } = watcherOptions; - const normalizedTargetPath = path.normalize(targetPath); - exists(normalizedTargetPath).then((pathExists): void => { - if (pathExists) { - const watcher = chokidar.watch(normalizedTargetPath, options); - watcher.on('error', onError); - watcher.on('ready', (): void => { - if (onReady) { - onReady(watcher, normalizedTargetPath); - } - resolve(watcher); - }); - } else { - reject(new Error(`Provided target path doesn't exist: ${normalizedTargetPath}`)); - } - }); - }, - ); +const watchFolder = async ( + watcherOptions: WatcherOptions, +): Promise => + new Promise((resolve, reject): void => { + const { targetPath, onReady, onError, options } = watcherOptions; + const normalizedTargetPath = path.normalize(targetPath); + exists(normalizedTargetPath).then((pathExists): void => { + if (pathExists) { + const watcher = chokidar.watch(normalizedTargetPath, options); + watcher.on('error', onError); + watcher.on('ready', (): void => { + if (onReady) { + onReady(watcher, normalizedTargetPath); + } + resolve(watcher); + }); + } else { + reject( + new Error( + `Provided target path doesn't exist: ${normalizedTargetPath}`, + ), + ); + } + }); + }); - export default watchFolder; +export default watchFolder;