From da7998cc0255298f816ddabe1b8574a6e76664ab Mon Sep 17 00:00:00 2001 From: Lenny Burdette Date: Wed, 28 Apr 2021 14:44:36 -0700 Subject: [PATCH] chore: format all files with prettier config is stored in package.json. this change also includes the lockfile which is a best practice for reproducible builds. --- .gitignore | 3 +- .vscode/extensions.json | 13 + package-lock.json | 5097 +++++++++++++++++ package.json | 6 + src/__tests__/githubCheckTests.ts | 38 +- src/__tests__/runTest.ts | 54 +- src/__tests__/suite/defaults.test.ts | 46 +- src/__tests__/suite/extension.test.ts | 22 +- src/__tests__/suite/helpers.ts | 53 +- src/__tests__/suite/index.ts | 67 +- src/__tests__/suite/noFolder.test.ts | 10 +- src/__tests__/test-workbench/index.ts | 2 +- src/__tests__/testRunner.ts | 41 +- src/__tests__/testsNoStatus.ts | 12 +- src/commands/extension.ts | 69 +- src/commands/local-supergraph-designs.ts | 635 +- src/commands/studio-graphs.ts | 96 +- src/commands/studio-operations.ts | 52 +- src/extension.ts | 418 +- src/graphql/composition.ts | 572 +- src/graphql/graphClient.ts | 263 +- src/graphql/graphRouter.ts | 306 +- src/graphql/graphql-language-service.d.ts | 21 +- src/graphql/parsers/csdlParser.ts | 241 +- src/graphql/parsers/runOnlineParser.ts | 350 +- src/graphql/parsers/schemaParser.ts | 191 +- src/graphql/types/AccountServiceVariants.ts | 8 +- src/graphql/types/CheckUserApiKey.ts | 8 +- src/graphql/types/GetGraphSchemas.ts | 16 +- src/graphql/types/GraphOperations.ts | 8 +- src/graphql/types/MyAccountIds.ts | 12 +- src/graphql/types/UserMemberships.ts | 12 +- src/utils/createJavascriptTemplate.ts | 69 +- src/utils/createTypescriptTemplate.ts | 76 +- src/utils/exportFiles.ts | 348 +- src/workbench/docProviders.ts | 55 +- src/workbench/federationCodeActionProvider.ts | 73 +- src/workbench/federationCompletionProvider.ts | 396 +- src/workbench/file-system/WorkbenchUri.ts | 117 +- src/workbench/file-system/fileProvider.ts | 722 ++- src/workbench/file-system/fileTypes.ts | 42 +- src/workbench/serverManager.ts | 442 +- src/workbench/stateManager.ts | 294 +- .../apolloStudioGraphOpsTreeDataProvider.ts | 145 +- .../apolloStudioGraphsTreeDataProvider.ts | 394 +- .../superGraphTreeDataProvider.ts | 479 +- 46 files changed, 9343 insertions(+), 3051 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 7a7732d..3fa26fa 100644 --- a/.gitignore +++ b/.gitignore @@ -107,6 +107,5 @@ dist # VS Code Extension files out -package-lock.json -.vscode-test/ \ No newline at end of file +.vscode-test/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..6c363ec --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,13 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "esbenp.prettier-vscode" + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [ + + ] +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..fb0f4bc --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5097 @@ +{ + "name": "apollo-workbench-vscode", + "version": "1.0.16", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@apollo/client": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.3.15.tgz", + "integrity": "sha512-/WQmNvLEZMA0mA3u+FkEPTXKzxZD/KhyO7WlbKcy3zKGrXKza83tAbNMzsitQE7DTcSc3DLEcIu1Z5Rc7PFq0Q==", + "requires": { + "@graphql-typed-document-node/core": "^3.0.0", + "@types/zen-observable": "^0.8.0", + "@wry/context": "^0.6.0", + "@wry/equality": "^0.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graphql-tag": "^2.12.0", + "hoist-non-react-statics": "^3.3.2", + "optimism": "^0.15.0", + "prop-types": "^15.7.2", + "symbol-observable": "^2.0.0", + "ts-invariant": "^0.7.0", + "tslib": "^1.10.0", + "zen-observable": "^0.8.14" + } + }, + "@apollo/federation": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/@apollo/federation/-/federation-0.23.2.tgz", + "integrity": "sha512-O3ZuKdjYpxyl9UAvE8dHK5dkHzS7DYagwR8Ts3oB3O4BshHh/9+SoPvyKQSDw25ZZXx2/87OZMvZWM8OSE4cgw==", + "requires": { + "apollo-graphql": "^0.9.2", + "lodash.xorby": "^4.7.0" + } + }, + "@apollo/gateway": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/@apollo/gateway/-/gateway-0.26.3.tgz", + "integrity": "sha512-gpjF3X5QQxh/suvQIt3dWOhSeO48LK4HiGNrwtGrLx6g7gJhqD/bS+/0vSfJLl9GFZPZ9Zg4pYYf3r+fT2FLzQ==", + "requires": { + "@apollo/federation": "^0.23.2", + "@apollo/query-planner": "^0.1.2", + "@types/node-fetch": "2.5.10", + "apollo-graphql": "^0.9.2", + "apollo-reporting-protobuf": "^0.6.0", + "apollo-server-caching": "^0.6.0", + "apollo-server-core": "^2.23.0", + "apollo-server-env": "^3.0.0", + "apollo-server-errors": "^2.5.0", + "apollo-server-types": "^0.7.0", + "loglevel": "^1.6.1", + "make-fetch-happen": "^8.0.0", + "pretty-format": "^26.0.0" + } + }, + "@apollo/protobufjs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.0.tgz", + "integrity": "sha512-TBgsADig/K4Hx71uQO6KPLxgoE/ORhPGh/HgouHru+cum8RLDfAfEY5Dde+cNala+luGI2X4Rs42pLWRud7/WA==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.17.59", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.59.tgz", + "integrity": "sha512-7Uc8IRrL8yZz5ti45RaFxpbU8TxlzdC3HvxV+hOWo1EyLsuKv/w7y0n+TwZzwL3vdx3oZ2k3ubxPq131hNtXyg==" + } + } + }, + "@apollo/query-planner": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@apollo/query-planner/-/query-planner-0.1.2.tgz", + "integrity": "sha512-RXcutdAsvKehjsE42nFaL6OD8vaYd65Jf/E+mVOMz82L3wV/k8uhWG0Sj5QcoC8ndoVG3O5xyeIIlI+iIb8u/g==", + "requires": { + "chalk": "^4.1.0", + "pretty-format": "^26.0.0" + } + }, + "@apollographql/apollo-tools": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.4.14.tgz", + "integrity": "sha512-oTTq9G3rC47H/xd6MEtLgpbXNUbsu0WpclJ5RjSARJvUd7jKwmwUABr9g1EG68tK7pCdCRU93QL3WQT0XWhDcw==", + "requires": { + "apollo-env": "^0.9.2" + } + }, + "@apollographql/graphql-language-service-interface": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-language-service-interface/-/graphql-language-service-interface-2.0.2.tgz", + "integrity": "sha512-28wePK0hlIVjgmvMXMAUq8qRSjz9O+6lqFp4PzOTHtfJfSsjVe9EfjF98zTpHsTgT3HcOxmbqDZZy8jlXtOqEA==", + "requires": { + "@apollographql/graphql-language-service-parser": "^2.0.0", + "@apollographql/graphql-language-service-types": "^2.0.0", + "@apollographql/graphql-language-service-utils": "^2.0.2" + } + }, + "@apollographql/graphql-language-service-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-language-service-parser/-/graphql-language-service-parser-2.0.2.tgz", + "integrity": "sha512-rpTPrEJu1PMaRQxz5P8BZWsixNNhYloS0H0dwTxNBuE3qctbARvR7o8UCKLsmKgTbo+cz3T3a6IAsWlkHgMWGg==", + "requires": { + "@apollographql/graphql-language-service-types": "^2.0.0" + } + }, + "@apollographql/graphql-language-service-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-language-service-types/-/graphql-language-service-types-2.0.2.tgz", + "integrity": "sha512-vE+Dz8pG+Xa1Z2nMl82LoO66lQ6JqBUjaXqLDvS3eMjvA3N4hf+YUDOWfPdNZ0zjhHhHXzUIIZCkax6bXfFbzQ==" + }, + "@apollographql/graphql-language-service-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-language-service-utils/-/graphql-language-service-utils-2.0.2.tgz", + "integrity": "sha512-fDj5rWlTi/czvUS5t7V7I45Ai6bOO3Z7JARYj21Y2xxfbRGtJi6h8FvLX0N/EbzQgo/fiZc/HAhtfwn+OCjD7A==", + "requires": { + "@apollographql/graphql-language-service-types": "^2.0.0" + } + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.27", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.27.tgz", + "integrity": "sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw==", + "requires": { + "xss": "^1.0.8" + } + }, + "@apollographql/graphql-upload-8-fork": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz", + "integrity": "sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g==", + "requires": { + "@types/express": "*", + "@types/fs-capacitor": "*", + "@types/koa": "*", + "busboy": "^0.3.1", + "fs-capacitor": "^2.0.4", + "http-errors": "^1.7.3", + "object-path": "^0.11.4" + } + }, + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@endemolshinegroup/cosmiconfig-typescript-loader": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-1.0.2.tgz", + "integrity": "sha512-ZHkXKq2XFFmAUdmSZrmqUSIrRM4O9gtkdpxMmV+LQl7kScUnbo6pMnXu6+FTDgZ12aW6SDoZoOJfS56WD+Eu6A==", + "requires": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^8", + "tslib": "^1" + } + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "@graphql-typed-document-node/core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.0.tgz", + "integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==" + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@josephg/resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.0.tgz", + "integrity": "sha512-OfTtjoqB2doov5aTJxkyAMK8dXoo7CjCUQSYUEtiY34jbWduOGV7+168tmCT8COMsUEd5DMSFg/0iAOPCBTNAQ==" + }, + "@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/archiver": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.1.0.tgz", + "integrity": "sha512-baFOhanb/hxmcOd1Uey2TfFg43kTSmM6py1Eo7Rjbv/ivcl7PXLhY0QgXGf50Hx/eskGCFqPfhs/7IZLb15C5g==", + "requires": { + "@types/glob": "*" + } + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==" + }, + "@types/cookies": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.6.tgz", + "integrity": "sha512-FK4U5Qyn7/Sc5ih233OuHO0qAkOpEcD/eG6584yEiLKizTFRny86qHLe/rej3HFQrkBuUjF4whFliAdODbVN/w==", + "requires": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/cors": { + "version": "2.8.10", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", + "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==" + }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, + "@types/express": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", + "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", + "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/fs-capacitor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz", + "integrity": "sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/graphql": { + "version": "14.5.0", + "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-14.5.0.tgz", + "integrity": "sha512-MOkzsEp1Jk5bXuAsHsUi6BVv0zCO+7/2PTiZMXWDSsMXvNU6w/PLMQT2vHn8hy2i0JqojPz1Sz6rsFjHtsU0lA==", + "dev": true, + "requires": { + "graphql": "*" + } + }, + "@types/http-assert": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", + "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==" + }, + "@types/http-errors": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz", + "integrity": "sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==" + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "@types/keygrip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", + "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==" + }, + "@types/koa": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.1.tgz", + "integrity": "sha512-Qbno7FWom9nNqu0yHZ6A0+RWt4mrYBhw3wpBAQ3+IuzGcLlfeYkzZrnMq5wsxulN2np8M4KKeUpTodsOsSad5Q==", + "requires": { + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/koa-compose": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", + "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", + "requires": { + "@types/koa": "*" + } + }, + "@types/lodash": { + "version": "4.14.168", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", + "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==", + "dev": true + }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "@types/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==" + }, + "@types/mocha": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "@types/node": { + "version": "14.14.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.43.tgz", + "integrity": "sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==", + "dev": true + }, + "@types/node-fetch": { + "version": "2.5.10", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz", + "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==", + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/vscode": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.55.0.tgz", + "integrity": "sha512-49hysH7jneTQoSC8TWbAi7nKK9Lc5osQNjmDHVosrcU8o3jecD9GrK0Qyul8q4aGPSXRfNGqIp9CBdb13akETg==", + "dev": true + }, + "@types/ws": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-PbeN0Eydl7LQl4OIav29YmkO2LxbVuz3nZD/kb19lOS+wLgIkRbWMNmU/QQR7ABpOJ7D7xDOU8co7iohObewrw==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + } + } + }, + "@types/yargs": { + "version": "15.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", + "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" + }, + "@types/zen-observable": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz", + "integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz", + "integrity": "sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "3.10.1", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz", + "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/types": "3.10.1", + "@typescript-eslint/typescript-estree": "3.10.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.10.1.tgz", + "integrity": "sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "3.10.1", + "@typescript-eslint/types": "3.10.1", + "@typescript-eslint/typescript-estree": "3.10.1", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/types": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz", + "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz", + "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "3.10.1", + "@typescript-eslint/visitor-keys": "3.10.1", + "debug": "^4.1.1", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz", + "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@wry/context": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.6.0.tgz", + "integrity": "sha512-sAgendOXR8dM7stJw3FusRxFHF/ZinU0lffsA2YTyyIOfic86JX02qlPqPVqJNZJPAxFt+2EE8bvq6ZlS0Kf+Q==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "@wry/equality": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.4.0.tgz", + "integrity": "sha512-DxN/uawWfhRbgYE55zVCPOoe+jvsQ4m7PT1Wlxjyb/LCCLuU1UsucV2BbCxFAX8bjcSueFBbB5Qfj1Zfe8e7Fw==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "@wry/trie": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.3.0.tgz", + "integrity": "sha512-Yw1akIogPhAT6XPYsRHlZZIS0tIGmAl9EYXHi2scf7LPKKqdqmow/Hu4kEqP2cJR3EjaU/9L0ZlAjFf3hFxmug==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "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": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", + "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "apollo-cache-control": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.12.0.tgz", + "integrity": "sha512-kClF5rfAm159Nboul1LxA+l58Tjz0M8L1GUknEMpZt0UHhILLAn3BfcG3ToX4TbNoR9M57kKMUcbPWLdy3Up7w==", + "requires": { + "apollo-server-env": "^3.0.0", + "apollo-server-plugin-base": "^0.11.0" + } + }, + "apollo-datasource": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.8.0.tgz", + "integrity": "sha512-gXgsGVLuejLc138z/2jUjPAzadDQxWbcLJyBgaQsg5BaXJNkv5uW/NjiSPk00cK51hyZrb0Xx8a+L+wPk2qIBA==", + "requires": { + "apollo-server-caching": "^0.6.0", + "apollo-server-env": "^3.0.0" + } + }, + "apollo-env": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.9.2.tgz", + "integrity": "sha512-YUai2qCVenzOr3v1K1Ad/cUqLqvIQxIWjjAWDU0Q00VjegHxjIOyamdpcYkACCIkrb0Kthj4Slql4+d5ZXyeXQ==", + "requires": { + "@types/node-fetch": "2.5.10", + "core-js": "^3.0.1", + "node-fetch": "^2.2.0", + "sha.js": "^2.4.11" + } + }, + "apollo-graphql": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.2.tgz", + "integrity": "sha512-+c/vqC2LPq3e5kO7MfBxDDiljzLog/THZr9Pd46HVaKAhHUxFL0rJEbT17VhjdOoZGWFWLYG7x9hiN6EQD1xZQ==", + "requires": { + "core-js-pure": "^3.10.2", + "lodash.sortby": "^4.7.0", + "sha.js": "^2.4.11" + } + }, + "apollo-language-server": { + "version": "1.25.7", + "resolved": "https://registry.npmjs.org/apollo-language-server/-/apollo-language-server-1.25.7.tgz", + "integrity": "sha512-mjttCG1t0mHwXK7NJZfw5BrnSGZcCgWBmyFEljvrbEi/llNgA8D4jmWEap6Slf9uk1pQd3eTAEk9Jlptf2ORxA==", + "requires": { + "@apollo/federation": "0.23.1", + "@apollographql/apollo-tools": "^0.4.14", + "@apollographql/graphql-language-service-interface": "^2.0.2", + "@endemolshinegroup/cosmiconfig-typescript-loader": "^1.0.0", + "apollo-datasource": "^0.8.0", + "apollo-env": "^0.9.2", + "apollo-graphql": "^0.9.2", + "apollo-link": "^1.2.3", + "apollo-link-context": "^1.0.9", + "apollo-link-error": "^1.1.1", + "apollo-link-http": "^1.5.5", + "apollo-server-errors": "^2.0.2", + "await-to-js": "^2.0.1", + "core-js": "^3.0.1", + "cosmiconfig": "^5.0.6", + "dotenv": "^8.0.0", + "glob": "^7.1.3", + "graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0", + "graphql-tag": "^2.10.1", + "lodash.debounce": "^4.0.8", + "lodash.merge": "^4.6.1", + "minimatch": "^3.0.4", + "moment": "2.29.1", + "vscode-languageserver": "^5.1.0", + "vscode-uri": "1.0.6" + }, + "dependencies": { + "@apollo/federation": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@apollo/federation/-/federation-0.23.1.tgz", + "integrity": "sha512-yFNZN9Z1KES6OKi8rO+xAJ6gqAsbSpb2Q1AugQsLVY3g73IZQoYV7qRuEsfv6UIpM5jW56gizgUQPom20xwO2g==", + "requires": { + "apollo-graphql": "^0.9.0", + "lodash.xorby": "^4.7.0" + } + } + } + }, + "apollo-link": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz", + "integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==", + "requires": { + "apollo-utilities": "^1.3.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.21" + }, + "dependencies": { + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "apollo-link-context": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/apollo-link-context/-/apollo-link-context-1.0.20.tgz", + "integrity": "sha512-MLLPYvhzNb8AglNsk2NcL9AvhO/Vc9hn2ZZuegbhRHGet3oGr0YH9s30NS9+ieoM0sGT11p7oZ6oAILM/kiRBA==", + "requires": { + "apollo-link": "^1.2.14", + "tslib": "^1.9.3" + } + }, + "apollo-link-error": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/apollo-link-error/-/apollo-link-error-1.1.13.tgz", + "integrity": "sha512-jAZOOahJU6bwSqb2ZyskEK1XdgUY9nkmeclCrW7Gddh1uasHVqmoYc4CKdb0/H0Y1J9lvaXKle2Wsw/Zx1AyUg==", + "requires": { + "apollo-link": "^1.2.14", + "apollo-link-http-common": "^0.2.16", + "tslib": "^1.9.3" + } + }, + "apollo-link-http": { + "version": "1.5.17", + "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.17.tgz", + "integrity": "sha512-uWcqAotbwDEU/9+Dm9e1/clO7hTB2kQ/94JYcGouBVLjoKmTeJTUPQKcJGpPwUjZcSqgYicbFqQSoJIW0yrFvg==", + "requires": { + "apollo-link": "^1.2.14", + "apollo-link-http-common": "^0.2.16", + "tslib": "^1.9.3" + } + }, + "apollo-link-http-common": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz", + "integrity": "sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==", + "requires": { + "apollo-link": "^1.2.14", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + }, + "dependencies": { + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "apollo-reporting-protobuf": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.6.2.tgz", + "integrity": "sha512-WJTJxLM+MRHNUxt1RTl4zD0HrLdH44F2mDzMweBj1yHL0kSt8I1WwoiF/wiGVSpnG48LZrBegCaOJeuVbJTbtw==", + "requires": { + "@apollo/protobufjs": "^1.0.3" + } + }, + "apollo-server": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.23.0.tgz", + "integrity": "sha512-BS+8uAJV2qYLqu+y+KIQyfR3yN2muBtql6lvfwJh4fRgUo6HU5Cc3nTA9jHbgEWE/uiyEn4eqOv1kieHIQmH6w==", + "requires": { + "apollo-server-core": "^2.23.0", + "apollo-server-express": "^2.23.0", + "express": "^4.0.0", + "graphql-subscriptions": "^1.0.0", + "graphql-tools": "^4.0.8", + "stoppable": "^1.1.0" + } + }, + "apollo-server-caching": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.6.0.tgz", + "integrity": "sha512-SfjKaccrhRzUQ8TAke9FrYppp4pZV3Rp8KCs+4Ox3kGtbco68acRPJkiYYtSVc4idR8XNAUOOVfAEZVNHdZQKQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "apollo-server-core": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.23.0.tgz", + "integrity": "sha512-3/a4LPgRADc8CdT/nRh7W0CAqQv3Q4DJvakWQgKqGSqDEb/0u4IBynYjlQKuPBi4wwKdeK2Hb1wiQLl+zu4StQ==", + "requires": { + "@apollographql/apollo-tools": "^0.4.3", + "@apollographql/graphql-playground-html": "1.6.27", + "@apollographql/graphql-upload-8-fork": "^8.1.3", + "@josephg/resolvable": "^1.0.0", + "@types/ws": "^7.0.0", + "apollo-cache-control": "^0.12.0", + "apollo-datasource": "^0.8.0", + "apollo-graphql": "^0.6.0", + "apollo-reporting-protobuf": "^0.6.2", + "apollo-server-caching": "^0.6.0", + "apollo-server-env": "^3.0.0", + "apollo-server-errors": "^2.5.0", + "apollo-server-plugin-base": "^0.11.0", + "apollo-server-types": "^0.7.0", + "apollo-tracing": "^0.13.0", + "async-retry": "^1.2.1", + "fast-json-stable-stringify": "^2.0.0", + "graphql-extensions": "^0.13.0", + "graphql-tag": "^2.11.0", + "graphql-tools": "^4.0.8", + "loglevel": "^1.6.7", + "lru-cache": "^6.0.0", + "sha.js": "^2.4.11", + "subscriptions-transport-ws": "^0.9.11", + "uuid": "^8.0.0", + "ws": "^6.0.0" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + }, + "@types/node-fetch": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz", + "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==", + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "apollo-env": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.6.6.tgz", + "integrity": "sha512-hXI9PjJtzmD34XviBU+4sPMOxnifYrHVmxpjykqI/dUD2G3yTiuRaiQqwRwB2RCdwC1Ug/jBfoQ/NHDTnnjndQ==", + "requires": { + "@types/node-fetch": "2.5.7", + "core-js": "^3.0.1", + "node-fetch": "^2.2.0", + "sha.js": "^2.4.11" + } + }, + "apollo-graphql": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.1.tgz", + "integrity": "sha512-ZRXAV+k+hboCVS+FW86FW/QgnDR7gm/xMUwJPGXEbV53OLGuQQdIT0NCYK7AzzVkCfsbb7NJ3mmEclkZY9uuxQ==", + "requires": { + "apollo-env": "^0.6.6", + "lodash.sortby": "^4.7.0" + } + } + } + }, + "apollo-server-env": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.0.0.tgz", + "integrity": "sha512-tPSN+VttnPsoQAl/SBVUpGbLA97MXG990XIwq6YUnJyAixrrsjW1xYG7RlaOqetxm80y5mBZKLrRDiiSsW/vog==", + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + } + }, + "apollo-server-errors": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.5.0.tgz", + "integrity": "sha512-lO5oTjgiC3vlVg2RKr3RiXIIQ5pGXBFxYGGUkKDhTud3jMIhs+gel8L8zsEjKaKxkjHhCQAA/bcEfYiKkGQIvA==" + }, + "apollo-server-express": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.23.0.tgz", + "integrity": "sha512-tzil7c51ODH0rT1Bc5VMksdWzHrYGavdLtnDz4M0ePiTm18Gc81HD7X/4DPczorerEpfwwkf2YlADtPQfRSxlw==", + "requires": { + "@apollographql/graphql-playground-html": "1.6.27", + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.19.0", + "@types/cors": "2.8.10", + "@types/express": "4.17.11", + "@types/express-serve-static-core": "4.17.19", + "accepts": "^1.3.5", + "apollo-server-core": "^2.23.0", + "apollo-server-types": "^0.7.0", + "body-parser": "^1.18.3", + "cors": "^2.8.5", + "express": "^4.17.1", + "graphql-subscriptions": "^1.0.0", + "graphql-tools": "^4.0.8", + "parseurl": "^1.3.2", + "subscriptions-transport-ws": "^0.9.16", + "type-is": "^1.6.16" + } + }, + "apollo-server-plugin-base": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.11.0.tgz", + "integrity": "sha512-Du68x0XCyQ6EWlgoL9Z+1s8fJfXgY131QbKP7ao617StQPzwB0aGCwxBDfcMt1A75VXf4TkvV1rdUH5YeJFlhQ==", + "requires": { + "apollo-server-types": "^0.7.0" + } + }, + "apollo-server-plugin-operation-registry": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-operation-registry/-/apollo-server-plugin-operation-registry-0.7.5.tgz", + "integrity": "sha512-nV6uAfzGm/HVYoA0B4+ziuXswsTaIXotG1ZWa5uMm1pwOMinbXCjCF8GBZSsuiPE2Uud1I8OdzIuSSdw4rdPMw==", + "requires": { + "apollo-graphql": "0.6.1", + "apollo-server-caching": "^0.5.3", + "apollo-server-env": "^3.0.0", + "apollo-server-errors": "^2.4.2", + "apollo-server-plugin-base": "^0.10.4", + "fast-json-stable-stringify": "^2.0.0", + "loglevel": "^1.6.1", + "make-fetch-happen": "^8.0.7" + }, + "dependencies": { + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + }, + "@types/node-fetch": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz", + "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==", + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "apollo-env": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.6.6.tgz", + "integrity": "sha512-hXI9PjJtzmD34XviBU+4sPMOxnifYrHVmxpjykqI/dUD2G3yTiuRaiQqwRwB2RCdwC1Ug/jBfoQ/NHDTnnjndQ==", + "requires": { + "@types/node-fetch": "2.5.7", + "core-js": "^3.0.1", + "node-fetch": "^2.2.0", + "sha.js": "^2.4.11" + } + }, + "apollo-graphql": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.1.tgz", + "integrity": "sha512-ZRXAV+k+hboCVS+FW86FW/QgnDR7gm/xMUwJPGXEbV53OLGuQQdIT0NCYK7AzzVkCfsbb7NJ3mmEclkZY9uuxQ==", + "requires": { + "apollo-env": "^0.6.6", + "lodash.sortby": "^4.7.0" + } + }, + "apollo-server-caching": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz", + "integrity": "sha512-iMi3087iphDAI0U2iSBE9qtx9kQoMMEWr6w+LwXruBD95ek9DWyj7OeC2U/ngLjRsXM43DoBDXlu7R+uMjahrQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "apollo-server-plugin-base": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.4.tgz", + "integrity": "sha512-HRhbyHgHFTLP0ImubQObYhSgpmVH4Rk1BinnceZmwudIVLKrqayIVOELdyext/QnSmmzg5W7vF3NLGBcVGMqDg==", + "requires": { + "apollo-server-types": "^0.6.3" + } + }, + "apollo-server-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.6.3.tgz", + "integrity": "sha512-aVR7SlSGGY41E1f11YYz5bvwA89uGmkVUtzMiklDhZ7IgRJhysT5Dflt5IuwDxp+NdQkIhVCErUXakopocFLAg==", + "requires": { + "apollo-reporting-protobuf": "^0.6.2", + "apollo-server-caching": "^0.5.3", + "apollo-server-env": "^3.0.0" + } + } + } + }, + "apollo-server-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.7.0.tgz", + "integrity": "sha512-pJ6ri2N4xJ+e2PUUPHeCNpMDzHUagJyn0DDZGQmXDz6aoMlSd4B2KUvK81hHyHkw3wHk9clgcpfM9hKqbfZweA==", + "requires": { + "apollo-reporting-protobuf": "^0.6.2", + "apollo-server-caching": "^0.6.0", + "apollo-server-env": "^3.0.0" + } + }, + "apollo-tracing": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.13.0.tgz", + "integrity": "sha512-28z4T+XfLQ6t696usU0nTFDxVN8BfF3o74d2p/zsT4eu1OuoyoDOEmVJqdInmVRpyTJK0tDEOjkIuDJJHZftog==", + "requires": { + "apollo-server-env": "^3.0.0", + "apollo-server-plugin-base": "^0.11.0" + } + }, + "apollo-utilities": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz", + "integrity": "sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "@wry/equality": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz", + "integrity": "sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==", + "requires": { + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "archiver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", + "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", + "requires": { + "archiver-utils": "^2.1.0", + "async": "^3.2.0", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.0.0", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "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==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "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==" + }, + "async-retry": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "requires": { + "retry": "0.12.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "await-to-js": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-2.1.1.tgz", + "integrity": "sha512-CHBC6gQGCIzjZ09tJ+XmpQoZOn4GdWePB4qUweCaKNJ0D3f115YdhmYVTZ4rMVpiJ3cFzZcTYK1VMYEICV4YXw==" + }, + "azure-devops-node-api": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", + "integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==", + "dev": true, + "requires": { + "os": "0.1.1", + "tunnel": "0.0.4", + "typed-rest-client": "1.2.0", + "underscore": "1.8.3" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", + "dev": true + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dev": true, + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "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==" + }, + "buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true + }, + "busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "requires": { + "dicer": "0.3.0" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacache": { + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.6.tgz", + "integrity": "sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w==", + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cheerio": { + "version": "1.0.0-rc.6", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.6.tgz", + "integrity": "sha512-hjx1XE1M/D5pAtMgvWwE21QClmAEeGHOIDfycgmndisdNgI6PE1cGRQkMGBcsbUbmEQyWu5PJLUcAOjtQS8DWw==", + "dev": true, + "requires": { + "cheerio-select": "^1.3.0", + "dom-serializer": "^1.3.1", + "domhandler": "^4.1.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1" + } + }, + "cheerio-select": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.4.0.tgz", + "integrity": "sha512-sobR3Yqz27L553Qa7cK6rtJlMDbiKPdNywtR95Sj/YgfpLfy0u6CGJuaBKe5YE/vTc23SCRKxWSdlon/w6I/Ew==", + "dev": true, + "requires": { + "css-select": "^4.1.2", + "css-what": "^5.0.0", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "compress-commons": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.0.tgz", + "integrity": "sha512-ofaaLqfraD1YRTkrRKPCrGJ1pFeDG/MVCkVVV2FNGeWquSlqw5wOrwOfPQ1xF2u+blpeWASie5EubHz+vsNIgA==", + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.11.1.tgz", + "integrity": "sha512-k93Isqg7e4txZWMGNYwevZL9MiogLk8pd1PtwrmFmi8IBq4GXqUaVW/a33Llt6amSI36uSjd0GWwc9pTT9ALlQ==" + }, + "core-js-pure": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.11.1.tgz", + "integrity": "sha512-2JukQi8HgAOCD5CSimxWWXVrUBoA9Br796uIA5Z06bIjt7PBBI19ircFaAxplgE1mJf3x2BY6MkT/HWA/UryPg==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "crc-32": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", + "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", + "requires": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + } + }, + "crc32-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", + "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "requires": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-select": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.2.tgz", + "integrity": "sha512-nu5ye2Hg/4ISq4XqdLY2bEatAcLIdt3OYGFc9Tm9n7VSlFBcfRv0gBNksHRgSdUDQGtN3XrZ94ztW+NfzkFSUw==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + } + }, + "css-what": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.0.tgz", + "integrity": "sha512-qxyKHQvgKwzwDWC/rGbT821eJalfupxYW2qbSJSAtdSTimsr/MlaGONoNLllaUPZWf8QnbcKM/kPVYUQuEKAFA==", + "dev": true + }, + "cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "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 + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "deprecated-decorator": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", + "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "requires": { + "streamsearch": "0.1.2" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.1.tgz", + "integrity": "sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", + "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + }, + "dependencies": { + "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", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "end-of-stream": { + "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==", + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + }, + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "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 + }, + "eslint": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.25.0.tgz", + "integrity": "sha512-TVpSovpvCNpLURIScDRB6g5CYu/ZFq9GfX2hLNIV4dSBKxIWojeDODvYl3t0k0VtMxYeR8OXPCFE5+oHMlGfhw==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + } + } + }, + "faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "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 + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-capacitor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", + "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==" + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "graphql": { + "version": "14.7.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", + "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", + "requires": { + "iterall": "^1.2.2" + } + }, + "graphql-extensions": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.13.0.tgz", + "integrity": "sha512-Bb7E97nvfX4gtrIdZ/i5YFlqOd6MGzrw8ED+t4wQVraYje6NQ+8P8MHMOV2WZLfbW8zsNTx8NdnnlbsdH5siag==", + "requires": { + "@apollographql/apollo-tools": "^0.4.3", + "apollo-server-env": "^3.0.0", + "apollo-server-types": "^0.7.0" + } + }, + "graphql-language-service-interface": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-2.8.3.tgz", + "integrity": "sha512-Gh4Q3dlCT1MrZGO0eaz7v31gkp8fh+ig94YH/A+1Th2q+k3RsRqfSJm5tKZ8TJ4rSADZ/dj+hzOpWCGzLyCiHQ==", + "requires": { + "graphql-language-service-parser": "^1.9.0", + "graphql-language-service-types": "^1.8.0", + "graphql-language-service-utils": "^2.5.1", + "vscode-languageserver-types": "^3.15.1" + }, + "dependencies": { + "vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" + } + } + }, + "graphql-language-service-parser": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.9.1.tgz", + "integrity": "sha512-GySsDrYxzxu6r1vF282xXDR2KlfVL5aOW7pgc75fF3UFiuqGm/SeoIljNM0mLpRl5KSxo1HNOxhkWoFBoy/h2w==", + "requires": { + "graphql-language-service-types": "^1.8.0" + } + }, + "graphql-language-service-types": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/graphql-language-service-types/-/graphql-language-service-types-1.8.1.tgz", + "integrity": "sha512-IpYS0mEHEmRsFlq+loWCpSYYYizAID7Alri6GoFN1QqUdux+8rp1Tkp2NGsGDpDmm3Dbz5ojmJWzNWQGpuwveA==" + }, + "graphql-language-service-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/graphql-language-service-utils/-/graphql-language-service-utils-2.5.2.tgz", + "integrity": "sha512-hXGd4ARhyD7WTmTwuYmCYo6BcY8FtTp+1JHLaUG0Q63k0NpZTuFuRZ+N7TSP9mcRb7labeozs3DYgaqStsDe1A==", + "requires": { + "graphql-language-service-types": "^1.8.0", + "nullthrows": "^1.0.0" + } + }, + "graphql-subscriptions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz", + "integrity": "sha512-95yD/tKi24q8xYa7Q9rhQN16AYj5wPbrb8tmHGM3WRc9EBmWrG/0kkMl+tQG8wcEuE9ibR4zyOM31p5Sdr2v4g==", + "requires": { + "iterall": "^1.3.0" + } + }, + "graphql-tag": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.3.tgz", + "integrity": "sha512-5wJMjSvj30yzdciEuk9dPuUBUR56AqDi3xncoYQl1i42pGdSqOJrJsdb/rz5BDoy+qoGvQwABcBeF0xXY3TrKw==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "graphql-tools": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", + "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", + "requires": { + "apollo-link": "^1.2.14", + "apollo-utilities": "^1.0.1", + "deprecated-decorator": "^0.1.6", + "iterall": "^1.1.3", + "uuid": "^3.1.0" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "http-errors": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", + "integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=" + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "iterall": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "^2.0.5" + }, + "dependencies": { + "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==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "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 + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "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=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + }, + "lodash.xorby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.xorby/-/lodash.xorby-4.7.0.tgz", + "integrity": "sha1-nBmm+fBjputT3QPBtocXmYAUY9c=" + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "loglevel": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "make-fetch-happen": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", + "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", + "requires": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.0.5", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + } + }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + } + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-fetch": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", + "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", + "requires": { + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "mocha": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-path": { + "version": "0.11.5", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.5.tgz", + "integrity": "sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optimism": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.15.0.tgz", + "integrity": "sha512-KLKl3Kb7hH++s9ewRcBhmfpXgXF0xQ+JZ3xQFuPjnoT6ib2TDmYyVkKENmGxivsN2G3VRxpXuauCkB4GYOhtPw==", + "requires": { + "@wry/context": "^0.6.0", + "@wry/trie": "^0.3.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz", + "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "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 + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + } + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", + "dev": true, + "requires": { + "semver": "^5.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } + } + }, + "printj": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", + "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + } + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-glob": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", + "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + } + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "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==" + }, + "socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz", + "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", + "requires": { + "agent-base": "6", + "debug": "4", + "socks": "^2.3.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "requires": { + "minipass": "^3.1.1" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==" + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "subscriptions-transport-ws": { + "version": "0.9.18", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz", + "integrity": "sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA==", + "requires": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^5.2.0" + }, + "dependencies": { + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "symbol-observable": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", + "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==" + }, + "table": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.6.0.tgz", + "integrity": "sha512-iZMtp5tUvcnAdtHpZTWLPF0M7AgiQsURR2DwmxnJwSy8I3+cY+ozzVvYha3BOLG2TB+L0CqjIz+91htuj6yCXg==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", + "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, + "ts-invariant": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.7.3.tgz", + "integrity": "sha512-UWDDeovyUTIMWj+45g5nhnl+8oo+GhxL5leTaHn5c8FkQWfh8v66gccLd2/YzVmV5hoQUjCEjhrXnQqVDJdvKA==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typed-rest-client": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz", + "integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==", + "dev": true, + "requires": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + } + }, + "typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, + "requires": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + }, + "dependencies": { + "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", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-join": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", + "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz", + "integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "for-each": "^0.3.3", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.1" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vsce": { + "version": "1.87.1", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.87.1.tgz", + "integrity": "sha512-3tSUWZl9AmhZrqy/UVUpdPODSzBiCGjIr/AMSSgF2PuFLSdrh+6kiOr2Ath7bpQEXOxf55hNgz3qdO5MuEJmww==", + "dev": true, + "requires": { + "azure-devops-node-api": "^7.2.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.1", + "commander": "^6.1.0", + "denodeify": "^1.2.1", + "glob": "^7.0.6", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "osenv": "^0.1.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "0.0.29", + "typed-rest-client": "1.2.0", + "url-join": "^1.1.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "vscode-jsonrpc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", + "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" + }, + "vscode-languageclient": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.1.4.tgz", + "integrity": "sha512-EUOU+bJu6axmt0RFNo3nrglQLPXMfanbYViJee3Fbn2VuQoX0ZOI4uTYhSRvYLP2vfwTP/juV62P/mksCdTZMA==", + "requires": { + "semver": "^6.3.0", + "vscode-languageserver-protocol": "3.15.3" + }, + "dependencies": { + "vscode-jsonrpc": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz", + "integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==" + }, + "vscode-languageserver-protocol": { + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz", + "integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==", + "requires": { + "vscode-jsonrpc": "^5.0.1", + "vscode-languageserver-types": "3.15.1" + } + }, + "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==" + } + } + }, + "vscode-languageserver": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", + "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", + "requires": { + "vscode-languageserver-protocol": "3.14.1", + "vscode-uri": "^1.0.6" + } + }, + "vscode-languageserver-protocol": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", + "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", + "requires": { + "vscode-jsonrpc": "^4.0.0", + "vscode-languageserver-types": "3.14.0" + } + }, + "vscode-languageserver-types": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", + "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" + }, + "vscode-test": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.5.2.tgz", + "integrity": "sha512-x9PVfKxF6EInH9iSFGQi0V8H5zIW1fC7RAer6yNQR6sy3WyOwlWkuT3I+wf75xW/cO53hxMi1aj/EvqQfDFOAg==", + "dev": true, + "requires": { + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "rimraf": "^3.0.2", + "unzipper": "^0.10.11" + } + }, + "vscode-uri": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", + "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "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" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "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 + }, + "workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xss": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.8.tgz", + "integrity": "sha512-3MgPdaXV8rfQ/pNn16Eio6VXYPTkqwa0vc7GkiymmY/DqR1SE/7VPAAVZz1GJsJFrllMYO3RHfEaiUGjab6TNw==", + "requires": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "zen-observable": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" + }, + "zen-observable-ts": { + "version": "0.8.21", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz", + "integrity": "sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==", + "requires": { + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + } + }, + "zip-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", + "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^4.1.0", + "readable-stream": "^3.6.0" + } + } + } +} diff --git a/package.json b/package.json index 47fe274..4a9a511 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@typescript-eslint/parser": "^3.0.2", "eslint": "^7.1.0", "mocha": "^8.2.1", + "prettier": "^2.2.1", "typescript": "^4.0.2", "vsce": "^1.83.0", "vscode-test": "^1.4.1" @@ -66,6 +67,11 @@ "node-fetch": "^2.6.1", "vscode-languageclient": "^6.1.3" }, + "prettier": { + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "all" + }, "contributes": { "configuration": { "title": "Apollo-Workbench", diff --git a/src/__tests__/githubCheckTests.ts b/src/__tests__/githubCheckTests.ts index 11543c4..09125ef 100644 --- a/src/__tests__/githubCheckTests.ts +++ b/src/__tests__/githubCheckTests.ts @@ -2,18 +2,21 @@ const fetch = require('node-fetch'); import { testRunner } from './testRunner'; async function setStatus(state, description) { - return fetch(`https://api.github.com/repos/apollographql/apollo-workbench-vscode/statuses/${process.env.GITHUB_SHA}`, { - method: 'POST', - body: JSON.stringify({ - state, - description, - context: "VSCode Extension Tests", - }), - headers: { - Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, - 'Content-Type': 'application/json', + return fetch( + `https://api.github.com/repos/apollographql/apollo-workbench-vscode/statuses/${process.env.GITHUB_SHA}`, + { + method: 'POST', + body: JSON.stringify({ + state, + description, + context: 'VSCode Extension Tests', + }), + headers: { + Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, + 'Content-Type': 'application/json', + }, }, - }); + ); } async function githubActionTests() { @@ -30,10 +33,17 @@ async function githubActionTests() { await setStatus('success', 'Tests for workbench folder open passed'); process.exit(result); } catch (err) { - console.log(err?.message ? `Failed to run tests: ${err.message}` : `Failed to run tests: ${err}`); - await setStatus('error', err?.message ? err.message : `Failed to run tests: ${err}`); + console.log( + err?.message + ? `Failed to run tests: ${err.message}` + : `Failed to run tests: ${err}`, + ); + await setStatus( + 'error', + err?.message ? err.message : `Failed to run tests: ${err}`, + ); process.exit(1); } } -githubActionTests(); \ No newline at end of file +githubActionTests(); diff --git a/src/__tests__/runTest.ts b/src/__tests__/runTest.ts index 432d282..c32f8b8 100644 --- a/src/__tests__/runTest.ts +++ b/src/__tests__/runTest.ts @@ -2,32 +2,40 @@ import * as path from 'path'; import { runTests } from 'vscode-test'; -async function mainTestRunner(loadFolder: boolean = false) { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); +async function mainTestRunner(loadFolder = false) { + try { + // The folder containing the Extension Manifest package.json + // Passed to `--extensionDevelopmentPath` + const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - // The path to the extension test script - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './suite/index'); - const testWorkbenchFolder = path.resolve(__dirname, './test-workbench'); + // The path to the extension test script + // Passed to --extensionTestsPath + const extensionTestsPath = path.resolve(__dirname, './suite/index'); + const testWorkbenchFolder = path.resolve(__dirname, './test-workbench'); - // let shouldLoadWorkbenchFolder = process.argv[2]; - // console.log('******shouldLoadWorkbenchFolder:' + shouldLoadWorkbenchFolder); + // let shouldLoadWorkbenchFolder = process.argv[2]; + // console.log('******shouldLoadWorkbenchFolder:' + shouldLoadWorkbenchFolder); - // console.log('******extensionDevelopmentPath:' + extensionDevelopmentPath); - // console.log('******extensionTestsPath:' + extensionTestsPath); - // console.log('******testWorkbenchFolder:' + testWorkbenchFolder); + // console.log('******extensionDevelopmentPath:' + extensionDevelopmentPath); + // console.log('******extensionTestsPath:' + extensionTestsPath); + // console.log('******testWorkbenchFolder:' + testWorkbenchFolder); - if (loadFolder) - await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: [testWorkbenchFolder, '--disable-extensions'] }); - else - await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: ['--disable-extensions'] }); - } catch (err) { - console.error('Failed to run tests'); - process.exit(1); - } + if (loadFolder) + await runTests({ + extensionDevelopmentPath, + extensionTestsPath, + launchArgs: [testWorkbenchFolder, '--disable-extensions'], + }); + else + await runTests({ + extensionDevelopmentPath, + extensionTestsPath, + launchArgs: ['--disable-extensions'], + }); + } catch (err) { + console.error('Failed to run tests'); + process.exit(1); + } } -mainTestRunner(); \ No newline at end of file +mainTestRunner(); diff --git a/src/__tests__/suite/defaults.test.ts b/src/__tests__/suite/defaults.test.ts index caf0b81..10b060c 100644 --- a/src/__tests__/suite/defaults.test.ts +++ b/src/__tests__/suite/defaults.test.ts @@ -5,26 +5,36 @@ import { StateManager } from '../../workbench/stateManager'; import { NotLoggedInTreeItem } from '../../workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider'; suite('Default Workbench Tests', () => { - before(activateExtension); + before(activateExtension); - it('Defaults:StudioGraphs - Should display login item', async function () { - //Setup - StateManager.instance.globalState_userApiKey = ""; + it('Defaults:StudioGraphs - Should display login item', async function () { + //Setup + StateManager.instance.globalState_userApiKey = ''; - //Get TreeView children - const studioGraphTreeItems = await StateManager.instance.apolloStudioGraphsProvider.getChildren(); + //Get TreeView children + const studioGraphTreeItems = await StateManager.instance.apolloStudioGraphsProvider.getChildren(); - //Assert - studioGraphTreeItems.forEach(studioGraphTreeItem => assert.notStrictEqual(studioGraphTreeItem as NotLoggedInTreeItem, undefined)); - }); - it('Defaults:StudioOperations - Should display login item', async function () { - //Setup - StateManager.instance.globalState_userApiKey = ""; + //Assert + studioGraphTreeItems.forEach((studioGraphTreeItem) => + assert.notStrictEqual( + studioGraphTreeItem as NotLoggedInTreeItem, + undefined, + ), + ); + }); + it('Defaults:StudioOperations - Should display login item', async function () { + //Setup + StateManager.instance.globalState_userApiKey = ''; - //Get TreeView children - const studioGraphTreeItems = await StateManager.instance.apolloStudioGraphsProvider.getChildren(); + //Get TreeView children + const studioGraphTreeItems = await StateManager.instance.apolloStudioGraphsProvider.getChildren(); - //Assert - studioGraphTreeItems.forEach(studioGraphTreeItem => assert.notStrictEqual(studioGraphTreeItem as NotLoggedInTreeItem, undefined)); - }); -}); \ No newline at end of file + //Assert + studioGraphTreeItems.forEach((studioGraphTreeItem) => + assert.notStrictEqual( + studioGraphTreeItem as NotLoggedInTreeItem, + undefined, + ), + ); + }); +}); diff --git a/src/__tests__/suite/extension.test.ts b/src/__tests__/suite/extension.test.ts index 4cd52c5..97d9a98 100644 --- a/src/__tests__/suite/extension.test.ts +++ b/src/__tests__/suite/extension.test.ts @@ -1,15 +1,21 @@ import * as assert from 'assert'; -import { suite, it } from 'mocha' -import { activateExtension, cleanupWorkbenchFiles, createAndLoadEmptyWorkbenchFile, simpleSchema } from './helpers'; +import { suite, it } from 'mocha'; +import { + activateExtension, + cleanupWorkbenchFiles, + createAndLoadEmptyWorkbenchFile, + simpleSchema, +} from './helpers'; import { FileProvider } from '../../workbench/file-system/fileProvider'; import { StateManager } from '../../workbench/stateManager'; -import { WorkbenchUri, WorkbenchUriType } from '../../workbench/file-system/WorkbenchUri'; +import { + WorkbenchUri, + WorkbenchUriType, +} from '../../workbench/file-system/WorkbenchUri'; const key = 'Loaded-Folder'; suite(key, () => { - before(activateExtension); - afterEach(cleanupWorkbenchFiles); - - -}) \ No newline at end of file + before(activateExtension); + afterEach(cleanupWorkbenchFiles); +}); diff --git a/src/__tests__/suite/helpers.ts b/src/__tests__/suite/helpers.ts index 246d4df..e821059 100644 --- a/src/__tests__/suite/helpers.ts +++ b/src/__tests__/suite/helpers.ts @@ -4,44 +4,43 @@ import { readdirSync, unlinkSync } from 'fs'; import { FileProvider } from '../../workbench/file-system/fileProvider'; export const activateExtension = async () => { - return new Promise(async (resolve) => { - let extension = vscode.extensions.getExtension('ApolloGraphQL.apollo-workbench-vscode'); - if (extension) { - await extension.activate(); - } - resolve(); - }); -} + return new Promise(async (resolve) => { + let extension = vscode.extensions.getExtension( + 'ApolloGraphQL.apollo-workbench-vscode', + ); + if (extension) { + await extension.activate(); + } + resolve(); + }); +}; export function cleanupWorkbenchFiles() { - try { - const directory = path.resolve(__dirname, '..', './test-workbench'); - const dirents = readdirSync(directory, { withFileTypes: true }); - for (const dirent of dirents) { - if (dirent.isFile() && dirent.name.includes('.apollo-workbench')) - unlinkSync(path.resolve(directory, dirent.name)); - } - } catch (err) { - console.log(`Cleanup Error: ${err}`); + try { + const directory = path.resolve(__dirname, '..', './test-workbench'); + const dirents = readdirSync(directory, { withFileTypes: true }); + for (const dirent of dirents) { + if (dirent.isFile() && dirent.name.includes('.apollo-workbench')) + unlinkSync(path.resolve(directory, dirent.name)); } - FileProvider.instance.clearWorkbenchFiles(); + } catch (err) { + console.log(`Cleanup Error: ${err}`); + } + FileProvider.instance.clearWorkbenchFiles(); } - export async function createAndLoadEmptyWorkbenchFile() { - // const workbenchFileName = 'empty-workbench'; - // const workbenchFilePath = FileProvider.instance.createNewWorkbenchFile(workbenchFileName); - // if (!workbenchFilePath) throw new Error('Workbench file was not created'); - - // await FileProvider.instance.loadWorkbenchFile(workbenchFileName, workbenchFilePath); + // const workbenchFileName = 'empty-workbench'; + // const workbenchFilePath = FileProvider.instance.createNewWorkbenchFile(workbenchFileName); + // if (!workbenchFilePath) throw new Error('Workbench file was not created'); + // await FileProvider.instance.loadWorkbenchFile(workbenchFileName, workbenchFilePath); } -export const simpleSchema = - ` +export const simpleSchema = ` type A @key(fields:"id"){ id: ID! } extend type Query { a: A } -`; \ No newline at end of file +`; diff --git a/src/__tests__/suite/index.ts b/src/__tests__/suite/index.ts index 835e942..3b727c3 100644 --- a/src/__tests__/suite/index.ts +++ b/src/__tests__/suite/index.ts @@ -4,43 +4,42 @@ import glob from 'glob'; import { StateManager } from '../../workbench/stateManager'; export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'tdd' - }); + // Create the mocha test + const mocha = new Mocha({ + ui: 'tdd', + }); - const testsRoot = path.resolve(__dirname, '..'); - let isWorkbenchFolderLoaded = StateManager.workspaceRoot ? true : false; + const testsRoot = path.resolve(__dirname, '..'); + let isWorkbenchFolderLoaded = StateManager.workspaceRoot ? true : false; - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } + return new Promise((c, e) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { + if (err) { + return e(err); + } - // Add files to the test suite - files.forEach(f => { - if (f.includes('defaults')) - mocha.addFile(path.resolve(testsRoot, f)) - else if (isWorkbenchFolderLoaded && !f.includes('noFolder')) - mocha.addFile(path.resolve(testsRoot, f)) - else if (!isWorkbenchFolderLoaded && f.includes('noFolder')) - mocha.addFile(path.resolve(testsRoot, f)) - }); + // Add files to the test suite + files.forEach((f) => { + if (f.includes('defaults')) mocha.addFile(path.resolve(testsRoot, f)); + else if (isWorkbenchFolderLoaded && !f.includes('noFolder')) + mocha.addFile(path.resolve(testsRoot, f)); + else if (!isWorkbenchFolderLoaded && f.includes('noFolder')) + mocha.addFile(path.resolve(testsRoot, f)); + }); - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(`Mocha Run Error: ${err}`); - e(err); - } + try { + // Run the mocha test + mocha.run((failures) => { + if (failures > 0) { + e(new Error(`${failures} tests failed.`)); + } else { + c(); + } }); + } catch (err) { + console.error(`Mocha Run Error: ${err}`); + e(err); + } }); -} \ No newline at end of file + }); +} diff --git a/src/__tests__/suite/noFolder.test.ts b/src/__tests__/suite/noFolder.test.ts index b32cfb5..440c62a 100644 --- a/src/__tests__/suite/noFolder.test.ts +++ b/src/__tests__/suite/noFolder.test.ts @@ -7,9 +7,7 @@ import { StateManager } from '../../workbench/stateManager'; import { ApolloWorkbenchFile } from '../../workbench/file-system/fileTypes'; suite('No Folder Loaded in Workbnech', () => { - vscode.window.showInformationMessage('Start all tests.'); - before(activateExtension); - after(() => { - - }) -}); \ No newline at end of file + vscode.window.showInformationMessage('Start all tests.'); + before(activateExtension); + after(() => {}); +}); diff --git a/src/__tests__/test-workbench/index.ts b/src/__tests__/test-workbench/index.ts index c5c6f83..27398a5 100644 --- a/src/__tests__/test-workbench/index.ts +++ b/src/__tests__/test-workbench/index.ts @@ -1 +1 @@ -//This is here to ensure the test workbench file is compiled over to out folder \ No newline at end of file +//This is here to ensure the test workbench file is compiled over to out folder diff --git a/src/__tests__/testRunner.ts b/src/__tests__/testRunner.ts index 4a26a8b..ca05697 100644 --- a/src/__tests__/testRunner.ts +++ b/src/__tests__/testRunner.ts @@ -2,26 +2,33 @@ import * as path from 'path'; import { runTests } from 'vscode-test'; - //Function for running the tests // @param `loadFolder` will load the testing folder and run the associated tests // default: No folder will be opened and default tests will be ran export async function testRunner(loadFolder: boolean = false) { - try { - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - const extensionTestsPath = path.resolve(__dirname, './suite/index'); - const testWorkbenchFolder = path.resolve(__dirname, './test-workbench'); + try { + const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + const extensionTestsPath = path.resolve(__dirname, './suite/index'); + const testWorkbenchFolder = path.resolve(__dirname, './test-workbench'); - let testResults = 1; - if (loadFolder) - testResults = await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: [testWorkbenchFolder, '--disable-extensions'] }); - else - testResults = await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: ['--disable-extensions'] }); + let testResults = 1; + if (loadFolder) + testResults = await runTests({ + extensionDevelopmentPath, + extensionTestsPath, + launchArgs: [testWorkbenchFolder, '--disable-extensions'], + }); + else + testResults = await runTests({ + extensionDevelopmentPath, + extensionTestsPath, + launchArgs: ['--disable-extensions'], + }); - return testResults; - } catch (err) { - console.error(err); - console.error('Failed to run tests'); - process.exit(1); - } -} \ No newline at end of file + return testResults; + } catch (err) { + console.error(err); + console.error('Failed to run tests'); + process.exit(1); + } +} diff --git a/src/__tests__/testsNoStatus.ts b/src/__tests__/testsNoStatus.ts index c935eef..88d6a95 100644 --- a/src/__tests__/testsNoStatus.ts +++ b/src/__tests__/testsNoStatus.ts @@ -1,9 +1,9 @@ -import { testRunner } from "./testRunner"; +import { testRunner } from './testRunner'; (async () => { - let result = 1; - result = await testRunner(); - result = await testRunner(true); + let result = 1; + result = await testRunner(); + result = await testRunner(true); - process.exit(result); -})() \ No newline at end of file + process.exit(result); +})(); diff --git a/src/commands/extension.ts b/src/commands/extension.ts index aa47250..945aae6 100644 --- a/src/commands/extension.ts +++ b/src/commands/extension.ts @@ -1,38 +1,57 @@ -import { StateManager } from "../workbench/stateManager"; -import { workspace, window, commands } from "vscode"; -import { isValidKey } from "../graphql/graphClient"; +import { StateManager } from '../workbench/stateManager'; +import { workspace, window, commands } from 'vscode'; +import { isValidKey } from '../graphql/graphClient'; export function deleteStudioApiKey() { - StateManager.instance.globalState_userApiKey = "" + StateManager.instance.globalState_userApiKey = ''; } export async function ensureFolderIsOpen() { - if (!workspace.workspaceFolders || (workspace.workspaceFolders && !workspace.workspaceFolders[0])) { - let openFolder = "Open Folder"; - let response = await window.showErrorMessage("You must open a folder to create Apollo Workbench files", openFolder); - if (response == openFolder) await commands.executeCommand('extension.openFolder'); - } -}; + if ( + !workspace.workspaceFolders || + (workspace.workspaceFolders && !workspace.workspaceFolders[0]) + ) { + let openFolder = 'Open Folder'; + let response = await window.showErrorMessage( + 'You must open a folder to create Apollo Workbench files', + openFolder, + ); + if (response == openFolder) + await commands.executeCommand('extension.openFolder'); + } +} export async function enterStudioApiKey() { - let apiKey = await window.showInputBox({ placeHolder: "Enter User API Key - user:gh.michael-watson:023jr324tj....", }) - if (apiKey && await isValidKey(apiKey)) { - StateManager.instance.globalState_userApiKey = apiKey; - } else if (apiKey) { - window.showErrorMessage("Invalid API key entered"); - } else if (apiKey == '') { - window.setStatusBarMessage("Login cancelled, no API key entered", 2000); - } + let apiKey = await window.showInputBox({ + placeHolder: 'Enter User API Key - user:gh.michael-watson:023jr324tj....', + }); + if (apiKey && (await isValidKey(apiKey))) { + StateManager.instance.globalState_userApiKey = apiKey; + } else if (apiKey) { + window.showErrorMessage('Invalid API key entered'); + } else if (apiKey == '') { + window.setStatusBarMessage('Login cancelled, no API key entered', 2000); + } } export async function gettingStarted(item) { - window.showTextDocument(item.uri) - .then(() => commands.executeCommand('markdown.showPreviewToSide')) - .then(() => commands.executeCommand('workbench.action.closeEditorsInOtherGroups')) - .then(() => { }, (e) => console.error(e)); + window + .showTextDocument(item.uri) + .then(() => commands.executeCommand('markdown.showPreviewToSide')) + .then(() => + commands.executeCommand('workbench.action.closeEditorsInOtherGroups'), + ) + .then( + () => {}, + (e) => console.error(e), + ); } export async function openFolder() { - let folder = await window.showOpenDialog({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false }); - if (folder) await commands.executeCommand('openFolder', folder[0]); -}; \ No newline at end of file + let folder = await window.showOpenDialog({ + canSelectFiles: false, + canSelectFolders: true, + canSelectMany: false, + }); + if (folder) await commands.executeCommand('openFolder', folder[0]); +} diff --git a/src/commands/local-supergraph-designs.ts b/src/commands/local-supergraph-designs.ts index 3c05d27..5a58844 100644 --- a/src/commands/local-supergraph-designs.ts +++ b/src/commands/local-supergraph-designs.ts @@ -1,297 +1,470 @@ -import { FileProvider } from "../workbench/file-system/fileProvider"; -import { window, ProgressLocation, Uri, workspace, Range, StatusBarAlignment, tasks, Task } from "vscode"; -import { StateManager } from "../workbench/stateManager"; -import { createTypescriptTemplate } from "../utils/createTypescriptTemplate"; -import { SubgraphTreeItem, OperationTreeItem, SubgraphSummaryTreeItem, SupergraphSchemaTreeItem, SupergraphApiSchemaTreeItem } from "../workbench/tree-data-providers/superGraphTreeDataProvider"; -import { WorkbenchUri, WorkbenchUriType } from "../workbench/file-system/WorkbenchUri"; -import { ServerManager } from "../workbench/serverManager"; -import { StudioGraphVariantTreeItem, StudioGraphTreeItem, PreloadedWorkbenchFile } from "../workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider"; -import { ApolloWorkbenchFile } from "../workbench/file-system/fileTypes"; -import { getGraphSchemasByVariant } from "../graphql/graphClient"; -import { GetGraphSchemas_service_implementingServices_NonFederatedImplementingService, GetGraphSchemas_service_implementingServices_FederatedImplementingServices } from "../graphql/types/GetGraphSchemas"; -import { resolve } from "path"; -import { writeFileSync, existsSync } from "fs"; -import { TextEncoder } from "util"; -import { GraphQLSchema, parse, extendSchema, printSchema } from "graphql"; -import { OverrideApolloGateway } from "../graphql/graphRouter"; -import { generateJsFederatedResolvers } from "../utils/exportFiles"; -import { getComposedSchema, superSchemaToSchema } from "../graphql/composition"; +import { FileProvider } from '../workbench/file-system/fileProvider'; +import { + window, + ProgressLocation, + Uri, + workspace, + Range, + StatusBarAlignment, + tasks, + Task, +} from 'vscode'; +import { StateManager } from '../workbench/stateManager'; +import { createTypescriptTemplate } from '../utils/createTypescriptTemplate'; +import { + SubgraphTreeItem, + OperationTreeItem, + SubgraphSummaryTreeItem, + SupergraphSchemaTreeItem, + SupergraphApiSchemaTreeItem, +} from '../workbench/tree-data-providers/superGraphTreeDataProvider'; +import { + WorkbenchUri, + WorkbenchUriType, +} from '../workbench/file-system/WorkbenchUri'; +import { ServerManager } from '../workbench/serverManager'; +import { + StudioGraphVariantTreeItem, + StudioGraphTreeItem, + PreloadedWorkbenchFile, +} from '../workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider'; +import { ApolloWorkbenchFile } from '../workbench/file-system/fileTypes'; +import { getGraphSchemasByVariant } from '../graphql/graphClient'; +import { + GetGraphSchemas_service_implementingServices_NonFederatedImplementingService, + GetGraphSchemas_service_implementingServices_FederatedImplementingServices, +} from '../graphql/types/GetGraphSchemas'; +import { resolve } from 'path'; +import { writeFileSync, existsSync } from 'fs'; +import { TextEncoder } from 'util'; +import { GraphQLSchema, parse, extendSchema, printSchema } from 'graphql'; +import { OverrideApolloGateway } from '../graphql/graphRouter'; +import { generateJsFederatedResolvers } from '../utils/exportFiles'; +import { getComposedSchema, superSchemaToSchema } from '../graphql/composition'; export async function startMocks(item: SubgraphSummaryTreeItem) { - if (item) - ServerManager.instance.startSupergraphMocks(item.filePath); - else { - let wbFiles: string[] = []; - FileProvider.instance.getWorkbenchFiles().forEach((value, key) => wbFiles.push(value.graphName)); - let wbFileToStartMocks = await window.showQuickPick(wbFiles, { placeHolder: "Select which supergraph design file to mock" }); - if (wbFileToStartMocks) { - let wbFilePath = ''; - FileProvider.instance.getWorkbenchFiles().forEach((value, key) => { - if (value.graphName == wbFileToStartMocks) - wbFilePath = key; - }) + if (item) ServerManager.instance.startSupergraphMocks(item.filePath); + else { + let wbFiles: string[] = []; + FileProvider.instance + .getWorkbenchFiles() + .forEach((value, key) => wbFiles.push(value.graphName)); + let wbFileToStartMocks = await window.showQuickPick(wbFiles, { + placeHolder: 'Select which supergraph design file to mock', + }); + if (wbFileToStartMocks) { + let wbFilePath = ''; + FileProvider.instance.getWorkbenchFiles().forEach((value, key) => { + if (value.graphName == wbFileToStartMocks) wbFilePath = key; + }); - if (existsSync(wbFilePath)) - ServerManager.instance.startSupergraphMocks(wbFilePath); - else - window.showInformationMessage('There was an error loading your workbench file for mocking, please file an issue on the repo with what happened and your workbench file'); - } else - window.showInformationMessage('No supergraph was selected, cancelling mocks') - } + if (existsSync(wbFilePath)) + ServerManager.instance.startSupergraphMocks(wbFilePath); + else + window.showInformationMessage( + 'There was an error loading your workbench file for mocking, please file an issue on the repo with what happened and your workbench file', + ); + } else + window.showInformationMessage( + 'No supergraph was selected, cancelling mocks', + ); + } } export async function stopMocks(item: SubgraphTreeItem) { - ServerManager.instance.stopMocks(); + ServerManager.instance.stopMocks(); } export async function editSubgraph(item: SubgraphTreeItem) { - const uri = WorkbenchUri.supergraph(item.wbFilePath, item.subgraphName, WorkbenchUriType.SCHEMAS); - try { - await window.showTextDocument(uri); - FileProvider.instance.loadWorkbenchForComposition(item.wbFilePath); - } catch (err) { - console.log(err) - } + const uri = WorkbenchUri.supergraph( + item.wbFilePath, + item.subgraphName, + WorkbenchUriType.SCHEMAS, + ); + try { + await window.showTextDocument(uri); + FileProvider.instance.loadWorkbenchForComposition(item.wbFilePath); + } catch (err) { + console.log(err); + } } export async function editSupergraphOperation(item: OperationTreeItem) { - await window.showTextDocument(WorkbenchUri.supergraph(item.filePath, item.operationName, WorkbenchUriType.QUERIES)); - FileProvider.instance.loadWorkbenchForComposition(item.filePath); + await window.showTextDocument( + WorkbenchUri.supergraph( + item.filePath, + item.operationName, + WorkbenchUriType.QUERIES, + ), + ); + FileProvider.instance.loadWorkbenchForComposition(item.filePath); } export async function viewSubgraphSettings(item: SubgraphTreeItem) { - await window.showTextDocument(WorkbenchUri.supergraph(item.wbFilePath, item.subgraphName, WorkbenchUriType.SCHEMAS_SETTINGS)); + await window.showTextDocument( + WorkbenchUri.supergraph( + item.wbFilePath, + item.subgraphName, + WorkbenchUriType.SCHEMAS_SETTINGS, + ), + ); } export async function addOperation(item: OperationTreeItem) { - let wbFilePath = item.filePath; - let wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); - if (wbFile) { - let operationName = await window.showInputBox({ placeHolder: "Enter a name for the operation" }) ?? ""; - if (!operationName) { - const message = `Create schema cancelled - No name entered.`; - console.log(message); - window.setStatusBarMessage(message, 3000); - } else { - wbFile.operations[operationName] = `query ${operationName} {\n\t\n}`; - FileProvider.instance.saveWorkbenchFile(wbFile, item.filePath); - } + let wbFilePath = item.filePath; + let wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); + if (wbFile) { + let operationName = + (await window.showInputBox({ + placeHolder: 'Enter a name for the operation', + })) ?? ''; + if (!operationName) { + const message = `Create schema cancelled - No name entered.`; + console.log(message); + window.setStatusBarMessage(message, 3000); + } else { + wbFile.operations[operationName] = `query ${operationName} {\n\t\n}`; + FileProvider.instance.saveWorkbenchFile(wbFile, item.filePath); } + } } export async function deleteOperation(item: OperationTreeItem) { - let wbFilePath = item.filePath; - let wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); - let operationName = item.operationName; - if (wbFile) { - delete wbFile.operations[operationName]; - FileProvider.instance.saveWorkbenchFile(wbFile, item.filePath); - } + let wbFilePath = item.filePath; + let wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); + let operationName = item.operationName; + if (wbFile) { + delete wbFile.operations[operationName]; + FileProvider.instance.saveWorkbenchFile(wbFile, item.filePath); + } } export async function viewQueryPlan(item: OperationTreeItem) { - await window.showTextDocument(WorkbenchUri.supergraph(item.filePath, item.operationName, WorkbenchUriType.QUERY_PLANS)); + await window.showTextDocument( + WorkbenchUri.supergraph( + item.filePath, + item.operationName, + WorkbenchUriType.QUERY_PLANS, + ), + ); } export async function viewSupergraphSchema(item: SupergraphSchemaTreeItem) { - await window.showTextDocument(WorkbenchUri.supergraph(item.filePath, item.wbFile.graphName, WorkbenchUriType.SUPERGRAPH_SCHEMA)); - FileProvider.instance.loadWorkbenchForComposition(item.filePath); + await window.showTextDocument( + WorkbenchUri.supergraph( + item.filePath, + item.wbFile.graphName, + WorkbenchUriType.SUPERGRAPH_SCHEMA, + ), + ); + FileProvider.instance.loadWorkbenchForComposition(item.filePath); } -export async function viewSupergraphApiSchema(item: SupergraphApiSchemaTreeItem) { - await window.showTextDocument(WorkbenchUri.supergraph(item.filePath, item.wbFile.graphName, WorkbenchUriType.SUPERGRAPH_API_SCHEMA)); - FileProvider.instance.loadWorkbenchForComposition(item.filePath); +export async function viewSupergraphApiSchema( + item: SupergraphApiSchemaTreeItem, +) { + await window.showTextDocument( + WorkbenchUri.supergraph( + item.filePath, + item.wbFile.graphName, + WorkbenchUriType.SUPERGRAPH_API_SCHEMA, + ), + ); + FileProvider.instance.loadWorkbenchForComposition(item.filePath); } export function refreshSupergraphs() { - StateManager.instance.localSupergraphTreeDataProvider.refresh(); + StateManager.instance.localSupergraphTreeDataProvider.refresh(); } export async function addSubgraph(item: SubgraphSummaryTreeItem) { - let wbFile = item.wbFile; - let serviceName = await window.showInputBox({ placeHolder: "Enter a unique name for the subgraph" }) ?? ""; - if (!serviceName) { - const message = `Create schema cancelled - No name entered.`; - console.log(message); - window.setStatusBarMessage(message, 3000); - } else { - wbFile.schemas[serviceName] = { shouldMock: true, sdl: "", autoUpdateSchemaFromUrl: false }; - FileProvider.instance.saveWorkbenchFile(wbFile, item.filePath); - } + let wbFile = item.wbFile; + let serviceName = + (await window.showInputBox({ + placeHolder: 'Enter a unique name for the subgraph', + })) ?? ''; + if (!serviceName) { + const message = `Create schema cancelled - No name entered.`; + console.log(message); + window.setStatusBarMessage(message, 3000); + } else { + wbFile.schemas[serviceName] = { + shouldMock: true, + sdl: '', + autoUpdateSchemaFromUrl: false, + }; + FileProvider.instance.saveWorkbenchFile(wbFile, item.filePath); + } } export async function deleteSubgraph(item: SubgraphTreeItem) { - let wbFilePath = item.wbFilePath; - let wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); - let subgraphName = item.subgraphName; - if (wbFile) { - delete wbFile.schemas[subgraphName]; - FileProvider.instance.saveWorkbenchFile(wbFile, item.wbFilePath); - } + let wbFilePath = item.wbFilePath; + let wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); + let subgraphName = item.subgraphName; + if (wbFile) { + delete wbFile.schemas[subgraphName]; + FileProvider.instance.saveWorkbenchFile(wbFile, item.wbFilePath); + } } export async function newDesign() { - if (!StateManager.workspaceRoot) { - await FileProvider.instance.promptOpenFolder(); + if (!StateManager.workspaceRoot) { + await FileProvider.instance.promptOpenFolder(); + } else { + let workbenchName = await window.showInputBox({ + placeHolder: 'Enter name for workbench file', + }); + if (!workbenchName) { + const msg = + 'No name was provided for the file.\n Cancelling new workbench create'; + console.log(msg); + window.showErrorMessage(msg); } else { - let workbenchName = await window.showInputBox({ placeHolder: "Enter name for workbench file" }); - if (!workbenchName) { - const msg = 'No name was provided for the file.\n Cancelling new workbench create'; - console.log(msg); - window.showErrorMessage(msg); - } else { - FileProvider.instance.createWorkbenchFileLocally(new ApolloWorkbenchFile(workbenchName)); - } + FileProvider.instance.createWorkbenchFileLocally( + new ApolloWorkbenchFile(workbenchName), + ); } + } } -export async function createWorkbenchFromSupergraphVariant(graphVariantTreeItem: StudioGraphVariantTreeItem) { - if (!StateManager.workspaceRoot) { - await FileProvider.instance.promptOpenFolder(); - } else { - await createWorkbench(graphVariantTreeItem.graphId, graphVariantTreeItem.graphVariant); - } +export async function createWorkbenchFromSupergraphVariant( + graphVariantTreeItem: StudioGraphVariantTreeItem, +) { + if (!StateManager.workspaceRoot) { + await FileProvider.instance.promptOpenFolder(); + } else { + await createWorkbench( + graphVariantTreeItem.graphId, + graphVariantTreeItem.graphVariant, + ); + } } -export async function createWorkbenchFromSupergraph(graphVariantTreeItem: StudioGraphTreeItem, selectedVariant?: string) { - if (!StateManager.workspaceRoot) { - await FileProvider.instance.promptOpenFolder(); - } else { - const graphId = graphVariantTreeItem.graphId; - const graphVariants = graphVariantTreeItem.variants; - if (!selectedVariant) { - if (graphVariants.length == 0) { - selectedVariant = 'currrent' - } else if (graphVariants.length == 1) { - selectedVariant = graphVariants[0]; - } else { - selectedVariant = await window.showQuickPick(graphVariants) ?? ''; - } - } +export async function createWorkbenchFromSupergraph( + graphVariantTreeItem: StudioGraphTreeItem, + selectedVariant?: string, +) { + if (!StateManager.workspaceRoot) { + await FileProvider.instance.promptOpenFolder(); + } else { + const graphId = graphVariantTreeItem.graphId; + const graphVariants = graphVariantTreeItem.variants; + if (!selectedVariant) { + if (graphVariants.length == 0) { + selectedVariant = 'currrent'; + } else if (graphVariants.length == 1) { + selectedVariant = graphVariants[0]; + } else { + selectedVariant = (await window.showQuickPick(graphVariants)) ?? ''; + } + } - if (selectedVariant == '') { - window.showInformationMessage("You must select a variant to load the graph from"); - } else { - await createWorkbench(graphId, selectedVariant); - } + if (selectedVariant == '') { + window.showInformationMessage( + 'You must select a variant to load the graph from', + ); + } else { + await createWorkbench(graphId, selectedVariant); } + } } async function createWorkbench(graphId: string, selectedVariant: string) { - let defaultGraphName = `${graphId}-${selectedVariant}-`; - let graphName = await window.showInputBox({ - prompt: "Enter a name for your new workbench file", - placeHolder: defaultGraphName, - value: defaultGraphName - }); - if (graphName) { - let workbenchFile: ApolloWorkbenchFile = new ApolloWorkbenchFile(graphName); - workbenchFile.graphName = graphName; + let defaultGraphName = `${graphId}-${selectedVariant}-`; + let graphName = await window.showInputBox({ + prompt: 'Enter a name for your new workbench file', + placeHolder: defaultGraphName, + value: defaultGraphName, + }); + if (graphName) { + let workbenchFile: ApolloWorkbenchFile = new ApolloWorkbenchFile(graphName); + workbenchFile.graphName = graphName; - const results = await getGraphSchemasByVariant(StateManager.instance.globalState_userApiKey, graphId, selectedVariant); - const monolithicService = results.service?.implementingServices as GetGraphSchemas_service_implementingServices_NonFederatedImplementingService; - if (monolithicService?.graphID) { - workbenchFile.schemas['monolith'] = { sdl: results.service?.schema?.document, shouldMock: true, autoUpdateSchemaFromUrl: false }; - } else { - const implementingServices = results.service?.implementingServices as GetGraphSchemas_service_implementingServices_FederatedImplementingServices; - implementingServices?.services?.map(service => workbenchFile.schemas[service.name] = { sdl: service.activePartialSchema.sdl, url: service.url ?? "", shouldMock: true, autoUpdateSchemaFromUrl: false }); - } - - const { supergraphSdl } = await getComposedSchema(workbenchFile); - if (supergraphSdl) workbenchFile.supergraphSdl = supergraphSdl; - - FileProvider.instance.createWorkbenchFileLocally(workbenchFile); + const results = await getGraphSchemasByVariant( + StateManager.instance.globalState_userApiKey, + graphId, + selectedVariant, + ); + const monolithicService = results.service + ?.implementingServices as GetGraphSchemas_service_implementingServices_NonFederatedImplementingService; + if (monolithicService?.graphID) { + workbenchFile.schemas['monolith'] = { + sdl: results.service?.schema?.document, + shouldMock: true, + autoUpdateSchemaFromUrl: false, + }; } else { - window.showInformationMessage("You must provide a name to create a new workbench file") + const implementingServices = results.service + ?.implementingServices as GetGraphSchemas_service_implementingServices_FederatedImplementingServices; + implementingServices?.services?.map( + (service) => + (workbenchFile.schemas[service.name] = { + sdl: service.activePartialSchema.sdl, + url: service.url ?? '', + shouldMock: true, + autoUpdateSchemaFromUrl: false, + }), + ); } + + const { supergraphSdl } = await getComposedSchema(workbenchFile); + if (supergraphSdl) workbenchFile.supergraphSdl = supergraphSdl; + + FileProvider.instance.createWorkbenchFileLocally(workbenchFile); + } else { + window.showInformationMessage( + 'You must provide a name to create a new workbench file', + ); + } } export async function updateSubgraphSchemaFromURL(item: SubgraphTreeItem) { - if (StateManager.settings_tlsRejectUnauthorized) process.env.NODE_TLS_REJECT_UNAUTHORIZED = ''; - else process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + if (StateManager.settings_tlsRejectUnauthorized) + process.env.NODE_TLS_REJECT_UNAUTHORIZED = ''; + else process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - let wbFile = FileProvider.instance.workbenchFileFromPath(item.wbFilePath); - if (wbFile?.schemas[item.subgraphName] && !wbFile?.schemas[item.subgraphName].url) { - let routingURL = await window.showInputBox({ placeHolder: "Enter a the url for the schema/service" }) ?? ""; - if (!routingURL) { - const message = `Set service URL cancelled for ${item.subgraphName} - No URL entered.`; - console.log(message); - window.setStatusBarMessage(message, 3000); - } else { - wbFile.schemas[item.subgraphName].url = routingURL; - } + let wbFile = FileProvider.instance.workbenchFileFromPath(item.wbFilePath); + if ( + wbFile?.schemas[item.subgraphName] && + !wbFile?.schemas[item.subgraphName].url + ) { + let routingURL = + (await window.showInputBox({ + placeHolder: 'Enter a the url for the schema/service', + })) ?? ''; + if (!routingURL) { + const message = `Set service URL cancelled for ${item.subgraphName} - No URL entered.`; + console.log(message); + window.setStatusBarMessage(message, 3000); + } else { + wbFile.schemas[item.subgraphName].url = routingURL; } - if (wbFile?.schemas[item.subgraphName].url) { - const sdl = await OverrideApolloGateway.getTypeDefs(wbFile.schemas[item.subgraphName].url ?? "", item.subgraphName); - if (sdl) { - wbFile.schemas[item.subgraphName].sdl = sdl; - - let editor = await window.showTextDocument(WorkbenchUri.supergraph(item.wbFilePath, item.subgraphName, WorkbenchUriType.SCHEMAS)); - if (editor) { - const document = editor.document; - await editor.edit((editor) => { - editor.replace(new Range(0, 0, document.lineCount, 0), sdl); - }); - await document.save(); - } - } + } + if (wbFile?.schemas[item.subgraphName].url) { + const sdl = await OverrideApolloGateway.getTypeDefs( + wbFile.schemas[item.subgraphName].url ?? '', + item.subgraphName, + ); + if (sdl) { + wbFile.schemas[item.subgraphName].sdl = sdl; - FileProvider.instance.saveWorkbenchFile(wbFile, item.wbFilePath, false); - } else {//No URL entered for schema - window.showErrorMessage("You must set a url for the service if you want to update the schema from it."); + let editor = await window.showTextDocument( + WorkbenchUri.supergraph( + item.wbFilePath, + item.subgraphName, + WorkbenchUriType.SCHEMAS, + ), + ); + if (editor) { + const document = editor.document; + await editor.edit((editor) => { + editor.replace(new Range(0, 0, document.lineCount, 0), sdl); + }); + await document.save(); + } } + + FileProvider.instance.saveWorkbenchFile(wbFile, item.wbFilePath, false); + } else { + //No URL entered for schema + window.showErrorMessage( + 'You must set a url for the service if you want to update the schema from it.', + ); + } } export async function viewSubgraphCustomMocks(item: SubgraphTreeItem) { - const subgraphMocksUri = WorkbenchUri.supergraph(item.supergraphName, item.subgraphName, WorkbenchUriType.MOCKS); - if (!existsSync(subgraphMocksUri.fsPath)) { - const wbFile = FileProvider.instance.workbenchFileFromPath(item.wbFilePath); - const customMocks = wbFile?.schemas[item.subgraphName].customMocks; - if (customMocks) writeFileSync(subgraphMocksUri.fsPath, customMocks, { encoding: "utf-8" }); - else writeFileSync(subgraphMocksUri.fsPath, "const faker = require('faker')\n\nconst mocks = {\n\n}\nmodule.exports = mocks;", { encoding: "utf-8" }); - } - try { - await window.showTextDocument(subgraphMocksUri); - } catch (err) { - console.log(err) - } + const subgraphMocksUri = WorkbenchUri.supergraph( + item.supergraphName, + item.subgraphName, + WorkbenchUriType.MOCKS, + ); + if (!existsSync(subgraphMocksUri.fsPath)) { + const wbFile = FileProvider.instance.workbenchFileFromPath(item.wbFilePath); + const customMocks = wbFile?.schemas[item.subgraphName].customMocks; + if (customMocks) + writeFileSync(subgraphMocksUri.fsPath, customMocks, { + encoding: 'utf-8', + }); + else + writeFileSync( + subgraphMocksUri.fsPath, + "const faker = require('faker')\n\nconst mocks = {\n\n}\nmodule.exports = mocks;", + { encoding: 'utf-8' }, + ); + } + try { + await window.showTextDocument(subgraphMocksUri); + } catch (err) { + console.log(err); + } } export async function exportSupergraphSchema(item: SupergraphSchemaTreeItem) { - if (item.wbFile.supergraphSdl && StateManager.workspaceRoot) { - const exportPath = resolve(StateManager.workspaceRoot, `${item.wbFile.graphName}-supergraph-schema.graphql`); - const exportUri = Uri.parse(exportPath); - writeFileSync(exportPath, item.wbFile.supergraphSdl, { encoding: 'utf-8' }); - window.showInformationMessage(`Supergraph Schema was exported to ${exportPath}`); - } + if (item.wbFile.supergraphSdl && StateManager.workspaceRoot) { + const exportPath = resolve( + StateManager.workspaceRoot, + `${item.wbFile.graphName}-supergraph-schema.graphql`, + ); + const exportUri = Uri.parse(exportPath); + writeFileSync(exportPath, item.wbFile.supergraphSdl, { encoding: 'utf-8' }); + window.showInformationMessage( + `Supergraph Schema was exported to ${exportPath}`, + ); + } } -export async function exportSupergraphApiSchema(item: SupergraphApiSchemaTreeItem) { - const supergraphSchema = item.wbFile.supergraphSdl; - if (supergraphSchema && StateManager.workspaceRoot) { - const exportPath = resolve(StateManager.workspaceRoot, `${item.wbFile.graphName}-api-schema.graphql`); - const finalSchema = superSchemaToSchema(supergraphSchema); - writeFileSync(exportPath, printSchema(finalSchema), { encoding: 'utf-8' }); - window.showInformationMessage(`Graph Core Schema was exported to ${exportPath}`); - } +export async function exportSupergraphApiSchema( + item: SupergraphApiSchemaTreeItem, +) { + const supergraphSchema = item.wbFile.supergraphSdl; + if (supergraphSchema && StateManager.workspaceRoot) { + const exportPath = resolve( + StateManager.workspaceRoot, + `${item.wbFile.graphName}-api-schema.graphql`, + ); + const finalSchema = superSchemaToSchema(supergraphSchema); + writeFileSync(exportPath, printSchema(finalSchema), { encoding: 'utf-8' }); + window.showInformationMessage( + `Graph Core Schema was exported to ${exportPath}`, + ); + } } export async function exportSubgraphSchema(item: SubgraphTreeItem) { - const exportPath = StateManager.workspaceRoot ? resolve(StateManager.workspaceRoot, `${item.subgraphName}.graphql`) : null; - if (exportPath) { - const schema = FileProvider.instance.workbenchFileFromPath(item.wbFilePath)?.schemas[item.subgraphName]?.sdl ?? ""; - writeFileSync(exportPath, schema, { encoding: 'utf-8' }); + const exportPath = StateManager.workspaceRoot + ? resolve(StateManager.workspaceRoot, `${item.subgraphName}.graphql`) + : null; + if (exportPath) { + const schema = + FileProvider.instance.workbenchFileFromPath(item.wbFilePath)?.schemas[ + item.subgraphName + ]?.sdl ?? ''; + writeFileSync(exportPath, schema, { encoding: 'utf-8' }); - window.showInformationMessage(`${item.subgraphName} schema was exported to ${exportPath}`); - } + window.showInformationMessage( + `${item.subgraphName} schema was exported to ${exportPath}`, + ); + } } export async function exportSubgraphResolvers(item: SubgraphTreeItem) { - let exportPath = StateManager.workspaceRoot ? resolve(StateManager.workspaceRoot, `${item.subgraphName}-resolvers`) : null; - if (exportPath) { - let resolvers = ''; - const schema = FileProvider.instance.workbenchFileFromPath(item.wbFilePath)?.schemas[item.subgraphName].sdl ?? ""; - resolvers = generateJsFederatedResolvers(schema); - //TODO: Future Feature could have a more robust typescript generation version - // let exportLanguage = await window.showQuickPick(["Javascript", "Typescript"], { canPickMany: false, placeHolder: "Would you like to use Javascript or Typescript for the exported project?" }); - // if (exportLanguage == "Typescript") { - // resolvers = generateTsFederatedResolvers(schema); - // exportPath += ".ts"; - // } else { - // resolvers = generateJsFederatedResolvers(schema); - // exportPath += ".js"; - // } + let exportPath = StateManager.workspaceRoot + ? resolve(StateManager.workspaceRoot, `${item.subgraphName}-resolvers`) + : null; + if (exportPath) { + let resolvers = ''; + const schema = + FileProvider.instance.workbenchFileFromPath(item.wbFilePath)?.schemas[ + item.subgraphName + ].sdl ?? ''; + resolvers = generateJsFederatedResolvers(schema); + //TODO: Future Feature could have a more robust typescript generation version + // let exportLanguage = await window.showQuickPick(["Javascript", "Typescript"], { canPickMany: false, placeHolder: "Would you like to use Javascript or Typescript for the exported project?" }); + // if (exportLanguage == "Typescript") { + // resolvers = generateTsFederatedResolvers(schema); + // exportPath += ".ts"; + // } else { + // resolvers = generateJsFederatedResolvers(schema); + // exportPath += ".js"; + // } - writeFileSync(`${exportPath}.js`, resolvers, { encoding: 'utf-8' }); - window.showInformationMessage(`${item.subgraphName} resolvers was exported to ${exportPath}`); - } + writeFileSync(`${exportPath}.js`, resolvers, { encoding: 'utf-8' }); + window.showInformationMessage( + `${item.subgraphName} resolvers was exported to ${exportPath}`, + ); + } +} +export async function createWorkbenchFromPreloaded( + preloadedItem: PreloadedWorkbenchFile, +) { + await FileProvider.instance.copyPreloadedWorkbenchFile( + preloadedItem.fileName, + ); } -export async function createWorkbenchFromPreloaded(preloadedItem: PreloadedWorkbenchFile) { - await FileProvider.instance.copyPreloadedWorkbenchFile(preloadedItem.fileName); -} \ No newline at end of file diff --git a/src/commands/studio-graphs.ts b/src/commands/studio-graphs.ts index 1a4722b..650de9f 100644 --- a/src/commands/studio-graphs.ts +++ b/src/commands/studio-graphs.ts @@ -1,53 +1,65 @@ -import { StateManager } from "../workbench/stateManager"; -import { StudioGraphTreeItem, StudioGraphVariantTreeItem } from "../workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider"; -import { FileProvider } from "../workbench/file-system/fileProvider"; -import { PreloadedWorkbenchFile } from "../workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider"; -import { StudioOperationTreeItem } from "../workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider"; -import { window } from "vscode"; -import { ApolloStudioOperationsProvider } from "../workbench/docProviders"; -import { getUserMemberships } from "../graphql/graphClient"; -import { enterStudioApiKey } from "./extension"; +import { StateManager } from '../workbench/stateManager'; +import { + StudioGraphTreeItem, + StudioGraphVariantTreeItem, +} from '../workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider'; +import { FileProvider } from '../workbench/file-system/fileProvider'; +import { PreloadedWorkbenchFile } from '../workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider'; +import { StudioOperationTreeItem } from '../workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider'; +import { window } from 'vscode'; +import { ApolloStudioOperationsProvider } from '../workbench/docProviders'; +import { getUserMemberships } from '../graphql/graphClient'; +import { enterStudioApiKey } from './extension'; export function refreshStudioGraphs() { - StateManager.instance.apolloStudioGraphsProvider.refresh() + StateManager.instance.apolloStudioGraphsProvider.refresh(); } -export async function loadOperations(graphTreeItem: any, graphVariant?: string) { - StateManager.instance.setSelectedGraph(graphTreeItem.graphId, graphVariant) +export async function loadOperations( + graphTreeItem: any, + graphVariant?: string, +) { + StateManager.instance.setSelectedGraph(graphTreeItem.graphId, graphVariant); } export async function viewStudioOperation(operation: StudioOperationTreeItem) { - await window.showTextDocument(ApolloStudioOperationsProvider.Uri(operation.operationName, operation.operationSignature)) + await window.showTextDocument( + ApolloStudioOperationsProvider.Uri( + operation.operationName, + operation.operationSignature, + ), + ); } export async function switchOrg() { - if (!StateManager.instance.globalState_userApiKey) - await enterStudioApiKey(); - - let accountId = ''; - let apiKey = StateManager.instance.globalState_userApiKey; - - if (apiKey) { - const myAccountIds = await getUserMemberships(apiKey); - const memberships = (myAccountIds?.me as any)?.memberships; - if (memberships?.length > 1) { - let accountMapping: { [key: string]: string } = {}; - memberships.map(membership => { - let accountId = membership.account.id; - let accountName = membership.account.name; - accountMapping[accountName] = accountId; - }); - - let selectedOrgName = await window.showQuickPick(Object.keys(accountMapping), { placeHolder: "Select an account to load graphs from" }) ?? ""; - accountId = accountMapping[selectedOrgName]; - - } else { - accountId = memberships[0]?.account?.id ?? ""; - } - - if (accountId) { - StateManager.instance.setSelectedGraph(""); - StateManager.instance.globalState_selectedApolloAccount = accountId; - } + if (!StateManager.instance.globalState_userApiKey) await enterStudioApiKey(); + + let accountId = ''; + let apiKey = StateManager.instance.globalState_userApiKey; + + if (apiKey) { + const myAccountIds = await getUserMemberships(apiKey); + const memberships = (myAccountIds?.me as any)?.memberships; + if (memberships?.length > 1) { + let accountMapping: { [key: string]: string } = {}; + memberships.map((membership) => { + let accountId = membership.account.id; + let accountName = membership.account.name; + accountMapping[accountName] = accountId; + }); + + let selectedOrgName = + (await window.showQuickPick(Object.keys(accountMapping), { + placeHolder: 'Select an account to load graphs from', + })) ?? ''; + accountId = accountMapping[selectedOrgName]; + } else { + accountId = memberships[0]?.account?.id ?? ''; } -} \ No newline at end of file + + if (accountId) { + StateManager.instance.setSelectedGraph(''); + StateManager.instance.globalState_selectedApolloAccount = accountId; + } + } +} diff --git a/src/commands/studio-operations.ts b/src/commands/studio-operations.ts index 2f337f2..0d49360 100644 --- a/src/commands/studio-operations.ts +++ b/src/commands/studio-operations.ts @@ -1,27 +1,35 @@ -import { StudioOperationTreeItem } from "../workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider"; -import { FileProvider } from "../workbench/file-system/fileProvider"; -import { window } from "vscode"; -import { StateManager } from "../workbench/stateManager"; -import { parse } from "graphql"; -import { print } from "graphql"; +import { StudioOperationTreeItem } from '../workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider'; +import { FileProvider } from '../workbench/file-system/fileProvider'; +import { window } from 'vscode'; +import { StateManager } from '../workbench/stateManager'; +import { parse } from 'graphql'; +import { print } from 'graphql'; export async function addToWorkbench(op: StudioOperationTreeItem) { - let supergraphs = FileProvider.instance.getWorkbenchFiles(); - let supergraphNames: string[] = []; - supergraphs.forEach(wbFile => supergraphNames.push(wbFile.graphName)); + let supergraphs = FileProvider.instance.getWorkbenchFiles(); + let supergraphNames: string[] = []; + supergraphs.forEach((wbFile) => supergraphNames.push(wbFile.graphName)); - let supergraphToAddOperationTo = await window.showQuickPick(supergraphNames, { placeHolder: "Select the Supergraph to add the operation to" }); - if (supergraphToAddOperationTo) { - let wbFile = Array.from(supergraphs.values()).find(wb => wb.graphName == supergraphToAddOperationTo); - if (wbFile) { - let wbPath = ''; - Array.from(supergraphs.keys()).forEach(path => { - const wb = FileProvider.instance.workbenchFileFromPath(path); - if (wb?.graphName == supergraphToAddOperationTo && supergraphToAddOperationTo) wbPath = path; - }) + let supergraphToAddOperationTo = await window.showQuickPick(supergraphNames, { + placeHolder: 'Select the Supergraph to add the operation to', + }); + if (supergraphToAddOperationTo) { + let wbFile = Array.from(supergraphs.values()).find( + (wb) => wb.graphName == supergraphToAddOperationTo, + ); + if (wbFile) { + let wbPath = ''; + Array.from(supergraphs.keys()).forEach((path) => { + const wb = FileProvider.instance.workbenchFileFromPath(path); + if ( + wb?.graphName == supergraphToAddOperationTo && + supergraphToAddOperationTo + ) + wbPath = path; + }); - wbFile.operations[op.operationName] = print(parse(op.operationSignature)); - FileProvider.instance.saveWorkbenchFile(wbFile, wbPath); - } + wbFile.operations[op.operationName] = print(parse(op.operationSignature)); + FileProvider.instance.saveWorkbenchFile(wbFile, wbPath); } -} \ No newline at end of file + } +} diff --git a/src/extension.ts b/src/extension.ts index b05d32d..586a056 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,4 +1,14 @@ -import { workspace, commands, languages, window, ExtensionContext, DiagnosticCollection, Range, Diagnostic, Position } from 'vscode'; +import { + workspace, + commands, + languages, + window, + ExtensionContext, + DiagnosticCollection, + Range, + Diagnostic, + Position, +} from 'vscode'; import { Kind, Source } from 'graphql'; import { DiagnosticSeverity } from 'vscode-languageclient'; import { GraphQLDocument } from 'apollo-language-server/lib/document'; @@ -10,154 +20,304 @@ import { ServerManager } from './workbench/serverManager'; import { FileProvider } from './workbench/file-system/fileProvider'; import { federationCompletionProvider } from './workbench/federationCompletionProvider'; import { FederationCodeActionProvider } from './workbench/federationCodeActionProvider'; -import { ApolloStudioOperationsProvider, GettingStartedDocProvider } from './workbench/docProviders'; +import { + ApolloStudioOperationsProvider, + GettingStartedDocProvider, +} from './workbench/docProviders'; import { addToWorkbench } from './commands/studio-operations'; -import { ensureFolderIsOpen, openFolder, enterStudioApiKey, gettingStarted, deleteStudioApiKey } from './commands/extension'; -import { refreshStudioGraphs, loadOperations, viewStudioOperation, switchOrg } from './commands/studio-graphs'; -import { createWorkbenchFromPreloaded, startMocks, stopMocks, deleteOperation, addOperation, viewQueryPlan, editSubgraph, deleteSubgraph, refreshSupergraphs, viewSubgraphSettings, addSubgraph, viewSupergraphSchema, editSupergraphOperation, newDesign, createWorkbenchFromSupergraph, exportSupergraphSchema, exportSupergraphApiSchema, viewSupergraphApiSchema, updateSubgraphSchemaFromURL, viewSubgraphCustomMocks, exportSubgraphSchema, exportSubgraphResolvers, createWorkbenchFromSupergraphVariant } from './commands/local-supergraph-designs'; +import { + ensureFolderIsOpen, + openFolder, + enterStudioApiKey, + gettingStarted, + deleteStudioApiKey, +} from './commands/extension'; +import { + refreshStudioGraphs, + loadOperations, + viewStudioOperation, + switchOrg, +} from './commands/studio-graphs'; +import { + createWorkbenchFromPreloaded, + startMocks, + stopMocks, + deleteOperation, + addOperation, + viewQueryPlan, + editSubgraph, + deleteSubgraph, + refreshSupergraphs, + viewSubgraphSettings, + addSubgraph, + viewSupergraphSchema, + editSupergraphOperation, + newDesign, + createWorkbenchFromSupergraph, + exportSupergraphSchema, + exportSupergraphApiSchema, + viewSupergraphApiSchema, + updateSubgraphSchemaFromURL, + viewSubgraphCustomMocks, + exportSubgraphSchema, + exportSubgraphResolvers, + createWorkbenchFromSupergraphVariant, +} from './commands/local-supergraph-designs'; import { resolve } from 'path'; import { mkdirSync, writeFileSync } from 'fs'; import { execSync } from 'child_process'; import { WorkbenchUri } from './workbench/file-system/WorkbenchUri'; -export const compositionDiagnostics: DiagnosticCollection = languages.createDiagnosticCollection("composition-errors"); -export const operationDiagnostics: DiagnosticCollection = languages.createDiagnosticCollection("operation-errors"); -export const outputChannel = window.createOutputChannel("Apollo Workbench"); +export const compositionDiagnostics: DiagnosticCollection = languages.createDiagnosticCollection( + 'composition-errors', +); +export const operationDiagnostics: DiagnosticCollection = languages.createDiagnosticCollection( + 'operation-errors', +); +export const outputChannel = window.createOutputChannel('Apollo Workbench'); //Redirect console.log to Output tab in extension console.log = function (str) { - outputChannel.appendLine(str); + outputChannel.appendLine(str); }; // Our event when vscode deactivates export async function deactivate(context: ExtensionContext) { - ServerManager.instance.stopMocks(); + ServerManager.instance.stopMocks(); } export async function activate(context: ExtensionContext) { - StateManager.init(context); - context.workspaceState.update("selectedWbFile", ""); - context.globalState.update("APOLLO_SELCTED_GRAPH_ID", ""); + StateManager.init(context); + context.workspaceState.update('selectedWbFile', ''); + context.globalState.update('APOLLO_SELCTED_GRAPH_ID', ''); - //Setting up the mocks project folder - need to isolate to mocks running - if (StateManager.instance.extensionGlobalStoragePath) { - const mocksPath = resolve(StateManager.instance.extensionGlobalStoragePath, `mocks`); - const packageJsonPath = resolve(mocksPath, `package.json`); - mkdirSync(mocksPath, { recursive: true }); - writeFileSync(packageJsonPath, '{"name":"mocks", "version":"1.0"}', { encoding: 'utf-8' }); - execSync(`npm i faker`, { cwd: mocksPath }); - } - context.subscriptions.push(compositionDiagnostics); - context.subscriptions.push(workspace.registerFileSystemProvider('workbench', FileProvider.instance, { isCaseSensitive: true })); + //Setting up the mocks project folder - need to isolate to mocks running + if (StateManager.instance.extensionGlobalStoragePath) { + const mocksPath = resolve( + StateManager.instance.extensionGlobalStoragePath, + `mocks`, + ); + const packageJsonPath = resolve(mocksPath, `package.json`); + mkdirSync(mocksPath, { recursive: true }); + writeFileSync(packageJsonPath, '{"name":"mocks", "version":"1.0"}', { + encoding: 'utf-8', + }); + execSync(`npm i faker`, { cwd: mocksPath }); + } + context.subscriptions.push(compositionDiagnostics); + context.subscriptions.push( + workspace.registerFileSystemProvider('workbench', FileProvider.instance, { + isCaseSensitive: true, + }), + ); - languages.registerCompletionItemProvider("graphql", federationCompletionProvider); - languages.registerCodeActionsProvider({ language: 'graphql' }, new FederationCodeActionProvider()); + languages.registerCompletionItemProvider( + 'graphql', + federationCompletionProvider, + ); + languages.registerCodeActionsProvider( + { language: 'graphql' }, + new FederationCodeActionProvider(), + ); - //Register Tree Data Providers - window.registerTreeDataProvider('local-supergraph-designs', StateManager.instance.localSupergraphTreeDataProvider); - window.registerTreeDataProvider('studio-graphs', StateManager.instance.apolloStudioGraphsProvider); - window.registerTreeDataProvider('studio-operations', StateManager.instance.apolloStudioGraphOpsProvider); + //Register Tree Data Providers + window.registerTreeDataProvider( + 'local-supergraph-designs', + StateManager.instance.localSupergraphTreeDataProvider, + ); + window.registerTreeDataProvider( + 'studio-graphs', + StateManager.instance.apolloStudioGraphsProvider, + ); + window.registerTreeDataProvider( + 'studio-operations', + StateManager.instance.apolloStudioGraphOpsProvider, + ); - //Register commands to ensure a folder is open in the window to store workbench files - commands.executeCommand('extension.ensureFolderIsOpen'); - commands.registerCommand('extension.ensureFolderIsOpen', ensureFolderIsOpen); - commands.registerCommand('extension.openFolder', openFolder); - //Global Extension Commands - commands.registerCommand('extension.enterStudioApiKey', enterStudioApiKey); - commands.registerCommand('extension.deleteStudioApiKey', deleteStudioApiKey); - commands.registerCommand('extension.gettingStarted', gettingStarted); + //Register commands to ensure a folder is open in the window to store workbench files + commands.executeCommand('extension.ensureFolderIsOpen'); + commands.registerCommand('extension.ensureFolderIsOpen', ensureFolderIsOpen); + commands.registerCommand('extension.openFolder', openFolder); + //Global Extension Commands + commands.registerCommand('extension.enterStudioApiKey', enterStudioApiKey); + commands.registerCommand('extension.deleteStudioApiKey', deleteStudioApiKey); + commands.registerCommand('extension.gettingStarted', gettingStarted); - //*Local Supergraph Designs TreeView - //**Navigation Menu Commands - commands.registerCommand('local-supergraph-designs.newDesign', newDesign); - commands.registerCommand('local-supergraph-designs.refresh', refreshSupergraphs); - //***Supergraph Commands - // commands.registerCommand('local-supergraph-designs.exportProject', exportProject);//right-click - // commands.registerCommand('local-supergraph-designs.dockerize', async (item: WorkbenchFileTreeItem) => DockerImageManager.create(item.filePath));//right-click - //***Supergraph Schema Commands - commands.registerCommand('local-supergraph-designs.viewSupergraphSchema', viewSupergraphSchema);//on-click - commands.registerCommand('local-supergraph-designs.viewSupergraphApiSchema', viewSupergraphApiSchema);//on-click - commands.registerCommand('local-supergraph-designs.exportSupergraphSchema', exportSupergraphSchema);//right-click - commands.registerCommand('local-supergraph-designs.exportSupergraphApiSchema', exportSupergraphApiSchema);//right-click - //****Subgraph Summary Commands - commands.registerCommand('local-supergraph-designs.startMocks', startMocks); - commands.registerCommand('local-supergraph-designs.stopMocks', stopMocks); - commands.registerCommand('local-supergraph-designs.addSubgraph', addSubgraph); - //****Subgraph Commands - commands.registerCommand('local-supergraph-designs.editSubgraph', editSubgraph);//on-click - commands.registerCommand('local-supergraph-designs.updateSubgraphSchemaFromURL', updateSubgraphSchemaFromURL);//right-click - commands.registerCommand('local-supergraph-designs.exportSubgraphResolvers', exportSubgraphResolvers);//right-click - commands.registerCommand('local-supergraph-designs.exportSubgraphSchema', exportSubgraphSchema);//right-click - commands.registerCommand('local-supergraph-designs.viewSubgraphCustomMocks', viewSubgraphCustomMocks);//right-click - commands.registerCommand('local-supergraph-designs.deleteSubgraph', deleteSubgraph); - commands.registerCommand('local-supergraph-designs.viewSettings', viewSubgraphSettings);//inline + //*Local Supergraph Designs TreeView + //**Navigation Menu Commands + commands.registerCommand('local-supergraph-designs.newDesign', newDesign); + commands.registerCommand( + 'local-supergraph-designs.refresh', + refreshSupergraphs, + ); + //***Supergraph Commands + // commands.registerCommand('local-supergraph-designs.exportProject', exportProject);//right-click + // commands.registerCommand('local-supergraph-designs.dockerize', async (item: WorkbenchFileTreeItem) => DockerImageManager.create(item.filePath));//right-click + //***Supergraph Schema Commands + commands.registerCommand( + 'local-supergraph-designs.viewSupergraphSchema', + viewSupergraphSchema, + ); //on-click + commands.registerCommand( + 'local-supergraph-designs.viewSupergraphApiSchema', + viewSupergraphApiSchema, + ); //on-click + commands.registerCommand( + 'local-supergraph-designs.exportSupergraphSchema', + exportSupergraphSchema, + ); //right-click + commands.registerCommand( + 'local-supergraph-designs.exportSupergraphApiSchema', + exportSupergraphApiSchema, + ); //right-click + //****Subgraph Summary Commands + commands.registerCommand('local-supergraph-designs.startMocks', startMocks); + commands.registerCommand('local-supergraph-designs.stopMocks', stopMocks); + commands.registerCommand('local-supergraph-designs.addSubgraph', addSubgraph); + //****Subgraph Commands + commands.registerCommand( + 'local-supergraph-designs.editSubgraph', + editSubgraph, + ); //on-click + commands.registerCommand( + 'local-supergraph-designs.updateSubgraphSchemaFromURL', + updateSubgraphSchemaFromURL, + ); //right-click + commands.registerCommand( + 'local-supergraph-designs.exportSubgraphResolvers', + exportSubgraphResolvers, + ); //right-click + commands.registerCommand( + 'local-supergraph-designs.exportSubgraphSchema', + exportSubgraphSchema, + ); //right-click + commands.registerCommand( + 'local-supergraph-designs.viewSubgraphCustomMocks', + viewSubgraphCustomMocks, + ); //right-click + commands.registerCommand( + 'local-supergraph-designs.deleteSubgraph', + deleteSubgraph, + ); + commands.registerCommand( + 'local-supergraph-designs.viewSettings', + viewSubgraphSettings, + ); //inline - commands.registerCommand('local-supergraph-designs.editOperation', editSupergraphOperation); - commands.registerCommand('local-supergraph-designs.addOperation', addOperation); - commands.registerCommand('local-supergraph-designs.deleteOperation', deleteOperation); - commands.registerCommand('local-supergraph-designs.viewQueryPlan', viewQueryPlan); - // commands.registerCommand('current-workbench-schemas.deleteSchemaDocTextRange', deleteSchemaDocTextRange); - // commands.registerCommand('current-workbench-schemas.makeSchemaDocTextRangeArray', makeSchemaDocTextRangeArray); + commands.registerCommand( + 'local-supergraph-designs.editOperation', + editSupergraphOperation, + ); + commands.registerCommand( + 'local-supergraph-designs.addOperation', + addOperation, + ); + commands.registerCommand( + 'local-supergraph-designs.deleteOperation', + deleteOperation, + ); + commands.registerCommand( + 'local-supergraph-designs.viewQueryPlan', + viewQueryPlan, + ); + // commands.registerCommand('current-workbench-schemas.deleteSchemaDocTextRange', deleteSchemaDocTextRange); + // commands.registerCommand('current-workbench-schemas.makeSchemaDocTextRangeArray', makeSchemaDocTextRangeArray); - //Apollo Studio Graphs Commands - commands.registerCommand('studio-graphs.refresh', refreshStudioGraphs); - commands.registerCommand('studio-graphs.createWorkbenchFromGraph', createWorkbenchFromSupergraph); - commands.registerCommand('studio-graphs.createWorkbenchFromSupergraphVariant', createWorkbenchFromSupergraphVariant); - commands.registerCommand('studio-graphs.createWorkbenchFromPreloaded', createWorkbenchFromPreloaded); - commands.registerCommand('studio-graphs.loadOperations', loadOperations); - commands.registerCommand('studio-graphs.viewStudioOperation', viewStudioOperation); - commands.registerCommand('studio-graphs.switchOrg', switchOrg); - //Apollo Studio Graph Operations Commands - commands.registerCommand('studio-operations.addToWorkbench', addToWorkbench); + //Apollo Studio Graphs Commands + commands.registerCommand('studio-graphs.refresh', refreshStudioGraphs); + commands.registerCommand( + 'studio-graphs.createWorkbenchFromGraph', + createWorkbenchFromSupergraph, + ); + commands.registerCommand( + 'studio-graphs.createWorkbenchFromSupergraphVariant', + createWorkbenchFromSupergraphVariant, + ); + commands.registerCommand( + 'studio-graphs.createWorkbenchFromPreloaded', + createWorkbenchFromPreloaded, + ); + commands.registerCommand('studio-graphs.loadOperations', loadOperations); + commands.registerCommand( + 'studio-graphs.viewStudioOperation', + viewStudioOperation, + ); + commands.registerCommand('studio-graphs.switchOrg', switchOrg); + //Apollo Studio Graph Operations Commands + commands.registerCommand('studio-operations.addToWorkbench', addToWorkbench); - //Workspace - Register Providers and Events - workspace.registerTextDocumentContentProvider(GettingStartedDocProvider.scheme, new GettingStartedDocProvider()); - workspace.registerTextDocumentContentProvider(ApolloStudioOperationsProvider.scheme, new ApolloStudioOperationsProvider()); - workspace.onDidChangeTextDocument(e => { - let uri = e.document.uri; - let document = new GraphQLDocument(new Source(e.document.getText())); - if (uri.scheme == 'workbench') { - if (uri.path.includes('queries')) { - const schema = StateManager.instance.workspaceState_schema; - if (schema) { - const fragments = Object.create(null); - if (document.ast) { - for (const definition of document.ast.definitions) { - if (definition.kind === Kind.FRAGMENT_DEFINITION) { - fragments[definition.name.value] = definition; - } - } - } - let opDiagnostics = collectExecutableDefinitionDiagnositics(schema, document, fragments, defaultValidationRules); - if (opDiagnostics.length > 0) { - operationDiagnostics.clear(); - let diagnostics = new Array(); - opDiagnostics.forEach(opDiag => { - let start = opDiag.range.start; - let end = opDiag.range.end; - let range = new Range(new Position(start.line, start.character), new Position(end.line, end.character)); - diagnostics.push(new Diagnostic(range, opDiag.message, opDiag.severity)) - }); - operationDiagnostics.set(uri, diagnostics); - } else { - operationDiagnostics.clear(); - } - } else { - operationDiagnostics.clear(); - operationDiagnostics.set(uri, [new Diagnostic(new Range(0, 0, 0, 0), "No valid composed schema", DiagnosticSeverity.Warning)]); - } - } - } - }) - workspace.onDidSaveTextDocument(async document => { - let uri = document.uri; - if (uri.path.includes('mocks')) { - const querySplit = uri.query.split(':'); - const { wbFile, path } = FileProvider.instance.workbenchFileByGraphName(querySplit[0]); - const newMocksText = document.getText(); - if (newMocksText != wbFile.schemas[querySplit[1]].customMocks) { - wbFile.schemas[querySplit[1]].customMocks = newMocksText; - FileProvider.instance.saveWorkbenchFile(wbFile, path); - } - } - }) -} \ No newline at end of file + //Workspace - Register Providers and Events + workspace.registerTextDocumentContentProvider( + GettingStartedDocProvider.scheme, + new GettingStartedDocProvider(), + ); + workspace.registerTextDocumentContentProvider( + ApolloStudioOperationsProvider.scheme, + new ApolloStudioOperationsProvider(), + ); + workspace.onDidChangeTextDocument((e) => { + let uri = e.document.uri; + let document = new GraphQLDocument(new Source(e.document.getText())); + if (uri.scheme == 'workbench') { + if (uri.path.includes('queries')) { + const schema = StateManager.instance.workspaceState_schema; + if (schema) { + const fragments = Object.create(null); + if (document.ast) { + for (const definition of document.ast.definitions) { + if (definition.kind === Kind.FRAGMENT_DEFINITION) { + fragments[definition.name.value] = definition; + } + } + } + let opDiagnostics = collectExecutableDefinitionDiagnositics( + schema, + document, + fragments, + defaultValidationRules, + ); + if (opDiagnostics.length > 0) { + operationDiagnostics.clear(); + let diagnostics = new Array(); + opDiagnostics.forEach((opDiag) => { + let start = opDiag.range.start; + let end = opDiag.range.end; + let range = new Range( + new Position(start.line, start.character), + new Position(end.line, end.character), + ); + diagnostics.push( + new Diagnostic(range, opDiag.message, opDiag.severity), + ); + }); + operationDiagnostics.set(uri, diagnostics); + } else { + operationDiagnostics.clear(); + } + } else { + operationDiagnostics.clear(); + operationDiagnostics.set(uri, [ + new Diagnostic( + new Range(0, 0, 0, 0), + 'No valid composed schema', + DiagnosticSeverity.Warning, + ), + ]); + } + } + } + }); + workspace.onDidSaveTextDocument(async (document) => { + let uri = document.uri; + if (uri.path.includes('mocks')) { + const querySplit = uri.query.split(':'); + const { wbFile, path } = FileProvider.instance.workbenchFileByGraphName( + querySplit[0], + ); + const newMocksText = document.getText(); + if (newMocksText != wbFile.schemas[querySplit[1]].customMocks) { + wbFile.schemas[querySplit[1]].customMocks = newMocksText; + FileProvider.instance.saveWorkbenchFile(wbFile, path); + } + } + }); +} diff --git a/src/graphql/composition.ts b/src/graphql/composition.ts index 1d8b33c..3f06422 100644 --- a/src/graphql/composition.ts +++ b/src/graphql/composition.ts @@ -1,265 +1,351 @@ -import { composeAndValidate, ServiceDefinition } from "@apollo/federation"; -import { GraphQLError, parse, extendSchema, GraphQLSchema } from "graphql"; -import { Diagnostic, DiagnosticSeverity, Range, } from "vscode"; -import { compositionDiagnostics } from "../extension"; -import { StateManager } from "../workbench/stateManager"; -import { extractDefinedEntitiesByService } from "./parsers/csdlParser"; -import { FileProvider } from "../workbench/file-system/fileProvider"; -import { WorkbenchUri, WorkbenchUriType } from "../workbench/file-system/WorkbenchUri"; -import { ApolloWorkbenchFile } from "../workbench/file-system/fileTypes"; -import { CompositionResult, CompositionFailure } from "@apollo/federation/dist/composition/utils"; +import { composeAndValidate, ServiceDefinition } from '@apollo/federation'; +import { GraphQLError, parse, extendSchema, GraphQLSchema } from 'graphql'; +import { Diagnostic, DiagnosticSeverity, Range } from 'vscode'; +import { compositionDiagnostics } from '../extension'; +import { StateManager } from '../workbench/stateManager'; +import { extractDefinedEntitiesByService } from './parsers/csdlParser'; +import { FileProvider } from '../workbench/file-system/fileProvider'; +import { + WorkbenchUri, + WorkbenchUriType, +} from '../workbench/file-system/WorkbenchUri'; +import { ApolloWorkbenchFile } from '../workbench/file-system/fileTypes'; +import { + CompositionResult, + CompositionFailure, +} from '@apollo/federation/dist/composition/utils'; export function superSchemaToSchema(supergraphSchema: string) { - const schema = new GraphQLSchema({ - query: undefined, - }); - const parsed = parse(supergraphSchema); - const finalSchema = extendSchema(schema, parsed, { assumeValidSDL: true }); + const schema = new GraphQLSchema({ + query: undefined, + }); + const parsed = parse(supergraphSchema); + const finalSchema = extendSchema(schema, parsed, { assumeValidSDL: true }); - return finalSchema; + return finalSchema; } -export async function getComposedSchemaLogCompositionErrorsForWbFile(wbFilePath: string) { - let workbenchFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); - if (workbenchFile) { - compositionDiagnostics.clear(); - try { - const { errors, supergraphSdl, schema } = await getComposedSchema(workbenchFile); - if (errors && errors.length > 0) { - console.log('Composition Errors Found:'); - - console.log(compositionDiagnostics.name); - let diagnosticsGroups = handleErrors(workbenchFile, errors); - for (var sn in diagnosticsGroups) { - compositionDiagnostics.set(WorkbenchUri.supergraph(wbFilePath, sn, WorkbenchUriType.SCHEMAS), diagnosticsGroups[sn]); - } - } - - if (supergraphSdl) { - workbenchFile.supergraphSdl = supergraphSdl ?? ""; - await extractDefinedEntitiesByService(wbFilePath); - } else { - workbenchFile.supergraphSdl = ""; - StateManager.instance.workspaceState_selectedWorkbenchAvailableEntities = {}; - } - - FileProvider.instance.saveWorkbenchFile(workbenchFile, wbFilePath); - - if (schema) - StateManager.instance.workspaceState_schema = schema; - else - StateManager.instance.clearWorkspaceSchema(); - } - catch (err) { - console.log(`${err}`); +export async function getComposedSchemaLogCompositionErrorsForWbFile( + wbFilePath: string, +) { + let workbenchFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); + if (workbenchFile) { + compositionDiagnostics.clear(); + try { + const { errors, supergraphSdl, schema } = await getComposedSchema( + workbenchFile, + ); + if (errors && errors.length > 0) { + console.log('Composition Errors Found:'); + + console.log(compositionDiagnostics.name); + let diagnosticsGroups = handleErrors(workbenchFile, errors); + for (var sn in diagnosticsGroups) { + compositionDiagnostics.set( + WorkbenchUri.supergraph(wbFilePath, sn, WorkbenchUriType.SCHEMAS), + diagnosticsGroups[sn], + ); } + } + + if (supergraphSdl) { + workbenchFile.supergraphSdl = supergraphSdl ?? ''; + await extractDefinedEntitiesByService(wbFilePath); + } else { + workbenchFile.supergraphSdl = ''; + StateManager.instance.workspaceState_selectedWorkbenchAvailableEntities = {}; + } + + FileProvider.instance.saveWorkbenchFile(workbenchFile, wbFilePath); + + if (schema) StateManager.instance.workspaceState_schema = schema; + else StateManager.instance.clearWorkspaceSchema(); + } catch (err) { + console.log(`${err}`); } + } } -export function getComposedSchema(workbenchFile: ApolloWorkbenchFile): CompositionResult { - let sdls: ServiceDefinition[] = []; - let errors: GraphQLError[] = []; - for (var key in workbenchFile.schemas) { - let localSchemaString = workbenchFile.schemas[key].sdl; - if (localSchemaString) { - try { - let doc = parse(localSchemaString); - //TODO: use onlineParser to find validation - sdls.push({ name: key, typeDefs: doc, url: workbenchFile.schemas[key].url }); - } catch (err) { - //Need to include any errors for invalid schema - //TODO: consider using online parser when there is a gql error to get a better placement of the error - let errorMessage = `Not valid GraphQL Schema: ${err.message}`; - let extensions: any = { invalidSchema: true, serviceName: key }; - - if (err.message.includes('Syntax Error: Unexpected Name ')) { - let quotedUnexpected = err.message.split('Syntax Error: Unexpected Name "')[1]; - let unexpectedName = quotedUnexpected.slice(0, quotedUnexpected.length - 1); - extensions.locations = err.locations; - extensions.unexpectedName = unexpectedName; - } else if (err.message.includes('Syntax Error: Expected Name, found }')) { - errorMessage = `You must define some fields: ${err.message}`; - extensions.noFieldsDefined = true; - extensions.locations = err.locations; - } else if (err.message.includes('Syntax Error: Expected Name, found ')) { - errorMessage = `You must define some fields: ${err.message}`; - let quotedUnexpected = err.message.split('Syntax Error: Expected Name, found ')[1]; - let offset = quotedUnexpected.length == 1 ? 0 : 1; - let unexpectedName = quotedUnexpected.slice(0, quotedUnexpected.length - offset); - extensions.noFieldsDefined = true; - extensions.locations = err.locations; - extensions.unexpectedName = unexpectedName; - } - - errors.push(new GraphQLError(errorMessage, undefined, undefined, undefined, undefined, undefined, extensions)); - } - } else { - let err = "No schema defined for service"; - errors.push(new GraphQLError(err, undefined, undefined, undefined, undefined, undefined, { noSchemaDefined: true, serviceName: key, message: err })); +export function getComposedSchema( + workbenchFile: ApolloWorkbenchFile, +): CompositionResult { + let sdls: ServiceDefinition[] = []; + let errors: GraphQLError[] = []; + for (var key in workbenchFile.schemas) { + let localSchemaString = workbenchFile.schemas[key].sdl; + if (localSchemaString) { + try { + let doc = parse(localSchemaString); + //TODO: use onlineParser to find validation + sdls.push({ + name: key, + typeDefs: doc, + url: workbenchFile.schemas[key].url, + }); + } catch (err) { + //Need to include any errors for invalid schema + //TODO: consider using online parser when there is a gql error to get a better placement of the error + let errorMessage = `Not valid GraphQL Schema: ${err.message}`; + let extensions: any = { invalidSchema: true, serviceName: key }; + + if (err.message.includes('Syntax Error: Unexpected Name ')) { + let quotedUnexpected = err.message.split( + 'Syntax Error: Unexpected Name "', + )[1]; + let unexpectedName = quotedUnexpected.slice( + 0, + quotedUnexpected.length - 1, + ); + extensions.locations = err.locations; + extensions.unexpectedName = unexpectedName; + } else if ( + err.message.includes('Syntax Error: Expected Name, found }') + ) { + errorMessage = `You must define some fields: ${err.message}`; + extensions.noFieldsDefined = true; + extensions.locations = err.locations; + } else if ( + err.message.includes('Syntax Error: Expected Name, found ') + ) { + errorMessage = `You must define some fields: ${err.message}`; + let quotedUnexpected = err.message.split( + 'Syntax Error: Expected Name, found ', + )[1]; + let offset = quotedUnexpected.length == 1 ? 0 : 1; + let unexpectedName = quotedUnexpected.slice( + 0, + quotedUnexpected.length - offset, + ); + extensions.noFieldsDefined = true; + extensions.locations = err.locations; + extensions.unexpectedName = unexpectedName; } - } - if (errors.length > 0) { - return { errors } as CompositionFailure; - } else { - //This blocks UI thread, why I have no clue but it is overworking VS Code - let compositionResults = composeAndValidate(sdls); - if (Object.keys(workbenchFile.schemas).length == 0) - compositionResults.errors = [new GraphQLError("No schemas defined in workbench yet", undefined, undefined, undefined, undefined, undefined, { noServicesDefined: true })]; - return { ...compositionResults } as CompositionResult; + errors.push( + new GraphQLError( + errorMessage, + undefined, + undefined, + undefined, + undefined, + undefined, + extensions, + ), + ); + } + } else { + let err = 'No schema defined for service'; + errors.push( + new GraphQLError( + err, + undefined, + undefined, + undefined, + undefined, + undefined, + { noSchemaDefined: true, serviceName: key, message: err }, + ), + ); } + } + if (errors.length > 0) { + return { errors } as CompositionFailure; + } else { + //This blocks UI thread, why I have no clue but it is overworking VS Code + let compositionResults = composeAndValidate(sdls); + + if (Object.keys(workbenchFile.schemas).length == 0) + compositionResults.errors = [ + new GraphQLError( + 'No schemas defined in workbench yet', + undefined, + undefined, + undefined, + undefined, + undefined, + { noServicesDefined: true }, + ), + ]; + return { ...compositionResults } as CompositionResult; + } } export function handleErrors(wb: ApolloWorkbenchFile, errors: GraphQLError[]) { - let schemas = wb.schemas; - let diagnosticsGroups: { [key: string]: Diagnostic[]; } = {}; - - for (var i = 0; i < errors.length; i++) { - let error = errors[i]; - let errorMessage = error.message; - let diagnosticCode = ''; - let typeToIgnore = ""; - let range = new Range(0, 0, 0, 1); - let serviceName = error.extensions?.serviceName ?? 'workbench'; - - if (error.extensions) { - if (error.extensions?.noServicesDefined) { - let emptySchemas = `"schemas":{}`; - let schemasIndex = 0; - range = new Range(0, schemasIndex, 0, schemasIndex + emptySchemas.length); - } else if (error.extensions?.noSchemaDefined || error.extensions?.invalidSchema) { - if (error.extensions.unexpectedName) { - let unexpectedName = error.extensions.unexpectedName; - let location = error.extensions.locations[0]; - let lineNumber = location.line - 1; - let textIndex = location.column - 1; - - if (unexpectedName == '[') - diagnosticCode = 'makeArray:deleteRange'; - else - diagnosticCode = 'deleteRange'; - - range = new Range(lineNumber, textIndex, lineNumber, textIndex + unexpectedName.length); - } else if (error.extensions.noFieldsDefined) { - let location = error.extensions.locations[0]; - let lineNumber = location.line - 1; - - range = new Range(lineNumber - 1, 0, lineNumber, 0); - } else { - // let doc = await workspace.openTextDocument(WorkbenchUri.parse(serviceName)); - // let lastLine = doc.lineAt(doc.lineCount - 1); - - // range = new Range(0, 0, lastLine.lineNumber, lastLine.text.length); - } - } else if (error.extensions?.code) { - //We have a federation error with code - let errSplit = error.message.split('] '); - serviceName = errSplit[0].substring(1); - - switch (error.extensions.code) { - case "KEY_FIELDS_MISSING_EXTERNAL": - case "KEY_FIELDS_MISSING_ON_BASE": - typeToIgnore = errSplit[1].split(' ->')[0]; - break; - - case "EXECUTABLE_DIRECTIVES_IN_ALL_SERVICES": - serviceName = "" - let services = error.message.split(':')[1].split(','); - if (services.length > 1) - services.map(service => { - let sn = service.includes('.') ? service.substring(1, service.length - 1) : service.substring(1, service.length); - serviceName += `${sn}-:-`; - }); - else serviceName = services[0]; - - typeToIgnore = serviceName; - break; - } - } - } else if (errorMessage.includes('Type Query must define one or more fields')) { - let serviceNames = Object.keys(schemas); - if (serviceNames.length >= 1) { - serviceName = serviceNames[0]; - } - } else if (errorMessage.includes('Field "Query.') || errorMessage.includes('Field "Mutation.')) { - let errorNodes = error.nodes ?? []; - let fieldName = errorNodes[0].kind; - serviceName = ''; - for (var sn in schemas) - if (schemas[sn].sdl.includes(fieldName)) - if (serviceName) serviceName += `${sn}-:-`; - else serviceName = sn; - } else if (errorMessage.includes('There can be only one type named')) { - let nameNode = error.nodes?.find(n => n.kind == "Name") as any; - serviceName = ''; - - for (var sn in schemas) - if (schemas[sn].sdl.includes(nameNode.value)) - serviceName += `${sn}-:-`; - - typeToIgnore = nameNode.value; - } else if (errorMessage.includes('Field') && errorMessage.includes('can only be defined once')) { - let splitMessage = errorMessage.split('.'); - typeToIgnore = splitMessage[0].split('"')[1]; - } else if (errorMessage.includes('Unknown type: ')) { - let splitMessage = errorMessage.split('"'); - let fieldType = splitMessage[1]; - - for (var sn in schemas) - if (schemas[sn].sdl.includes(typeToIgnore)) - serviceName = sn; - - // let typeRange = getRangeForFieldNamedType(fieldType, schemas[serviceName].sdl); - // range = new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn); + let schemas = wb.schemas; + let diagnosticsGroups: { [key: string]: Diagnostic[] } = {}; + + for (var i = 0; i < errors.length; i++) { + let error = errors[i]; + let errorMessage = error.message; + let diagnosticCode = ''; + let typeToIgnore = ''; + let range = new Range(0, 0, 0, 1); + let serviceName = error.extensions?.serviceName ?? 'workbench'; + + if (error.extensions) { + if (error.extensions?.noServicesDefined) { + let emptySchemas = `"schemas":{}`; + let schemasIndex = 0; + range = new Range( + 0, + schemasIndex, + 0, + schemasIndex + emptySchemas.length, + ); + } else if ( + error.extensions?.noSchemaDefined || + error.extensions?.invalidSchema + ) { + if (error.extensions.unexpectedName) { + let unexpectedName = error.extensions.unexpectedName; + let location = error.extensions.locations[0]; + let lineNumber = location.line - 1; + let textIndex = location.column - 1; + + if (unexpectedName == '[') diagnosticCode = 'makeArray:deleteRange'; + else diagnosticCode = 'deleteRange'; + + range = new Range( + lineNumber, + textIndex, + lineNumber, + textIndex + unexpectedName.length, + ); + } else if (error.extensions.noFieldsDefined) { + let location = error.extensions.locations[0]; + let lineNumber = location.line - 1; + + range = new Range(lineNumber - 1, 0, lineNumber, 0); + } else { + // let doc = await workspace.openTextDocument(WorkbenchUri.parse(serviceName)); + // let lastLine = doc.lineAt(doc.lineCount - 1); + // range = new Range(0, 0, lastLine.lineNumber, lastLine.text.length); } - - //If we have a typeToIgnore, try getting a valid range for it - if (typeToIgnore) { - if (serviceName == 'workbench') { - for (var sn in schemas) - if (schemas[sn].sdl.includes(typeToIgnore)) - serviceName = sn; - } - - // if (schemas[serviceName]) { - // let typeRange = getRangeForFieldNamedType(typeToIgnore, schemas[serviceName].sdl); - // range = new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn); - // } + } else if (error.extensions?.code) { + //We have a federation error with code + let errSplit = error.message.split('] '); + serviceName = errSplit[0].substring(1); + + switch (error.extensions.code) { + case 'KEY_FIELDS_MISSING_EXTERNAL': + case 'KEY_FIELDS_MISSING_ON_BASE': + typeToIgnore = errSplit[1].split(' ->')[0]; + break; + + case 'EXECUTABLE_DIRECTIVES_IN_ALL_SERVICES': + serviceName = ''; + let services = error.message.split(':')[1].split(','); + if (services.length > 1) + services.map((service) => { + let sn = service.includes('.') + ? service.substring(1, service.length - 1) + : service.substring(1, service.length); + serviceName += `${sn}-:-`; + }); + else serviceName = services[0]; + + typeToIgnore = serviceName; + break; } + } + } else if ( + errorMessage.includes('Type Query must define one or more fields') + ) { + let serviceNames = Object.keys(schemas); + if (serviceNames.length >= 1) { + serviceName = serviceNames[0]; + } + } else if ( + errorMessage.includes('Field "Query.') || + errorMessage.includes('Field "Mutation.') + ) { + let errorNodes = error.nodes ?? []; + let fieldName = errorNodes[0].kind; + serviceName = ''; + for (var sn in schemas) + if (schemas[sn].sdl.includes(fieldName)) + if (serviceName) serviceName += `${sn}-:-`; + else serviceName = sn; + } else if (errorMessage.includes('There can be only one type named')) { + let nameNode = error.nodes?.find((n) => n.kind == 'Name') as any; + serviceName = ''; + + for (var sn in schemas) + if (schemas[sn].sdl.includes(nameNode.value)) serviceName += `${sn}-:-`; + + typeToIgnore = nameNode.value; + } else if ( + errorMessage.includes('Field') && + errorMessage.includes('can only be defined once') + ) { + let splitMessage = errorMessage.split('.'); + typeToIgnore = splitMessage[0].split('"')[1]; + } else if (errorMessage.includes('Unknown type: ')) { + let splitMessage = errorMessage.split('"'); + let fieldType = splitMessage[1]; + + for (var sn in schemas) + if (schemas[sn].sdl.includes(typeToIgnore)) serviceName = sn; + + // let typeRange = getRangeForFieldNamedType(fieldType, schemas[serviceName].sdl); + // range = new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn); + } - //If we have multiple services, we'll need to create multiple diagnostics - if (serviceName.includes('-:-')) { - let services = serviceName.split('-:-'); - services.map(s => { - if (s) { - let schema = schemas[s].sdl; - let diagnostic = new Diagnostic(range, errorMessage, DiagnosticSeverity.Error); - if (!diagnosticsGroups[s]) diagnosticsGroups[s] = new Array(); - // if (typeToIgnore && schema.includes(typeToIgnore)) { - // let typeRange = getRangeForTypeDef(typeToIgnore, schema); - // diagnostic = new Diagnostic(new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn), errorMessage, DiagnosticSeverity.Error); - - // if (diagnosticCode) - // diagnostic.code = diagnosticCode; - // } - - diagnosticsGroups[s].push(diagnostic); - } - }) - } else { - let diagnostic = new Diagnostic(range, errorMessage, DiagnosticSeverity.Error); - // if (typeToIgnore && schemas[serviceName] && schemas[serviceName].sdl.includes(typeToIgnore)) { - // let typeRange = getRangeForTypeDef(typeToIgnore, schemas[serviceName].sdl); - // diagnostic = new Diagnostic(new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn), errorMessage, DiagnosticSeverity.Error); - // } - - if (diagnosticCode) - diagnostic.code = diagnosticCode; + //If we have a typeToIgnore, try getting a valid range for it + if (typeToIgnore) { + if (serviceName == 'workbench') { + for (var sn in schemas) + if (schemas[sn].sdl.includes(typeToIgnore)) serviceName = sn; + } + + // if (schemas[serviceName]) { + // let typeRange = getRangeForFieldNamedType(typeToIgnore, schemas[serviceName].sdl); + // range = new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn); + // } + } - if (!diagnosticsGroups[serviceName]) diagnosticsGroups[serviceName] = new Array(); - diagnosticsGroups[serviceName].push(diagnostic); + //If we have multiple services, we'll need to create multiple diagnostics + if (serviceName.includes('-:-')) { + let services = serviceName.split('-:-'); + services.map((s) => { + if (s) { + let schema = schemas[s].sdl; + let diagnostic = new Diagnostic( + range, + errorMessage, + DiagnosticSeverity.Error, + ); + if (!diagnosticsGroups[s]) + diagnosticsGroups[s] = new Array(); + // if (typeToIgnore && schema.includes(typeToIgnore)) { + // let typeRange = getRangeForTypeDef(typeToIgnore, schema); + // diagnostic = new Diagnostic(new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn), errorMessage, DiagnosticSeverity.Error); + + // if (diagnosticCode) + // diagnostic.code = diagnosticCode; + // } + + diagnosticsGroups[s].push(diagnostic); } + }); + } else { + let diagnostic = new Diagnostic( + range, + errorMessage, + DiagnosticSeverity.Error, + ); + // if (typeToIgnore && schemas[serviceName] && schemas[serviceName].sdl.includes(typeToIgnore)) { + // let typeRange = getRangeForTypeDef(typeToIgnore, schemas[serviceName].sdl); + // diagnostic = new Diagnostic(new Range(typeRange.startLine, typeRange.startColumn, typeRange.endLine, typeRange.endColumn), errorMessage, DiagnosticSeverity.Error); + // } + + if (diagnosticCode) diagnostic.code = diagnosticCode; + + if (!diagnosticsGroups[serviceName]) + diagnosticsGroups[serviceName] = new Array(); + diagnosticsGroups[serviceName].push(diagnostic); } + } - return diagnosticsGroups; -} \ No newline at end of file + return diagnosticsGroups; +} diff --git a/src/graphql/graphClient.ts b/src/graphql/graphClient.ts index b6f207f..43c41dd 100644 --- a/src/graphql/graphClient.ts +++ b/src/graphql/graphClient.ts @@ -5,160 +5,187 @@ import { UserMemberships } from './types/UserMemberships'; import { AccountServiceVariants } from './types/AccountServiceVariants'; import { GetGraphSchemas } from './types/GetGraphSchemas'; import { GraphOperations } from './types/GraphOperations'; -import { CheckUserApiKey, CheckUserApiKey_me_User } from './types/CheckUserApiKey'; +import { + CheckUserApiKey, + CheckUserApiKey_me_User, +} from './types/CheckUserApiKey'; import { StateManager } from '../workbench/stateManager'; const keyCheck = gql` - query CheckUserApiKey { - me { - ...on User { - id - } - } - }`; + query CheckUserApiKey { + me { + ... on User { + id + } + } + } +`; const userMemberships = gql` - query UserMemberships { - me { - ... on User { - memberships { - account { - id - name - } - } - } + query UserMemberships { + me { + ... on User { + memberships { + account { + id + name + } } - }`; + } + } + } +`; const accountServiceVariants = gql` - query AccountServiceVariants($accountId: ID!) { - account(id: $accountId) { - name - services(includeDeleted: false) { - id - title - devGraphOwner { - ...on User { - id - } - } - variants { - name - } - } + query AccountServiceVariants($accountId: ID!) { + account(id: $accountId) { + name + services(includeDeleted: false) { + id + title + devGraphOwner { + ... on User { + id + } + } + variants { + name } - }` + } + } + } +`; const getGraphSchemas = gql` - query GetGraphSchemas($id: ID!, $graphVariant: String!) { - service(id: $id) { - schema(tag:$graphVariant) { - document - } - implementingServices(graphVariant: $graphVariant){ - ...on NonFederatedImplementingService { - graphID - } - ...on FederatedImplementingServices{ - services { - name - url - activePartialSchema { - sdl - } + query GetGraphSchemas($id: ID!, $graphVariant: String!) { + service(id: $id) { + schema(tag: $graphVariant) { + document + } + implementingServices(graphVariant: $graphVariant) { + ... on NonFederatedImplementingService { + graphID + } + ... on FederatedImplementingServices { + services { + name + url + activePartialSchema { + sdl } } } } } - `; + } +`; const getGraphOperations = gql` - query GraphOperations($id: ID! $from: Timestamp! $variant: String) { - service(id: $id) { - title - stats(from: $from) { - queryStats (filter:{schemaTag: $variant}){ - groupBy { - queryName - queryId - querySignature - } - } + query GraphOperations($id: ID!, $from: Timestamp!, $variant: String) { + service(id: $id) { + title + stats(from: $from) { + queryStats(filter: { schemaTag: $variant }) { + groupBy { + queryName + queryId + querySignature } + } } - }` + } + } +`; export async function isValidKey(apiKey: string) { - let result = await toPromise(execute(createLink({ apiKey }), { query: keyCheck })); - let data = result.data as CheckUserApiKey; - if ((data.me as CheckUserApiKey_me_User)?.id) return true; - return false; - + let result = await toPromise( + execute(createLink({ apiKey }), { query: keyCheck }), + ); + let data = result.data as CheckUserApiKey; + if ((data.me as CheckUserApiKey_me_User)?.id) return true; + return false; } export async function getUserMemberships(apiKey: string) { - let result = await toPromise(execute(createLink({ apiKey }), { query: userMemberships })); - return result.data as UserMemberships + let result = await toPromise( + execute(createLink({ apiKey }), { query: userMemberships }), + ); + return result.data as UserMemberships; } export async function getAccountGraphs(apiKey: string, accountId: string) { - let result = await toPromise(execute(createLink({ apiKey, accountId }), { - query: accountServiceVariants, - variables: { - "accountId": accountId - } - })); - return result.data as AccountServiceVariants + let result = await toPromise( + execute(createLink({ apiKey, accountId }), { + query: accountServiceVariants, + variables: { + accountId: accountId, + }, + }), + ); + return result.data as AccountServiceVariants; } -export async function getGraphOps(apiKey: string, graphId: string, graphVariant: string) { - let days = StateManager.settings_daysOfOperationsToFetch; - let result = await toPromise(execute(createLink({ apiKey, graphId, graphVariant }), { - query: getGraphOperations, - variables: { - "id": graphId, - "from": (-86400 * days).toString(), - "variant": graphVariant - } - })); - return result.data as GraphOperations +export async function getGraphOps( + apiKey: string, + graphId: string, + graphVariant: string, +) { + let days = StateManager.settings_daysOfOperationsToFetch; + let result = await toPromise( + execute(createLink({ apiKey, graphId, graphVariant }), { + query: getGraphOperations, + variables: { + id: graphId, + from: (-86400 * days).toString(), + variant: graphVariant, + }, + }), + ); + return result.data as GraphOperations; } -export async function getGraphSchemasByVariant(apiKey: string, graphId: string, graphVariant: string) { - let result = await toPromise(execute(createLink({ apiKey, graphId, graphVariant }), { - query: getGraphSchemas, - variables: { - "id": graphId, - "graphVariant": graphVariant - } - })); - return result.data as GetGraphSchemas +export async function getGraphSchemasByVariant( + apiKey: string, + graphId: string, + graphVariant: string, +) { + let result = await toPromise( + execute(createLink({ apiKey, graphId, graphVariant }), { + query: getGraphSchemas, + variables: { + id: graphId, + graphVariant: graphVariant, + }, + }), + ); + return result.data as GetGraphSchemas; } const { version } = require('../../package.json'); interface CreateLinkOptions { - apiKey: string; - accountId?: string; - graphId?: string; - graphVariant?: string; + apiKey: string; + accountId?: string; + graphId?: string; + graphVariant?: string; } function createLink(options: CreateLinkOptions) { - let userId = options.apiKey.split(':')[1]; - let headers = { - 'x-api-key': options.apiKey, - 'studio-user-id': userId, - 'apollographql-client-name': 'Apollo Workbench', - 'apollographql-client-version': version - }; + let userId = options.apiKey.split(':')[1]; + let headers = { + 'x-api-key': options.apiKey, + 'studio-user-id': userId, + 'apollographql-client-name': 'Apollo Workbench', + 'apollographql-client-version': version, + }; - if (options.accountId) headers["studio-account-id"] = options.accountId; - if (options.graphId) headers["studio-graph-id"] = options.graphId; - if (options.graphVariant) headers["studio-graph-graphVariant"] = options.graphVariant; + if (options.accountId) headers['studio-account-id'] = options.accountId; + if (options.graphId) headers['studio-graph-id'] = options.graphId; + if (options.graphVariant) + headers['studio-graph-graphVariant'] = options.graphVariant; - if (StateManager.settings_apolloOrg) headers["apollo-sudo"] = "true"; + if (StateManager.settings_apolloOrg) headers['apollo-sudo'] = 'true'; - return createHttpLink({ - fetch, - headers, - uri: vscode.workspace.getConfiguration("apollo-workbench").get('apolloApiUrl') as string - }); + return createHttpLink({ + fetch, + headers, + uri: vscode.workspace + .getConfiguration('apollo-workbench') + .get('apolloApiUrl') as string, + }); } diff --git a/src/graphql/graphRouter.ts b/src/graphql/graphRouter.ts index 56ec2a6..a0f39ce 100644 --- a/src/graphql/graphRouter.ts +++ b/src/graphql/graphRouter.ts @@ -1,133 +1,199 @@ -import { ApolloGateway, RemoteGraphQLDataSource, GatewayConfig, Experimental_UpdateComposition } from "@apollo/gateway"; -import { buildClientSchema, getIntrospectionQuery, parse, IntrospectionQuery, printIntrospectionSchema, printSchema } from 'graphql'; -import { Headers } from "apollo-server-env"; +import { + ApolloGateway, + RemoteGraphQLDataSource, + GatewayConfig, + Experimental_UpdateComposition, +} from '@apollo/gateway'; +import { + buildClientSchema, + getIntrospectionQuery, + parse, + IntrospectionQuery, + printIntrospectionSchema, + printSchema, +} from 'graphql'; +import { Headers } from 'apollo-server-env'; import { ServiceDefinition } from '@apollo/federation'; -import { ServerManager } from "../workbench/serverManager"; -import { FileProvider } from "../workbench/file-system/fileProvider"; -import { StateManager } from "../workbench/stateManager"; -import { window } from "vscode"; -import { WorkbenchUri, WorkbenchUriType } from "../workbench/file-system/WorkbenchUri"; - -function log(message: string) { console.log(`GATEWAY-${message}`); } +import { ServerManager } from '../workbench/serverManager'; +import { FileProvider } from '../workbench/file-system/fileProvider'; +import { StateManager } from '../workbench/stateManager'; +import { window } from 'vscode'; +import { + WorkbenchUri, + WorkbenchUriType, +} from '../workbench/file-system/WorkbenchUri'; + +function log(message: string) { + console.log(`GATEWAY-${message}`); +} export class GatewayForwardHeadersDataSource extends RemoteGraphQLDataSource { - serviceName: string = ""; - willSendRequest({ request, context }) { - StateManager.settings_headersToForwardFromGateway.forEach(key => { - if (context.incomingHeaders[key]) - request.http.headers.set(key, context.incomingHeaders[key]); - else - log(`Header ${key} was not found on incoming request, did you forget to set it in your client application?`); - }); - - let service = FileProvider.instance.loadedWorkbenchFile?.schemas[this.serviceName]; - if (service) { - service.requiredHeaders?.forEach(requiredHeader => { - if (requiredHeader) - request.http.headers.set(requiredHeader.key, context.incomingHeaders[requiredHeader.key] ?? requiredHeader.value ?? ""); - }) - } + serviceName: string = ''; + willSendRequest({ request, context }) { + StateManager.settings_headersToForwardFromGateway.forEach((key) => { + if (context.incomingHeaders[key]) + request.http.headers.set(key, context.incomingHeaders[key]); + else + log( + `Header ${key} was not found on incoming request, did you forget to set it in your client application?`, + ); + }); + + let service = + FileProvider.instance.loadedWorkbenchFile?.schemas[this.serviceName]; + if (service) { + service.requiredHeaders?.forEach((requiredHeader) => { + if (requiredHeader) + request.http.headers.set( + requiredHeader.key, + context.incomingHeaders[requiredHeader.key] ?? + requiredHeader.value ?? + '', + ); + }); } + } } export class OverrideApolloGateway extends ApolloGateway { - protected async loadServiceDefinitions(config: GatewayConfig): ReturnType { - if (StateManager.settings_tlsRejectUnauthorized) process.env.NODE_TLS_REJECT_UNAUTHORIZED = ''; - else process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - - let newDefinitions: Array = []; - - let wb = FileProvider.instance.loadedWorkbenchFile; - if (wb) { - for (var serviceName in wb.schemas) { - const service = wb.schemas[serviceName]; - - if (service.shouldMock) { - let typeDefs = parse(service.sdl); - let url = `http://localhost:${ServerManager.instance.portMapping[serviceName]}`; - newDefinitions.push({ name: serviceName, url, typeDefs }); - } else { - let typeDefs = await OverrideApolloGateway.getTypeDefs(service.url as string, serviceName); - if (typeDefs) { - newDefinitions.push({ name: serviceName, url: service.url, typeDefs: parse(typeDefs) }); - - if (service.autoUpdateSchemaFromUrl) - FileProvider.instance.writeFile(WorkbenchUri.supergraph(FileProvider.instance.loadedWorbenchFilePath, serviceName, WorkbenchUriType.SCHEMAS), Buffer.from(typeDefs), { create: true, overwrite: true }) - } else { - log("Falling back to schema defined in workbench"); - newDefinitions.push({ name: serviceName, url: service.url, typeDefs: parse(service.sdl) }); - } - } - } + protected async loadServiceDefinitions( + config: GatewayConfig, + ): ReturnType { + if (StateManager.settings_tlsRejectUnauthorized) + process.env.NODE_TLS_REJECT_UNAUTHORIZED = ''; + else process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + + let newDefinitions: Array = []; + + let wb = FileProvider.instance.loadedWorkbenchFile; + if (wb) { + for (var serviceName in wb.schemas) { + const service = wb.schemas[serviceName]; + + if (service.shouldMock) { + let typeDefs = parse(service.sdl); + let url = `http://localhost:${ServerManager.instance.portMapping[serviceName]}`; + newDefinitions.push({ name: serviceName, url, typeDefs }); + } else { + let typeDefs = await OverrideApolloGateway.getTypeDefs( + service.url as string, + serviceName, + ); + if (typeDefs) { + newDefinitions.push({ + name: serviceName, + url: service.url, + typeDefs: parse(typeDefs), + }); + + if (service.autoUpdateSchemaFromUrl) + FileProvider.instance.writeFile( + WorkbenchUri.supergraph( + FileProvider.instance.loadedWorbenchFilePath, + serviceName, + WorkbenchUriType.SCHEMAS, + ), + Buffer.from(typeDefs), + { create: true, overwrite: true }, + ); + } else { + log('Falling back to schema defined in workbench'); + newDefinitions.push({ + name: serviceName, + url: service.url, + typeDefs: parse(service.sdl), + }); + } } - - return { - isNewSchema: true, - serviceDefinitions: newDefinitions - }; + } } - public static async getTypeDefs(serviceURLOverride: string, serviceName: string) { - let source = new RemoteGraphQLDataSource({ url: serviceURLOverride, }); - let requiredHeaders = FileProvider.instance.loadedWorkbenchFile?.schemas[serviceName]?.requiredHeaders; - let headers = new Headers(); - requiredHeaders?.forEach(requiredHeader => { - if (requiredHeader && requiredHeader.value) - headers.append(requiredHeader.key, requiredHeader.value); - }); - - try { - const request = { - query: 'query __ApolloGetServiceDefinition__ { _service { sdl } }', - http: { - url: serviceURLOverride, - method: 'POST', - headers - }, - }; - - let { data, errors } = await source.process({ request, context: {} }); - if (data && !errors) { - return data._service.sdl as string; - } else if (errors) { - errors.map(error => log(error.message)); - //If we got errors, it could be that the graphql server running at that url doesn't support Apollo Federation Spec - // In this case, we can try and get the server schema from introspection - return await this.getSchemaByIntrospection(serviceURLOverride, source, headers); - } - } catch (err) { - if (err.code == 'ECONNREFUSED') - log(`Do you have service ${serviceName} running? \n\t${err.message}`); - else if (err.code == 'ENOTFOUND') - log(`Do you have service ${serviceName} running? \n\t${err.message}`); - else if (err.message == 'Only absolute URLs are supported') - log(`${serviceName}-${err.message}`); - else - return await this.getSchemaByIntrospection(serviceURLOverride, source, headers); - } - - return; + return { + isNewSchema: true, + serviceDefinitions: newDefinitions, + }; + } + + public static async getTypeDefs( + serviceURLOverride: string, + serviceName: string, + ) { + let source = new RemoteGraphQLDataSource({ url: serviceURLOverride }); + let requiredHeaders = + FileProvider.instance.loadedWorkbenchFile?.schemas[serviceName] + ?.requiredHeaders; + let headers = new Headers(); + requiredHeaders?.forEach((requiredHeader) => { + if (requiredHeader && requiredHeader.value) + headers.append(requiredHeader.key, requiredHeader.value); + }); + + try { + const request = { + query: 'query __ApolloGetServiceDefinition__ { _service { sdl } }', + http: { + url: serviceURLOverride, + method: 'POST', + headers, + }, + }; + + let { data, errors } = await source.process({ request, context: {} }); + if (data && !errors) { + return data._service.sdl as string; + } else if (errors) { + errors.map((error) => log(error.message)); + //If we got errors, it could be that the graphql server running at that url doesn't support Apollo Federation Spec + // In this case, we can try and get the server schema from introspection + return await this.getSchemaByIntrospection( + serviceURLOverride, + source, + headers, + ); + } + } catch (err) { + if (err.code == 'ECONNREFUSED') + log(`Do you have service ${serviceName} running? \n\t${err.message}`); + else if (err.code == 'ENOTFOUND') + log(`Do you have service ${serviceName} running? \n\t${err.message}`); + else if (err.message == 'Only absolute URLs are supported') + log(`${serviceName}-${err.message}`); + else + return await this.getSchemaByIntrospection( + serviceURLOverride, + source, + headers, + ); } - private static async getSchemaByIntrospection(serviceURLOverride: string, source: RemoteGraphQLDataSource, requiredHeaders: Headers) { - let introspectionQuery = getIntrospectionQuery(); - const request = { - query: introspectionQuery, - http: { - url: serviceURLOverride, - method: 'POST', - headers: requiredHeaders - }, - }; - - let { data, errors } = await source.process({ request, context: {} }); - if (data && !errors) { - const schema = buildClientSchema(data as any); - - return printSchema(schema); - } else if (errors) { - errors.map(error => log(error.message)); - window.showErrorMessage(`Unable to get the schema from the underlying server running at ${serviceURLOverride}. Your GraphQL server must support the Apollo Federation specification or have introspection enabled`); - } + return; + } + + private static async getSchemaByIntrospection( + serviceURLOverride: string, + source: RemoteGraphQLDataSource, + requiredHeaders: Headers, + ) { + let introspectionQuery = getIntrospectionQuery(); + const request = { + query: introspectionQuery, + http: { + url: serviceURLOverride, + method: 'POST', + headers: requiredHeaders, + }, + }; + + let { data, errors } = await source.process({ request, context: {} }); + if (data && !errors) { + const schema = buildClientSchema(data as any); + + return printSchema(schema); + } else if (errors) { + errors.map((error) => log(error.message)); + window.showErrorMessage( + `Unable to get the schema from the underlying server running at ${serviceURLOverride}. Your GraphQL server must support the Apollo Federation specification or have introspection enabled`, + ); } -} \ No newline at end of file + } +} diff --git a/src/graphql/graphql-language-service.d.ts b/src/graphql/graphql-language-service.d.ts index 76194c6..1396f83 100644 --- a/src/graphql/graphql-language-service.d.ts +++ b/src/graphql/graphql-language-service.d.ts @@ -1,25 +1,24 @@ - -declare module "@apollographql/graphql-language-service-interface" { - import { DocumentNode, GraphQLSchema, Location } from "graphql"; +declare module '@apollographql/graphql-language-service-interface' { + import { DocumentNode, GraphQLSchema, Location } from 'graphql'; import { Diagnostic, Position, Range, - CompletionItem - } from "vscode-languageserver"; + CompletionItem, + } from 'vscode-languageserver'; function getAutocompleteSuggestions( schema: GraphQLSchema, queryText: string, - position: Position + position: Position, ): CompletionItem[]; } -declare module "@apollographql/graphql-language-service-interface/dist/getAutocompleteSuggestions"; +declare module '@apollographql/graphql-language-service-interface/dist/getAutocompleteSuggestions'; -declare module "@apollographql/graphql-language-service-interface/dist/getDiagnostics" { - import { Location } from "graphql"; - import { Range } from "vscode-languageserver"; +declare module '@apollographql/graphql-language-service-interface/dist/getDiagnostics' { + import { Location } from 'graphql'; + import { Range } from 'vscode-languageserver'; function getRange(location: Location, queryText: string): Range; -} \ No newline at end of file +} diff --git a/src/graphql/parsers/csdlParser.ts b/src/graphql/parsers/csdlParser.ts index 606ddc6..1b03ac8 100644 --- a/src/graphql/parsers/csdlParser.ts +++ b/src/graphql/parsers/csdlParser.ts @@ -1,119 +1,156 @@ -import { FieldWithType } from "../../workbench/federationCompletionProvider"; -import { FileProvider } from "../../workbench/file-system/fileProvider"; -import { StateManager } from "../../workbench/stateManager"; -import { visit, parse, ArgumentNode, EnumValueNode, StringValueNode } from 'graphql'; +import { FieldWithType } from '../../workbench/federationCompletionProvider'; +import { FileProvider } from '../../workbench/file-system/fileProvider'; +import { StateManager } from '../../workbench/stateManager'; +import { + visit, + parse, + ArgumentNode, + EnumValueNode, + StringValueNode, +} from 'graphql'; function getFieldTypeString(field): string { - switch (field.kind) { - case 'FieldDefinition': - return getFieldTypeString(field.type); + switch (field.kind) { + case 'FieldDefinition': + return getFieldTypeString(field.type); + case 'ListType': + return `[${getFieldTypeString(field.type)}]`; + case 'NamedType': + return field.name.value; + //Need to add the ! for NonNull + case 'NonNullType': + switch (field.type.kind) { case 'ListType': - return `[${getFieldTypeString(field.type)}]`; + return `${getFieldTypeString(field.type)}!`; case 'NamedType': - return field.name.value; - //Need to add the ! for NonNull - case 'NonNullType': - switch (field.type.kind) { - case 'ListType': - return `${getFieldTypeString(field.type)}!`; - case 'NamedType': - return `${field.type.name.value}!`; - } - default: return ""; - } + return `${field.type.name.value}!`; + } + default: + return ''; + } } export async function extractDefinedEntitiesByService(wbFilePath: string) { - let extendables: { [serviceName: string]: { type: string, keys: { [key: string]: FieldWithType[] } }[] } = {}; - let joinGraphEnumValues: { [joinGraphEnum: string]: string } = {}; + let extendables: { + [serviceName: string]: { + type: string; + keys: { [key: string]: FieldWithType[] }; + }[]; + } = {}; + let joinGraphEnumValues: { [joinGraphEnum: string]: string } = {}; - try { - const wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); - if (wbFile) { - visit(parse(wbFile.supergraphSdl), { - ObjectTypeDefinition(node) { - let joinOwnerDirective = node.directives?.find(d => d.name.value == 'join__owner'); - if (joinOwnerDirective && joinOwnerDirective.arguments) { - let joinGraphEnumValue = ((joinOwnerDirective.arguments[0] as ArgumentNode).value as EnumValueNode).value; - let entity: { type: string, keys: { [key: string]: FieldWithType[] } } = { type: node.name.value, keys: {} }; + try { + const wbFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); + if (wbFile) { + visit(parse(wbFile.supergraphSdl), { + ObjectTypeDefinition(node) { + let joinOwnerDirective = node.directives?.find( + (d) => d.name.value == 'join__owner', + ); + if (joinOwnerDirective && joinOwnerDirective.arguments) { + let joinGraphEnumValue = ((joinOwnerDirective + .arguments[0] as ArgumentNode).value as EnumValueNode).value; + let entity: { + type: string; + keys: { [key: string]: FieldWithType[] }; + } = { type: node.name.value, keys: {} }; - let joinKeyDirectives = node.directives?.filter(d => d.name.value == 'join__type' && (d.arguments?.find(a => a.name.value == 'graph' && (a.value as StringValueNode)?.value == joinGraphEnumValue)?.value as EnumValueNode)?.value); - if (joinKeyDirectives) { - joinKeyDirectives?.forEach(jkd => { - let keyBlock = (jkd.arguments?.find(a => a.name.value == 'key')?.value as StringValueNode).value; - let parsedFields: string[] = []; - let startIndex = -1; - let notComposite = true; - for (var i = 0; i < keyBlock.length; i++) { - let lastParsedField = ''; - let char = keyBlock[i]; - switch (char) { - case ' ': - if (startIndex != -1 && notComposite) { - lastParsedField = keyBlock.substring(startIndex, i); - parsedFields.push(lastParsedField); - } + let joinKeyDirectives = node.directives?.filter( + (d) => + d.name.value == 'join__type' && + (d.arguments?.find( + (a) => + a.name.value == 'graph' && + (a.value as StringValueNode)?.value == joinGraphEnumValue, + )?.value as EnumValueNode)?.value, + ); + if (joinKeyDirectives) { + joinKeyDirectives?.forEach((jkd) => { + let keyBlock = (jkd.arguments?.find( + (a) => a.name.value == 'key', + )?.value as StringValueNode).value; + let parsedFields: string[] = []; + let startIndex = -1; + let notComposite = true; + for (var i = 0; i < keyBlock.length; i++) { + let lastParsedField = ''; + let char = keyBlock[i]; + switch (char) { + case ' ': + if (startIndex != -1 && notComposite) { + lastParsedField = keyBlock.substring(startIndex, i); + parsedFields.push(lastParsedField); + } - startIndex = -1 - break; - case '{': - notComposite = false; - break; - case '}': - notComposite = true; - break; - default: - if (startIndex == 0 && i == keyBlock.length - 1) - parsedFields.push(keyBlock); - else if (i == keyBlock.length - 1) - parsedFields.push(keyBlock.substring(startIndex)); - else if (startIndex == -1) - startIndex = i; - break; - } - } - - parsedFields.forEach(parsedField => { - let finalKey = keyBlock.trim(); - let field = node.fields?.find(f => f.name.value == parsedField); - let fieldType = ''; - if (field) - fieldType = getFieldTypeString(field); + startIndex = -1; + break; + case '{': + notComposite = false; + break; + case '}': + notComposite = true; + break; + default: + if (startIndex == 0 && i == keyBlock.length - 1) + parsedFields.push(keyBlock); + else if (i == keyBlock.length - 1) + parsedFields.push(keyBlock.substring(startIndex)); + else if (startIndex == -1) startIndex = i; + break; + } + } - if (entity.keys[finalKey]) - entity.keys[finalKey].push({ field: parsedField, type: fieldType }); - else - entity.keys[finalKey] = [{ field: parsedField, type: fieldType }]; - }); - }) - } + parsedFields.forEach((parsedField) => { + let finalKey = keyBlock.trim(); + let field = node.fields?.find( + (f) => f.name.value == parsedField, + ); + let fieldType = ''; + if (field) fieldType = getFieldTypeString(field); + if (entity.keys[finalKey]) + entity.keys[finalKey].push({ + field: parsedField, + type: fieldType, + }); + else + entity.keys[finalKey] = [ + { field: parsedField, type: fieldType }, + ]; + }); + }); + } - if (!extendables[joinGraphEnumValue]) { - extendables[joinGraphEnumValue] = [entity]; - } else { - extendables[joinGraphEnumValue].push(entity); - } - } - }, - EnumTypeDefinition(node) { - if (node.name.value == 'join__Graph') { - node.values?.forEach(enumValueDefinition => { - joinGraphEnumValues[enumValueDefinition.name.value] = (enumValueDefinition.directives?.find(d => d.name.value == 'join__graph')?.arguments?.find(a => a.name.value == 'name')?.value as StringValueNode)?.value; - }) - } - } + if (!extendables[joinGraphEnumValue]) { + extendables[joinGraphEnumValue] = [entity]; + } else { + extendables[joinGraphEnumValue].push(entity); + } + } + }, + EnumTypeDefinition(node) { + if (node.name.value == 'join__Graph') { + node.values?.forEach((enumValueDefinition) => { + joinGraphEnumValues[ + enumValueDefinition.name.value + ] = (enumValueDefinition.directives + ?.find((d) => d.name.value == 'join__graph') + ?.arguments?.find((a) => a.name.value == 'name') + ?.value as StringValueNode)?.value; }); - Object.keys(extendables).forEach(k => { - extendables[joinGraphEnumValues[k]] = extendables[k]; - delete extendables[k]; - }) - } - } catch (err) { - console.log(err); + } + }, + }); + Object.keys(extendables).forEach((k) => { + extendables[joinGraphEnumValues[k]] = extendables[k]; + delete extendables[k]; + }); } + } catch (err) { + console.log(err); + } - StateManager.instance.workspaceState_selectedWorkbenchAvailableEntities = extendables; + StateManager.instance.workspaceState_selectedWorkbenchAvailableEntities = extendables; - return extendables; -} \ No newline at end of file + return extendables; +} diff --git a/src/graphql/parsers/runOnlineParser.ts b/src/graphql/parsers/runOnlineParser.ts index 91cd0c8..152a3ad 100644 --- a/src/graphql/parsers/runOnlineParser.ts +++ b/src/graphql/parsers/runOnlineParser.ts @@ -1,200 +1,196 @@ - import { zip } from 'lodash'; -import { Position, Range } from "vscode"; -import { CharacterStream, onlineParser, State } from "graphql-language-service-parser"; +import { Position, Range } from 'vscode'; +import { + CharacterStream, + onlineParser, + State, +} from 'graphql-language-service-parser'; export function runOnlineParser( - documentText: string, - callback: ( - state: State, - ruleRange: Range, - tokens: Node['tokens'], - ) => void, + documentText: string, + callback: (state: State, ruleRange: Range, tokens: Node['tokens']) => void, ) { - runOnlineParserInternal(documentText).forEach((rule) => - callback(rule.state, rule.range, rule.tokens), - ); + runOnlineParserInternal(documentText).forEach((rule) => + callback(rule.state, rule.range, rule.tokens), + ); } function getAncestorStates(state: State): State[] { - const stateAncestors = [state]; - let currentState = state; - while (currentState.prevState) { - stateAncestors.push(currentState.prevState); - currentState = currentState.prevState; - } - stateAncestors.reverse(); - return stateAncestors; + const stateAncestors = [state]; + let currentState = state; + while (currentState.prevState) { + stateAncestors.push(currentState.prevState); + currentState = currentState.prevState; + } + stateAncestors.reverse(); + return stateAncestors; } interface Rule { - state: State; - range: Range; - tokens: Node['tokens']; + state: State; + range: Range; + tokens: Node['tokens']; } interface Node { - state: State; - range: Range; - tokens: Array<{ range: Range; state: State }>; + state: State; + range: Range; + tokens: Array<{ range: Range; state: State }>; } function runOnlineParserInternal(documentText: string): Rule[] { - const lines = documentText.split('\n'); - const parser = onlineParser(); - let mutableState: State = { ...parser.startState() }; - let savedAncestorStates: Node[] = []; - const allRules: Rule[] = []; - let blockComment = false; - lines.forEach((line, lineIndex) => { - const stream = new CharacterStream(`${line}\n`); - while (!stream.eol()) { - // The parser doesn not handle multi line comments well, patch support - // for that in - if (blockComment) { - const restOfLine = line.slice(stream.getCurrentPosition()); - const match = restOfLine.match(/^([^"]|("(?!"")))*"""/); - const matchEnd = match?.[0].length; - if (matchEnd) { - blockComment = false; - stream.skipTo(matchEnd); - } else { - stream.skipToEnd(); - } - } else { - const tokenType = parser.token(stream, mutableState); - // Aliased fields do not have their alias in the state, instead we get - // two different names at different steps in the rule. Attach the name - // for the first two steps as an alias. - if (mutableState.kind === 'AliasedField' && mutableState.step < 2) { - // mutableState.alias = mutableState.name; - } - const state: State = { ...mutableState }; - const ancestorStates = getAncestorStates(state); - // monaco positions - const lineNumber = lineIndex; - const startColumn = stream.getStartOfToken(); - const endColumn = stream.getCurrentPosition(); - const tokenText = line.slice( - stream.getStartOfToken(), - stream.getCurrentPosition(), + const lines = documentText.split('\n'); + const parser = onlineParser(); + let mutableState: State = { ...parser.startState() }; + let savedAncestorStates: Node[] = []; + const allRules: Rule[] = []; + let blockComment = false; + lines.forEach((line, lineIndex) => { + const stream = new CharacterStream(`${line}\n`); + while (!stream.eol()) { + // The parser doesn not handle multi line comments well, patch support + // for that in + if (blockComment) { + const restOfLine = line.slice(stream.getCurrentPosition()); + const match = restOfLine.match(/^([^"]|("(?!"")))*"""/); + const matchEnd = match?.[0].length; + if (matchEnd) { + blockComment = false; + stream.skipTo(matchEnd); + } else { + stream.skipToEnd(); + } + } else { + const tokenType = parser.token(stream, mutableState); + // Aliased fields do not have their alias in the state, instead we get + // two different names at different steps in the rule. Attach the name + // for the first two steps as an alias. + if (mutableState.kind === 'AliasedField' && mutableState.step < 2) { + // mutableState.alias = mutableState.name; + } + const state: State = { ...mutableState }; + const ancestorStates = getAncestorStates(state); + // monaco positions + const lineNumber = lineIndex; + const startColumn = stream.getStartOfToken(); + const endColumn = stream.getCurrentPosition(); + const tokenText = line.slice( + stream.getStartOfToken(), + stream.getCurrentPosition(), + ); + if (tokenType === 'invalidchar' && tokenText === '"""') { + blockComment = true; + } + const tokenRange = new Range( + lineNumber, + startColumn, + lineNumber, + endColumn, + ); + const lastState = savedAncestorStates.length + ? savedAncestorStates.slice(-1)[0] + : undefined; + if ( + lastState && + lastState.state.kind === state.kind && + lastState.state.step <= state.step && + ancestorStates.length === savedAncestorStates.length + ) { + // Continuing previous rule + // For each ancestor, send an incomplete callback + // These are non null as we checked + // `ancestorStates.length === savedAncestorStates.length` above + (zip(ancestorStates, savedAncestorStates) as [State, Node][]).forEach( + ([ancestorState, savedAncestorState]: [State, Node]) => { + // eslint-disable-next-line no-param-reassign + savedAncestorState.state = ancestorState; + if (tokenType !== 'ws' && state.kind !== 'Invalid') { + // eslint-disable-next-line no-param-reassign + savedAncestorState.range = savedAncestorState.range.with( + undefined, + new Position(lineNumber, endColumn), ); - if (tokenType === 'invalidchar' && tokenText === '"""') { - blockComment = true; - } - const tokenRange = new Range( - lineNumber, - startColumn, - lineNumber, - endColumn, + } + }, + ); + } else { + // Starting a new rule + let ancestorsToAdd: Node[] = []; + let includePunctuation = false; + // For each node that this is not a part of (complete nodes), call + // the callback + const ancestorPairs = zip(ancestorStates, savedAncestorStates); + ancestorPairs.reverse(); + // eslint-disable-next-line no-loop-func + ancestorPairs.forEach(([ancestorState, savedAncestorState]) => { + // Node matched, update saved node + if ( + ancestorState && + savedAncestorState && + savedAncestorState.state.kind === ancestorState.kind && + (savedAncestorState.state.step === ancestorState.step || + ancestorState.step > 1 || + // `FragmentSpread`s start parsing at step 1 + (ancestorState.step > 0 && + savedAncestorState.state.kind !== 'FragmentSpread')) + ) { + // eslint-disable-next-line no-param-reassign + savedAncestorState.state = ancestorState; + if (tokenType !== 'ws' && state.kind !== 'Invalid') { + // eslint-disable-next-line no-param-reassign + savedAncestorState.range = savedAncestorState.range.with( + undefined, + new Position(lineNumber, endColumn), ); - const lastState = savedAncestorStates.length - ? savedAncestorStates.slice(-1)[0] - : undefined; + } + } else { + if (savedAncestorState) { + // Update node and call the complete callback. + // Punctuation is not included as part of the rule, add it + // manually. + const rule = savedAncestorState.state.rule; + const finalRule = Array.isArray(rule) && rule.slice(-1)[0]; if ( - lastState && - lastState.state.kind === state.kind && - lastState.state.step <= state.step && - ancestorStates.length === savedAncestorStates.length + includePunctuation || + (finalRule && + typeof finalRule === 'object' && + finalRule.style === 'punctuation') ) { - // Continuing previous rule - // For each ancestor, send an incomplete callback - // These are non null as we checked - // `ancestorStates.length === savedAncestorStates.length` above - (zip(ancestorStates, savedAncestorStates) as [ - State, - Node, - ][]).forEach( - ([ancestorState, savedAncestorState]: [State, Node]) => { - // eslint-disable-next-line no-param-reassign - savedAncestorState.state = ancestorState; - if (tokenType !== 'ws' && state.kind !== 'Invalid') { - // eslint-disable-next-line no-param-reassign - savedAncestorState.range = savedAncestorState.range.with( - undefined, - new Position(lineNumber, endColumn) - ); - } - }, - ); - } else { - // Starting a new rule - let ancestorsToAdd: Node[] = []; - let includePunctuation = false; - // For each node that this is not a part of (complete nodes), call - // the callback - const ancestorPairs = zip(ancestorStates, savedAncestorStates); - ancestorPairs.reverse(); - // eslint-disable-next-line no-loop-func - ancestorPairs.forEach(([ancestorState, savedAncestorState]) => { - // Node matched, update saved node - if ( - ancestorState && - savedAncestorState && - savedAncestorState.state.kind === ancestorState.kind && - (savedAncestorState.state.step === ancestorState.step || - ancestorState.step > 1 || - // `FragmentSpread`s start parsing at step 1 - (ancestorState.step > 0 && - savedAncestorState.state.kind !== 'FragmentSpread')) - ) { - // eslint-disable-next-line no-param-reassign - savedAncestorState.state = ancestorState; - if (tokenType !== 'ws' && state.kind !== 'Invalid') { - // eslint-disable-next-line no-param-reassign - savedAncestorState.range = savedAncestorState.range.with( - undefined, - new Position(lineNumber, endColumn) - ); - } - } else { - if (savedAncestorState) { - // Update node and call the complete callback. - // Punctuation is not included as part of the rule, add it - // manually. - const rule = savedAncestorState.state.rule; - const finalRule = Array.isArray(rule) && rule.slice(-1)[0]; - if ( - includePunctuation || - (finalRule && - typeof finalRule === 'object' && - finalRule.style === 'punctuation') - ) { - // eslint-disable-next-line no-param-reassign - savedAncestorState.range = savedAncestorState.range.with( - undefined, - new Position(lineNumber, startColumn + 1), - ); - includePunctuation = true; - } - allRules.push(savedAncestorState); - savedAncestorStates.pop(); - } - if (ancestorState) { - const newAncestor = { - state: ancestorState, - range: tokenRange, - tokens: [], - }; - ancestorsToAdd = [newAncestor, ...ancestorsToAdd]; - } - } - }); - savedAncestorStates = [...savedAncestorStates, ...ancestorsToAdd]; - } - if (tokenType !== 'ws' && savedAncestorStates.length) { - savedAncestorStates.forEach((savedAncestorState) => { - savedAncestorState.tokens.push({ range: tokenRange, state }); - }); + // eslint-disable-next-line no-param-reassign + savedAncestorState.range = savedAncestorState.range.with( + undefined, + new Position(lineNumber, startColumn + 1), + ); + includePunctuation = true; } + allRules.push(savedAncestorState); + savedAncestorStates.pop(); + } + if (ancestorState) { + const newAncestor = { + state: ancestorState, + range: tokenRange, + tokens: [], + }; + ancestorsToAdd = [newAncestor, ...ancestorsToAdd]; + } } + }); + savedAncestorStates = [...savedAncestorStates, ...ancestorsToAdd]; } - // If we reached an invalid state, reset to the base Document state - if (!mutableState.kind) { - mutableState = parser.startState(); + if (tokenType !== 'ws' && savedAncestorStates.length) { + savedAncestorStates.forEach((savedAncestorState) => { + savedAncestorState.tokens.push({ range: tokenRange, state }); + }); } - }); - while (savedAncestorStates.length) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - allRules.push(savedAncestorStates.pop()!); + } + } + // If we reached an invalid state, reset to the base Document state + if (!mutableState.kind) { + mutableState = parser.startState(); } - return allRules; -} \ No newline at end of file + }); + while (savedAncestorStates.length) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + allRules.push(savedAncestorStates.pop()!); + } + return allRules; +} diff --git a/src/graphql/parsers/schemaParser.ts b/src/graphql/parsers/schemaParser.ts index 340baeb..f31045f 100644 --- a/src/graphql/parsers/schemaParser.ts +++ b/src/graphql/parsers/schemaParser.ts @@ -1,101 +1,116 @@ -import { BREAK, EnumTypeDefinitionNode, InterfaceTypeDefinitionNode, ObjectTypeDefinitionNode, parse, ScalarTypeDefinitionNode, visit } from "graphql"; -import { FileProvider } from "../../workbench/file-system/fileProvider"; +import { + BREAK, + EnumTypeDefinitionNode, + InterfaceTypeDefinitionNode, + ObjectTypeDefinitionNode, + parse, + ScalarTypeDefinitionNode, + visit, +} from 'graphql'; +import { FileProvider } from '../../workbench/file-system/fileProvider'; -import { runOnlineParser } from "./runOnlineParser"; +import { runOnlineParser } from './runOnlineParser'; -export function getServiceAvailableTypes(serviceName: string, wbFilePath: string): string[] { - let types: string[] = []; - let interfaces: string[] = []; - let objectTypes: string[] = []; - let enums: string[] = []; - let scalars: string[] = []; +export function getServiceAvailableTypes( + serviceName: string, + wbFilePath: string, +): string[] { + let types: string[] = []; + let interfaces: string[] = []; + let objectTypes: string[] = []; + let enums: string[] = []; + let scalars: string[] = []; - try { - let localSchema = FileProvider.instance.workbenchFileFromPath(wbFilePath)?.schemas[serviceName]; - if (localSchema) { - let doc = parse(localSchema.sdl); + try { + let localSchema = FileProvider.instance.workbenchFileFromPath(wbFilePath) + ?.schemas[serviceName]; + if (localSchema) { + let doc = parse(localSchema.sdl); - visit(doc, { - ObjectTypeDefinition(objectTypeNode: ObjectTypeDefinitionNode) { - let typeNode = `O:${objectTypeNode.name.value}`; - if (!interfaces.includes(typeNode)) { - interfaces.push(typeNode); - interfaces.push(`[${typeNode}]`); - } - }, - InterfaceTypeDefinition(interfaceNode: InterfaceTypeDefinitionNode) { - let typeNode = `I:${interfaceNode.name.value}`; - if (!objectTypes.includes(typeNode)) { - objectTypes.push(typeNode); - objectTypes.push(`[${typeNode}]`); - } - }, - EnumTypeDefinition(enumNode: EnumTypeDefinitionNode) { - let typeNode = `E:${enumNode.name.value}`; - if (!enums.includes(typeNode)) { - enums.push(typeNode); - enums.push(`[${typeNode}]`); - } - }, - ScalarTypeDefinition(scalarNode: ScalarTypeDefinitionNode) { - let typeNode = `S:${scalarNode.name.value}`; - if (!scalars.includes(typeNode)) { - scalars.push(typeNode); - scalars.push(`[${typeNode}]`); - } - } - }); - } - } catch (err) { - console.log(err.message); + visit(doc, { + ObjectTypeDefinition(objectTypeNode: ObjectTypeDefinitionNode) { + let typeNode = `O:${objectTypeNode.name.value}`; + if (!interfaces.includes(typeNode)) { + interfaces.push(typeNode); + interfaces.push(`[${typeNode}]`); + } + }, + InterfaceTypeDefinition(interfaceNode: InterfaceTypeDefinitionNode) { + let typeNode = `I:${interfaceNode.name.value}`; + if (!objectTypes.includes(typeNode)) { + objectTypes.push(typeNode); + objectTypes.push(`[${typeNode}]`); + } + }, + EnumTypeDefinition(enumNode: EnumTypeDefinitionNode) { + let typeNode = `E:${enumNode.name.value}`; + if (!enums.includes(typeNode)) { + enums.push(typeNode); + enums.push(`[${typeNode}]`); + } + }, + ScalarTypeDefinition(scalarNode: ScalarTypeDefinitionNode) { + let typeNode = `S:${scalarNode.name.value}`; + if (!scalars.includes(typeNode)) { + scalars.push(typeNode); + scalars.push(`[${typeNode}]`); + } + }, + }); } + } catch (err) { + console.log(err.message); + } - //Add Object/Interface/Enum/Scalars definitions - types.push(...objectTypes); - types.push(...interfaces); - types.push(...enums); - types.push(...scalars); + //Add Object/Interface/Enum/Scalars definitions + types.push(...objectTypes); + types.push(...interfaces); + types.push(...enums); + types.push(...scalars); - //Add GraphQQL default scalar types: - types.push('ID'); - types.push('Int'); - types.push('String'); - types.push('[String]'); - types.push('[Int]'); - types.push('Float'); - types.push('[Float]'); - types.push('Boolean'); - types.push('[Boolean]'); + //Add GraphQQL default scalar types: + types.push('ID'); + types.push('Int'); + types.push('String'); + types.push('[String]'); + types.push('[Int]'); + types.push('Float'); + types.push('[Float]'); + types.push('Boolean'); + types.push('[Boolean]'); - return types; + return types; } export function extractEntityNames(schema: string): string[] { - let entityName: string[] = []; - try { - runOnlineParser(schema, (state, range, tokens) => { - switch (state.kind) { - case "StringValue" as any: - let argument = state?.prevState?.prevState; - let directive = argument?.prevState?.prevState; - let objectType = directive?.prevState; - let definitionType = objectType?.prevState; + let entityName: string[] = []; + try { + runOnlineParser(schema, (state, range, tokens) => { + switch (state.kind) { + case 'StringValue' as any: + let argument = state?.prevState?.prevState; + let directive = argument?.prevState?.prevState; + let objectType = directive?.prevState; + let definitionType = objectType?.prevState; - if (objectType?.name - && definitionType?.kind == "Definition" as any - && objectType?.kind == 'ObjectTypeDef' - && directive?.kind == "Directive" - && argument?.kind == "Argument" - && argument.name == 'fields' - && directive.name == 'key') { - if (!entityName.includes(objectType.name)) entityName.push(objectType.name); - } - break; - } - }); - } catch (err) { - console.log(err); - } + if ( + objectType?.name && + definitionType?.kind == ('Definition' as any) && + objectType?.kind == 'ObjectTypeDef' && + directive?.kind == 'Directive' && + argument?.kind == 'Argument' && + argument.name == 'fields' && + directive.name == 'key' + ) { + if (!entityName.includes(objectType.name)) + entityName.push(objectType.name); + } + break; + } + }); + } catch (err) { + console.log(err); + } - return entityName; -} \ No newline at end of file + return entityName; +} diff --git a/src/graphql/types/AccountServiceVariants.ts b/src/graphql/types/AccountServiceVariants.ts index aed01e3..8e78729 100644 --- a/src/graphql/types/AccountServiceVariants.ts +++ b/src/graphql/types/AccountServiceVariants.ts @@ -8,12 +8,12 @@ // ==================================================== export interface AccountServiceVariants_account_services_devGraphOwner { - __typename: "User"; + __typename: 'User'; id: string; } export interface AccountServiceVariants_account_services_variants { - __typename: "GraphVariant"; + __typename: 'GraphVariant'; /** * Name of the variant, like `variant`. */ @@ -21,7 +21,7 @@ export interface AccountServiceVariants_account_services_variants { } export interface AccountServiceVariants_account_services { - __typename: "Service"; + __typename: 'Service'; id: string; title: string; devGraphOwner: AccountServiceVariants_account_services_devGraphOwner | null; @@ -32,7 +32,7 @@ export interface AccountServiceVariants_account_services { } export interface AccountServiceVariants_account { - __typename: "Account"; + __typename: 'Account'; name: string; services: AccountServiceVariants_account_services[]; } diff --git a/src/graphql/types/CheckUserApiKey.ts b/src/graphql/types/CheckUserApiKey.ts index 9fbd524..8d1de5a 100644 --- a/src/graphql/types/CheckUserApiKey.ts +++ b/src/graphql/types/CheckUserApiKey.ts @@ -8,15 +8,17 @@ // ==================================================== export interface CheckUserApiKey_me_InternalIdentity { - __typename: "InternalIdentity" | "Service"; + __typename: 'InternalIdentity' | 'Service'; } export interface CheckUserApiKey_me_User { - __typename: "User"; + __typename: 'User'; id: string; } -export type CheckUserApiKey_me = CheckUserApiKey_me_InternalIdentity | CheckUserApiKey_me_User; +export type CheckUserApiKey_me = + | CheckUserApiKey_me_InternalIdentity + | CheckUserApiKey_me_User; export interface CheckUserApiKey { /** diff --git a/src/graphql/types/GetGraphSchemas.ts b/src/graphql/types/GetGraphSchemas.ts index 6e63b94..c19d7e7 100644 --- a/src/graphql/types/GetGraphSchemas.ts +++ b/src/graphql/types/GetGraphSchemas.ts @@ -8,12 +8,12 @@ // ==================================================== export interface GetGraphSchemas_service_schema { - __typename: "Schema"; + __typename: 'Schema'; document: any; } export interface GetGraphSchemas_service_implementingServices_NonFederatedImplementingService { - __typename: "NonFederatedImplementingService"; + __typename: 'NonFederatedImplementingService'; /** * Identifies which graph this non-implementing service belongs to. * Formerly known as "service_id" @@ -22,7 +22,7 @@ export interface GetGraphSchemas_service_implementingServices_NonFederatedImplem } export interface GetGraphSchemas_service_implementingServices_FederatedImplementingServices_services_activePartialSchema { - __typename: "PartialSchema"; + __typename: 'PartialSchema'; /** * The enriched sdl of a partial schema */ @@ -30,7 +30,7 @@ export interface GetGraphSchemas_service_implementingServices_FederatedImplement } export interface GetGraphSchemas_service_implementingServices_FederatedImplementingServices_services { - __typename: "FederatedImplementingService"; + __typename: 'FederatedImplementingService'; /** * Name of the implementing service */ @@ -47,14 +47,16 @@ export interface GetGraphSchemas_service_implementingServices_FederatedImplement } export interface GetGraphSchemas_service_implementingServices_FederatedImplementingServices { - __typename: "FederatedImplementingServices"; + __typename: 'FederatedImplementingServices'; services: GetGraphSchemas_service_implementingServices_FederatedImplementingServices_services[]; } -export type GetGraphSchemas_service_implementingServices = GetGraphSchemas_service_implementingServices_NonFederatedImplementingService | GetGraphSchemas_service_implementingServices_FederatedImplementingServices; +export type GetGraphSchemas_service_implementingServices = + | GetGraphSchemas_service_implementingServices_NonFederatedImplementingService + | GetGraphSchemas_service_implementingServices_FederatedImplementingServices; export interface GetGraphSchemas_service { - __typename: "Service"; + __typename: 'Service'; /** * Get a schema by hash OR current tag */ diff --git a/src/graphql/types/GraphOperations.ts b/src/graphql/types/GraphOperations.ts index f99f7eb..2b701f2 100644 --- a/src/graphql/types/GraphOperations.ts +++ b/src/graphql/types/GraphOperations.ts @@ -8,14 +8,14 @@ // ==================================================== export interface GraphOperations_service_stats_queryStats_groupBy { - __typename: "ServiceQueryStatsDimensions"; + __typename: 'ServiceQueryStatsDimensions'; queryName: string | null; queryId: string | null; querySignature: string | null; } export interface GraphOperations_service_stats_queryStats { - __typename: "ServiceQueryStatsRecord"; + __typename: 'ServiceQueryStatsRecord'; /** * Dimensions of ServiceQueryStats that can be grouped by. */ @@ -23,12 +23,12 @@ export interface GraphOperations_service_stats_queryStats { } export interface GraphOperations_service_stats { - __typename: "ServiceStatsWindow"; + __typename: 'ServiceStatsWindow'; queryStats: GraphOperations_service_stats_queryStats[]; } export interface GraphOperations_service { - __typename: "Service"; + __typename: 'Service'; title: string; stats: GraphOperations_service_stats; } diff --git a/src/graphql/types/MyAccountIds.ts b/src/graphql/types/MyAccountIds.ts index eccd4f2..28f1aa4 100644 --- a/src/graphql/types/MyAccountIds.ts +++ b/src/graphql/types/MyAccountIds.ts @@ -8,25 +8,27 @@ // ==================================================== export interface MyAccountIds_me_InternalIdentity { - __typename: "InternalIdentity" | "Service"; + __typename: 'InternalIdentity' | 'Service'; } export interface MyAccountIds_me_User_memberships_account { - __typename: "Account"; + __typename: 'Account'; id: string; } export interface MyAccountIds_me_User_memberships { - __typename: "UserMembership"; + __typename: 'UserMembership'; account: MyAccountIds_me_User_memberships_account; } export interface MyAccountIds_me_User { - __typename: "User"; + __typename: 'User'; memberships: MyAccountIds_me_User_memberships[]; } -export type MyAccountIds_me = MyAccountIds_me_InternalIdentity | MyAccountIds_me_User; +export type MyAccountIds_me = + | MyAccountIds_me_InternalIdentity + | MyAccountIds_me_User; export interface MyAccountIds { /** diff --git a/src/graphql/types/UserMemberships.ts b/src/graphql/types/UserMemberships.ts index e0898de..6b57cb1 100644 --- a/src/graphql/types/UserMemberships.ts +++ b/src/graphql/types/UserMemberships.ts @@ -8,26 +8,28 @@ // ==================================================== export interface UserMemberships_me_InternalIdentity { - __typename: "InternalIdentity" | "Service"; + __typename: 'InternalIdentity' | 'Service'; } export interface UserMemberships_me_User_memberships_account { - __typename: "Account"; + __typename: 'Account'; id: string; name: string; } export interface UserMemberships_me_User_memberships { - __typename: "UserMembership"; + __typename: 'UserMembership'; account: UserMemberships_me_User_memberships_account; } export interface UserMemberships_me_User { - __typename: "User"; + __typename: 'User'; memberships: UserMemberships_me_User_memberships[]; } -export type UserMemberships_me = UserMemberships_me_InternalIdentity | UserMemberships_me_User; +export type UserMemberships_me = + | UserMemberships_me_InternalIdentity + | UserMemberships_me_User; export interface UserMemberships { /** diff --git a/src/utils/createJavascriptTemplate.ts b/src/utils/createJavascriptTemplate.ts index 4cd88eb..a6ff1a0 100644 --- a/src/utils/createJavascriptTemplate.ts +++ b/src/utils/createJavascriptTemplate.ts @@ -1,36 +1,57 @@ import { resolve } from 'path'; -import { create } from "archiver"; +import { create } from 'archiver'; import { createWriteStream } from 'fs'; import { StateManager } from '../workbench/stateManager'; -import { generateJsVsCodeLaunch, generateJsgatewayPackageJson, generateJsGatewayTempalte, generateJsFederatedServerPackageJson, generateJsFederatedServerTemplate, generateCodeWorkspaceFile } from './exportFiles'; +import { + generateJsVsCodeLaunch, + generateJsgatewayPackageJson, + generateJsGatewayTempalte, + generateJsFederatedServerPackageJson, + generateJsFederatedServerTemplate, + generateCodeWorkspaceFile, +} from './exportFiles'; import { ApolloWorkbenchFile } from '../workbench/file-system/fileTypes'; export function createJavascriptTemplate(workbenchFile: ApolloWorkbenchFile) { - let port = StateManager.settings_startingServerPort; - const archive = create('zip', { zlib: { level: 9 } }); + let port = StateManager.settings_startingServerPort; + const archive = create('zip', { zlib: { level: 9 } }); - const fileName = workbenchFile.graphName.replace(/[\/|\\:*?"<>]/g, " "); - archive.append(generateJsVsCodeLaunch("Gateway"), { name: 'launch.json' }); - archive.append(generateJsgatewayPackageJson(), { name: 'package.json' }); - archive.append(generateJsGatewayTempalte(), { name: 'index.js' }); + const fileName = workbenchFile.graphName.replace(/[\/|\\:*?"<>]/g, ' '); + archive.append(generateJsVsCodeLaunch('Gateway'), { name: 'launch.json' }); + archive.append(generateJsgatewayPackageJson(), { name: 'package.json' }); + archive.append(generateJsGatewayTempalte(), { name: 'index.js' }); - for (var serviceName in workbenchFile.schemas) { - let serviceFolder = `services/${serviceName}`; - let serviceVsCodeFolder = `${serviceFolder}/.vscode`; - let serviceSrcFolder = `${serviceFolder}/src`; + for (var serviceName in workbenchFile.schemas) { + let serviceFolder = `services/${serviceName}`; + let serviceVsCodeFolder = `${serviceFolder}/.vscode`; + let serviceSrcFolder = `${serviceFolder}/src`; - archive.append(generateJsFederatedServerPackageJson(serviceName), { name: `${serviceFolder}/package.json` }); - archive.append(workbenchFile.schemas[serviceName].sdl, { name: `${serviceSrcFolder}/schema.graphql` }); - archive.append(generateJsFederatedServerTemplate(port, serviceName), { name: `${serviceSrcFolder}/index.js` }); - archive.append(generateJsVsCodeLaunch(serviceName), { name: `${serviceVsCodeFolder}/launch.json` }); + archive.append(generateJsFederatedServerPackageJson(serviceName), { + name: `${serviceFolder}/package.json`, + }); + archive.append(workbenchFile.schemas[serviceName].sdl, { + name: `${serviceSrcFolder}/schema.graphql`, + }); + archive.append(generateJsFederatedServerTemplate(port, serviceName), { + name: `${serviceSrcFolder}/index.js`, + }); + archive.append(generateJsVsCodeLaunch(serviceName), { + name: `${serviceVsCodeFolder}/launch.json`, + }); - port++; - } + port++; + } - archive.append(generateCodeWorkspaceFile(Object.keys(workbenchFile.schemas)), { name: 'gateway.code-workspace' }); + archive.append( + generateCodeWorkspaceFile(Object.keys(workbenchFile.schemas)), + { name: 'gateway.code-workspace' }, + ); - const destPath = resolve(StateManager.workspaceRoot ?? __dirname, `${fileName}-ts.zip`); - const output = createWriteStream(destPath); - archive.pipe(output); - archive.finalize(); -} \ No newline at end of file + const destPath = resolve( + StateManager.workspaceRoot ?? __dirname, + `${fileName}-ts.zip`, + ); + const output = createWriteStream(destPath); + archive.pipe(output); + archive.finalize(); +} diff --git a/src/utils/createTypescriptTemplate.ts b/src/utils/createTypescriptTemplate.ts index 1aa93c3..e16a008 100644 --- a/src/utils/createTypescriptTemplate.ts +++ b/src/utils/createTypescriptTemplate.ts @@ -1,38 +1,62 @@ import { resolve } from 'path'; -import { create } from "archiver"; +import { create } from 'archiver'; import { createWriteStream } from 'fs'; import { StateManager } from '../workbench/stateManager'; -import { generateTsVsCodeLaunch, generateTsConfig, generateTsgatewayPackageJson, generateTsGatewayTempalte, generateTsFederatedServerPackageJson, generateTsFederatedServerTemplate, generateCodeWorkspaceFile } from './exportFiles'; +import { + generateTsVsCodeLaunch, + generateTsConfig, + generateTsgatewayPackageJson, + generateTsGatewayTempalte, + generateTsFederatedServerPackageJson, + generateTsFederatedServerTemplate, + generateCodeWorkspaceFile, +} from './exportFiles'; import { ApolloWorkbenchFile } from '../workbench/file-system/fileTypes'; export function createTypescriptTemplate(workbenchFile: ApolloWorkbenchFile) { - let port = StateManager.settings_startingServerPort; - const archive = create('zip', { zlib: { level: 9 } }); + let port = StateManager.settings_startingServerPort; + const archive = create('zip', { zlib: { level: 9 } }); - const fileName = workbenchFile.graphName.replace(/[\/|\\:*?"<>]/g, " "); - archive.append(generateTsVsCodeLaunch("Gateway"), { name: 'launch.json' }); - archive.append(generateTsConfig(), { name: 'tsconfig.json' }); - archive.append(generateTsgatewayPackageJson(), { name: 'package.json' }); - archive.append(generateTsGatewayTempalte(), { name: 'index.ts' }); + const fileName = workbenchFile.graphName.replace(/[\/|\\:*?"<>]/g, ' '); + archive.append(generateTsVsCodeLaunch('Gateway'), { name: 'launch.json' }); + archive.append(generateTsConfig(), { name: 'tsconfig.json' }); + archive.append(generateTsgatewayPackageJson(), { name: 'package.json' }); + archive.append(generateTsGatewayTempalte(), { name: 'index.ts' }); - for (var serviceName in workbenchFile.schemas) { - let serviceFolder = `services/${serviceName}`; - let serviceVsCodeFolder = `${serviceFolder}/.vscode`; - let serviceSrcFolder = `${serviceFolder}/src`; + for (var serviceName in workbenchFile.schemas) { + let serviceFolder = `services/${serviceName}`; + let serviceVsCodeFolder = `${serviceFolder}/.vscode`; + let serviceSrcFolder = `${serviceFolder}/src`; - archive.append(generateTsConfig(), { name: `${serviceFolder}/tsconfig.json` }); - archive.append(generateTsFederatedServerPackageJson(serviceName), { name: `${serviceFolder}/package.json` }); - archive.append(workbenchFile.schemas[serviceName].sdl, { name: `${serviceSrcFolder}/schema.graphql` }); - archive.append(generateTsFederatedServerTemplate(port, serviceName), { name: `${serviceSrcFolder}/index.ts` }); - archive.append(generateTsVsCodeLaunch(serviceName), { name: `${serviceVsCodeFolder}/launch.json` }); + archive.append(generateTsConfig(), { + name: `${serviceFolder}/tsconfig.json`, + }); + archive.append(generateTsFederatedServerPackageJson(serviceName), { + name: `${serviceFolder}/package.json`, + }); + archive.append(workbenchFile.schemas[serviceName].sdl, { + name: `${serviceSrcFolder}/schema.graphql`, + }); + archive.append(generateTsFederatedServerTemplate(port, serviceName), { + name: `${serviceSrcFolder}/index.ts`, + }); + archive.append(generateTsVsCodeLaunch(serviceName), { + name: `${serviceVsCodeFolder}/launch.json`, + }); - port++; - } + port++; + } - archive.append(generateCodeWorkspaceFile(Object.keys(workbenchFile.schemas)), { name: 'gateway.code-workspace' }); + archive.append( + generateCodeWorkspaceFile(Object.keys(workbenchFile.schemas)), + { name: 'gateway.code-workspace' }, + ); - const destPath = resolve(StateManager.workspaceRoot ?? __dirname, `${fileName}-ts.zip`); - const output = createWriteStream(destPath); - archive.pipe(output); - archive.finalize(); -} \ No newline at end of file + const destPath = resolve( + StateManager.workspaceRoot ?? __dirname, + `${fileName}-ts.zip`, + ); + const output = createWriteStream(destPath); + archive.pipe(output); + archive.finalize(); +} diff --git a/src/utils/exportFiles.ts b/src/utils/exportFiles.ts index 2aa0ced..ace6200 100644 --- a/src/utils/exportFiles.ts +++ b/src/utils/exportFiles.ts @@ -1,169 +1,186 @@ -import { StateManager } from "../workbench/stateManager"; -import { extractEntityNames } from "../graphql/parsers/schemaParser"; +import { StateManager } from '../workbench/stateManager'; +import { extractEntityNames } from '../graphql/parsers/schemaParser'; export function generateTsConfig() { - return JSON.stringify({ - "compilerOptions": { - "module": "commonjs", - "target": "ES2019", - "lib": ["ES2019"], - "outDir": "dist", - "sourceMap": true, - "strict": true, - "rootDir": "src", - "noImplicitAny": false, - "esModuleInterop": true, - "skipLibCheck": true - }, - "exclude": ["node_modules"] - }) + return JSON.stringify({ + compilerOptions: { + module: 'commonjs', + target: 'ES2019', + lib: ['ES2019'], + outDir: 'dist', + sourceMap: true, + strict: true, + rootDir: 'src', + noImplicitAny: false, + esModuleInterop: true, + skipLibCheck: true, + }, + exclude: ['node_modules'], + }); } export function generateCodeWorkspaceFile(serviceNames: string[]) { - let codeWorkspaceFile = { - folders: new Array(), - launch: { - configurations: new Array(), - compounds: [ - { - name: "Launch All", - configurations: new Array() - } - ] + let codeWorkspaceFile = { + folders: new Array(), + launch: { + configurations: new Array(), + compounds: [ + { + name: 'Launch All', + configurations: new Array(), }, - tasks: { - version: "2.0.0", - tasks: new Array() - } - } + ], + }, + tasks: { + version: '2.0.0', + tasks: new Array(), + }, + }; + codeWorkspaceFile.tasks.tasks.push({ + label: 'setup', + dependsOn: ['setup gateway'], + runOptions: { runOn: 'folderOpen' }, + }); + codeWorkspaceFile.tasks.tasks.push({ + label: `setup gateway`, + type: 'shell', + command: 'npm i', + options: { cwd: `\${workspaceRoot:Gateway}` }, + }); + codeWorkspaceFile.folders.push({ name: `Gateway`, path: `gateway` }); + + serviceNames.map((serviceName) => { + let codeServiceName = `Service - ${serviceName}`; + codeWorkspaceFile.tasks.tasks[0].dependsOn.push(`setup ${serviceName}`); codeWorkspaceFile.tasks.tasks.push({ - label: "setup", - dependsOn: ['setup gateway'], - runOptions: { runOn: "folderOpen" } - }) - codeWorkspaceFile.tasks.tasks.push({ - label: `setup gateway`, - type: "shell", - command: "npm i", - options: { "cwd": `\${workspaceRoot:Gateway}` } + label: `setup ${serviceName}`, + type: 'shell', + command: 'npm i', + options: { cwd: `\${workspaceRoot:${codeServiceName}}` }, }); - codeWorkspaceFile.folders.push({ name: `Gateway`, path: `gateway` }); - - serviceNames.map(serviceName => { - let codeServiceName = `Service - ${serviceName}`; - codeWorkspaceFile.tasks.tasks[0].dependsOn.push(`setup ${serviceName}`); - codeWorkspaceFile.tasks.tasks.push({ - label: `setup ${serviceName}`, - type: "shell", - command: "npm i", - options: { "cwd": `\${workspaceRoot:${codeServiceName}}` } - }); - codeWorkspaceFile.folders.push({ name: codeServiceName, path: `services/${serviceName}` }); - codeWorkspaceFile.launch.compounds[0].configurations.push(`Launch ${serviceName}`); - }) + codeWorkspaceFile.folders.push({ + name: codeServiceName, + path: `services/${serviceName}`, + }); + codeWorkspaceFile.launch.compounds[0].configurations.push( + `Launch ${serviceName}`, + ); + }); - codeWorkspaceFile.launch.compounds[0].configurations.push(`Launch Gateway`); + codeWorkspaceFile.launch.compounds[0].configurations.push(`Launch Gateway`); - return JSON.stringify(codeWorkspaceFile); + return JSON.stringify(codeWorkspaceFile); } let federatedServerPackageJson: any = { - "scripts": { - "local-schema-validation": "apollo service:check --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --localSchemaFile=src/schema.graphql", - "local-schema-push-local": "apollo service:push --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --serviceURL=$(grep SERVICE_URL .env | cut -d '=' -f2) --localSchemaFile=src/schema.graphql", - "start": "node src/index.js" - }, - "main": "src/index.js", - "dependencies": { - "@apollo/federation": "latest", - "apollo-datasource": "latest", - "apollo-server": "latest" - }, - "devDependencies": { - "apollo": "latest" - } -} + scripts: { + 'local-schema-validation': + "apollo service:check --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --localSchemaFile=src/schema.graphql", + 'local-schema-push-local': + "apollo service:push --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --serviceURL=$(grep SERVICE_URL .env | cut -d '=' -f2) --localSchemaFile=src/schema.graphql", + start: 'node src/index.js', + }, + main: 'src/index.js', + dependencies: { + '@apollo/federation': 'latest', + 'apollo-datasource': 'latest', + 'apollo-server': 'latest', + }, + devDependencies: { + apollo: 'latest', + }, +}; export function generateJsFederatedServerPackageJson(serviceName: string) { - federatedServerPackageJson.name = serviceName; - return JSON.stringify(federatedServerPackageJson); + federatedServerPackageJson.name = serviceName; + return JSON.stringify(federatedServerPackageJson); } export function generateTsFederatedServerPackageJson(serviceName: string) { - let base = federatedServerPackageJson; - base.name = serviceName; - base.devDependencies = { - "@types/node": "latest", - "@types/node-fetch": "latest", - "apollo": "latest", - "typescript": "latest", - "copyfiles": "2.3.0" - } - base.scripts = { - "local-schema-validation": "apollo service:check --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --localSchemaFile=src/schema.graphql", - "local-schema-push-local": "apollo service:push --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --serviceURL=$(grep SERVICE_URL .env | cut -d '=' -f2) --localSchemaFile=src/schema.graphql", - "copy-schema": "copyfiles -u 1 src/schema.graphql dist", - "postinstall": "npm run copy-schema && tsc --build tsconfig.json", - "start": "node dist/index.js", - "watch": "tsc --build tsconfig.json --watch" - }; + let base = federatedServerPackageJson; + base.name = serviceName; + base.devDependencies = { + '@types/node': 'latest', + '@types/node-fetch': 'latest', + apollo: 'latest', + typescript: 'latest', + copyfiles: '2.3.0', + }; + base.scripts = { + 'local-schema-validation': + "apollo service:check --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --localSchemaFile=src/schema.graphql", + 'local-schema-push-local': + "apollo service:push --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2) --serviceName=${serviceName} --serviceURL=$(grep SERVICE_URL .env | cut -d '=' -f2) --localSchemaFile=src/schema.graphql", + 'copy-schema': 'copyfiles -u 1 src/schema.graphql dist', + postinstall: 'npm run copy-schema && tsc --build tsconfig.json', + start: 'node dist/index.js', + watch: 'tsc --build tsconfig.json --watch', + }; - return JSON.stringify(base); + return JSON.stringify(base); } let gatewayPackageJson: any = { - "name": "graphql-gateway", - "scripts": { - "list-services": "apollo service:list --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2)", - "start": "node src/index.js" - }, - "main": "src/index.js", - "dependencies": { - "@apollo/gateway": "latest", - "apollo-server": "latest" - }, - "devDependencies": { - "apollo": "latest", - "dotenv": "latest" - } -} + name: 'graphql-gateway', + scripts: { + 'list-services': + "apollo service:list --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2)", + start: 'node src/index.js', + }, + main: 'src/index.js', + dependencies: { + '@apollo/gateway': 'latest', + 'apollo-server': 'latest', + }, + devDependencies: { + apollo: 'latest', + dotenv: 'latest', + }, +}; export function generateJsgatewayPackageJson() { - return JSON.stringify(gatewayPackageJson); + return JSON.stringify(gatewayPackageJson); } export function generateTsgatewayPackageJson() { - let base = gatewayPackageJson; - base.devDependencies = { - "@types/node": "latest", - "@types/node-fetch": "latest", - "apollo": "latest", - "typescript": "latest", - "dotenv": "latest" - } - base.scripts = { - "list-services": "apollo service:list --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2)", - "postinstall": "tsc --build tsconfig.json", - "start": "node dist/index.js", - "watch": "tsc --build tsconfig.json --watch" - }; + let base = gatewayPackageJson; + base.devDependencies = { + '@types/node': 'latest', + '@types/node-fetch': 'latest', + apollo: 'latest', + typescript: 'latest', + dotenv: 'latest', + }; + base.scripts = { + 'list-services': + "apollo service:list --variant=$(grep APOLLO_GRAPH_VARIANT .env | cut -d '=' -f2)", + postinstall: 'tsc --build tsconfig.json', + start: 'node dist/index.js', + watch: 'tsc --build tsconfig.json --watch', + }; - return JSON.stringify(base); + return JSON.stringify(base); } export function generateJsFederatedResolvers(schema: string) { - let resolvers = 'const resolvers = {\n'; - let entities = extractEntityNames(schema); - entities.forEach(entity => resolvers += `\t${entity}: {\n\t\t__resolveReference(parent, args) {\n\t\t\treturn { ...parent }\n\t\t}\n\t}\n`); - resolvers += '}\nmodule.exports = resolvers;'; + let resolvers = 'const resolvers = {\n'; + let entities = extractEntityNames(schema); + entities.forEach( + (entity) => + (resolvers += `\t${entity}: {\n\t\t__resolveReference(parent, args) {\n\t\t\treturn { ...parent }\n\t\t}\n\t}\n`), + ); + resolvers += '}\nmodule.exports = resolvers;'; - return resolvers; + return resolvers; } -export function generateJsFederatedServerTemplate(port: number, serviceName: string) { - return `const { resolve } = require('path'); +export function generateJsFederatedServerTemplate( + port: number, + serviceName: string, +) { + return `const { resolve } = require('path'); const { readFileSync } = require('fs'); const { gql, ApolloServer, addMockFunctionsToSchema } = require('apollo-server'); const { buildFederatedSchema } = require('@apollo/federation'); @@ -182,11 +199,14 @@ const server = new ApolloServer({ const port = process.env.PORT || ${port}; server.listen({ port }).then(({ url }) => { console.log(\`🚀 ${serviceName} service ready at \${url}\`); -});` +});`; } -export function generateTsFederatedServerTemplate(port: number, serviceName: string) { - return `import { resolve } from 'path'; +export function generateTsFederatedServerTemplate( + port: number, + serviceName: string, +) { + return `import { resolve } from 'path'; import { readFileSync } from 'fs'; import { gql, ApolloServer } from 'apollo-server'; import { buildFederatedSchema } from '@apollo/federation'; @@ -202,11 +222,11 @@ const server = new ApolloServer({ const port = process.env.PORT || ${port}; server.listen({ port }).then(({ url }) => { console.log(\`🚀 ${serviceName} service ready at \${url}\`); -});` +});`; } export function generateJsGatewayTempalte() { - return `const { ApolloServer } = require('apollo-server'); + return `const { ApolloServer } = require('apollo-server'); const { ApolloGateway } = require('@apollo/gateway'); const isProd = process.env.NODE_ENV === "production"; @@ -221,11 +241,11 @@ const server = new ApolloServer({ const port = process.env.PORT ||4000; server.listen({ port }).then(({ url }) => { console.log(\`🚀 Gateway ready at \${url}\`); -});` +});`; } export function generateTsGatewayTempalte() { - return `import { ApolloServer } from 'apollo-server'; + return `import { ApolloServer } from 'apollo-server'; import { ApolloGateway } from '@apollo/gateway'; const isProd = process.env.NODE_ENV === "production"; @@ -240,37 +260,35 @@ const server = new ApolloServer({ const port = process.env.PORT || ${StateManager.settings_gatewayServerPort}; server.listen({ port }).then(({ url }) => { console.log(\`🚀 Gateway ready at \${url}\`); -});` +});`; } export function generateJsVsCodeLaunch(serviceName: string) { - return JSON.stringify({ - version: "0.2.0", - configurations: [ - { - type: "node", - request: "launch", - name: `Launch ${serviceName}`, - program: "${workspaceFolder}/src/index.js" - } - ] - }); + return JSON.stringify({ + version: '0.2.0', + configurations: [ + { + type: 'node', + request: 'launch', + name: `Launch ${serviceName}`, + program: '${workspaceFolder}/src/index.js', + }, + ], + }); } export function generateTsVsCodeLaunch(serviceName: string) { - return JSON.stringify({ - version: "0.2.0", - configurations: [ - { - type: "node", - request: "launch", - name: `Launch ${serviceName}`, - program: "${workspaceFolder}/src/index.ts", - outFiles: [ - "${workspaceFolder}/dist/**/*.js" - ], - preLaunchTask: "tsc: build - tsconfig.json" - } - ] - }); -} \ No newline at end of file + return JSON.stringify({ + version: '0.2.0', + configurations: [ + { + type: 'node', + request: 'launch', + name: `Launch ${serviceName}`, + program: '${workspaceFolder}/src/index.ts', + outFiles: ['${workspaceFolder}/dist/**/*.js'], + preLaunchTask: 'tsc: build - tsconfig.json', + }, + ], + }); +} diff --git a/src/workbench/docProviders.ts b/src/workbench/docProviders.ts index cb05cab..539f54d 100644 --- a/src/workbench/docProviders.ts +++ b/src/workbench/docProviders.ts @@ -1,28 +1,37 @@ -import { readFileSync } from "fs"; -import { getOperationAST, parse, print } from "graphql"; -import path from "path"; -import { TextDocumentContentProvider, Uri } from "vscode"; +import { readFileSync } from 'fs'; +import { getOperationAST, parse, print } from 'graphql'; +import path from 'path'; +import { TextDocumentContentProvider, Uri } from 'vscode'; export class GettingStartedDocProvider implements TextDocumentContentProvider { - static scheme: string = 'getting-started'; - provideTextDocumentContent(uri: Uri): string { - let gettingStartedPath = path.join(__filename, '..', '..', '..', 'media', 'getting-started', uri.path) - return readFileSync(gettingStartedPath, { encoding: 'utf-8' }); - } + static scheme: string = 'getting-started'; + provideTextDocumentContent(uri: Uri): string { + let gettingStartedPath = path.join( + __filename, + '..', + '..', + '..', + 'media', + 'getting-started', + uri.path, + ); + return readFileSync(gettingStartedPath, { encoding: 'utf-8' }); + } } -export class ApolloStudioOperationsProvider implements TextDocumentContentProvider { - static scheme: string = 'apollo-studio-operations'; - static Uri(operationName: string, document: string): Uri { - return Uri.parse(`${ApolloStudioOperationsProvider.scheme}:${operationName}.graphql?${document}`); - } - provideTextDocumentContent(uri: Uri): string { - let operationName = uri.path.split('.graphql')[0]; - let doc = parse(uri.query); - let ast = getOperationAST(doc, operationName); - if (ast) - return print(ast); - return uri.query; - } +export class ApolloStudioOperationsProvider + implements TextDocumentContentProvider { + static scheme: string = 'apollo-studio-operations'; + static Uri(operationName: string, document: string): Uri { + return Uri.parse( + `${ApolloStudioOperationsProvider.scheme}:${operationName}.graphql?${document}`, + ); + } + provideTextDocumentContent(uri: Uri): string { + let operationName = uri.path.split('.graphql')[0]; + let doc = parse(uri.query); + let ast = getOperationAST(doc, operationName); + if (ast) return print(ast); + return uri.query; + } } - diff --git a/src/workbench/federationCodeActionProvider.ts b/src/workbench/federationCodeActionProvider.ts index 70179b7..120cb8e 100644 --- a/src/workbench/federationCodeActionProvider.ts +++ b/src/workbench/federationCodeActionProvider.ts @@ -1,35 +1,48 @@ -import { CodeAction, CodeActionKind, CodeActionProvider, CodeActionContext, Range, TextDocument } from "vscode"; +import { + CodeAction, + CodeActionKind, + CodeActionProvider, + CodeActionContext, + Range, + TextDocument, +} from 'vscode'; export class FederationCodeActionProvider implements CodeActionProvider { - public provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext): CodeAction[] | undefined { - let code = context.diagnostics[0]?.code as string; - let selectors: CodeAction[] = []; - if (code.includes('makeArray')) { - let line = document.lineAt(range.start.line); - let trimmedText = line.text.trim(); - if (trimmedText != '[' && trimmedText != '[]' && trimmedText != '[ ]') { - let selector = new CodeAction("Make array", CodeActionKind.QuickFix); - selector.command = { - command: "current-workbench-schemas.makeSchemaDocTextRangeArray", - title: "Make into array", - arguments: [document, range] - }; + public provideCodeActions( + document: TextDocument, + range: Range, + context: CodeActionContext, + ): CodeAction[] | undefined { + let code = context.diagnostics[0]?.code as string; + let selectors: CodeAction[] = []; + if (code.includes('makeArray')) { + let line = document.lineAt(range.start.line); + let trimmedText = line.text.trim(); + if (trimmedText != '[' && trimmedText != '[]' && trimmedText != '[ ]') { + let selector = new CodeAction('Make array', CodeActionKind.QuickFix); + selector.command = { + command: 'current-workbench-schemas.makeSchemaDocTextRangeArray', + title: 'Make into array', + arguments: [document, range], + }; - selectors.push(selector); - } - } - if (code.includes('deleteRange')) { - let selector = new CodeAction("Delete this selection", CodeActionKind.QuickFix); - selector.command = { - command: "current-workbench-schemas.deleteSchemaDocTextRange", - title: "Delete this selection", - arguments: [document, range] - }; - - selectors.push(selector); - } + selectors.push(selector); + } + } + if (code.includes('deleteRange')) { + let selector = new CodeAction( + 'Delete this selection', + CodeActionKind.QuickFix, + ); + selector.command = { + command: 'current-workbench-schemas.deleteSchemaDocTextRange', + title: 'Delete this selection', + arguments: [document, range], + }; - if (selectors.length > 0) - return selectors; + selectors.push(selector); } -} \ No newline at end of file + + if (selectors.length > 0) return selectors; + } +} diff --git a/src/workbench/federationCompletionProvider.ts b/src/workbench/federationCompletionProvider.ts index e05aa60..c204d3a 100644 --- a/src/workbench/federationCompletionProvider.ts +++ b/src/workbench/federationCompletionProvider.ts @@ -1,204 +1,250 @@ -import { CancellationToken, CompletionItem, CompletionItemKind, MarkdownString, Position, SnippetString, TextDocument, window, workspace } from "vscode"; -import { getServiceAvailableTypes } from "../graphql/parsers/schemaParser"; -import { StateManager } from "./stateManager"; -import { getAutocompleteSuggestions } from "@apollographql/graphql-language-service-interface"; +import { + CancellationToken, + CompletionItem, + CompletionItemKind, + MarkdownString, + Position, + SnippetString, + TextDocument, + window, + workspace, +} from 'vscode'; +import { getServiceAvailableTypes } from '../graphql/parsers/schemaParser'; +import { StateManager } from './stateManager'; +import { getAutocompleteSuggestions } from '@apollographql/graphql-language-service-interface'; export interface FieldWithType { - field: string; - type?: string; + field: string; + type?: string; } //Extremely basic/naive implementation to find extendable entities // This should be in language server export const federationCompletionProvider = { - async provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken) { - //Only provide completion items for schemas open in workbench - let uri = document.uri; - let completionItems = new Array(); - - if (uri.scheme == 'workbench' && uri.path.includes('/subgraphs')) { - let line = document.lineAt(position.line); - let lineText = line.text; - let serviceName = document.uri.query; - - if (lineText && serviceName) { - //If not undefined, we're inside a word/something and shouldn't return anything - let trimmedText = lineText.trim(); - let character = trimmedText.charAt(trimmedText.length - 1); - if (character == ':') { - let completionTypes = await getServiceAvailableTypes(serviceName, uri.path.split('/subgraphs')[0]); - for (var i = 0; i < completionTypes.length; i++) { - let typeName = completionTypes[i]; - let details = ''; - let documentation = new MarkdownString(); - let completionKind = CompletionItemKind.Value; - - if (typeName.includes(':')) { - let typeSplit = typeName.split(':'); - if (typeSplit[0] == 'I') { - details = `Interface ${typeSplit[1]}`; - completionKind = CompletionItemKind.Interface; - documentation.appendText('To learn more about interfaces, click [here](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#interface-type).'); - } else if (typeSplit[0] == 'O') { - details = `Object Types ${typeSplit[1]}`; - completionKind = CompletionItemKind.Class; - documentation.appendText('To learn more about object types, click [here](https://www.apollographql.com/docs/apollo-server/schema/schema/#object-types).'); - } else if (typeSplit[0] == 'S') { - details = `Scalar Types ${typeSplit[1]}`; - completionKind = CompletionItemKind.Struct; - documentation.appendText('To learn more about object types, click [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars).'); - } - else if (typeSplit[0] == 'E') { - details = `Enum Types ${typeSplit[1]}`; - completionKind = CompletionItemKind.Enum; - documentation.appendText('To learn more about object types, click [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#enums).'); - } - - - typeName = typeSplit[1]; - } else { - documentation.appendText(`To learn more about GraphQL's default scalar types, click [here](https://www.apollographql.com/docs/apollo-server/schema/schema/#scalar-types).`); - } - - let completionItem = new CompletionItem(typeName, completionKind); - completionItem.insertText = typeName; - completionItem.detail = details; - completionItem.documentation = documentation; - completionItems.push(completionItem); - } - } - } - else { - //Add federation items that can be extended - - let extendableTypes = StateManager.instance.workspaceState_selectedWorkbenchAvailableEntities; - // await extractDefinedEntitiesByService(); - - for (var sn in extendableTypes) - if (sn != serviceName) - extendableTypes[sn].map(({ type, keys }) => { - Object.keys(keys).forEach(key => { - completionItems.push(new FederationEntityExtensionItem(key, type, keys[key], sn)) - }) - }); - - //Add default items for creating new entity/type/interface - completionItems.push(new ObjectTypeCompletionItem()); - completionItems.push(new InterfaceCompletionItem()); - completionItems.push(new EntityObjectTypeCompletionItem()); - } - } - else if (uri.scheme == 'workbench' && uri.path.includes('/queries/')) { - let schema = StateManager.instance.workspaceState_schema; - if (schema) { - let query = document.getText(); - let suggestions = getAutocompleteSuggestions(schema, query, position); - if (suggestions.length > 0) { - suggestions.forEach(ci => completionItems.push(new QueryCompletionItem(ci))); - } + async provideCompletionItems( + document: TextDocument, + position: Position, + token: CancellationToken, + ) { + //Only provide completion items for schemas open in workbench + let uri = document.uri; + let completionItems = new Array(); + + if (uri.scheme == 'workbench' && uri.path.includes('/subgraphs')) { + let line = document.lineAt(position.line); + let lineText = line.text; + let serviceName = document.uri.query; + + if (lineText && serviceName) { + //If not undefined, we're inside a word/something and shouldn't return anything + let trimmedText = lineText.trim(); + let character = trimmedText.charAt(trimmedText.length - 1); + if (character == ':') { + let completionTypes = await getServiceAvailableTypes( + serviceName, + uri.path.split('/subgraphs')[0], + ); + for (var i = 0; i < completionTypes.length; i++) { + let typeName = completionTypes[i]; + let details = ''; + let documentation = new MarkdownString(); + let completionKind = CompletionItemKind.Value; + + if (typeName.includes(':')) { + let typeSplit = typeName.split(':'); + if (typeSplit[0] == 'I') { + details = `Interface ${typeSplit[1]}`; + completionKind = CompletionItemKind.Interface; + documentation.appendText( + 'To learn more about interfaces, click [here](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#interface-type).', + ); + } else if (typeSplit[0] == 'O') { + details = `Object Types ${typeSplit[1]}`; + completionKind = CompletionItemKind.Class; + documentation.appendText( + 'To learn more about object types, click [here](https://www.apollographql.com/docs/apollo-server/schema/schema/#object-types).', + ); + } else if (typeSplit[0] == 'S') { + details = `Scalar Types ${typeSplit[1]}`; + completionKind = CompletionItemKind.Struct; + documentation.appendText( + 'To learn more about object types, click [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars).', + ); + } else if (typeSplit[0] == 'E') { + details = `Enum Types ${typeSplit[1]}`; + completionKind = CompletionItemKind.Enum; + documentation.appendText( + 'To learn more about object types, click [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#enums).', + ); + } + + typeName = typeSplit[1]; } else { - completionItems.push(new NoValidSchema()); + documentation.appendText( + `To learn more about GraphQL's default scalar types, click [here](https://www.apollographql.com/docs/apollo-server/schema/schema/#scalar-types).`, + ); } - } - if (completionItems.length > 0) return completionItems; + let completionItem = new CompletionItem(typeName, completionKind); + completionItem.insertText = typeName; + completionItem.detail = details; + completionItem.documentation = documentation; + completionItems.push(completionItem); + } + } + } else { + //Add federation items that can be extended + + let extendableTypes = + StateManager.instance + .workspaceState_selectedWorkbenchAvailableEntities; + // await extractDefinedEntitiesByService(); + + for (var sn in extendableTypes) + if (sn != serviceName) + extendableTypes[sn].map(({ type, keys }) => { + Object.keys(keys).forEach((key) => { + completionItems.push( + new FederationEntityExtensionItem(key, type, keys[key], sn), + ); + }); + }); + + //Add default items for creating new entity/type/interface + completionItems.push(new ObjectTypeCompletionItem()); + completionItems.push(new InterfaceCompletionItem()); + completionItems.push(new EntityObjectTypeCompletionItem()); + } + } else if (uri.scheme == 'workbench' && uri.path.includes('/queries/')) { + let schema = StateManager.instance.workspaceState_schema; + if (schema) { + let query = document.getText(); + let suggestions = getAutocompleteSuggestions(schema, query, position); + if (suggestions.length > 0) { + suggestions.forEach((ci) => + completionItems.push(new QueryCompletionItem(ci)), + ); + } + } else { + completionItems.push(new NoValidSchema()); + } } -} + + if (completionItems.length > 0) return completionItems; + }, +}; class NoValidSchema extends CompletionItem { - constructor() { - super("No composed schema in workbench", CompletionItemKind.Constant); - this.insertText = ""; - } + constructor() { + super('No composed schema in workbench', CompletionItemKind.Constant); + this.insertText = ''; + } } export class QueryCompletionItem extends CompletionItem { - constructor(ci: any) { - super(ci.label, CompletionItemKind.Constant); - this.detail = ci.detail; - this.insertText = ci.label; - this.documentation = ci.documentation - } + constructor(ci: any) { + super(ci.label, CompletionItemKind.Constant); + this.detail = ci.detail; + this.insertText = ci.label; + this.documentation = ci.documentation; + } } export class EntityObjectTypeCompletionItem extends CompletionItem { - constructor() { - super('Entity Object type', CompletionItemKind.Snippet); - this.sortText = 'b'; - - let comments = `"""\nThis is an Entity, docs:https://www.apollographql.com/docs/federation/entities/\nYou will need to define a __resolveReference resolver for the type you define, docs: https://www.apollographql.com/docs/federation/entities/#resolving\n"""`; - let insertSnippet = new SnippetString(`${comments}\ntype `); - insertSnippet.appendTabstop(1); - insertSnippet.appendText(` @key(fields:"id") {\n\tid:ID!\n}`); - - this.detail = "Define a new Entity Object Type"; - this.insertText = insertSnippet; - this.documentation = new MarkdownString(`To learn more about entities, click [here](https://www.apollographql.com/docs/federation/entities/).`); - } + constructor() { + super('Entity Object type', CompletionItemKind.Snippet); + this.sortText = 'b'; + + let comments = `"""\nThis is an Entity, docs:https://www.apollographql.com/docs/federation/entities/\nYou will need to define a __resolveReference resolver for the type you define, docs: https://www.apollographql.com/docs/federation/entities/#resolving\n"""`; + let insertSnippet = new SnippetString(`${comments}\ntype `); + insertSnippet.appendTabstop(1); + insertSnippet.appendText(` @key(fields:"id") {\n\tid:ID!\n}`); + + this.detail = 'Define a new Entity Object Type'; + this.insertText = insertSnippet; + this.documentation = new MarkdownString( + `To learn more about entities, click [here](https://www.apollographql.com/docs/federation/entities/).`, + ); + } } export class ObjectTypeCompletionItem extends CompletionItem { - constructor() { - super('Object type', CompletionItemKind.Snippet); - this.sortText = 'b'; - - let insertSnippet = new SnippetString('"""\nHere are some helpful details about your type\n"""\ntype '); - insertSnippet.appendTabstop(1); - insertSnippet.appendText(` {\n\n}`); - - this.detail = "Define a new Object Type"; - this.insertText = insertSnippet; - this.documentation = new MarkdownString(`To learn more about Object Types, click [here](https://www.apollographql.com/docs/apollo-server/schema/schema/#object-types).`); - } + constructor() { + super('Object type', CompletionItemKind.Snippet); + this.sortText = 'b'; + + let insertSnippet = new SnippetString( + '"""\nHere are some helpful details about your type\n"""\ntype ', + ); + insertSnippet.appendTabstop(1); + insertSnippet.appendText(` {\n\n}`); + + this.detail = 'Define a new Object Type'; + this.insertText = insertSnippet; + this.documentation = new MarkdownString( + `To learn more about Object Types, click [here](https://www.apollographql.com/docs/apollo-server/schema/schema/#object-types).`, + ); + } } export class InterfaceCompletionItem extends CompletionItem { - constructor() { - super('Interface', CompletionItemKind.Snippet); - this.sortText = 'b'; - - let insertSnippet = new SnippetString('interface '); - insertSnippet.appendTabstop(1); - insertSnippet.appendText(` {\nHere are some helpful details about your interface\n}`); - - this.detail = "Define a new Interface"; - this.insertText = insertSnippet; - this.documentation = new MarkdownString(`To learn more about interfaces, click [here](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#interface-type).`); - } + constructor() { + super('Interface', CompletionItemKind.Snippet); + this.sortText = 'b'; + + let insertSnippet = new SnippetString('interface '); + insertSnippet.appendTabstop(1); + insertSnippet.appendText( + ` {\nHere are some helpful details about your interface\n}`, + ); + + this.detail = 'Define a new Interface'; + this.insertText = insertSnippet; + this.documentation = new MarkdownString( + `To learn more about interfaces, click [here](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#interface-type).`, + ); + } } export class FederationEntityExtensionItem extends CompletionItem { - constructor(key: string, typeToExtend: string, keyFields: FieldWithType[], owningServiceName: string) { - super(`extend ${typeToExtend} by "${key}"`, CompletionItemKind.Reference); - this.sortText = 'a'; - - let insertSnippet = new SnippetString(`extend type `); - let typeExtensionCodeBlock = `extend type ${typeToExtend} @key(fields:"${key}") {\n`; - - insertSnippet.appendVariable("typeToExtend", typeToExtend); - insertSnippet.appendText(' @key(fields:"'); - insertSnippet.appendVariable("key", key); - insertSnippet.appendText('") {\n'); - - for (var i = 0; i < keyFields.length; i++) { - let keyField = keyFields[i]; - let fieldLine = `\t${keyField.field}: ${keyField.type} @external\n`; - typeExtensionCodeBlock += fieldLine; - insertSnippet.appendText(fieldLine); - } - - insertSnippet.appendText(`\t`); - insertSnippet.appendTabstop(1); - typeExtensionCodeBlock += '}'; - insertSnippet.appendText(`\n}`); - - let mkdDocs = new MarkdownString(); - mkdDocs.appendCodeblock(typeExtensionCodeBlock, 'graphql'); - mkdDocs.appendText(`Owning Service: ${owningServiceName}\n`); - mkdDocs.appendMarkdown(`To learn more about extending entities, click [here](https://www.apollographql.com/docs/federation/entities/#extending).`); - - this.documentation = mkdDocs; - this.detail = `Extend entity ${typeToExtend}`; - this.insertText = insertSnippet; + constructor( + key: string, + typeToExtend: string, + keyFields: FieldWithType[], + owningServiceName: string, + ) { + super(`extend ${typeToExtend} by "${key}"`, CompletionItemKind.Reference); + this.sortText = 'a'; + + let insertSnippet = new SnippetString(`extend type `); + let typeExtensionCodeBlock = `extend type ${typeToExtend} @key(fields:"${key}") {\n`; + + insertSnippet.appendVariable('typeToExtend', typeToExtend); + insertSnippet.appendText(' @key(fields:"'); + insertSnippet.appendVariable('key', key); + insertSnippet.appendText('") {\n'); + + for (var i = 0; i < keyFields.length; i++) { + let keyField = keyFields[i]; + let fieldLine = `\t${keyField.field}: ${keyField.type} @external\n`; + typeExtensionCodeBlock += fieldLine; + insertSnippet.appendText(fieldLine); } -} \ No newline at end of file + + insertSnippet.appendText(`\t`); + insertSnippet.appendTabstop(1); + typeExtensionCodeBlock += '}'; + insertSnippet.appendText(`\n}`); + + let mkdDocs = new MarkdownString(); + mkdDocs.appendCodeblock(typeExtensionCodeBlock, 'graphql'); + mkdDocs.appendText(`Owning Service: ${owningServiceName}\n`); + mkdDocs.appendMarkdown( + `To learn more about extending entities, click [here](https://www.apollographql.com/docs/federation/entities/#extending).`, + ); + + this.documentation = mkdDocs; + this.detail = `Extend entity ${typeToExtend}`; + this.insertText = insertSnippet; + } +} diff --git a/src/workbench/file-system/WorkbenchUri.ts b/src/workbench/file-system/WorkbenchUri.ts index ca7655d..83d515e 100644 --- a/src/workbench/file-system/WorkbenchUri.ts +++ b/src/workbench/file-system/WorkbenchUri.ts @@ -1,49 +1,80 @@ -import { Uri } from "vscode"; -import { resolve } from "path"; -import { StateManager } from "../stateManager"; -import { FileProvider } from "./fileProvider"; +import { Uri } from 'vscode'; +import { resolve } from 'path'; +import { StateManager } from '../stateManager'; +import { FileProvider } from './fileProvider'; export enum WorkbenchUriType { - SCHEMAS, - SCHEMAS_SETTINGS, - QUERIES, - QUERY_PLANS, - MOCKS, - SUPERGRAPH_SCHEMA, - SUPERGRAPH_API_SCHEMA + SCHEMAS, + SCHEMAS_SETTINGS, + QUERIES, + QUERY_PLANS, + MOCKS, + SUPERGRAPH_SCHEMA, + SUPERGRAPH_API_SCHEMA, } export class WorkbenchUri { - static supergraph(path: string, name?: string, type: WorkbenchUriType = WorkbenchUriType.SUPERGRAPH_SCHEMA): Uri { - switch (type) { - case WorkbenchUriType.SCHEMAS: - let subgraphPath = resolve(path, 'subgraphs', `${name}.graphql`); - if (subgraphPath.includes('C:')) subgraphPath = subgraphPath.slice(2).replace(/\\/g, '/'); - return Uri.parse(`workbench:${subgraphPath}?${name}`); - case WorkbenchUriType.SCHEMAS_SETTINGS: - let schemaSettingPath = resolve(path, 'subgraph-settings', `${name}-settings.json`); - if (schemaSettingPath.includes('C:')) schemaSettingPath = schemaSettingPath.slice(2).replace(/\\/g, '/'); - return Uri.parse(`workbench:${schemaSettingPath}?${name}`); - case WorkbenchUriType.QUERIES: - let queryPath = resolve(path, 'queries', `${name}.graphql`); - if (queryPath.includes('C:')) queryPath = queryPath.slice(2).replace(/\\/g, '/'); - return Uri.parse(`workbench:${queryPath}?${name}`); - case WorkbenchUriType.QUERY_PLANS: - let queryPlanPath = resolve(path, 'queryplans', `${name}.queryplan`); - if (queryPlanPath.includes('C:')) queryPlanPath = queryPlanPath.slice(2).replace(/\\/g, '/'); - return Uri.parse(`workbench:${queryPlanPath}?${name}`); - case WorkbenchUriType.SUPERGRAPH_SCHEMA: - let superGraphSchemaPath = resolve(path, 'supergraph-schema', `${name}-supergraph.graphql`); - if (superGraphSchemaPath.includes('C:')) superGraphSchemaPath = superGraphSchemaPath.slice(2).replace(/\\/g, '/'); - return Uri.parse(`workbench:${superGraphSchemaPath}?${name}`); - case WorkbenchUriType.SUPERGRAPH_API_SCHEMA: - let superGraphApiSchemaPath = resolve(path, 'supergraph-api-schema', `${name}-api-schema.graphql`); - if (superGraphApiSchemaPath.includes('C:')) superGraphApiSchemaPath = superGraphApiSchemaPath.slice(2).replace(/\\/g, '/'); - return Uri.parse(`workbench:${superGraphApiSchemaPath}?${name}`); - case WorkbenchUriType.MOCKS: - let subgarphMocksPath = resolve(StateManager.instance.extensionGlobalStoragePath ?? '', 'mocks', `${name}-mocks.js`); - if (subgarphMocksPath.toLowerCase().includes('c:')) subgarphMocksPath = subgarphMocksPath.slice(2).replace(/\\/g, '/'); + static supergraph( + path: string, + name?: string, + type: WorkbenchUriType = WorkbenchUriType.SUPERGRAPH_SCHEMA, + ): Uri { + switch (type) { + case WorkbenchUriType.SCHEMAS: + let subgraphPath = resolve(path, 'subgraphs', `${name}.graphql`); + if (subgraphPath.includes('C:')) + subgraphPath = subgraphPath.slice(2).replace(/\\/g, '/'); + return Uri.parse(`workbench:${subgraphPath}?${name}`); + case WorkbenchUriType.SCHEMAS_SETTINGS: + let schemaSettingPath = resolve( + path, + 'subgraph-settings', + `${name}-settings.json`, + ); + if (schemaSettingPath.includes('C:')) + schemaSettingPath = schemaSettingPath.slice(2).replace(/\\/g, '/'); + return Uri.parse(`workbench:${schemaSettingPath}?${name}`); + case WorkbenchUriType.QUERIES: + let queryPath = resolve(path, 'queries', `${name}.graphql`); + if (queryPath.includes('C:')) + queryPath = queryPath.slice(2).replace(/\\/g, '/'); + return Uri.parse(`workbench:${queryPath}?${name}`); + case WorkbenchUriType.QUERY_PLANS: + let queryPlanPath = resolve(path, 'queryplans', `${name}.queryplan`); + if (queryPlanPath.includes('C:')) + queryPlanPath = queryPlanPath.slice(2).replace(/\\/g, '/'); + return Uri.parse(`workbench:${queryPlanPath}?${name}`); + case WorkbenchUriType.SUPERGRAPH_SCHEMA: + let superGraphSchemaPath = resolve( + path, + 'supergraph-schema', + `${name}-supergraph.graphql`, + ); + if (superGraphSchemaPath.includes('C:')) + superGraphSchemaPath = superGraphSchemaPath + .slice(2) + .replace(/\\/g, '/'); + return Uri.parse(`workbench:${superGraphSchemaPath}?${name}`); + case WorkbenchUriType.SUPERGRAPH_API_SCHEMA: + let superGraphApiSchemaPath = resolve( + path, + 'supergraph-api-schema', + `${name}-api-schema.graphql`, + ); + if (superGraphApiSchemaPath.includes('C:')) + superGraphApiSchemaPath = superGraphApiSchemaPath + .slice(2) + .replace(/\\/g, '/'); + return Uri.parse(`workbench:${superGraphApiSchemaPath}?${name}`); + case WorkbenchUriType.MOCKS: + let subgarphMocksPath = resolve( + StateManager.instance.extensionGlobalStoragePath ?? '', + 'mocks', + `${name}-mocks.js`, + ); + if (subgarphMocksPath.toLowerCase().includes('c:')) + subgarphMocksPath = subgarphMocksPath.slice(2).replace(/\\/g, '/'); - return Uri.parse(`${subgarphMocksPath}?${path}:${name}`); - } + return Uri.parse(`${subgarphMocksPath}?${path}:${name}`); } -} \ No newline at end of file + } +} diff --git a/src/workbench/file-system/fileProvider.ts b/src/workbench/file-system/fileProvider.ts index 343f449..bd2dbb5 100644 --- a/src/workbench/file-system/fileProvider.ts +++ b/src/workbench/file-system/fileProvider.ts @@ -1,347 +1,435 @@ import { existsSync, readdirSync, readFileSync, writeFileSync } from 'fs'; import path, { join, resolve } from 'path'; -import { commands, Disposable, EventEmitter, FileChangeEvent, FileStat, FileSystemProvider, FileType, Uri, window, workspace } from 'vscode'; +import { + commands, + Disposable, + EventEmitter, + FileChangeEvent, + FileStat, + FileSystemProvider, + FileType, + Uri, + window, + workspace, +} from 'vscode'; import { StateManager } from '../stateManager'; import { getComposedSchemaLogCompositionErrorsForWbFile } from '../../graphql/composition'; import { ApolloWorkbenchFile, WorkbenchSettings } from './fileTypes'; import { parse, GraphQLSchema, extendSchema, printSchema } from 'graphql'; -import { buildOperationContext, buildComposedSchema, QueryPlanner } from '@apollo/query-planner'; +import { + buildOperationContext, + buildComposedSchema, + QueryPlanner, +} from '@apollo/query-planner'; import { serializeQueryPlan } from '@apollo/query-planner'; export class FileProvider implements FileSystemProvider { - //Singleton implementation - private static _instance: FileProvider; - static get instance(): FileProvider { - if (!this._instance) - this._instance = new FileProvider(StateManager.workspaceRoot); - - return this._instance; - } - - constructor(workspaceRoot?: string) { - } - - //All workbench files in opened VS Code folder - private workbenchFiles: Map = new Map(); - refreshLocalWorkbenchFiles() { - this.workbenchFiles.clear(); - const workspaceRoot = StateManager.workspaceRoot; - if (workspaceRoot) { - let workbenchFiles = this.getWorkbenchFilesInDirectory(workspaceRoot); - workbenchFiles.forEach(workbenchFile => { - try { - let test = JSON.parse(readFileSync(workbenchFile.path, { encoding: 'utf-8' })); - const wbFile = JSON.parse(readFileSync(workbenchFile.path, { encoding: 'utf-8' })) as ApolloWorkbenchFile; - this.workbenchFiles.set(workbenchFile.path, wbFile); - } catch (err) { - window.showErrorMessage(`Workbench file was not in the correct format. File located at ${workbenchFile.fsPath}`); - } - }); + //Singleton implementation + private static _instance: FileProvider; + static get instance(): FileProvider { + if (!this._instance) + this._instance = new FileProvider(StateManager.workspaceRoot); + + return this._instance; + } + + constructor(workspaceRoot?: string) {} + + //All workbench files in opened VS Code folder + private workbenchFiles: Map = new Map(); + refreshLocalWorkbenchFiles() { + this.workbenchFiles.clear(); + const workspaceRoot = StateManager.workspaceRoot; + if (workspaceRoot) { + let workbenchFiles = this.getWorkbenchFilesInDirectory(workspaceRoot); + workbenchFiles.forEach((workbenchFile) => { + try { + let test = JSON.parse( + readFileSync(workbenchFile.path, { encoding: 'utf-8' }), + ); + const wbFile = JSON.parse( + readFileSync(workbenchFile.path, { encoding: 'utf-8' }), + ) as ApolloWorkbenchFile; + this.workbenchFiles.set(workbenchFile.path, wbFile); + } catch (err) { + window.showErrorMessage( + `Workbench file was not in the correct format. File located at ${workbenchFile.fsPath}`, + ); } - - return this.workbenchFiles; - } - clearWorkbenchFiles() { - this.workbenchFiles.clear(); - } - getWorkbenchFiles() { - return this.workbenchFiles; + }); } - loadedWorbenchFilePath = ''; - loadedWorkbenchFile?: ApolloWorkbenchFile; - loadWorkbenchForComposition(wbFilePath: string, forceCompose: boolean = false) { - if (this.loadedWorbenchFilePath != wbFilePath) { - this.loadedWorbenchFilePath = wbFilePath; - this.loadedWorkbenchFile = this.workbenchFileFromPath(wbFilePath); - this.refreshComposition(wbFilePath); - } else if (forceCompose) { - this.refreshComposition(wbFilePath); - } - } - refreshComposition(wbFilePath: string) { - window.setStatusBarMessage('Composition Running', getComposedSchemaLogCompositionErrorsForWbFile(wbFilePath)); + return this.workbenchFiles; + } + clearWorkbenchFiles() { + this.workbenchFiles.clear(); + } + getWorkbenchFiles() { + return this.workbenchFiles; + } + + loadedWorbenchFilePath = ''; + loadedWorkbenchFile?: ApolloWorkbenchFile; + loadWorkbenchForComposition( + wbFilePath: string, + forceCompose: boolean = false, + ) { + if (this.loadedWorbenchFilePath != wbFilePath) { + this.loadedWorbenchFilePath = wbFilePath; + this.loadedWorkbenchFile = this.workbenchFileFromPath(wbFilePath); + this.refreshComposition(wbFilePath); + } else if (forceCompose) { + this.refreshComposition(wbFilePath); } - - async promptOpenFolder() { - let openFolder = "Open Folder"; - let response = await window.showErrorMessage("You must open a folder to create Apollo Workbench files", openFolder); - if (response == openFolder) - await commands.executeCommand('extension.openFolder'); + } + refreshComposition(wbFilePath: string) { + window.setStatusBarMessage( + 'Composition Running', + getComposedSchemaLogCompositionErrorsForWbFile(wbFilePath), + ); + } + + async promptOpenFolder() { + let openFolder = 'Open Folder'; + let response = await window.showErrorMessage( + 'You must open a folder to create Apollo Workbench files', + openFolder, + ); + if (response == openFolder) + await commands.executeCommand('extension.openFolder'); + } + + //Workbench File Implementations + createWorkbenchFileLocally(wbFile: ApolloWorkbenchFile) { + if (StateManager.workspaceRoot) { + const path = resolve( + StateManager.workspaceRoot, + `${wbFile.graphName}.apollo-workbench`, + ); + writeFileSync(path, JSON.stringify(wbFile), { encoding: 'utf8' }); + StateManager.instance.localSupergraphTreeDataProvider.refresh(); } - - //Workbench File Implementations - createWorkbenchFileLocally(wbFile: ApolloWorkbenchFile) { - if (StateManager.workspaceRoot) { - const path = resolve(StateManager.workspaceRoot, `${wbFile.graphName}.apollo-workbench`); - writeFileSync(path, JSON.stringify(wbFile), { encoding: "utf8" }); - StateManager.instance.localSupergraphTreeDataProvider.refresh(); - } + } + async copyPreloadedWorkbenchFile(fileName: string) { + if (!StateManager.workspaceRoot) { + await this.promptOpenFolder(); + } else { + const preloadFileDir = join( + __dirname, + '..', + '..', + '..', + 'media', + `preloaded-files`, + `${fileName}.apollo-workbench`, + ); + const workbenchFile = JSON.parse( + readFileSync(preloadFileDir, { encoding: 'utf-8' }), + ) as ApolloWorkbenchFile; + + this.createWorkbenchFileLocally(workbenchFile); } - async copyPreloadedWorkbenchFile(fileName: string) { - if (!StateManager.workspaceRoot) { - await this.promptOpenFolder(); - } else { - const preloadFileDir = join(__dirname, '..', '..', '..', 'media', `preloaded-files`, `${fileName}.apollo-workbench`); - const workbenchFile = JSON.parse(readFileSync(preloadFileDir, { encoding: 'utf-8' })) as ApolloWorkbenchFile; - - this.createWorkbenchFileLocally(workbenchFile); + } + saveWorkbenchFile( + wbFile: ApolloWorkbenchFile, + wbFilePath: string, + refreshTree: boolean = true, + ) { + writeFileSync(wbFilePath, JSON.stringify(wbFile), { encoding: 'utf8' }); + if (refreshTree) + StateManager.instance.localSupergraphTreeDataProvider.refresh(); + } + workbenchFileFromPath(path: string) { + let wbFile = this.workbenchFiles.get(path); + if (!wbFile) + //we're on Windows + wbFile = this.workbenchFiles.get(path.replace(/\//g, '\\')); + + return wbFile; + } + workbenchFileByGraphName(name: string) { + let path = ''; + let wbFile: ApolloWorkbenchFile = new ApolloWorkbenchFile(name); + this.workbenchFiles.forEach((value, key) => { + if (value.graphName == name) { + path = key; + wbFile = value; + } + }); + // let wbFile = this.workbenchFiles.get(path); + // if (!wbFile) //we're on Windows + // wbFile = this.workbenchFiles.get(path.replace(/\//g, '\\')); + + return { wbFile, path }; + } + //FileSystemProvider Implementations + //File chagnes are watched at the `vscode.workspace.onDidChangeTextDocument` level + readFile(uri: Uri): Uint8Array | Thenable { + const name = uri.query; + if (uri.path.includes('/subgraphs')) { + const wbFilePath = uri.path.split('/subgraphs')[0]; + const wbFile = this.workbenchFileFromPath(wbFilePath); + + return Buffer.from(wbFile?.schemas[name].sdl ?? ''); + } else if (uri.path.includes('/queries')) { + const wbFilePath = uri.path.split('/queries')[0]; + const wbFile = this.workbenchFileFromPath(wbFilePath); + return Buffer.from(wbFile?.operations[name] ?? ''); + } else if (uri.path.includes('/queryplans')) { + const wbFilePath = uri.path.split('/queryplans')[0]; + const wbFile = this.workbenchFileFromPath(wbFilePath); + //If we don't have a queryplan and we have a supergraphSdl, try generating query plan + if (wbFile?.supergraphSdl) { + if (!wbFile?.queryPlans[name]) { + wbFile.queryPlans[name] = this.generateQueryPlan(name, wbFile); + this.saveWorkbenchFile(wbFile, wbFilePath, false); } + } else + window.showInformationMessage( + `No valid Superschema SDL available, unable to generate a query plan.`, + ); + + return Buffer.from( + wbFile?.queryPlans[name] + ? wbFile?.queryPlans[name] + : 'Unable to generate Query Plan, do you have a supergraph schema available?', + ); + } else if (uri.path.includes('/subgraph-settings')) { + const wbFilePath = uri.path.split('/subgraph-settings')[0]; + const wbFile = this.workbenchFileFromPath(wbFilePath); + const subgraph = wbFile?.schemas[name]; + if (subgraph) { + let settings: WorkbenchSettings = { + url: subgraph?.url ?? '', + requiredHeaders: subgraph?.requiredHeaders ?? [], + mocks: { + shouldMock: subgraph?.shouldMock ?? true, + autoUpdateSchemaFromUrl: subgraph?.autoUpdateSchemaFromUrl ?? false, + }, + }; + + return Buffer.from(JSON.stringify(settings, null, 2)); + } else + return Buffer.from(JSON.stringify(new WorkbenchSettings(), null, 2)); + } else if (uri.path.includes('/supergraph-schema')) { + const wbFilePath = uri.path.split('/supergraph-schema')[0]; + const wbFile = this.workbenchFileFromPath(wbFilePath); + return Buffer.from(wbFile?.supergraphSdl ?? ''); + } else if (uri.path.includes('/supergraph-api-schema')) { + const wbFilePath = uri.path.split('/supergraph-api-schema')[0]; + const wbFile = this.workbenchFileFromPath(wbFilePath); + const schema = new GraphQLSchema({ + query: undefined, + }); + const parsed = parse(wbFile?.supergraphSdl ?? ''); + const finalSchema = extendSchema(schema, parsed, { + assumeValidSDL: true, + }); + + return Buffer.from(printSchema(finalSchema)); } - saveWorkbenchFile(wbFile: ApolloWorkbenchFile, wbFilePath: string, refreshTree: boolean = true) { - writeFileSync(wbFilePath, JSON.stringify(wbFile), { encoding: "utf8" }); - if (refreshTree) StateManager.instance.localSupergraphTreeDataProvider.refresh(); - } - workbenchFileFromPath(path: string) { - let wbFile = this.workbenchFiles.get(path); - if (!wbFile) //we're on Windows - wbFile = this.workbenchFiles.get(path.replace(/\//g, '\\')); - return wbFile; + throw new Error('Unhandled workbench URI'); + } + getPath(path: string) { + if (path.includes('/subgraphs')) { + return path.split('/subgraphs')[0]; + } else if (path.includes('/queries')) { + return path.split('/queries')[0]; + } else if (path.includes('/queryplans')) { + return path.split('/queryplans')[0]; + } else if (path.includes('/subgraph-settings')) { + return path.split('/subgraph-settings')[0]; + } else if (path.includes('/mocks')) { + return path.split('/mocks')[0]; } - workbenchFileByGraphName(name: string) { - let path = ''; - let wbFile: ApolloWorkbenchFile = new ApolloWorkbenchFile(name); - this.workbenchFiles.forEach((value, key) => { - if (value.graphName == name) { - path = key; - wbFile = value; - } - }) - // let wbFile = this.workbenchFiles.get(path); - // if (!wbFile) //we're on Windows - // wbFile = this.workbenchFiles.get(path.replace(/\//g, '\\')); - - return { wbFile, path }; + throw new Error('Unknown path type'); + } + generateQueryPlan(operationName: string, wbFile: ApolloWorkbenchFile) { + try { + const operation = wbFile.operations[operationName]; + const schema = buildComposedSchema(parse(wbFile.supergraphSdl)); + const operationContext = buildOperationContext( + schema, + parse(operation), + operationName, + ); + const queryPlanner = new QueryPlanner(schema); + const queryPlan = queryPlanner.buildQueryPlan(operationContext, { + autoFragmentization: false, + }); + const queryPlanString = serializeQueryPlan(queryPlan); + + return queryPlanString; + } catch (err) { + console.log(err); + return ''; } - //FileSystemProvider Implementations - //File chagnes are watched at the `vscode.workspace.onDidChangeTextDocument` level - readFile(uri: Uri): Uint8Array | Thenable { - const name = uri.query; - if (uri.path.includes('/subgraphs')) { - const wbFilePath = uri.path.split('/subgraphs')[0] - const wbFile = this.workbenchFileFromPath(wbFilePath); - - return Buffer.from(wbFile?.schemas[name].sdl ?? ""); - } else if (uri.path.includes('/queries')) { - const wbFilePath = uri.path.split('/queries')[0]; - const wbFile = this.workbenchFileFromPath(wbFilePath); - return Buffer.from(wbFile?.operations[name] ?? ""); - } else if (uri.path.includes('/queryplans')) { - const wbFilePath = uri.path.split('/queryplans')[0]; - const wbFile = this.workbenchFileFromPath(wbFilePath); - //If we don't have a queryplan and we have a supergraphSdl, try generating query plan - if (wbFile?.supergraphSdl) { - if (!wbFile?.queryPlans[name]) { - wbFile.queryPlans[name] = this.generateQueryPlan(name, wbFile); - this.saveWorkbenchFile(wbFile, wbFilePath, false); - } - } else window.showInformationMessage(`No valid Superschema SDL available, unable to generate a query plan.`) - - return Buffer.from(wbFile?.queryPlans[name] ? wbFile?.queryPlans[name] : "Unable to generate Query Plan, do you have a supergraph schema available?"); - } else if (uri.path.includes('/subgraph-settings')) { - const wbFilePath = uri.path.split('/subgraph-settings')[0]; - const wbFile = this.workbenchFileFromPath(wbFilePath); - const subgraph = wbFile?.schemas[name]; - if (subgraph) { - let settings: WorkbenchSettings = { - url: subgraph?.url ?? '', - requiredHeaders: subgraph?.requiredHeaders ?? [], - mocks: { - shouldMock: subgraph?.shouldMock ?? true, - autoUpdateSchemaFromUrl: subgraph?.autoUpdateSchemaFromUrl ?? false - } - }; - - return Buffer.from(JSON.stringify(settings, null, 2)); - } else return Buffer.from(JSON.stringify(new WorkbenchSettings(), null, 2)); - } else if (uri.path.includes('/supergraph-schema')) { - const wbFilePath = uri.path.split('/supergraph-schema')[0]; - const wbFile = this.workbenchFileFromPath(wbFilePath); - return Buffer.from(wbFile?.supergraphSdl ?? ""); - } else if (uri.path.includes('/supergraph-api-schema')) { - const wbFilePath = uri.path.split('/supergraph-api-schema')[0]; - const wbFile = this.workbenchFileFromPath(wbFilePath); - const schema = new GraphQLSchema({ - query: undefined, - }); - const parsed = parse(wbFile?.supergraphSdl ?? ""); - const finalSchema = extendSchema(schema, parsed, { assumeValidSDL: true }); - - return Buffer.from(printSchema(finalSchema)); + } + writeFile( + uri: Uri, + content: Uint8Array, + options: { create: boolean; overwrite: boolean }, + ): void | Thenable { + //Supergraph schema and queryplans are read-only + if ( + uri.path.includes('supergraph-schema') || + uri.path.includes('supergraph-api-schema') || + uri.path.includes('queryplans') + ) + return; + + const name = uri.query; + const wbFilePath = this.getPath(uri.path); + const wbFile = this.workbenchFileFromPath(wbFilePath); + const stringContent = content.toString(); + + if (wbFile) { + let shouldRecompose = false; + if (uri.path.includes('/subgraphs')) { + if (wbFile.schemas[name].sdl != stringContent) { + wbFile.schemas[name].sdl = stringContent; + shouldRecompose = true; } + } else if (uri.path.includes('/queries')) { + wbFile.operations[name] = stringContent; - throw new Error('Unhandled workbench URI'); - } - getPath(path: string) { - if (path.includes('/subgraphs')) { - return path.split('/subgraphs')[0]; - } else if (path.includes('/queries')) { - return path.split('/queries')[0]; - } else if (path.includes('/queryplans')) { - return path.split('/queryplans')[0]; - } else if (path.includes('/subgraph-settings')) { - return path.split('/subgraph-settings')[0]; - } else if (path.includes('/mocks')) { - return path.split('/mocks')[0]; - } - throw new Error('Unknown path type') - } - generateQueryPlan(operationName: string, wbFile: ApolloWorkbenchFile) { - try { - const operation = wbFile.operations[operationName]; - const schema = buildComposedSchema(parse(wbFile.supergraphSdl)) - const operationContext = buildOperationContext(schema, parse(operation), operationName) - const queryPlanner = new QueryPlanner(schema); - const queryPlan = queryPlanner.buildQueryPlan(operationContext, { autoFragmentization: false }); - const queryPlanString = serializeQueryPlan(queryPlan); + if (wbFile.supergraphSdl) { + try { + const queryPlanString = this.generateQueryPlan(name, wbFile); - return queryPlanString; - } catch (err) { + wbFile.queryPlans[name] = queryPlanString; + } catch (err) { console.log(err); - return ""; - } - } - writeFile(uri: Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): void | Thenable { - //Supergraph schema and queryplans are read-only - if (uri.path.includes('supergraph-schema') || uri.path.includes('supergraph-api-schema') || uri.path.includes('queryplans')) return; - - const name = uri.query; - const wbFilePath = this.getPath(uri.path); - const wbFile = this.workbenchFileFromPath(wbFilePath); - const stringContent = content.toString(); - - if (wbFile) { - let shouldRecompose = false; - if (uri.path.includes('/subgraphs')) { - if (wbFile.schemas[name].sdl != stringContent) { - wbFile.schemas[name].sdl = stringContent; - shouldRecompose = true; - } - } else if (uri.path.includes('/queries')) { - wbFile.operations[name] = stringContent; - - if (wbFile.supergraphSdl) { - try { - const queryPlanString = this.generateQueryPlan(name, wbFile) - - wbFile.queryPlans[name] = queryPlanString; - } catch (err) { - console.log(err); - } - } - } else if (uri.path.includes('/subgraph-settings')) { - const savedSettings: WorkbenchSettings = JSON.parse(stringContent); - wbFile.schemas[name].url = savedSettings.url; - wbFile.schemas[name].shouldMock = savedSettings.mocks.shouldMock; - wbFile.schemas[name].autoUpdateSchemaFromUrl = savedSettings.mocks.autoUpdateSchemaFromUrl; - wbFile.schemas[name].requiredHeaders = savedSettings.requiredHeaders; - } else if (uri.path.includes('/mocks')) { - wbFile.schemas[name].customMocks = stringContent; - } else if (uri.path.includes('/supergraph-schema')) { - wbFile.supergraphSdl = stringContent; - } - - this.saveWorkbenchFile(wbFile, wbFilePath); - if (shouldRecompose) - this.loadWorkbenchForComposition(wbFilePath, true); - } else throw new Error('Workbench file was unable to load'); - } - delete(uri: Uri, options: { recursive: boolean; }): void | Thenable { - // if (uri.scheme == 'workbench') { - // if (uri.path.includes('/schemas')) { - // const serviceName = uri.query; - // delete this.currrentWorkbenchSchemas[serviceName]; - // } else if (uri.path.includes('/queries')) { - // const operationName = uri.query; - // delete this.currrentWorkbenchOperations[operationName]; - // } else { - // throw new Error('Unknown uri format') - // } - - // window.showTextDocument(uri, { preview: true, preserveFocus: false }) - // .then(() => commands.executeCommand('workbench.action.closeActiveEditor')); - - // // this.saveCurrentWorkbench(false); - // } - } - rename(oldUri: Uri, newUri: Uri, options: { overwrite: boolean; }): void | Thenable { - // if (this.currrentWorkbench && oldUri.scheme == 'workbench' && newUri.scheme == 'workbench') { - // const oldName = oldUri.query; - // const newName = newUri.query; - - // if (oldUri.path.includes('/schemas')) { - // this.currrentWorkbenchSchemas[newName] = this.currrentWorkbenchSchemas[oldName]; - // delete this.currrentWorkbenchSchemas[oldName]; - - // // getComposedSchemaLogCompositionErrors().next(); - // } else if (oldUri.path.includes('/queries')) { - // this.currrentWorkbenchOperations[newName] = this.currrentWorkbenchOperations[oldName]; - // delete this.currrentWorkbenchOperations[oldName]; - // } else { - // throw new Error('Unknown uri format') - // } - - // // this.saveCurrentWorkbench(); - // } - } - watch(uri: Uri, options: { recursive: boolean; excludes: string[]; }): Disposable { - return new Disposable(() => { }); - } - stat(uri: Uri): FileStat | Thenable { - const now = Date.now(); - return { - ctime: now, - mtime: now, - size: 0, - type: FileType.File + } } - } - readDirectory(uri: Uri): [string, FileType][] | Thenable<[string, FileType][]> { - throw new Error('Method not implemented.'); - } - createDirectory(uri: Uri): void | Thenable { - throw new Error('Method not implemented.'); - } - onDidChangeEmitter = new EventEmitter(); - onDidChangeFile = this.onDidChangeEmitter.event; - - - private getWorkbenchFilesInDirectory(dirPath: string) { - if (!dirPath || dirPath == '.') return []; - - let workbenchFiles = new Array(); - let directories = new Array(); - directories.push(dirPath); - - while (directories.length > 0) { - let directory = directories[0]; - const dirents = readdirSync(directory, { withFileTypes: true }); - for (const dirent of dirents) { - const directoryPath = path.resolve(directory, dirent.name); - if (dirent.isDirectory() && dirent.name != 'node_modules') { - directories.push(directoryPath); - } else if (dirent.name.includes('.apollo-workbench')) { - const uri = Uri.parse(directoryPath); - workbenchFiles.push(uri); - } - } - - directories.splice(0, 1); + } else if (uri.path.includes('/subgraph-settings')) { + const savedSettings: WorkbenchSettings = JSON.parse(stringContent); + wbFile.schemas[name].url = savedSettings.url; + wbFile.schemas[name].shouldMock = savedSettings.mocks.shouldMock; + wbFile.schemas[name].autoUpdateSchemaFromUrl = + savedSettings.mocks.autoUpdateSchemaFromUrl; + wbFile.schemas[name].requiredHeaders = savedSettings.requiredHeaders; + } else if (uri.path.includes('/mocks')) { + wbFile.schemas[name].customMocks = stringContent; + } else if (uri.path.includes('/supergraph-schema')) { + wbFile.supergraphSdl = stringContent; + } + + this.saveWorkbenchFile(wbFile, wbFilePath); + if (shouldRecompose) this.loadWorkbenchForComposition(wbFilePath, true); + } else throw new Error('Workbench file was unable to load'); + } + delete(uri: Uri, options: { recursive: boolean }): void | Thenable { + // if (uri.scheme == 'workbench') { + // if (uri.path.includes('/schemas')) { + // const serviceName = uri.query; + // delete this.currrentWorkbenchSchemas[serviceName]; + // } else if (uri.path.includes('/queries')) { + // const operationName = uri.query; + // delete this.currrentWorkbenchOperations[operationName]; + // } else { + // throw new Error('Unknown uri format') + // } + // window.showTextDocument(uri, { preview: true, preserveFocus: false }) + // .then(() => commands.executeCommand('workbench.action.closeActiveEditor')); + // // this.saveCurrentWorkbench(false); + // } + } + rename( + oldUri: Uri, + newUri: Uri, + options: { overwrite: boolean }, + ): void | Thenable { + // if (this.currrentWorkbench && oldUri.scheme == 'workbench' && newUri.scheme == 'workbench') { + // const oldName = oldUri.query; + // const newName = newUri.query; + // if (oldUri.path.includes('/schemas')) { + // this.currrentWorkbenchSchemas[newName] = this.currrentWorkbenchSchemas[oldName]; + // delete this.currrentWorkbenchSchemas[oldName]; + // // getComposedSchemaLogCompositionErrors().next(); + // } else if (oldUri.path.includes('/queries')) { + // this.currrentWorkbenchOperations[newName] = this.currrentWorkbenchOperations[oldName]; + // delete this.currrentWorkbenchOperations[oldName]; + // } else { + // throw new Error('Unknown uri format') + // } + // // this.saveCurrentWorkbench(); + // } + } + watch( + uri: Uri, + options: { recursive: boolean; excludes: string[] }, + ): Disposable { + return new Disposable(() => {}); + } + stat(uri: Uri): FileStat | Thenable { + const now = Date.now(); + return { + ctime: now, + mtime: now, + size: 0, + type: FileType.File, + }; + } + readDirectory( + uri: Uri, + ): [string, FileType][] | Thenable<[string, FileType][]> { + throw new Error('Method not implemented.'); + } + createDirectory(uri: Uri): void | Thenable { + throw new Error('Method not implemented.'); + } + onDidChangeEmitter = new EventEmitter(); + onDidChangeFile = this.onDidChangeEmitter.event; + + private getWorkbenchFilesInDirectory(dirPath: string) { + if (!dirPath || dirPath == '.') return []; + + let workbenchFiles = new Array(); + let directories = new Array(); + directories.push(dirPath); + + while (directories.length > 0) { + let directory = directories[0]; + const dirents = readdirSync(directory, { withFileTypes: true }); + for (const dirent of dirents) { + const directoryPath = path.resolve(directory, dirent.name); + if (dirent.isDirectory() && dirent.name != 'node_modules') { + directories.push(directoryPath); + } else if (dirent.name.includes('.apollo-workbench')) { + const uri = Uri.parse(directoryPath); + workbenchFiles.push(uri); } + } - return workbenchFiles; + directories.splice(0, 1); } - getPreloadedWorkbenchFiles() { - let items: { fileName: string, path: string }[] = []; - let preloadFileDir = join(__dirname, '..', '..', '..', 'media', `preloaded-files`); - if (existsSync(preloadFileDir)) { - let preloadedDirectory = readdirSync(preloadFileDir, { encoding: 'utf-8' }); - preloadedDirectory.map(item => { - items.push({ fileName: item.split('.')[0], path: `${preloadFileDir}/${item}` }); - }); - } - return items; + return workbenchFiles; + } + + getPreloadedWorkbenchFiles() { + let items: { fileName: string; path: string }[] = []; + let preloadFileDir = join( + __dirname, + '..', + '..', + '..', + 'media', + `preloaded-files`, + ); + if (existsSync(preloadFileDir)) { + let preloadedDirectory = readdirSync(preloadFileDir, { + encoding: 'utf-8', + }); + preloadedDirectory.map((item) => { + items.push({ + fileName: item.split('.')[0], + path: `${preloadFileDir}/${item}`, + }); + }); } -} \ No newline at end of file + return items; + } +} diff --git a/src/workbench/file-system/fileTypes.ts b/src/workbench/file-system/fileTypes.ts index d2cd1e9..e846370 100644 --- a/src/workbench/file-system/fileTypes.ts +++ b/src/workbench/file-system/fileTypes.ts @@ -1,33 +1,33 @@ export interface RequiredHeader { - key: string; - value?: string; + key: string; + value?: string; } export interface WorkbenchSchema { - url?: string; - sdl: string; - shouldMock: boolean; - autoUpdateSchemaFromUrl: boolean; - requiredHeaders?: [RequiredHeader?], - //this will be serialized into javascript using eval - customMocks?: string + url?: string; + sdl: string; + shouldMock: boolean; + autoUpdateSchemaFromUrl: boolean; + requiredHeaders?: [RequiredHeader?]; + //this will be serialized into javascript using eval + customMocks?: string; } export class ApolloWorkbenchFile { - operations: { [opName: string]: string } = {}; - queryPlans: { [opName: string]: string } = {}; - schemas: { [serviceName: string]: WorkbenchSchema } = {}; - supergraphSdl: string = ""; + operations: { [opName: string]: string } = {}; + queryPlans: { [opName: string]: string } = {}; + schemas: { [serviceName: string]: WorkbenchSchema } = {}; + supergraphSdl: string = ''; - constructor(public graphName: string) { } + constructor(public graphName: string) {} } ///This is the user facing settings displayed export class WorkbenchSettings { - url: string = ""; - requiredHeaders?: [RequiredHeader?]; - mocks: { - shouldMock: boolean; - autoUpdateSchemaFromUrl: boolean; - } = { shouldMock: true, autoUpdateSchemaFromUrl: false }; -} \ No newline at end of file + url: string = ''; + requiredHeaders?: [RequiredHeader?]; + mocks: { + shouldMock: boolean; + autoUpdateSchemaFromUrl: boolean; + } = { shouldMock: true, autoUpdateSchemaFromUrl: false }; +} diff --git a/src/workbench/serverManager.ts b/src/workbench/serverManager.ts index a562c65..904af61 100644 --- a/src/workbench/serverManager.ts +++ b/src/workbench/serverManager.ts @@ -1,225 +1,271 @@ -import { addMockFunctionsToSchema, ApolloServer, gql, IMocks, CorsOptions } from "apollo-server"; +import { + addMockFunctionsToSchema, + ApolloServer, + gql, + IMocks, + CorsOptions, +} from 'apollo-server'; import plugin from 'apollo-server-plugin-operation-registry'; -import { buildFederatedSchema } from "@apollo/federation"; +import { buildFederatedSchema } from '@apollo/federation'; import { ApolloServerPluginUsageReportingDisabled } from 'apollo-server-core'; -import { StateManager } from "./stateManager"; -import { OverrideApolloGateway, GatewayForwardHeadersDataSource } from "../graphql/graphRouter"; -import { FileProvider } from "./file-system/fileProvider"; -import { extractEntityNames } from "../graphql/parsers/schemaParser"; -import { resolve } from "path"; -import { mkdirSync, writeFileSync, readFileSync } from "fs"; -import { workspace, Uri, window, StatusBarAlignment, tasks } from "vscode"; -import { execSync } from "child_process"; -import { Disposable } from "vscode-languageclient"; -import { WorkbenchUri, WorkbenchUriType } from "./file-system/WorkbenchUri"; +import { StateManager } from './stateManager'; +import { + OverrideApolloGateway, + GatewayForwardHeadersDataSource, +} from '../graphql/graphRouter'; +import { FileProvider } from './file-system/fileProvider'; +import { extractEntityNames } from '../graphql/parsers/schemaParser'; +import { resolve } from 'path'; +import { mkdirSync, writeFileSync, readFileSync } from 'fs'; +import { workspace, Uri, window, StatusBarAlignment, tasks } from 'vscode'; +import { execSync } from 'child_process'; +import { Disposable } from 'vscode-languageclient'; +import { WorkbenchUri, WorkbenchUriType } from './file-system/WorkbenchUri'; const { name } = require('../../package.json'); export class ServerManager { - private static _instance: ServerManager; - static get instance(): ServerManager { - if (!this._instance) - this._instance = new ServerManager(); - return this._instance; - } - - //For any service being mocked, we will store a port mapping of serviceName to port - portMapping: { [serviceName: string]: string } = {}; - //serverState will hold the ApolloServer/ApolloGateway instances based on the ports they are running on - private serversState: { [port: string]: any } = {}; - - private corsConfiguration: CorsOptions = { - origin: '*', - credentials: true, - }; - - async startSupergraphMocks(wbFilePath: string) { - if (StateManager.settings_tlsRejectUnauthorized) process.env.NODE_TLS_REJECT_UNAUTHORIZED = ''; - else process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - - console.log(`${name}:Setting up mocks`); - let workbenchFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); - if (workbenchFile) { - console.log(`${name}:Mocking workbench file: ${workbenchFile.graphName}`); - FileProvider.instance.loadedWorkbenchFile = workbenchFile; - for (var serviceName in workbenchFile.schemas) { - //Check if we should be mocking this service - if (workbenchFile.schemas[serviceName].shouldMock) { - //Check if Custom Mocks are defined in workbench - let customMocks = workbenchFile.schemas[serviceName].customMocks; - if (customMocks) { - //By default we add the export shown to the user, but they may delete it - if (!customMocks.includes('module.exports')) - customMocks = customMocks.concat('\nmodule.exports = mocks'); - - try { - let mocks = eval(customMocks); - this.startServer(serviceName, workbenchFile.schemas[serviceName].sdl, mocks); - } catch (err) { - //Most likely wasn't valid javascript - console.log(err); - this.startServer(serviceName, workbenchFile.schemas[serviceName].sdl); - } - } else - this.startServer(serviceName, workbenchFile.schemas[serviceName].sdl); - } - } - - this.startGateway(); - } else - console.log(`${name}:No selected workbench file to setup`); - } - stopMocks() { - if (this.serversState?.gateway) - this.serversState.gateway.experimental_pollInterval = 10000000; - - for (var port in this.serversState) { - if (port != 'gateway') { - console.log(`${name}:Stopping server running at port ${port}...`); - this.stopServerOnPort(port); - } - } - this.stopGateway(); - this.portMapping = {}; - } - private startServer(serviceName: string, schemaString: string, mocks?: IMocks) { - //Ensure we don't have an empty schema string - meaning a blank new service was created - if (schemaString == '') { - console.log(`${name}:No schema defined for ${serviceName} service.`) - return; - } + private static _instance: ServerManager; + static get instance(): ServerManager { + if (!this._instance) this._instance = new ServerManager(); + return this._instance; + } - //Establish what port the server should be running on - const port = this.portMapping[serviceName] ?? this.getNextAvailablePort(); - console.log(`${name}:Starting ${serviceName} on port ${port}`); + //For any service being mocked, we will store a port mapping of serviceName to port + portMapping: { [serviceName: string]: string } = {}; + //serverState will hold the ApolloServer/ApolloGateway instances based on the ports they are running on + private serversState: { [port: string]: any } = {}; - //Check local server state to stop server running at a specific port - if (this.serversState[port]) { - console.log(`${name}:Stopping previous running server at port ${port}`); - this.serversState[port].stop(); - delete this.serversState[port]; - } + private corsConfiguration: CorsOptions = { + origin: '*', + credentials: true, + }; - //Surround server startup in try/catch to prevent UI errors from schema errors - most likey a blank schema file - try { - const typeDefs = gql(schemaString); + async startSupergraphMocks(wbFilePath: string) { + if (StateManager.settings_tlsRejectUnauthorized) + process.env.NODE_TLS_REJECT_UNAUTHORIZED = ''; + else process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - //Create mock for _Service type - if (mocks) { - mocks._Service = () => { return { sdl: schemaString } } - } else { - mocks = { _Service: () => { return { sdl: schemaString } } }; - } + console.log(`${name}:Setting up mocks`); + let workbenchFile = FileProvider.instance.workbenchFileFromPath(wbFilePath); + if (workbenchFile) { + console.log(`${name}:Mocking workbench file: ${workbenchFile.graphName}`); + FileProvider.instance.loadedWorkbenchFile = workbenchFile; + for (var serviceName in workbenchFile.schemas) { + //Check if we should be mocking this service + if (workbenchFile.schemas[serviceName].shouldMock) { + //Check if Custom Mocks are defined in workbench + let customMocks = workbenchFile.schemas[serviceName].customMocks; + if (customMocks) { + //By default we add the export shown to the user, but they may delete it + if (!customMocks.includes('module.exports')) + customMocks = customMocks.concat('\nmodule.exports = mocks'); - //Dynamically create __resolveReference resolvers based on defined entites in Graph - let resolvers = {}; - let entities = extractEntityNames(schemaString); - entities.forEach(entity => resolvers[entity] = { __resolveReference(parent, args) { return { ...parent } } }); - - //Build federated schema with resolvers and then add custom mocks to that schema - const schema = buildFederatedSchema({ typeDefs, resolvers }); - addMockFunctionsToSchema({ schema, mocks, preserveResolvers: true }); - - //Create and start up server locally - const server = new ApolloServer({ - cors: this.corsConfiguration, - schema, - // mocks, - // mockEntireSchema: false, - subscriptions: false - }); - server.listen({ port }).then(({ url }) => console.log(`${name}:🚀 ${serviceName} mocked server ready at ${url}`)); - - //Set the port and server to local state - this.serversState[port] = server; - this.portMapping[serviceName] = port; - } catch (err) { - if (err.message.includes('EOF')) { - console.log(`${name}:${serviceName} has no contents, try defining a schema`); - } else { - console.log(`${name}:${serviceName} had errors starting up mocked server: ${err}`); + try { + let mocks = eval(customMocks); + this.startServer( + serviceName, + workbenchFile.schemas[serviceName].sdl, + mocks, + ); + } catch (err) { + //Most likely wasn't valid javascript + console.log(err); + this.startServer( + serviceName, + workbenchFile.schemas[serviceName].sdl, + ); } + } else + this.startServer( + serviceName, + workbenchFile.schemas[serviceName].sdl, + ); } - } - private stopServerOnPort(port: string) { - let serviceName = ''; - for (var sn in this.portMapping) - if (this.portMapping[sn] == port) - serviceName = sn; + } - this.stopServer(port); + this.startGateway(); + } else console.log(`${name}:No selected workbench file to setup`); + } + stopMocks() { + if (this.serversState?.gateway) + this.serversState.gateway.experimental_pollInterval = 10000000; - if (this.portMapping[serviceName]) - delete this.portMapping[serviceName]; + for (var port in this.serversState) { + if (port != 'gateway') { + console.log(`${name}:Stopping server running at port ${port}...`); + this.stopServerOnPort(port); + } } - statusBarMessage: Disposable = window.setStatusBarMessage(""); - private stopGateway() { - let gatewayPort = StateManager.settings_gatewayServerPort; - if (this.serversState[gatewayPort]) { - console.log(`${name}:Stopping previous running gateway`); - this.serversState[gatewayPort].stop(); - delete this.serversState[gatewayPort]; - } - if (this.statusBarMessage) - this.statusBarMessage.dispose(); + this.stopGateway(); + this.portMapping = {}; + } + private startServer( + serviceName: string, + schemaString: string, + mocks?: IMocks, + ) { + //Ensure we don't have an empty schema string - meaning a blank new service was created + if (schemaString == '') { + console.log(`${name}:No schema defined for ${serviceName} service.`); + return; } - private startGateway() { - let gatewayPort = StateManager.settings_gatewayServerPort; - if (this.serversState[gatewayPort]) { - console.log(`${name}:Stopping previous running gateway`); - this.serversState[gatewayPort].stop(); - delete this.serversState[gatewayPort]; - } - const graphApiKey = StateManager.settings_apiKey; - const graphVariant = StateManager.settings_graphVariant; - let plugins = [ApolloServerPluginUsageReportingDisabled()]; - const shouldRunOpReg = StateManager.settings_shouldRunOpRegistry; - if (shouldRunOpReg) { - console.log(`${name}:Enabling operation registry for ${graphVariant}`); - plugins = [ApolloServerPluginUsageReportingDisabled()];//, plugin({ graphVariant, forbidUnregisteredOperations: shouldRunOpReg, debug: true })()]; - } + //Establish what port the server should be running on + const port = this.portMapping[serviceName] ?? this.getNextAvailablePort(); + console.log(`${name}:Starting ${serviceName} on port ${port}`); + + //Check local server state to stop server running at a specific port + if (this.serversState[port]) { + console.log(`${name}:Stopping previous running server at port ${port}`); + this.serversState[port].stop(); + delete this.serversState[port]; + } + + //Surround server startup in try/catch to prevent UI errors from schema errors - most likey a blank schema file + try { + const typeDefs = gql(schemaString); - const server = new ApolloServer({ - cors: this.corsConfiguration, - gateway: new OverrideApolloGateway({ - debug: true, - buildService({ url, name }) { - let source = new GatewayForwardHeadersDataSource({ url }); - source.serviceName = name; - return source; - } - }), - subscriptions: false, - apollo: { - key: graphApiKey, - graphVariant + //Create mock for _Service type + if (mocks) { + mocks._Service = () => { + return { sdl: schemaString }; + }; + } else { + mocks = { + _Service: () => { + return { sdl: schemaString }; + }, + }; + } + + //Dynamically create __resolveReference resolvers based on defined entites in Graph + let resolvers = {}; + let entities = extractEntityNames(schemaString); + entities.forEach( + (entity) => + (resolvers[entity] = { + __resolveReference(parent, args) { + return { ...parent }; }, - plugins, - context: ({ req }) => { - return { incomingHeaders: req.headers }; - } - }); + }), + ); + + //Build federated schema with resolvers and then add custom mocks to that schema + const schema = buildFederatedSchema({ typeDefs, resolvers }); + addMockFunctionsToSchema({ schema, mocks, preserveResolvers: true }); - server.listen({ port: gatewayPort }).then(({ url }) => { - console.log(`${name}:🚀 Apollo Workbench gateway ready at ${url}`); - ServerManager.instance.statusBarMessage = window.setStatusBarMessage("Apollo Workbench Mocks Running"); - }).then(undefined, err => { - console.error('I am error'); - }); + //Create and start up server locally + const server = new ApolloServer({ + cors: this.corsConfiguration, + schema, + // mocks, + // mockEntireSchema: false, + subscriptions: false, + }); + server + .listen({ port }) + .then(({ url }) => + console.log( + `${name}:🚀 ${serviceName} mocked server ready at ${url}`, + ), + ); - this.serversState[gatewayPort] = server; + //Set the port and server to local state + this.serversState[port] = server; + this.portMapping[serviceName] = port; + } catch (err) { + if (err.message.includes('EOF')) { + console.log( + `${name}:${serviceName} has no contents, try defining a schema`, + ); + } else { + console.log( + `${name}:${serviceName} had errors starting up mocked server: ${err}`, + ); + } } - private stopServer(port: string) { - this.serversState[port].stop(); - delete this.serversState[port]; + } + private stopServerOnPort(port: string) { + let serviceName = ''; + for (var sn in this.portMapping) + if (this.portMapping[sn] == port) serviceName = sn; + + this.stopServer(port); + + if (this.portMapping[serviceName]) delete this.portMapping[serviceName]; + } + statusBarMessage: Disposable = window.setStatusBarMessage(''); + private stopGateway() { + let gatewayPort = StateManager.settings_gatewayServerPort; + if (this.serversState[gatewayPort]) { + console.log(`${name}:Stopping previous running gateway`); + this.serversState[gatewayPort].stop(); + delete this.serversState[gatewayPort]; + } + if (this.statusBarMessage) this.statusBarMessage.dispose(); + } + private startGateway() { + let gatewayPort = StateManager.settings_gatewayServerPort; + if (this.serversState[gatewayPort]) { + console.log(`${name}:Stopping previous running gateway`); + this.serversState[gatewayPort].stop(); + delete this.serversState[gatewayPort]; } - private getNextAvailablePort() { - let port = StateManager.settings_startingServerPort; - while (this.serversState[port]) - port++; - return port; + const graphApiKey = StateManager.settings_apiKey; + const graphVariant = StateManager.settings_graphVariant; + let plugins = [ApolloServerPluginUsageReportingDisabled()]; + const shouldRunOpReg = StateManager.settings_shouldRunOpRegistry; + if (shouldRunOpReg) { + console.log(`${name}:Enabling operation registry for ${graphVariant}`); + plugins = [ApolloServerPluginUsageReportingDisabled()]; //, plugin({ graphVariant, forbidUnregisteredOperations: shouldRunOpReg, debug: true })()]; } -} \ No newline at end of file + + const server = new ApolloServer({ + cors: this.corsConfiguration, + gateway: new OverrideApolloGateway({ + debug: true, + buildService({ url, name }) { + let source = new GatewayForwardHeadersDataSource({ url }); + source.serviceName = name; + return source; + }, + }), + subscriptions: false, + apollo: { + key: graphApiKey, + graphVariant, + }, + plugins, + context: ({ req }) => { + return { incomingHeaders: req.headers }; + }, + }); + + server + .listen({ port: gatewayPort }) + .then(({ url }) => { + console.log(`${name}:🚀 Apollo Workbench gateway ready at ${url}`); + ServerManager.instance.statusBarMessage = window.setStatusBarMessage( + 'Apollo Workbench Mocks Running', + ); + }) + .then(undefined, (err) => { + console.error('I am error'); + }); + + this.serversState[gatewayPort] = server; + } + private stopServer(port: string) { + this.serversState[port].stop(); + delete this.serversState[port]; + } + private getNextAvailablePort() { + let port = StateManager.settings_startingServerPort; + while (this.serversState[port]) port++; + + return port; + } +} diff --git a/src/workbench/stateManager.ts b/src/workbench/stateManager.ts index 85bac00..0411f93 100644 --- a/src/workbench/stateManager.ts +++ b/src/workbench/stateManager.ts @@ -1,132 +1,188 @@ -import { GraphQLSchema } from "graphql"; -import { ExtensionContext, window, workspace, StatusBarItem } from "vscode"; -import { getUserMemberships } from "../graphql/graphClient"; -import { FieldWithType } from "./federationCompletionProvider"; -import { ApolloStudioGraphsTreeDataProvider } from "./tree-data-providers/apolloStudioGraphsTreeDataProvider"; -import { ApolloStudioGraphOpsTreeDataProvider } from "./tree-data-providers/apolloStudioGraphOpsTreeDataProvider"; -import { LocalSupergraphTreeDataProvider } from "./tree-data-providers/superGraphTreeDataProvider"; +import { GraphQLSchema } from 'graphql'; +import { ExtensionContext, window, workspace, StatusBarItem } from 'vscode'; +import { getUserMemberships } from '../graphql/graphClient'; +import { FieldWithType } from './federationCompletionProvider'; +import { ApolloStudioGraphsTreeDataProvider } from './tree-data-providers/apolloStudioGraphsTreeDataProvider'; +import { ApolloStudioGraphOpsTreeDataProvider } from './tree-data-providers/apolloStudioGraphOpsTreeDataProvider'; +import { LocalSupergraphTreeDataProvider } from './tree-data-providers/superGraphTreeDataProvider'; export class StateManager { - context?: ExtensionContext; + context?: ExtensionContext; - private static _instance: StateManager; - static get instance(): StateManager { - if (!this._instance) - throw new Error('You must call init() before using the state manager'); + private static _instance: StateManager; + static get instance(): StateManager { + if (!this._instance) + throw new Error('You must call init() before using the state manager'); - return this._instance; - } - constructor(context: ExtensionContext) { - this.context = context; - } + return this._instance; + } + constructor(context: ExtensionContext) { + this.context = context; + } - static init(context: ExtensionContext) { - this._instance = new StateManager(context); - } + static init(context: ExtensionContext) { + this._instance = new StateManager(context); + } - apolloStudioGraphsProvider: ApolloStudioGraphsTreeDataProvider = new ApolloStudioGraphsTreeDataProvider(workspace.rootPath ?? ".");; - apolloStudioGraphOpsProvider: ApolloStudioGraphOpsTreeDataProvider = new ApolloStudioGraphOpsTreeDataProvider(); - localSupergraphTreeDataProvider: LocalSupergraphTreeDataProvider = new LocalSupergraphTreeDataProvider(); + apolloStudioGraphsProvider: ApolloStudioGraphsTreeDataProvider = new ApolloStudioGraphsTreeDataProvider( + workspace.rootPath ?? '.', + ); + apolloStudioGraphOpsProvider: ApolloStudioGraphOpsTreeDataProvider = new ApolloStudioGraphOpsTreeDataProvider(); + localSupergraphTreeDataProvider: LocalSupergraphTreeDataProvider = new LocalSupergraphTreeDataProvider(); - get extensionGlobalStoragePath(): string | undefined { - try { - //Running version 1.49+ - return this.context?.globalStorageUri?.fsPath; - } catch (err) { - //Running version 1.48 or lower - return this.context?.globalStoragePath; - } - } + get extensionGlobalStoragePath(): string | undefined { + try { + //Running version 1.49+ + return this.context?.globalStorageUri?.fsPath; + } catch (err) { + //Running version 1.48 or lower + return this.context?.globalStoragePath; + } + } - static get workspaceRoot(): string | undefined { - return workspace.workspaceFolders ? workspace.workspaceFolders[0]?.uri?.fsPath : undefined; - } + static get workspaceRoot(): string | undefined { + return workspace.workspaceFolders + ? workspace.workspaceFolders[0]?.uri?.fsPath + : undefined; + } - static get settings_startingServerPort(): number { - return workspace?.getConfiguration("apollo-workbench")?.get('startingServerPort') ?? 4000 as number; - } - static get settings_gatewayServerPort(): number { - return workspace?.getConfiguration("apollo-workbench")?.get('gatewayPort') ?? 4001 as number; - } - static get settings_apiKey() { - return workspace.getConfiguration("apollo-workbench").get('graphApiKey') as string ?? process.env.APOLLO_KEY ?? ""; - } - static get settings_graphVariant() { - return workspace.getConfiguration("apollo-workbench").get('graphVariant') as string ?? process.env.APOLLO_GRAPH_VARIANT ?? ""; - } - static get settings_daysOfOperationsToFetch(): number { - return workspace.getConfiguration("apollo-workbench").get('daysOfOperationsToFetch') as number;; - } - static get settings_shouldRunOpRegistry() { - return workspace.getConfiguration("apollo-workbench").get('runOperationRegistry') as boolean; - } - static get settings_gatewayReCompositionInterval() { - return workspace.getConfiguration("apollo-workbench").get('gatewayReCompositionInterval') as number; - } - static get settings_displayGettingStarted() { - return workspace.getConfiguration("apollo-workbench").get('displayGettingStarted') as boolean; - } - static get settings_displayExampleGraphs() { - return workspace.getConfiguration("apollo-workbench").get('displayExampleGraphs') as boolean; - } - static get settings_tlsRejectUnauthorized() { - return workspace.getConfiguration("apollo-workbench").get('tlsRejectUnauthorized') as boolean; - } - static get settings_headersToForwardFromGateway() { - return workspace.getConfiguration("apollo-workbench").get('headersToForwardFromGateway') as Array; - } - static get settings_apolloOrg() { - return workspace.getConfiguration("apollo-workbench").get('apolloOrg') as string; - } - get globalState_userApiKey() { - return this.context?.globalState.get('APOLLO_KEY') as string; - } - set globalState_userApiKey(apiKey: string) { - this.context?.globalState.update('APOLLO_KEY', apiKey); + static get settings_startingServerPort(): number { + return ( + workspace + ?.getConfiguration('apollo-workbench') + ?.get('startingServerPort') ?? (4000 as number) + ); + } + static get settings_gatewayServerPort(): number { + return ( + workspace?.getConfiguration('apollo-workbench')?.get('gatewayPort') ?? + (4001 as number) + ); + } + static get settings_apiKey() { + return ( + (workspace + .getConfiguration('apollo-workbench') + .get('graphApiKey') as string) ?? + process.env.APOLLO_KEY ?? + '' + ); + } + static get settings_graphVariant() { + return ( + (workspace + .getConfiguration('apollo-workbench') + .get('graphVariant') as string) ?? + process.env.APOLLO_GRAPH_VARIANT ?? + '' + ); + } + static get settings_daysOfOperationsToFetch(): number { + return workspace + .getConfiguration('apollo-workbench') + .get('daysOfOperationsToFetch') as number; + } + static get settings_shouldRunOpRegistry() { + return workspace + .getConfiguration('apollo-workbench') + .get('runOperationRegistry') as boolean; + } + static get settings_gatewayReCompositionInterval() { + return workspace + .getConfiguration('apollo-workbench') + .get('gatewayReCompositionInterval') as number; + } + static get settings_displayGettingStarted() { + return workspace + .getConfiguration('apollo-workbench') + .get('displayGettingStarted') as boolean; + } + static get settings_displayExampleGraphs() { + return workspace + .getConfiguration('apollo-workbench') + .get('displayExampleGraphs') as boolean; + } + static get settings_tlsRejectUnauthorized() { + return workspace + .getConfiguration('apollo-workbench') + .get('tlsRejectUnauthorized') as boolean; + } + static get settings_headersToForwardFromGateway() { + return workspace + .getConfiguration('apollo-workbench') + .get('headersToForwardFromGateway') as Array; + } + static get settings_apolloOrg() { + return workspace + .getConfiguration('apollo-workbench') + .get('apolloOrg') as string; + } + get globalState_userApiKey() { + return this.context?.globalState.get('APOLLO_KEY') as string; + } + set globalState_userApiKey(apiKey: string) { + this.context?.globalState.update('APOLLO_KEY', apiKey); - if (!apiKey) this.globalState_selectedApolloAccount = ""; + if (!apiKey) this.globalState_selectedApolloAccount = ''; - this.apolloStudioGraphsProvider.refresh(); - this.apolloStudioGraphOpsProvider.refresh(); - this.localSupergraphTreeDataProvider.refresh(); - } - get globalState_selectedApolloAccount() { - if (StateManager.settings_apolloOrg) return StateManager.settings_apolloOrg; - return this.context?.globalState.get('APOLLO_SELCTED_ACCOUNT') as string; - } - set globalState_selectedApolloAccount(accountId: string) { - this.context?.globalState.update("APOLLO_SELCTED_ACCOUNT", accountId); - } - setSelectedGraph(graphId: string, variant?: string) { - this.context?.globalState.update("APOLLO_SELCTED_GRAPH_ID", graphId); - this.context?.globalState.update("APOLLO_SELCTED_GRAPH_VARIANT", variant); + this.apolloStudioGraphsProvider.refresh(); + this.apolloStudioGraphOpsProvider.refresh(); + this.localSupergraphTreeDataProvider.refresh(); + } + get globalState_selectedApolloAccount() { + if (StateManager.settings_apolloOrg) return StateManager.settings_apolloOrg; + return this.context?.globalState.get('APOLLO_SELCTED_ACCOUNT') as string; + } + set globalState_selectedApolloAccount(accountId: string) { + this.context?.globalState.update('APOLLO_SELCTED_ACCOUNT', accountId); + } + setSelectedGraph(graphId: string, variant?: string) { + this.context?.globalState.update('APOLLO_SELCTED_GRAPH_ID', graphId); + this.context?.globalState.update('APOLLO_SELCTED_GRAPH_VARIANT', variant); - this.apolloStudioGraphOpsProvider.refresh(); - } - get globalState_selectedGraphVariant() { - return this.context?.globalState.get('APOLLO_SELCTED_GRAPH_VARIANT') as string; - } - get globalState_selectedGraph() { - return this.context?.globalState.get('APOLLO_SELCTED_GRAPH_ID') as string; - } - // set globalState_selectedGraph(graphId: string) { - // this.context?.globalState.update("APOLLO_SELCTED_GRAPH_ID", graphId); + this.apolloStudioGraphOpsProvider.refresh(); + } + get globalState_selectedGraphVariant() { + return this.context?.globalState.get( + 'APOLLO_SELCTED_GRAPH_VARIANT', + ) as string; + } + get globalState_selectedGraph() { + return this.context?.globalState.get('APOLLO_SELCTED_GRAPH_ID') as string; + } + // set globalState_selectedGraph(graphId: string) { + // this.context?.globalState.update("APOLLO_SELCTED_GRAPH_ID", graphId); - // this.apolloStudioGraphOpsProvider.refresh(); - // } - get workspaceState_selectedWorkbenchAvailableEntities() { - return this.context?.workspaceState.get('selectedWorkbenchAvailableEntities') as { [serviceName: string]: { type: string, keys: { [key: string]: FieldWithType[] } }[] }; - } - set workspaceState_selectedWorkbenchAvailableEntities(entities: { [serviceName: string]: { type: string, keys: { [key: string]: FieldWithType[] } }[] }) { - this.context?.workspaceState.update('selectedWorkbenchAvailableEntities', entities); - } - clearWorkspaceSchema() { - this.context?.workspaceState.update("schema", undefined); - } - get workspaceState_schema() { - return this.context?.workspaceState.get("schema") as GraphQLSchema; - } - set workspaceState_schema(schema: GraphQLSchema) { - this.context?.workspaceState.update("schema", schema); - } -} \ No newline at end of file + // this.apolloStudioGraphOpsProvider.refresh(); + // } + get workspaceState_selectedWorkbenchAvailableEntities() { + return this.context?.workspaceState.get( + 'selectedWorkbenchAvailableEntities', + ) as { + [serviceName: string]: { + type: string; + keys: { [key: string]: FieldWithType[] }; + }[]; + }; + } + set workspaceState_selectedWorkbenchAvailableEntities(entities: { + [serviceName: string]: { + type: string; + keys: { [key: string]: FieldWithType[] }; + }[]; + }) { + this.context?.workspaceState.update( + 'selectedWorkbenchAvailableEntities', + entities, + ); + } + clearWorkspaceSchema() { + this.context?.workspaceState.update('schema', undefined); + } + get workspaceState_schema() { + return this.context?.workspaceState.get('schema') as GraphQLSchema; + } + set workspaceState_schema(schema: GraphQLSchema) { + this.context?.workspaceState.update('schema', schema); + } +} diff --git a/src/workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider.ts b/src/workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider.ts index db882ec..3cfa784 100644 --- a/src/workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider.ts +++ b/src/workbench/tree-data-providers/apolloStudioGraphOpsTreeDataProvider.ts @@ -3,73 +3,104 @@ import { getGraphOps } from '../../graphql/graphClient'; import { StateManager } from '../stateManager'; import { NotLoggedInTreeItem } from './apolloStudioGraphsTreeDataProvider'; -export class ApolloStudioGraphOpsTreeDataProvider implements vscode.TreeDataProvider { - private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); - readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; +export class ApolloStudioGraphOpsTreeDataProvider + implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter< + vscode.TreeItem | undefined + > = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this + ._onDidChangeTreeData.event; - refresh(): void { - this._onDidChangeTreeData.fire(undefined); - } - - getTreeItem(element: vscode.TreeItem): vscode.TreeItem { - return element; - } - - async getChildren(element?: any): Promise { - if (element) - return element.versions ?? element.operations; + refresh(): void { + this._onDidChangeTreeData.fire(undefined); + } - let noOperationsFoundMessage = ''; - let items: { [operationName: string]: { operationId: string, operationSignature: string } } = {}; - let apiKey = StateManager.instance.globalState_userApiKey; - if (!apiKey) return [new NotLoggedInTreeItem()]; + getTreeItem(element: vscode.TreeItem): vscode.TreeItem { + return element; + } - let selectedGraphId = StateManager.instance.globalState_selectedGraph; - let graphVariant = StateManager.instance.globalState_selectedGraphVariant; - if (selectedGraphId) { - //Create objects for next for loop - // Return A specific account with all graphs - let graphOps = await getGraphOps(apiKey, selectedGraphId, graphVariant); + async getChildren(element?: any): Promise { + if (element) return element.versions ?? element.operations; - noOperationsFoundMessage = graphVariant ? `No operations found for ${graphOps.service?.title}@${graphVariant}` : `No operations found for ${graphOps.service?.title}`; - if (graphOps?.service?.stats?.queryStats) { - graphOps?.service?.stats?.queryStats.map(queryStat => { - if (queryStat.groupBy.queryName && queryStat.groupBy.queryId && queryStat.groupBy.querySignature) { - items[queryStat.groupBy.queryName] = { operationId: queryStat.groupBy.queryId, operationSignature: queryStat.groupBy.querySignature }; - } - }) - } - } else return [new vscode.TreeItem('Select a graph above to load operations from Apollo Studio', vscode.TreeItemCollapsibleState.None)] + let noOperationsFoundMessage = ''; + let items: { + [operationName: string]: { + operationId: string; + operationSignature: string; + }; + } = {}; + let apiKey = StateManager.instance.globalState_userApiKey; + if (!apiKey) return [new NotLoggedInTreeItem()]; - let itemsToReturn: vscode.TreeItem[] = new Array(); + let selectedGraphId = StateManager.instance.globalState_selectedGraph; + let graphVariant = StateManager.instance.globalState_selectedGraphVariant; + if (selectedGraphId) { + //Create objects for next for loop + // Return A specific account with all graphs + let graphOps = await getGraphOps(apiKey, selectedGraphId, graphVariant); - for (var operationName in items) { - let op = items[operationName]; - itemsToReturn.push(new StudioOperationTreeItem(op.operationId, operationName, op.operationSignature)); - } + noOperationsFoundMessage = graphVariant + ? `No operations found for ${graphOps.service?.title}@${graphVariant}` + : `No operations found for ${graphOps.service?.title}`; + if (graphOps?.service?.stats?.queryStats) { + graphOps?.service?.stats?.queryStats.map((queryStat) => { + if ( + queryStat.groupBy.queryName && + queryStat.groupBy.queryId && + queryStat.groupBy.querySignature + ) { + items[queryStat.groupBy.queryName] = { + operationId: queryStat.groupBy.queryId, + operationSignature: queryStat.groupBy.querySignature, + }; + } + }); + } + } else + return [ + new vscode.TreeItem( + 'Select a graph above to load operations from Apollo Studio', + vscode.TreeItemCollapsibleState.None, + ), + ]; - if (itemsToReturn.length > 0) - return itemsToReturn; + let itemsToReturn: vscode.TreeItem[] = new Array(); - - return [new vscode.TreeItem(`${noOperationsFoundMessage} in last ${StateManager.settings_daysOfOperationsToFetch} days`, vscode.TreeItemCollapsibleState.None)]; + for (var operationName in items) { + let op = items[operationName]; + itemsToReturn.push( + new StudioOperationTreeItem( + op.operationId, + operationName, + op.operationSignature, + ), + ); } + if (itemsToReturn.length > 0) return itemsToReturn; + + return [ + new vscode.TreeItem( + `${noOperationsFoundMessage} in last ${StateManager.settings_daysOfOperationsToFetch} days`, + vscode.TreeItemCollapsibleState.None, + ), + ]; + } } export class StudioOperationTreeItem extends vscode.TreeItem { - constructor( - public readonly operationId: string, - public readonly operationName: string, - public readonly operationSignature: string - ) { - super(operationName, vscode.TreeItemCollapsibleState.None); - this.contextValue = 'studioOperationTreeItem'; - this.description = `id:${operationId.substring(0, 6)}`; - this.command = { - title: "View Operation", - command: "studio-graphs.viewStudioOperation", - arguments: [this] - } - } -} \ No newline at end of file + constructor( + public readonly operationId: string, + public readonly operationName: string, + public readonly operationSignature: string, + ) { + super(operationName, vscode.TreeItemCollapsibleState.None); + this.contextValue = 'studioOperationTreeItem'; + this.description = `id:${operationId.substring(0, 6)}`; + this.command = { + title: 'View Operation', + command: 'studio-graphs.viewStudioOperation', + arguments: [this], + }; + } +} diff --git a/src/workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider.ts b/src/workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider.ts index f6b5486..a22a11b 100644 --- a/src/workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider.ts +++ b/src/workbench/tree-data-providers/apolloStudioGraphsTreeDataProvider.ts @@ -1,208 +1,248 @@ import path from 'path'; -import { getAccountGraphs, getUserMemberships } from '../../graphql/graphClient'; +import { + getAccountGraphs, + getUserMemberships, +} from '../../graphql/graphClient'; import { StateManager } from '../stateManager'; -import { TreeItem, TreeDataProvider, EventEmitter, Event, window, commands, TreeItemCollapsibleState } from 'vscode'; +import { + TreeItem, + TreeDataProvider, + EventEmitter, + Event, + window, + commands, + TreeItemCollapsibleState, +} from 'vscode'; import { FileProvider } from '../file-system/fileProvider'; - -export class ApolloStudioGraphsTreeDataProvider implements TreeDataProvider { - constructor(private workspaceRoot: string) { } - - private _onDidChangeTreeData: EventEmitter = new EventEmitter(); - readonly onDidChangeTreeData: Event = this._onDidChangeTreeData.event; - - refresh(): void { - this._onDidChangeTreeData.fire(undefined); - } - - getTreeItem(element: TreeItem): TreeItem { - return element; - } - - async getChildren(element?: StudioAccountTreeItem): Promise { - if (element) return element.children; - let items: TreeItem[] = new Array(); - - let apiKey = StateManager.instance.globalState_userApiKey; - if (apiKey) { - let accountId = StateManager.instance.globalState_selectedApolloAccount; - if (!accountId) { - const myAccountIds = await getUserMemberships(apiKey); - const memberships = (myAccountIds?.me as any)?.memberships; - if (memberships?.length > 1) { - let accountIds: string[] = new Array(); - memberships.map(membership => accountIds.push(membership.account.id)); - - accountId = await window.showQuickPick(accountIds, { placeHolder: "Select an account to load graphs from" }) ?? ""; - } else { - accountId = memberships[0]?.account?.id ?? ""; - } +export class ApolloStudioGraphsTreeDataProvider + implements TreeDataProvider { + constructor(private workspaceRoot: string) {} + + private _onDidChangeTreeData: EventEmitter< + TreeItem | undefined + > = new EventEmitter(); + readonly onDidChangeTreeData: Event = this + ._onDidChangeTreeData.event; + + refresh(): void { + this._onDidChangeTreeData.fire(undefined); + } + + getTreeItem(element: TreeItem): TreeItem { + return element; + } + + async getChildren(element?: StudioAccountTreeItem): Promise { + if (element) return element.children; + let items: TreeItem[] = new Array(); + + let apiKey = StateManager.instance.globalState_userApiKey; + if (apiKey) { + let accountId = StateManager.instance.globalState_selectedApolloAccount; + if (!accountId) { + const myAccountIds = await getUserMemberships(apiKey); + const memberships = (myAccountIds?.me as any)?.memberships; + if (memberships?.length > 1) { + let accountIds: string[] = new Array(); + memberships.map((membership) => + accountIds.push(membership.account.id), + ); + + accountId = + (await window.showQuickPick(accountIds, { + placeHolder: 'Select an account to load graphs from', + })) ?? ''; + } else { + accountId = memberships[0]?.account?.id ?? ''; + } + } + + if (accountId) { + StateManager.instance.globalState_selectedApolloAccount = accountId; + + //Create objects for next for loop + // Return A specific account with all graphs + let services = await getAccountGraphs(apiKey, accountId); + let accountTreeItem = new StudioAccountTreeItem( + accountId, + services?.account?.name, + ); + + if (services?.account?.services) { + let accountServiceTreeItems = new Array(); + + for (var j = 0; j < services?.account?.services.length ?? 0; j++) { + //Cast graph + let graph = services?.account?.services[j]; + if (graph.devGraphOwner?.id) { + continue; } - - if (accountId) { - StateManager.instance.globalState_selectedApolloAccount = accountId; - - //Create objects for next for loop - // Return A specific account with all graphs - let services = await getAccountGraphs(apiKey, accountId); - let accountTreeItem = new StudioAccountTreeItem(accountId, services?.account?.name); - - if (services?.account?.services) { - let accountServiceTreeItems = new Array(); - - for (var j = 0; j < services?.account?.services.length ?? 0; j++) { - //Cast graph - let graph = services?.account?.services[j]; - if (graph.devGraphOwner?.id) { - continue; - } - //Create objects for next for loop - // Return A specific Graph with all variants - let graphTreeItem = new StudioGraphTreeItem(graph.id, graph.title); - let graphVariantTreeItems = new Array(); - - //Loop through graph variants and add to return objects - for (var k = 0; k < graph.variants.length; k++) { - //Cast graph variant - let graphVariant = graph.variants[k]; - graphTreeItem.variants.push(graphVariant.name); - - let accountgraphVariantTreeItem = new StudioGraphVariantTreeItem(graph.id, graphVariant.name); - graphVariantTreeItems.push(accountgraphVariantTreeItem); - } - if (graphVariantTreeItems.length == 0) - graphVariantTreeItems.push(new StudioGraphVariantTreeItem(graph.id, 'current')); - - //Set the implementing service tree items on the return objects - graphTreeItem.children = graphVariantTreeItems; - accountServiceTreeItems.push(graphTreeItem); - } - - accountTreeItem.children = accountServiceTreeItems; - } - items.push(accountTreeItem); + //Create objects for next for loop + // Return A specific Graph with all variants + let graphTreeItem = new StudioGraphTreeItem(graph.id, graph.title); + let graphVariantTreeItems = new Array(); + + //Loop through graph variants and add to return objects + for (var k = 0; k < graph.variants.length; k++) { + //Cast graph variant + let graphVariant = graph.variants[k]; + graphTreeItem.variants.push(graphVariant.name); + + let accountgraphVariantTreeItem = new StudioGraphVariantTreeItem( + graph.id, + graphVariant.name, + ); + graphVariantTreeItems.push(accountgraphVariantTreeItem); } + if (graphVariantTreeItems.length == 0) + graphVariantTreeItems.push( + new StudioGraphVariantTreeItem(graph.id, 'current'), + ); - if (StateManager.settings_displayExampleGraphs) - items.push(new PreloadedWorkbenchTopLevel()); - } else { - items.push(new NotLoggedInTreeItem()); - items.push(new NotLoggedInTreeItem("Login to see Example Graphs")); - window.showInformationMessage('No user api key was found.', "Login").then(response => { - if (response === "Login") - commands.executeCommand("extension.enterStudioApiKey"); - }); - } + //Set the implementing service tree items on the return objects + graphTreeItem.children = graphVariantTreeItems; + accountServiceTreeItems.push(graphTreeItem); + } - return items; + accountTreeItem.children = accountServiceTreeItems; + } + items.push(accountTreeItem); + } + + if (StateManager.settings_displayExampleGraphs) + items.push(new PreloadedWorkbenchTopLevel()); + } else { + items.push(new NotLoggedInTreeItem()); + items.push(new NotLoggedInTreeItem('Login to see Example Graphs')); + window + .showInformationMessage('No user api key was found.', 'Login') + .then((response) => { + if (response === 'Login') + commands.executeCommand('extension.enterStudioApiKey'); + }); } + + return items; + } } export class NotLoggedInTreeItem extends TreeItem { - constructor(message: string = "Click here to login with your user api key") { - super(message, TreeItemCollapsibleState.None); - this.command = { - title: "Login to Apollo", - command: "extension.enterStudioApiKey" - } - } + constructor(message: string = 'Click here to login with your user api key') { + super(message, TreeItemCollapsibleState.None); + this.command = { + title: 'Login to Apollo', + command: 'extension.enterStudioApiKey', + }; + } } export class StudioAccountTreeItem extends TreeItem { - children: StudioGraphTreeItem[] = new Array(); - - constructor( - public readonly accountId: string, - public readonly accountName?: string - ) { - super(accountName ?? accountId, TreeItemCollapsibleState.Expanded); - this.contextValue = 'studioAccountTreeItem'; - } - getChildren(element?: TreeItem): Thenable { - return new Promise(() => this.children); - } + children: StudioGraphTreeItem[] = new Array(); + + constructor( + public readonly accountId: string, + public readonly accountName?: string, + ) { + super(accountName ?? accountId, TreeItemCollapsibleState.Expanded); + this.contextValue = 'studioAccountTreeItem'; + } + getChildren(element?: TreeItem): Thenable { + return new Promise(() => this.children); + } } export class StudioGraphTreeItem extends TreeItem { - children: StudioGraphVariantTreeItem[] = new Array(); - variants: string[] = []; - - constructor( - public readonly graphId: string, - public readonly graphName: string - ) { - super(graphName, TreeItemCollapsibleState.Collapsed); - this.contextValue = 'studioGraphTreeItem'; - this.command = - { - title: "Load Graph Operations", - command: "studio-graphs.loadOperations", - arguments: [this] - } - } - getChildren(element?: TreeItem): Thenable { - return new Promise(() => this.children); - } + children: StudioGraphVariantTreeItem[] = new Array(); + variants: string[] = []; + + constructor( + public readonly graphId: string, + public readonly graphName: string, + ) { + super(graphName, TreeItemCollapsibleState.Collapsed); + this.contextValue = 'studioGraphTreeItem'; + this.command = { + title: 'Load Graph Operations', + command: 'studio-graphs.loadOperations', + arguments: [this], + }; + } + getChildren(element?: TreeItem): Thenable { + return new Promise(() => this.children); + } } export class StudioGraphVariantTreeItem extends TreeItem { - children: StudioGraphVariantServiceTreeItem[] = new Array(); - - constructor( - public readonly graphId: string, - public readonly graphVariant: string - ) { - super(graphVariant, TreeItemCollapsibleState.None); - this.contextValue = 'studioGraphVariantTreeItem'; - this.command = - { - title: "Load Graph Operations", - command: "studio-graphs.loadOperations", - arguments: [this, graphVariant] - } - } - getChildren(element?: TreeItem): Thenable { - return new Promise(() => this.children); - } + children: StudioGraphVariantServiceTreeItem[] = new Array(); + + constructor( + public readonly graphId: string, + public readonly graphVariant: string, + ) { + super(graphVariant, TreeItemCollapsibleState.None); + this.contextValue = 'studioGraphVariantTreeItem'; + this.command = { + title: 'Load Graph Operations', + command: 'studio-graphs.loadOperations', + arguments: [this, graphVariant], + }; + } + getChildren(element?: TreeItem): Thenable { + return new Promise(() => this.children); + } } export class StudioGraphVariantServiceTreeItem extends TreeItem { - constructor( - public readonly graphId: string, - public readonly graphVariant: string, - public readonly name, - public readonly sdl: string - ) { - super(name, TreeItemCollapsibleState.None); - this.contextValue = 'studioGraphVariantServiceTreeItem'; - this.iconPath = { - light: path.join(__filename, '..', '..', '..', '..', 'media', 'graphql-logo.png'), - dark: path.join(__filename, '..', '..', '..', '..', 'media', 'graphql-logo.png') - }; - } + constructor( + public readonly graphId: string, + public readonly graphVariant: string, + public readonly name, + public readonly sdl: string, + ) { + super(name, TreeItemCollapsibleState.None); + this.contextValue = 'studioGraphVariantServiceTreeItem'; + this.iconPath = { + light: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'graphql-logo.png', + ), + dark: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'graphql-logo.png', + ), + }; + } } export class PreloadedWorkbenchTopLevel extends TreeItem { - children: PreloadedWorkbenchFile[] = new Array(); + children: PreloadedWorkbenchFile[] = new Array(); - constructor() { - super("Example Graphs", TreeItemCollapsibleState.Collapsed); + constructor() { + super('Example Graphs', TreeItemCollapsibleState.Collapsed); - let preloadedFiles = FileProvider.instance?.getPreloadedWorkbenchFiles(); - preloadedFiles.map(preloadedFile => { - this.children.push(new PreloadedWorkbenchFile(preloadedFile.fileName)); - }) - } + let preloadedFiles = FileProvider.instance?.getPreloadedWorkbenchFiles(); + preloadedFiles.map((preloadedFile) => { + this.children.push(new PreloadedWorkbenchFile(preloadedFile.fileName)); + }); + } - getChildren(element?: PreloadedWorkbenchTopLevel): Thenable { - return new Promise(() => this.children); - } + getChildren(element?: PreloadedWorkbenchTopLevel): Thenable { + return new Promise(() => this.children); + } } export class PreloadedWorkbenchFile extends TreeItem { + constructor(public readonly fileName: string) { + super(fileName, TreeItemCollapsibleState.None); - constructor( - public readonly fileName: string - ) { - super(fileName, TreeItemCollapsibleState.None); - - this.contextValue = 'preloadedWorkbenchFile'; - } -} \ No newline at end of file + this.contextValue = 'preloadedWorkbenchFile'; + } +} diff --git a/src/workbench/tree-data-providers/superGraphTreeDataProvider.ts b/src/workbench/tree-data-providers/superGraphTreeDataProvider.ts index 479d253..34edc84 100644 --- a/src/workbench/tree-data-providers/superGraphTreeDataProvider.ts +++ b/src/workbench/tree-data-providers/superGraphTreeDataProvider.ts @@ -1,214 +1,325 @@ import * as path from 'path'; import { FileProvider } from '../file-system/fileProvider'; -import { TreeItem, TreeItemCollapsibleState, TreeDataProvider, EventEmitter, Event, window, Uri, ThemeIcon } from "vscode"; +import { + TreeItem, + TreeItemCollapsibleState, + TreeDataProvider, + EventEmitter, + Event, + window, + Uri, + ThemeIcon, +} from 'vscode'; import { ApolloWorkbenchFile, WorkbenchSchema } from '../file-system/fileTypes'; import { newDesign } from '../../commands/local-supergraph-designs'; import { StateManager } from '../stateManager'; -export class LocalSupergraphTreeDataProvider implements TreeDataProvider { - constructor() { } +export class LocalSupergraphTreeDataProvider + implements TreeDataProvider { + constructor() {} - private _onDidChangeTreeData: EventEmitter = new EventEmitter(); - readonly onDidChangeTreeData: Event = this._onDidChangeTreeData.event; + private _onDidChangeTreeData: EventEmitter = new EventEmitter(); + readonly onDidChangeTreeData: Event = this._onDidChangeTreeData + .event; - refresh(): void { - this._onDidChangeTreeData.fire(undefined); - } + refresh(): void { + this._onDidChangeTreeData.fire(undefined); + } - getTreeItem(element: SupergraphTreeItem): TreeItem { - return element; - } + getTreeItem(element: SupergraphTreeItem): TreeItem { + return element; + } + + getChildren(element?: TreeItem): Thenable { + if (element == undefined) { + let items = new Array(); + const workbenchFiles = FileProvider.instance.refreshLocalWorkbenchFiles(); + workbenchFiles.forEach((wbFile, wbFilePath) => { + items.push(new SupergraphTreeItem(wbFile, wbFilePath)); + }); + + if (items.length == 0) { + window + .showInformationMessage( + 'No workspace files found in current directory', + 'Create New Workbench', + ) + .then((value) => { + if (value === 'Create New Workbench') newDesign(); + }); + } + + return Promise.resolve(items); + } else { + switch (element.contextValue) { + case 'supergraphTreeItem': + const supergraphItem = element as SupergraphTreeItem; + let subgraphItem = element as SupergraphTreeItem; + + //Support legacy composition in workbench files + if ( + (supergraphItem.wbFile as any)?.composedSchema && + !subgraphItem.wbFile.supergraphSdl + ) { + subgraphItem.wbFile.supergraphSdl = (supergraphItem.wbFile as any)?.composedSchema; + delete (supergraphItem.wbFile as any)?.composedSchema; + } - getChildren(element?: TreeItem): Thenable { - if (element == undefined) { - let items = new Array(); - const workbenchFiles = FileProvider.instance.refreshLocalWorkbenchFiles(); - workbenchFiles.forEach((wbFile, wbFilePath) => { - items.push(new SupergraphTreeItem(wbFile, wbFilePath)); - }); - - if (items.length == 0) { - window.showInformationMessage("No workspace files found in current directory", "Create New Workbench").then((value) => { - if (value === "Create New Workbench") - newDesign(); - }); - } - - return Promise.resolve(items); - } else { - switch (element.contextValue) { - case 'supergraphTreeItem': - const supergraphItem = element as SupergraphTreeItem; - let subgraphItem = element as SupergraphTreeItem; - - //Support legacy composition in workbench files - if ((supergraphItem.wbFile as any)?.composedSchema && !subgraphItem.wbFile.supergraphSdl) { - subgraphItem.wbFile.supergraphSdl = (supergraphItem.wbFile as any)?.composedSchema; - delete (supergraphItem.wbFile as any)?.composedSchema; - } - - if (subgraphItem.wbFile.supergraphSdl) { - return Promise.resolve([ - new SupergraphSchemaTreeItem(supergraphItem.wbFile, supergraphItem.filePath), - new SupergraphApiSchemaTreeItem(supergraphItem.wbFile, supergraphItem.filePath), - supergraphItem.subgraphsChild, - supergraphItem.operationsChild] - ); - } else { - let invalidCompositionItem = new TreeItem("INVALID COMPOSITION", TreeItemCollapsibleState.None); - invalidCompositionItem.iconPath = new ThemeIcon('notebook-state-error'); - return Promise.resolve([invalidCompositionItem, subgraphItem.subgraphsChild, subgraphItem.operationsChild]); - } - case 'subgraphSummaryTreeItem': - return Promise.resolve((element as SubgraphSummaryTreeItem).subgraphs); - case 'operationSummaryTreeItem': - return Promise.resolve((element as OperationSummaryTreeItem).operations); - default: - return Promise.resolve([]); - } - } + if (subgraphItem.wbFile.supergraphSdl) { + return Promise.resolve([ + new SupergraphSchemaTreeItem( + supergraphItem.wbFile, + supergraphItem.filePath, + ), + new SupergraphApiSchemaTreeItem( + supergraphItem.wbFile, + supergraphItem.filePath, + ), + supergraphItem.subgraphsChild, + supergraphItem.operationsChild, + ]); + } else { + let invalidCompositionItem = new TreeItem( + 'INVALID COMPOSITION', + TreeItemCollapsibleState.None, + ); + invalidCompositionItem.iconPath = new ThemeIcon( + 'notebook-state-error', + ); + return Promise.resolve([ + invalidCompositionItem, + subgraphItem.subgraphsChild, + subgraphItem.operationsChild, + ]); + } + case 'subgraphSummaryTreeItem': + return Promise.resolve( + (element as SubgraphSummaryTreeItem).subgraphs, + ); + case 'operationSummaryTreeItem': + return Promise.resolve( + (element as OperationSummaryTreeItem).operations, + ); + default: + return Promise.resolve([]); + } } + } } export class SupergraphTreeItem extends TreeItem { - subgraphsChild: SubgraphSummaryTreeItem; - operationsChild: OperationSummaryTreeItem; - - constructor( - public readonly wbFile: ApolloWorkbenchFile, - public readonly filePath: string - ) { - super(wbFile.graphName, TreeItemCollapsibleState.Collapsed); - this.subgraphsChild = new SubgraphSummaryTreeItem(wbFile, filePath); - this.operationsChild = new OperationSummaryTreeItem(wbFile, filePath); - this.tooltip = this.wbFile.graphName; - - this.contextValue = 'supergraphTreeItem'; - } + subgraphsChild: SubgraphSummaryTreeItem; + operationsChild: OperationSummaryTreeItem; + + constructor( + public readonly wbFile: ApolloWorkbenchFile, + public readonly filePath: string, + ) { + super(wbFile.graphName, TreeItemCollapsibleState.Collapsed); + this.subgraphsChild = new SubgraphSummaryTreeItem(wbFile, filePath); + this.operationsChild = new OperationSummaryTreeItem(wbFile, filePath); + this.tooltip = this.wbFile.graphName; + + this.contextValue = 'supergraphTreeItem'; + } } export class SupergraphSchemaTreeItem extends TreeItem { - constructor( - public readonly wbFile: ApolloWorkbenchFile, - public readonly filePath: string - ) { - super("Supergraph Schema", TreeItemCollapsibleState.None); - this.contextValue = 'supergraphSchemaTreeItem'; - this.command = { - command: "local-supergraph-designs.viewSupergraphSchema", - title: "View Supergraph Schema", - arguments: [this] - }; - this.iconPath = path.join(__filename, '..', '..', '..', '..', 'media', 'supergraph.svg'); - } + constructor( + public readonly wbFile: ApolloWorkbenchFile, + public readonly filePath: string, + ) { + super('Supergraph Schema', TreeItemCollapsibleState.None); + this.contextValue = 'supergraphSchemaTreeItem'; + this.command = { + command: 'local-supergraph-designs.viewSupergraphSchema', + title: 'View Supergraph Schema', + arguments: [this], + }; + this.iconPath = path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'supergraph.svg', + ); + } } export class SupergraphApiSchemaTreeItem extends TreeItem { - constructor( - public readonly wbFile: ApolloWorkbenchFile, - public readonly filePath: string - ) { - super("API Schema", TreeItemCollapsibleState.None); - this.contextValue = 'supergraphApiSchemaTreeItem'; - this.command = { - command: "local-supergraph-designs.viewSupergraphApiSchema", - title: "View API Schema for Supergraph", - arguments: [this] - }; - this.iconPath = { - light: path.join(__filename, '..', '..', '..', '..', 'media', 'graphql-logo.png'), - dark: path.join(__filename, '..', '..', '..', '..', 'media', 'graphql-logo.png') - }; - } + constructor( + public readonly wbFile: ApolloWorkbenchFile, + public readonly filePath: string, + ) { + super('API Schema', TreeItemCollapsibleState.None); + this.contextValue = 'supergraphApiSchemaTreeItem'; + this.command = { + command: 'local-supergraph-designs.viewSupergraphApiSchema', + title: 'View API Schema for Supergraph', + arguments: [this], + }; + this.iconPath = { + light: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'graphql-logo.png', + ), + dark: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'graphql-logo.png', + ), + }; + } } export class SubgraphSummaryTreeItem extends TreeItem { - subgraphs: TreeItem[] = new Array(); - - constructor( - public readonly wbFile: ApolloWorkbenchFile, - public readonly filePath: string - ) { - super(`${Object.keys(wbFile.schemas).length} subgraphs`, TreeItemCollapsibleState.Expanded); - - this.tooltip = `${Object.keys(wbFile.schemas).length} Subgraphs`; - this.contextValue = 'subgraphSummaryTreeItem'; - - Object.keys(wbFile.schemas).forEach(subgraphName => { - this.subgraphs.push(new SubgraphTreeItem(wbFile.graphName, subgraphName, wbFile.schemas[subgraphName], filePath)) - }) - this.iconPath = { - light: path.join(__filename, '..', '..', '..', '..', 'media', 'subgraph.svg'), - dark: path.join(__filename, '..', '..', '..', '..', 'media', 'subgraph.svg') - }; - } + subgraphs: TreeItem[] = new Array(); + constructor( + public readonly wbFile: ApolloWorkbenchFile, + public readonly filePath: string, + ) { + super( + `${Object.keys(wbFile.schemas).length} subgraphs`, + TreeItemCollapsibleState.Expanded, + ); + + this.tooltip = `${Object.keys(wbFile.schemas).length} Subgraphs`; + this.contextValue = 'subgraphSummaryTreeItem'; + + Object.keys(wbFile.schemas).forEach((subgraphName) => { + this.subgraphs.push( + new SubgraphTreeItem( + wbFile.graphName, + subgraphName, + wbFile.schemas[subgraphName], + filePath, + ), + ); + }); + this.iconPath = { + light: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'subgraph.svg', + ), + dark: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'subgraph.svg', + ), + }; + } } export class SubgraphTreeItem extends TreeItem { - children: TreeItem[] = new Array(); - - constructor( - public readonly supergraphName: string, - public readonly subgraphName: string, - public readonly wbSchema: WorkbenchSchema, - public readonly wbFilePath: string - ) { - super(subgraphName, TreeItemCollapsibleState.None); - - this.contextValue = 'subgraphTreeItem'; - this.tooltip = this.subgraphName; - this.command = { - command: "local-supergraph-designs.editSubgraph", - title: "Edit Schema", - arguments: [this] - }; - this.iconPath = { - light: path.join(__filename, '..', '..', '..', '..', 'media', 'graphql-logo.png'), - dark: path.join(__filename, '..', '..', '..', '..', 'media', 'graphql-logo.png') - }; - } + children: TreeItem[] = new Array(); + + constructor( + public readonly supergraphName: string, + public readonly subgraphName: string, + public readonly wbSchema: WorkbenchSchema, + public readonly wbFilePath: string, + ) { + super(subgraphName, TreeItemCollapsibleState.None); + + this.contextValue = 'subgraphTreeItem'; + this.tooltip = this.subgraphName; + this.command = { + command: 'local-supergraph-designs.editSubgraph', + title: 'Edit Schema', + arguments: [this], + }; + this.iconPath = { + light: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'graphql-logo.png', + ), + dark: path.join( + __filename, + '..', + '..', + '..', + '..', + 'media', + 'graphql-logo.png', + ), + }; + } } export class OperationSummaryTreeItem extends TreeItem { - operations: TreeItem[] = new Array(); + operations: TreeItem[] = new Array(); - constructor( - public readonly wbFile: ApolloWorkbenchFile, - public readonly filePath: string - ) { - super(`${Object.keys(wbFile.operations).length} Operations`, TreeItemCollapsibleState.Collapsed); + constructor( + public readonly wbFile: ApolloWorkbenchFile, + public readonly filePath: string, + ) { + super( + `${Object.keys(wbFile.operations).length} Operations`, + TreeItemCollapsibleState.Collapsed, + ); - this.tooltip = `${Object.keys(wbFile.operations).length} operations`; - this.contextValue = 'operationSummaryTreeItem'; + this.tooltip = `${Object.keys(wbFile.operations).length} operations`; + this.contextValue = 'operationSummaryTreeItem'; - Object.keys(wbFile.operations).forEach(operationName => { - this.operations.push(new OperationTreeItem(operationName, wbFile.operations[operationName], filePath)) - }) - } + Object.keys(wbFile.operations).forEach((operationName) => { + this.operations.push( + new OperationTreeItem( + operationName, + wbFile.operations[operationName], + filePath, + ), + ); + }); + } } export class OperationTreeItem extends TreeItem { - children: TreeItem[] = new Array(); - - constructor( - public readonly operationName: string, - public readonly operationString: string, - public readonly filePath: string - ) { - super(operationName, TreeItemCollapsibleState.None); - - this.contextValue = 'operationTreeItem'; - this.tooltip = this.operationName; - this.command = { - command: "local-supergraph-designs.editOperation", - title: "Edit Operation", - arguments: [this] - }; - - if (this.operationString.includes('mutation')) - this.iconPath = { - light: path.join(__filename, '..', '..', '..', '..', 'media', 'm.svg'), - dark: path.join(__filename, '..', '..', '..', '..', 'media', 'm.svg') - }; - else - this.iconPath = { - light: path.join(__filename, '..', '..', '..', '..', 'media', 'q.svg'), - dark: path.join(__filename, '..', '..', '..', '..', 'media', 'q.svg') - }; - } -} \ No newline at end of file + children: TreeItem[] = new Array(); + + constructor( + public readonly operationName: string, + public readonly operationString: string, + public readonly filePath: string, + ) { + super(operationName, TreeItemCollapsibleState.None); + + this.contextValue = 'operationTreeItem'; + this.tooltip = this.operationName; + this.command = { + command: 'local-supergraph-designs.editOperation', + title: 'Edit Operation', + arguments: [this], + }; + + if (this.operationString.includes('mutation')) + this.iconPath = { + light: path.join(__filename, '..', '..', '..', '..', 'media', 'm.svg'), + dark: path.join(__filename, '..', '..', '..', '..', 'media', 'm.svg'), + }; + else + this.iconPath = { + light: path.join(__filename, '..', '..', '..', '..', 'media', 'q.svg'), + dark: path.join(__filename, '..', '..', '..', '..', 'media', 'q.svg'), + }; + } +}