diff --git a/README.md b/README.md index eddf2a9..2bedb59 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Use the Appwrite extension to quickly monitor, manage, and interact with your Appwrite instance directly from VS Code. -[![Version](https://vsmarketplacebadge.apphb.com/version/streamlux.vscode-appwrite.svg)](https://marketplace.visualstudio.com/items?itemName=streamlux.vscode-appwrite) [![Installs](https://vsmarketplacebadge.apphb.com/installs-short/streamlux.vscode-appwrite.svg)](https://marketplace.visualstudio.com/items?itemName=streamlux.vscode-appwrite) +[View on VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=streamlux.vscode-appwrite) ## What is Appwrite? diff --git a/package-lock.json b/package-lock.json index 2484cf5..cc233b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,113 +1,164 @@ { "name": "vscode-appwrite", - "version": "0.0.9", - "lockfileVersion": 1, + "version": "0.1.3", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "vscode-appwrite", + "version": "0.1.3", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "cron-validate": "^1.4.3", + "cronstrue": "^1.113.0", + "dayjs": "^1.10.4", + "fs-extra": "^9.1.0", + "node-appwrite": "^21.1.0", + "tar": "^6.1.0" + }, + "devDependencies": { + "@types/fs-extra": "^9.0.11", + "@types/glob": "^7.1.3", + "@types/mocha": "^8.0.4", + "@types/node": "^12.11.7", + "@types/tar": "^4.0.4", + "@types/vscode": "^1.55.0", + "@typescript-eslint/eslint-plugin": "^4.14.1", + "@typescript-eslint/parser": "^4.14.1", + "eslint": "^7.19.0", + "glob": "^7.1.6", + "mocha": "^8.2.1", + "ts-loader": "^8.0.14", + "typescript": "^4.1.3", + "vsce": "^1.88.0", + "vscode-test": "^1.5.0", + "webpack": "^5.19.0", + "webpack-cli": "^4.4.0" + }, + "engines": { + "vscode": "^1.55.0" + } + }, + "node_modules/@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": { + "dependencies": { "@babel/highlight": "^7.10.4" } }, - "@babel/helper-validator-identifier": { + "node_modules/@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": { + "node_modules/@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": { + "dependencies": { "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/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, "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 - }, - "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 - }, - "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" - } - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/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, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/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, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "@babel/runtime": { + "node_modules/@babel/runtime": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "requires": { + "dependencies": { "regenerator-runtime": "^0.13.4" } }, - "@discoveryjs/json-ext": { + "node_modules/@discoveryjs/json-ext": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==", - "dev": true + "dev": true, + "engines": { + "node": ">=10.0.0" + } }, - "@eslint/eslintrc": { + "node_modules/@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": { + "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", @@ -118,161 +169,183 @@ "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, "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" - } - }, - "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-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@nodelib/fs.scandir": { + "node_modules/@eslint/eslintrc/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", "dev": true, - "requires": { + "dependencies": { "@nodelib/fs.stat": "2.0.4", "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "@nodelib/fs.stat": { + "node_modules/@nodelib/fs.stat": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", - "dev": true + "dev": true, + "engines": { + "node": ">= 8" + } }, - "@nodelib/fs.walk": { + "node_modules/@nodelib/fs.walk": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", "dev": true, - "requires": { + "dependencies": { "@nodelib/fs.scandir": "2.1.4", "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "@tootallnate/once": { + "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true + "dev": true, + "engines": { + "node": ">= 6" + } }, - "@types/eslint": { + "node_modules/@types/eslint": { "version": "7.2.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", "dev": true, - "requires": { + "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "@types/eslint-scope": { + "node_modules/@types/eslint-scope": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", "dev": true, - "requires": { + "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, - "@types/estree": { + "node_modules/@types/estree": { "version": "0.0.46", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz", "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==", "dev": true }, - "@types/fs-extra": { + "node_modules/@types/fs-extra": { "version": "9.0.11", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.11.tgz", "integrity": "sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/glob": { + "node_modules/@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", "dev": true, - "requires": { + "dependencies": { "@types/minimatch": "*", "@types/node": "*" } }, - "@types/json-schema": { + "node_modules/@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/lodash": { + "node_modules/@types/lodash": { "version": "4.14.170", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz", "integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==" }, - "@types/minimatch": { + "node_modules/@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==", "dev": true }, - "@types/minipass": { + "node_modules/@types/minipass": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@types/minipass/-/minipass-2.2.0.tgz", "integrity": "sha512-wuzZksN4w4kyfoOv/dlpov4NOunwutLA/q7uc00xU02ZyUY+aoM5PWIXEKBMnm0NHd4a+N71BMjq+x7+2Af1fg==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/mocha": { + "node_modules/@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": { + "node_modules/@types/node": { "version": "12.20.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.10.tgz", "integrity": "sha512-TxCmnSSppKBBOzYzPR2BR25YlX5Oay8z2XGwFBInuA/Co0V9xJhLlW4kjbxKtgeNo3NOMbQP1A5Rc03y+XecPw==", "dev": true }, - "@types/tar": { + "node_modules/@types/tar": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/tar/-/tar-4.0.4.tgz", "integrity": "sha512-0Xv+xcmkTsOZdIF4yCnd7RkOOyfyqPaqJ7RZFKnwdxfDbkN3eAAE9sHl8zJFqBz4VhxolW9EErbjR1oyH7jK2A==", "dev": true, - "requires": { + "dependencies": { "@types/minipass": "*", "@types/node": "*" } }, - "@types/vscode": { + "node_modules/@types/vscode": { "version": "1.55.0", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.55.0.tgz", "integrity": "sha512-49hysH7jneTQoSC8TWbAi7nKK9Lc5osQNjmDHVosrcU8o3jecD9GrK0Qyul8q4aGPSXRfNGqIp9CBdb13akETg==", "dev": true }, - "@typescript-eslint/eslint-plugin": { + "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", "dev": true, - "requires": { + "dependencies": { "@typescript-eslint/experimental-utils": "4.22.0", "@typescript-eslint/scope-manager": "4.22.0", "debug": "^4.1.1", @@ -281,56 +354,111 @@ "regexpp": "^3.0.0", "semver": "^7.3.2", "tsutils": "^3.17.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "@typescript-eslint/experimental-utils": { + "node_modules/@typescript-eslint/experimental-utils": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", "dev": true, - "requires": { + "dependencies": { "@types/json-schema": "^7.0.3", "@typescript-eslint/scope-manager": "4.22.0", "@typescript-eslint/types": "4.22.0", "@typescript-eslint/typescript-estree": "4.22.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, - "@typescript-eslint/parser": { + "node_modules/@typescript-eslint/parser": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", "dev": true, - "requires": { + "dependencies": { "@typescript-eslint/scope-manager": "4.22.0", "@typescript-eslint/types": "4.22.0", "@typescript-eslint/typescript-estree": "4.22.0", "debug": "^4.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", "dev": true, - "requires": { + "dependencies": { "@typescript-eslint/types": "4.22.0", "@typescript-eslint/visitor-keys": "4.22.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==", - "dev": true + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", "dev": true, - "requires": { + "dependencies": { "@typescript-eslint/types": "4.22.0", "@typescript-eslint/visitor-keys": "4.22.0", "debug": "^4.1.1", @@ -338,111 +466,130 @@ "is-glob": "^4.0.1", "semver": "^7.3.2", "tsutils": "^3.17.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", "dev": true, - "requires": { + "dependencies": { "@typescript-eslint/types": "4.22.0", "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "@ungap/promise-all-settled": { + "node_modules/@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 }, - "@webassemblyjs/ast": { + "node_modules/@webassemblyjs/ast": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/helper-numbers": "1.11.0", "@webassemblyjs/helper-wasm-bytecode": "1.11.0" } }, - "@webassemblyjs/floating-point-hex-parser": { + "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", "dev": true }, - "@webassemblyjs/helper-api-error": { + "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", "dev": true }, - "@webassemblyjs/helper-buffer": { + "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", "dev": true }, - "@webassemblyjs/helper-numbers": { + "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.0", "@webassemblyjs/helper-api-error": "1.11.0", "@xtuc/long": "4.2.2" } }, - "@webassemblyjs/helper-wasm-bytecode": { + "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", "dev": true }, - "@webassemblyjs/helper-wasm-section": { + "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/ast": "1.11.0", "@webassemblyjs/helper-buffer": "1.11.0", "@webassemblyjs/helper-wasm-bytecode": "1.11.0", "@webassemblyjs/wasm-gen": "1.11.0" } }, - "@webassemblyjs/ieee754": { + "node_modules/@webassemblyjs/ieee754": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", "dev": true, - "requires": { + "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, - "@webassemblyjs/leb128": { + "node_modules/@webassemblyjs/leb128": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", "dev": true, - "requires": { + "dependencies": { "@xtuc/long": "4.2.2" } }, - "@webassemblyjs/utf8": { + "node_modules/@webassemblyjs/utf8": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", "dev": true }, - "@webassemblyjs/wasm-edit": { + "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/ast": "1.11.0", "@webassemblyjs/helper-buffer": "1.11.0", "@webassemblyjs/helper-wasm-bytecode": "1.11.0", @@ -453,12 +600,12 @@ "@webassemblyjs/wast-printer": "1.11.0" } }, - "@webassemblyjs/wasm-gen": { + "node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/ast": "1.11.0", "@webassemblyjs/helper-wasm-bytecode": "1.11.0", "@webassemblyjs/ieee754": "1.11.0", @@ -466,24 +613,24 @@ "@webassemblyjs/utf8": "1.11.0" } }, - "@webassemblyjs/wasm-opt": { + "node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/ast": "1.11.0", "@webassemblyjs/helper-buffer": "1.11.0", "@webassemblyjs/wasm-gen": "1.11.0", "@webassemblyjs/wasm-parser": "1.11.0" } }, - "@webassemblyjs/wasm-parser": { + "node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/ast": "1.11.0", "@webassemblyjs/helper-api-error": "1.11.0", "@webassemblyjs/helper-wasm-bytecode": "1.11.0", @@ -492,337 +639,439 @@ "@webassemblyjs/utf8": "1.11.0" } }, - "@webassemblyjs/wast-printer": { + "node_modules/@webassemblyjs/wast-printer": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", "dev": true, - "requires": { + "dependencies": { "@webassemblyjs/ast": "1.11.0", "@xtuc/long": "4.2.2" } }, - "@webpack-cli/configtest": { + "node_modules/@webpack-cli/configtest": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==", - "dev": true + "dev": true, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" + } }, - "@webpack-cli/info": { + "node_modules/@webpack-cli/info": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", "dev": true, - "requires": { + "dependencies": { "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" } }, - "@webpack-cli/serve": { + "node_modules/@webpack-cli/serve": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==", - "dev": true + "dev": true, + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } }, - "@xtuc/ieee754": { + "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "dev": true }, - "@xtuc/long": { + "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "acorn": { + "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "acorn-jsx": { + "node_modules/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 + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "agent-base": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" } }, - "ajv": { + "node_modules/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": { + "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "ajv-keywords": { + "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } }, - "ansi-colors": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "ansi-regex": { + "node_modules/ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { + "dependencies": { "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "anymatch": { + "node_modules/anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, - "requires": { + "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "argparse": { + "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "requires": { + "dependencies": { "sprintf-js": "~1.0.2" } }, - "array-union": { + "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "astral-regex": { + "node_modules/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 - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "dev": true, + "engines": { + "node": ">=8" + } }, - "at-least-node": { + "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" } }, - "azure-devops-node-api": { + "node_modules/azure-devops-node-api": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-10.2.2.tgz", "integrity": "sha512-4TVv2X7oNStT0vLaEfExmy3J4/CzfuXolEcQl/BRUmvGySqKStTG2O55/hUQ0kM7UJlZBLgniM0SBq4d/WkKow==", "dev": true, - "requires": { + "dependencies": { "tunnel": "0.0.6", "typed-rest-client": "^1.8.4" } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "big-integer": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.6" + } }, - "big.js": { + "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "binary": { + "node_modules/binary": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", "dev": true, - "requires": { + "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" } }, - "binary-extensions": { + "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "bluebird": { + "node_modules/bluebird": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", "dev": true }, - "boolbase": { + "node_modules/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": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { + "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "requires": { + "dependencies": { "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" } }, - "browser-stdout": { + "node_modules/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 }, - "browserslist": { + "node_modules/browserslist": { "version": "4.16.6", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, - "requires": { + "dependencies": { "caniuse-lite": "^1.0.30001219", "colorette": "^1.2.2", "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", "node-releases": "^1.1.71" }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.742", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz", - "integrity": "sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q==", - "dev": true - } + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/browserslist/node_modules/caniuse-lite": { + "version": "1.0.30001230", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", + "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, - "buffer-crc32": { + "node_modules/browserslist/node_modules/electron-to-chromium": { + "version": "1.3.742", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz", + "integrity": "sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q==", + "dev": true + }, + "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "buffer-from": { + "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "buffer-indexof-polyfill": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10" + } }, - "buffers": { + "node_modules/buffers": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.2.0" + } }, - "call-bind": { + "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "callsites": { + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "chainsaw": { + "node_modules/chainsaw": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", "dev": true, - "requires": { + "dependencies": { "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" } }, - "chalk": { + "node_modules/chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "cheerio": { + "node_modules/cheerio": { "version": "1.0.0-rc.9", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.9.tgz", "integrity": "sha512-QF6XVdrLONO6DXRF5iaolY+odmhj2CLj+xzNod7INPWMi/x9X4SOylH0S/vaPpX+AUU6t04s34SQNh7DbkuCng==", "dev": true, - "requires": { + "dependencies": { "cheerio-select": "^1.4.0", "dom-serializer": "^1.3.1", "domhandler": "^4.2.0", @@ -831,351 +1080,446 @@ "parse5-htmlparser2-tree-adapter": "^6.0.1", "tslib": "^2.2.0" }, - "dependencies": { - "tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", - "dev": true - } + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" } }, - "cheerio-select": { + "node_modules/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": { + "dependencies": { "css-select": "^4.1.2", "css-what": "^5.0.0", "domelementtype": "^2.2.0", "domhandler": "^4.2.0", "domutils": "^2.6.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "chokidar": { + "node_modules/cheerio/node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + }, + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" } }, - "chownr": { + "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } }, - "chrome-trace-event": { + "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.0" + } }, - "cliui": { + "node_modules/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": { + "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, - "clone-deep": { + "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, - "requires": { + "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "color-convert": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "color-name": { + "node_modules/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==", "dev": true }, - "colorette": { + "node_modules/colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, - "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": { + "node_modules/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==", "dev": true }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "core-util-is": { + "node_modules/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=", "dev": true }, - "cron-validate": { + "node_modules/cron-validate": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/cron-validate/-/cron-validate-1.4.3.tgz", "integrity": "sha512-N+qKw019oQBEPIP5Qwi8Z5XelQ00ThN6Maahwv+9UGu2u/b/MPb35zngMQI0T8pBoNiBrIXGlhvsmspNSYae/w==", - "requires": { + "dependencies": { "yup": "0.32.9" } }, - "cronstrue": { + "node_modules/cronstrue": { "version": "1.113.0", "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-1.113.0.tgz", "integrity": "sha512-j0+CQsQx0g0Iv6nQs0bHkLcpeCzYShWUdQ3QwSHV+dUyTLqI/3NPrHceeDfTXmC3Re4osMli5+wAYpffNO+e9w==" }, - "cross-spawn": { + "node_modules/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": { + "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "css-select": { + "node_modules/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": { + "dependencies": { "boolbase": "^1.0.0", "css-what": "^5.0.0", "domhandler": "^4.2.0", "domutils": "^2.6.0", "nth-check": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "css-what": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } }, - "dayjs": { + "node_modules/dayjs": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz", "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==" }, - "debug": { + "node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, - "requires": { + "dependencies": { "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "decamelize": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "deep-is": { + "node_modules/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 }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "denodeify": { + "node_modules/denodeify": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", "dev": true }, - "diff": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.3.1" + } }, - "dir-glob": { + "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "requires": { + "dependencies": { "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "doctrine": { + "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "requires": { + "dependencies": { "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "dom-serializer": { + "node_modules/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": { + "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "domelementtype": { + "node_modules/domelementtype": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] }, - "domhandler": { + "node_modules/domhandler": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", "dev": true, - "requires": { + "dependencies": { "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "domutils": { + "node_modules/domutils": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", "dev": true, - "requires": { + "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "duplexer2": { + "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, - "requires": { + "dependencies": { "readable-stream": "^2.0.2" } }, - "emoji-regex": { + "node_modules/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 }, - "emojis-list": { + "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">= 4" + } }, - "enhanced-resolve": { + "node_modules/enhanced-resolve": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.2", "memory-fs": "^0.5.0", "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "enquirer": { + "node_modules/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": { + "dependencies": { "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" } }, - "entities": { + "node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, - "envinfo": { + "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } }, - "errno": { + "node_modules/errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, - "requires": { + "dependencies": { "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" } }, - "es-module-lexer": { + "node_modules/es-module-lexer": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", "dev": true }, - "escalade": { + "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "eslint": { + "node_modules/eslint": { "version": "7.24.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.0", "ajv": "^6.10.0", @@ -1213,124 +1557,174 @@ "table": "^6.0.4", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "eslint-scope": { + "node_modules/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": { + "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" } }, - "eslint-utils": { + "node_modules/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": { + "dependencies": { "eslint-visitor-keys": "^1.1.0" }, - "dependencies": { - "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 - } + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "eslint-visitor-keys": { + "node_modules/eslint-utils/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/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 + "dev": true, + "engines": { + "node": ">=10" + } }, - "espree": { + "node_modules/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": { + "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" }, - "dependencies": { - "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 - } + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/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, + "engines": { + "node": ">=4" } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "esquery": { + "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, - "requires": { + "dependencies": { "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 - } + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "esrecurse": { + "node_modules/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": { + "dependencies": { "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 - } + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "estraverse": { + "node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "events": { + "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.x" + } }, - "execa": { + "node_modules/execa": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", "dev": true, - "requires": { + "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", @@ -1340,263 +1734,322 @@ "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "fast-deep-equal": { + "node_modules/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-glob": { + "node_modules/fast-glob": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, - "requires": { + "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.0", "merge2": "^1.3.0", "micromatch": "^4.0.2", "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" } }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "fast-levenshtein": { + "node_modules/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 }, - "fastest-levenshtein": { + "node_modules/fastest-levenshtein": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, - "fastq": { + "node_modules/fastq": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, - "requires": { + "dependencies": { "reusify": "^1.0.4" } }, - "fd-slicer": { + "node_modules/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": { + "dependencies": { "pend": "~1.2.0" } }, - "file-entry-cache": { + "node_modules/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": { + "dependencies": { "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "fill-range": { + "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "requires": { + "dependencies": { "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "find-up": { + "node_modules/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": { + "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "flat": { + "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true + "dev": true, + "bin": { + "flat": "cli.js" + } }, - "flat-cache": { + "node_modules/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": { + "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "flatted": { + "node_modules/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 }, - "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs-extra": { + "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { + "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "fs-minipass": { + "node_modules/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": { + "dependencies": { "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" } }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { + "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "optional": true + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, - "fstream": { + "node_modules/fstream": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", "mkdirp": ">=0.5 0", "rimraf": "2" }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, "dependencies": { - "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" - } - } + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { + "node_modules/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": { + "node_modules/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 + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "get-intrinsic": { + "node_modules/get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-stream": { + "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "glob": { + "node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "requires": { + "dependencies": { "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "glob-parent": { + "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "requires": { + "dependencies": { "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "glob-to-regexp": { + "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "globals": { + "node_modules/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": { + "dependencies": { "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "globby": { + "node_modules/globby": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, - "requires": { + "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.1.1", @@ -1604,554 +2057,745 @@ "merge2": "^1.3.0", "slash": "^3.0.0" }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" } }, - "graceful-fs": { + "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, - "growl": { + "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4.x" + } }, - "has": { + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-flag": { + "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "has-symbols": { + "node_modules/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==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "he": { + "node_modules/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 + "dev": true, + "bin": { + "he": "bin/he" + } }, - "htmlparser2": { + "node_modules/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": { + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", "domutils": "^2.5.2", "entities": "^2.0.0" } }, - "http-proxy-agent": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "@tootallnate/once": "1", "agent-base": "6", "debug": "4" + }, + "engines": { + "node": ">= 6" } }, - "https-proxy-agent": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "agent-base": "6", "debug": "4" + }, + "engines": { + "node": ">= 6" } }, - "human-signals": { + "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true + "dev": true, + "engines": { + "node": ">=10.17.0" + } }, - "ignore": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">= 4" + } }, - "import-fresh": { + "node_modules/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": { + "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "import-local": { + "node_modules/import-local": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", "dev": true, - "requires": { + "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "interpret": { + "node_modules/interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "is-binary-path": { + "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "requires": { + "dependencies": { "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "is-boolean-object": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-core-module": { + "node_modules/is-core-module": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", "dev": true, - "requires": { + "dependencies": { "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-fullwidth-code-point": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-glob": { + "node_modules/is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, - "requires": { + "dependencies": { "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-number": { + "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.12.0" + } }, - "is-number-object": { + "node_modules/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==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-plain-obj": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-plain-object": { + "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, - "requires": { + "dependencies": { "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-stream": { + "node_modules/is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-string": { + "node_modules/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==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "isarray": { + "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isobject": { + "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "jest-worker": { + "node_modules/jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "json-parse-better-errors": { + "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema-traverse": { + "node_modules/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": { + "node_modules/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 }, - "json5": { + "node_modules/json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, - "requires": { + "dependencies": { "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "jsonfile": { + "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", + "dependencies": { "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "kind-of": { + "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "leven": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "levn": { + "node_modules/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": { + "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "linkify-it": { + "node_modules/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": { + "dependencies": { "uc.micro": "^1.0.1" } }, - "listenercount": { + "node_modules/listenercount": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", "dev": true }, - "loader-runner": { + "node_modules/loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.11.5" + } }, - "loader-utils": { + "node_modules/loader-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "dev": true, - "requires": { + "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" } }, - "locate-path": { + "node_modules/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": { + "dependencies": { "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lodash": { + "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash-es": { + "node_modules/lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "lodash.clonedeep": { + "node_modules/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.flatten": { + "node_modules/lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", "dev": true }, - "lodash.truncate": { + "node_modules/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 }, - "log-symbols": { + "node_modules/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": { + "dependencies": { "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "lru-cache": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "markdown-it": { + "node_modules/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": { + "dependencies": { "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 - } + "bin": { + "markdown-it": "bin/markdown-it.js" } }, - "mdurl": { - "version": "1.0.1", + "node_modules/markdown-it/node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, + "node_modules/mdurl": { + "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", "dev": true }, - "memory-fs": { + "node_modules/memory-fs": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", "dev": true, - "requires": { + "dependencies": { "errno": "^0.1.3", "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" } }, - "merge-stream": { + "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "merge2": { + "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 8" + } }, - "micromatch": { + "node_modules/micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, - "requires": { + "dependencies": { "braces": "^3.0.1", "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" } }, - "mime": { + "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } }, - "mime-db": { + "node_modules/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==" + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/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": { + "dev": true, + "dependencies": { "mime-db": "1.47.0" + }, + "engines": { + "node": ">= 0.6" } }, - "mimic-fn": { + "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { + "node_modules/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": { + "node_modules/minipass": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "requires": { + "dependencies": { "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "minizlib": { + "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { + "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" } }, - "mkdirp": { + "node_modules/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": { + "dependencies": { "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "mocha": { + "node_modules/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": { + "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", @@ -2178,402 +2822,545 @@ "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/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 + }, + "node_modules/mocha/node_modules/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, "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 - }, - "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" - } - } + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "ms": { + "node_modules/mocha/node_modules/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 + }, + "node_modules/mocha/node_modules/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "mute-stream": { + "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "nanoclone": { + "node_modules/nanoclone": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, - "nanoid": { + "node_modules/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 + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } }, - "natural-compare": { + "node_modules/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 }, - "neo-async": { + "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node-appwrite": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/node-appwrite/-/node-appwrite-2.2.3.tgz", - "integrity": "sha512-2j7AIKUxbjN25QrqZfMBRuWVRYlB5fixmW0HF/XP5QnrttCfozjPa5wWrgVRrJLYCoqwe2wwgWc9S3fyZeP/0g==", - "requires": { - "axios": "^0.21.1", - "form-data": "^4.0.0" + "node_modules/node-appwrite": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/node-appwrite/-/node-appwrite-21.1.0.tgz", + "integrity": "sha512-HRK5BzN19vgvaH/EeNsigK24t4ngJ1AoiltK5JtahxP6uyMRztzkD8cXP+z9jj/xOjz7ySfQ9YypNyhNr6zVkA==", + "license": "BSD-3-Clause", + "dependencies": { + "node-fetch-native-with-agent": "1.7.2" } }, - "node-releases": { + "node_modules/node-fetch-native-with-agent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-fetch-native-with-agent/-/node-fetch-native-with-agent-1.7.2.tgz", + "integrity": "sha512-5MaOOCuJEvcckoz7/tjdx1M6OusOY6Xc5f459IaruGStWnKzlI1qpNgaAwmn4LmFYcsSlj+jBMk84wmmRxfk5g==", + "license": "MIT" + }, + "node_modules/node-releases": { "version": "1.1.71", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", "dev": true }, - "normalize-path": { + "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "npm-run-path": { + "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "requires": { + "dependencies": { "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "nth-check": { + "node_modules/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": { + "dependencies": { "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "object-inspect": { + "node_modules/object-inspect": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "onetime": { + "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { + "dependencies": { "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optionator": { + "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "requires": { + "dependencies": { "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" + }, + "engines": { + "node": ">= 0.8.0" } }, - "os-homedir": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "os-tmpdir": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "osenv": { + "node_modules/osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "deprecated": "This package is no longer supported.", "dev": true, - "requires": { + "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" } }, - "p-limit": { + "node_modules/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": { + "dependencies": { "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/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": { + "dependencies": { "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-try": { + "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "parent-module": { + "node_modules/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": { + "dependencies": { "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "parse-semver": { + "node_modules/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 - } + "semver": "^5.1.0" } }, - "parse5": { + "node_modules/parse-semver/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/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": { + "node_modules/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": { + "dependencies": { "parse5": "^6.0.1" } }, - "path-exists": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-type": { + "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "pend": { + "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "picomatch": { + "node_modules/picomatch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "requires": { + "dependencies": { "find-up": "^4.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "prelude-ls": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "process-nextick-args": { + "node_modules/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==", "dev": true }, - "progress": { + "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "property-expr": { + "node_modules/property-expr": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz", "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==" }, - "prr": { + "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, - "punycode": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "qs": { + "node_modules/qs": { "version": "6.10.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", "dev": true, - "requires": { + "dependencies": { "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "queue-microtask": { + "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "randombytes": { + "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "^5.1.0" } }, - "read": { + "node_modules/read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", "dev": true, - "requires": { + "dependencies": { "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" } }, - "readable-stream": { + "node_modules/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": { + "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", @@ -2581,305 +3368,423 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } } }, - "readdirp": { + "node_modules/readable-stream/node_modules/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 + }, + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "rechoir": { + "node_modules/rechoir": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", "dev": true, - "requires": { + "dependencies": { "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" } }, - "regenerator-runtime": { + "node_modules/regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, - "regexpp": { + "node_modules/regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } }, - "require-directory": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "require-from-string": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "resolve": { + "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, - "requires": { + "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-cwd": { + "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "requires": { + "dependencies": { "resolve-from": "^5.0.0" }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" } }, - "resolve-from": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=4" + } }, - "reusify": { + "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, - "rimraf": { + "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, - "requires": { + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "run-parallel": { + "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "requires": { + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { "queue-microtask": "^1.2.2" } }, - "safe-buffer": { + "node_modules/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==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "schema-utils": { + "node_modules/schema-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, - "requires": { + "dependencies": { "@types/json-schema": "^7.0.6", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "semver": { + "node_modules/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": { + "dependencies": { "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "serialize-javascript": { + "node_modules/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": { + "dependencies": { "randombytes": "^2.1.0" } }, - "setimmediate": { + "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, - "shallow-clone": { + "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, - "requires": { + "dependencies": { "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" } }, - "shebang-command": { + "node_modules/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": { + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=8" + } }, - "side-channel": { + "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "slash": { + "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "slice-ansi": { + "node_modules/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": { + "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "source-list-map": { + "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", "dev": true }, - "source-map": { + "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "source-map-support": { + "node_modules/source-map-support": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, - "requires": { + "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "string-width": { + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/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 + }, + "node_modules/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": { + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } + "engines": { + "node": ">=8" } }, - "strip-ansi": { + "node_modules/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": { + "dependencies": { "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "strip-json-comments": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "supports-color": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "table": { + "node_modules/table": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/table/-/table-6.1.0.tgz", "integrity": "sha512-T4G5KMmqIk6X87gLKWyU5exPpTjLjY5KyrFWaIjv3SvgaIUGXV7UEzGEnZJdTA38/yUS6f9PlKezQ0bYXG3iIQ==", "dev": true, - "requires": { + "dependencies": { "ajv": "^8.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", @@ -2890,38 +3795,47 @@ "slice-ansi": "^4.0.0", "string-width": "^4.2.0" }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", + "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", + "dev": true, "dependencies": { - "ajv": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", - "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", - "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 - } + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "tapable": { + "node_modules/table/node_modules/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 + }, + "node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "tar": { + "node_modules/tar": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "requires": { + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me", + "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^3.0.0", @@ -2929,171 +3843,239 @@ "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - } + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, - "terser": { + "node_modules/terser": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", "dev": true, - "requires": { + "dependencies": { "commander": "^2.20.0", "source-map": "~0.7.2", "source-map-support": "~0.5.19" }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" } }, - "terser-webpack-plugin": { + "node_modules/terser-webpack-plugin": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", "dev": true, - "requires": { + "dependencies": { "jest-worker": "^26.6.2", "p-limit": "^3.1.0", "schema-utils": "^3.0.0", "serialize-javascript": "^5.0.1", "source-map": "^0.6.1", "terser": "^5.5.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" } }, - "text-table": { + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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": { + "node_modules/tmp": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", "dev": true, - "requires": { + "dependencies": { "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" } }, - "to-regex-range": { + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "toposort": { + "node_modules/toposort": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=" }, - "traverse": { + "node_modules/traverse": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "ts-loader": { + "node_modules/ts-loader": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^4.0.0", "loader-utils": "^2.0.0", "micromatch": "^4.0.0", "semver": "^7.3.4" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "*" } }, - "tslib": { + "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "tsutils": { + "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "requires": { + "dependencies": { "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "tunnel": { + "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } }, - "type-check": { + "node_modules/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": { + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-fest": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "typed-rest-client": { + "node_modules/typed-rest-client": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.4.tgz", "integrity": "sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg==", "dev": true, - "requires": { + "dependencies": { "qs": "^6.9.1", "tunnel": "0.0.6", "underscore": "^1.12.1" } }, - "typescript": { + "node_modules/typescript": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", - "dev": true + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "uc.micro": { + "node_modules/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 }, - "underscore": { + "node_modules/underscore": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", "dev": true }, - "universalify": { + "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } }, - "unzipper": { + "node_modules/unzipper": { "version": "0.10.11", "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", "dev": true, - "requires": { + "dependencies": { "big-integer": "^1.6.17", "binary": "~0.3.0", "bluebird": "~3.4.1", @@ -3106,39 +4088,40 @@ "setimmediate": "~1.0.4" } }, - "uri-js": { + "node_modules/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": { + "dependencies": { "punycode": "^2.1.0" } }, - "url-join": { + "node_modules/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": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "v8-compile-cache": { + "node_modules/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 }, - "vsce": { + "node_modules/vsce": { "version": "1.88.0", "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.88.0.tgz", "integrity": "sha512-FS5ou3G+WRnPPr/tWVs8b/jVzeDacgZHy/y7/QQW7maSPFEAmRt2bFGUJtJVEUDLBqtDm/3VGMJ7D31cF2U1tw==", + "deprecated": "vsce has been renamed to @vscode/vsce. Install using @vscode/vsce instead.", "dev": true, - "requires": { + "dependencies": { "azure-devops-node-api": "^10.2.2", "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.1", @@ -3160,105 +4143,137 @@ "yauzl": "^2.3.1", "yazl": "^2.2.2" }, + "bin": { + "vsce": "out/vsce" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/vsce/node_modules/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, "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 - }, - "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 - }, - "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" - } - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "vscode-test": { + "node_modules/vsce/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/vsce/node_modules/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, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/vsce/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/vsce/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/vsce/node_modules/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, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/vsce/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/vsce/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/vsce/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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==", + "deprecated": "This package has been renamed to @vscode/test-electron, please update to the new name", "dev": true, - "requires": { + "dependencies": { "http-proxy-agent": "^4.0.1", "https-proxy-agent": "^5.0.0", "rimraf": "^3.0.2", "unzipper": "^0.10.11" + }, + "engines": { + "node": ">=8.9.3" } }, - "watchpack": { + "node_modules/watchpack": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", "dev": true, - "requires": { + "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" } }, - "webpack": { + "node_modules/webpack": { "version": "5.33.2", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.33.2.tgz", "integrity": "sha512-X4b7F1sYBmJx8mlh2B7mV5szEkE0jYNJ2y3akgAP0ERi0vLCG1VvdsIxt8lFd4st6SUy0lf7W0CCQS566MBpJg==", "dev": true, - "requires": { + "dependencies": { "@types/eslint-scope": "^3.7.0", "@types/estree": "^0.0.46", "@webassemblyjs/ast": "1.11.0", @@ -3283,37 +4298,28 @@ "watchpack": "^2.0.0", "webpack-sources": "^2.1.1" }, - "dependencies": { - "acorn": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", - "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", - "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true } } }, - "webpack-cli": { + "node_modules/webpack-cli": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", "dev": true, - "requires": { + "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^1.0.2", "@webpack-cli/info": "^1.2.3", @@ -3329,138 +4335,230 @@ "v8-compile-cache": "^2.2.0", "webpack-merge": "^5.7.3" }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true } } }, - "webpack-merge": { + "node_modules/webpack-cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-merge": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", "dev": true, - "requires": { + "dependencies": { "clone-deep": "^4.0.1", "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "webpack-sources": { + "node_modules/webpack-sources": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", "dev": true, - "requires": { + "dependencies": { "source-list-map": "^2.0.1", "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" } }, - "which": { + "node_modules/webpack/node_modules/acorn": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", + "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/enhanced-resolve": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", + "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "wide-align": { + "node_modules/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": { + "dependencies": { "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, "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" - } - } + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "wildcard": { + "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "dev": true }, - "word-wrap": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "workerpool": { + "node_modules/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": { + "node_modules/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": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "yallist": { + "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "yargs": { + "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "requires": { + "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", @@ -3468,56 +4566,71 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "yargs-parser": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=10" + } }, - "yargs-unparser": { + "node_modules/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": { + "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" } }, - "yauzl": { + "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, - "requires": { + "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, - "yazl": { + "node_modules/yazl": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", "dev": true, - "requires": { + "dependencies": { "buffer-crc32": "~0.2.3" } }, - "yocto-queue": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "yup": { + "node_modules/yup": { "version": "0.32.9", "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.9.tgz", "integrity": "sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==", - "requires": { + "dependencies": { "@babel/runtime": "^7.10.5", "@types/lodash": "^4.14.165", "lodash": "^4.17.20", @@ -3525,6 +4638,9 @@ "nanoclone": "^0.2.1", "property-expr": "^2.0.4", "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" } } } diff --git a/package.json b/package.json index 13b816a..56622cc 100644 --- a/package.json +++ b/package.json @@ -737,9 +737,9 @@ }, "scripts": { "vscode:prepublish": "npm run package", - "compile": "webpack", - "watch": "webpack --watch", - "package": "webpack --mode production --devtool hidden-source-map", + "compile": "NODE_OPTIONS=--openssl-legacy-provider webpack", + "watch": "NODE_OPTIONS=--openssl-legacy-provider webpack --watch", + "package": "NODE_OPTIONS=--openssl-legacy-provider webpack --mode production --devtool hidden-source-map", "test-compile": "tsc -p ./", "test-watch": "tsc -watch -p ./", "pretest": "npm run test-compile && npm run lint", @@ -770,7 +770,7 @@ "cronstrue": "^1.113.0", "dayjs": "^1.10.4", "fs-extra": "^9.1.0", - "node-appwrite": "^2.2.3", + "node-appwrite": "^21.1.0", "tar": "^6.1.0" } } diff --git a/resources/AppwriteIcon.png b/resources/AppwriteIcon.png index ad5860e..5d993a6 100644 Binary files a/resources/AppwriteIcon.png and b/resources/AppwriteIcon.png differ diff --git a/resources/vscode-appwrite.svg b/resources/vscode-appwrite.svg index 063d1d3..2034a81 100644 --- a/resources/vscode-appwrite.svg +++ b/resources/vscode-appwrite.svg @@ -1,5 +1,9 @@ - - - - - + + + + \ No newline at end of file diff --git a/src/appwrite.d.ts b/src/appwrite.d.ts index dda0ed0..33864b6 100644 --- a/src/appwrite.d.ts +++ b/src/appwrite.d.ts @@ -1,454 +1,784 @@ import { ReadStream } from 'fs'; -import { Stream } from 'node:stream'; + +// ============================================================================ +// Common Types +// ============================================================================ export type Token = { - /** - * Token ID. - */ $id: string; - /** - * User ID. - */ + $createdAt: string; + $updatedAt: string; userId: string; - /** - * Token secret key. This will return an empty string unless the response is returned using an API key or as part of a webhook payload. - */ secret: string; - /** - * Token expiration date in Unix timestamp. - */ - expire: number; + expire: string; + phrase: string; +}; + +export type Error = { + message: string; + code: number; + type: string; + version: string; }; +type ClientInfo = { + osCode: string; + osName: string; + osVersion: string; + clientType: string; + clientCode: string; + clientName: string; + clientVersion: string; + clientEngine: string; + clientEngineVersion: string; + deviceName: string; + deviceBrand: string; + deviceModel: string; + countryCode: string; + countryName: string; +}; + +// ============================================================================ +// User Types +// ============================================================================ + export type User = { - /** - * User ID. - */ $id: string; - /** - * User name. - */ + $createdAt: string; + $updatedAt: string; name: string; - /** - * User registration date in Unix timestamp. - */ - registration: number; - /** - * User status. 0 for Unactivated, 1 for active and 2 is blocked. - * @deprecated according to developers - */ - status: number; - /** - * User email address. - */ + password?: string; + hash?: string; + hashOptions?: Record; + registration: string; + status: boolean; + labels: string[]; + passwordUpdate: string; email: string; - /** - * Email verification status. - */ + phone: string; emailVerification: boolean; - /** - * User preferences as a key-value object - */ + phoneVerification: boolean; + mfa: boolean; prefs: Record; + targets: Target[]; + accessedAt: string; }; -export type UsersList = { - /** - * Total sum of items in the list. - */ - sum: number; - /** - * List of users. - */ - users: User[]; +export type Target = { + $id: string; + $createdAt: string; + $updatedAt: string; + name: string; + userId: string; + providerId?: string; + providerType: string; + identifier: string; }; -export type Error = { - /** - * Error message. - */ - message: string; - - /** - * Error code. - */ - code: string; - - /** - * Server version number. - */ - version: string; +export type UsersList = { + total: number; + users: User[]; }; export type Session = { - /** - * Session ID. - */ $id: string; - /** - * User ID. - */ + $createdAt: string; + $updatedAt: string; userId: string; - /** - * Session expiration date in Unix timestamp. - */ - expire: number; - /** - * IP in use when the session was created. - */ + expire: string; + provider: string; + providerUid: string; + providerAccessToken: string; + providerAccessTokenExpiry: string; + providerRefreshToken: string; ip: string; - /** - * Returns true if this the current user session. - */ + osCode: string; + osName: string; + osVersion: string; + clientType: string; + clientCode: string; + clientName: string; + clientVersion: string; + clientEngine: string; + clientEngineVersion: string; + deviceName: string; + deviceBrand: string; + deviceModel: string; + countryCode: string; + countryName: string; current: boolean; -} & ClientInfo; + factors: string[]; + secret: string; + mfaUpdatedAt: string; +}; + +export type SessionList = { + total: number; + sessions: Session[]; +}; export type Log = { - /** - * Event name. - */ event: string; - /** - * IP session in use when the session was created. - */ + userId: string; + userEmail: string; + userName: string; + mode: string; ip: string; - /** - * Log creation time in Unix timestamp. - */ - time: number; -} & ClientInfo; - -type ClientInfo = { - /** - * Operating system code name. View list of possible values: - * https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json - */ + time: string; osCode: string; - /** - * Operating system name. - */ osName: string; - /** - * Operating system version. - */ osVersion: string; - /** - * Client type. - */ clientType: string; - /** - * Client code name. View list of possible values: - * https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json - */ clientCode: string; - /** - * Client name. - */ clientName: string; - /** - * Client version. - */ clientVersion: string; - /** - * Client engine name. - */ clientEngine: string; - /** - * Client engine version. - */ clientEngineVersion: string; - /** - * Device name. - */ deviceName: string; - /** - * Device brand name. - */ deviceBrand: string; - /** - * Device model name. - */ deviceModel: string; - /** - * Country two-character ISO 3166-1 alpha code. - */ countryCode: string; - /** - * Country name. - */ countryName: string; }; +export type LogsList = { + total: number; + logs: Log[]; +}; + +// ============================================================================ +// Team Types +// ============================================================================ + export type Team = { - /** - * Team ID. - */ $id: string; - /** - * Team name. - */ + $createdAt: string; + $updatedAt: string; name: string; - /** - * Team creation date in Unix timestamp. - */ - dateCreated: number; - /** - * Total sum of team members. - */ - sum: number; -}; - -type Membership = { - /** - * Membership ID. - */ - $id: string; + total: number; + prefs: Record; +}; - /** - * User ID. - */ +export type Membership = { + $id: string; + $createdAt: string; + $updatedAt: string; userId: string; - - /** - * Team ID. - */ + userName: string; + userEmail: string; teamId: string; - - /** - * User name. - */ - name: string; - - /** - * User email address. - */ - email: string; - - /** - * Date, the user has been invited to join the team in Unix timestamp. - */ - invited: number; - - /** - * Date, the user has accepted the invitation to join the team in Unix timestamp. - */ - joined: number; - - /** - * User confirmation status, true if the user has joined the team or false otherwise. - */ + teamName: string; + invited: string; + joined: string; confirm: boolean; - - /** - * User list of roles - */ + mfa: boolean; roles: string[]; }; -export type FilesList = { - sum: number; - files: File[]; -}; +// ============================================================================ +// Database Types +// ============================================================================ -export type File = { +export type Database = { $id: string; - $permissions: Permissions; name: string; - dateCreated: number; - signature: string; - mimeType: string; - sizeOriginal: number; + $createdAt: string; + $updatedAt: string; + enabled: boolean; +}; + +export type DatabasesList = { + total: number; + databases: Database[]; }; export type Collection = { $id: string; - $permissions: Permissions; + $createdAt: string; + $updatedAt: string; + $permissions: string[]; + databaseId: string; name: string; - dateCreated: number; - dateUpdated: number; - rules: Rule[]; + enabled: boolean; + documentSecurity: boolean; + attributes: Attribute[]; + indexes: Index[]; }; export type CreatedCollection = Partial & Pick; export type CollectionsList = { - sum: number; + total: number; collections: Collection[]; }; -export type CreatedRule = Omit; +export type Attribute = { + key: string; + type: string; + status: string; + error: string; + required: boolean; + array: boolean; + size?: number; + default?: unknown; + min?: number; + max?: number; + format?: string; + elements?: string[]; +}; + +export type AttributesList = { + total: number; + attributes: Attribute[]; +}; + +export type Index = { + key: string; + type: string; + status: string; + error: string; + attributes: string[]; + orders?: string[]; +}; + +export type IndexesList = { + total: number; + indexes: Index[]; +}; + +export type Document = { + $id: string; + $collectionId: string; + $databaseId: string; + $createdAt: string; + $updatedAt: string; + $permissions: string[]; + [key: string]: unknown; +}; +export type DocumentsList = { + total: number; + documents: Document[]; +}; + +/** @deprecated Use Attribute instead */ export type Rule = { $id: string; $collection: string; type: string; key: string; label: string; - default?: any; + default?: unknown; required: boolean; array: boolean; list?: string[]; }; +/** @deprecated Use Attribute instead */ +export type CreatedRule = Omit; + +/** @deprecated Use string[] permissions instead */ export type Permissions = { read: string[]; write: string[]; -} +}; -export type Client = { - // Your API Endpoint - setEndpoint: (endpoint: string) => Client; - // Your project ID - setProject: (projectId: string) => Client; - // Your secret API key - setKey: (key: string) => Client; - setSelfSigned: (value: boolean) => void; +// ============================================================================ +// Storage Types +// ============================================================================ + +export type Bucket = { + $id: string; + $createdAt: string; + $updatedAt: string; + $permissions: string[]; + fileSecurity: boolean; + name: string; + enabled: boolean; + maximumFileSize: number; + allowedFileExtensions: string[]; + compression: string; + encryption: boolean; + antivirus: boolean; }; -export type UsersClient = { - delete: (id: string) => Promise; - deleteSessions: (id: string) => Promise; - create: (email: string, password: string, name?: string) => Promise; - getLogs: (id: string) => Promise; + +export type BucketsList = { + total: number; + buckets: Bucket[]; }; -export type DatabaseClient = { - listCollections: () => Promise; - listDocuments: (collectionId: string) => Promise; - updateCollection: (collectionId: string, name: string, read: string[], write: string[], rules?: (Rule | CreatedRule)[]) => Promise; - deleteCollection: (collectionId: string) => Promise; - getCollection: (collectionId: string) => Promise; - deleteDocument: (collectionId: string, documentId: string) => Promise; - createCollection: (name: string, read: string[], write: string[], rules: Rule[]) => Promise; +export type File = { + $id: string; + $createdAt: string; + $updatedAt: string; + $permissions: string[]; + bucketId: string; + name: string; + signature: string; + mimeType: string; + sizeOriginal: number; + chunksTotal: number; + chunksUploaded: number; }; -export type DocumentsList = { - sum: number; - documents: any[]; +export type FilesList = { + total: number; + files: File[]; }; -type GetHealth = () => any; +// ============================================================================ +// Health Types +// ============================================================================ -export type HealthClient = { - get: GetHealth; - getDB: GetHealth; - getCache: GetHealth; - getTime: GetHealth; - getQueueWebhooks: GetHealth; - getQueueTasks: GetHealth; - getQueueLogs: GetHealth; - getQueueUsage: GetHealth; - getQueueCertificates: GetHealth; - getQueueFunctions: GetHealth; - getStorageLocal: GetHealth; - getAntiVirus: GetHealth; +export type HealthStatus = { + name: string; + ping: number; + status: string; +}; + +export type HealthTime = { + remoteTime: number; + localTime: number; + diff: number; +}; + +export type HealthQueue = { + size: number; +}; + +export type HealthAntivirus = { + version: string; + status: string; +}; + +export type HealthCertificate = { + name: string; + subjectSN: string; + issuerOrganisation: string; + validFrom: string; + validTo: string; + signatureTypeSN: string; }; export type AppwriteHealth = { - HTTP: any; - DB: any; - Cache: any; - Time: any; - QueueWebhooks: any; - QueueTasks: any; - QueueLogs: any; - QueueUsage: any; - QueueCertificates: any; - QueueFunctions: any; - StorageLocal: any; - AntiVirus: any; + HTTP: HealthStatus; + DB: HealthStatus; + Cache: HealthStatus; + PubSub: HealthStatus; + Time: HealthTime; + Storage: HealthStatus; + StorageLocal: HealthStatus; + Antivirus: HealthAntivirus; + QueueWebhooks: HealthQueue; + QueueLogs: HealthQueue; + QueueUsage: HealthQueue; + QueueCertificates: HealthQueue; + QueueFunctions: HealthQueue; + QueueBuilds: HealthQueue; + QueueMails: HealthQueue; + QueueMessaging: HealthQueue; + QueueMigrations: HealthQueue; + QueueDeletes: HealthQueue; }; -export type StorageClient = { - createFile: (file: any, read?: string[], write?: string[]) => Promise; - listFiles: () => Promise; - getFile: (fileId: string) => Promise; +// ============================================================================ +// Functions Types +// ============================================================================ + +export type Variable = { + $id: string; + $createdAt: string; + $updatedAt: string; + key: string; + value: string; + resourceType: string; + resourceId: string; }; -type Vars = Record; +export type VariableList = { + total: number; + variables: Variable[]; +}; export type Function = { - '$id': string; - '$permissions': Permissions; - name: string; - dateCreated: number; - dateUpdated: number; - status: string; - env: string; - tag: string; - vars: Vars; - events: string[]; - schedule: string; - scheduleNext: number; - schedulePrevious: number; - timeout: number; -} + $id: string; + $createdAt: string; + $updatedAt: string; + execute: string[]; + name: string; + enabled: boolean; + live: boolean; + logging: boolean; + runtime: string; + deployment: string; + scopes: string[]; + vars: Variable[]; + events: string[]; + schedule: string; + timeout: number; + entrypoint: string; + commands: string; + version: string; + installationId: string; + providerRepositoryId: string; + providerBranch: string; + providerRootDirectory: string; + providerSilentMode: boolean; +}; export type FunctionsList = { - sum: number; + total: number; functions: Function[]; -} +}; -export type Tag = { - '$id': string; - functionId: string; - dateCreated: number; - command: string; - size: string; +export type Deployment = { + $id: string; + $createdAt: string; + $updatedAt: string; + type: string; + resourceId: string; + resourceType: string; + entrypoint: string; + size: number; + buildId: string; + activate: boolean; + status: string; + buildLogs: string; + buildTime: number; + providerRepositoryName: string; + providerRepositoryOwner: string; + providerRepositoryUrl: string; + providerBranch: string; + providerCommitHash: string; + providerCommitAuthorUrl: string; + providerCommitAuthor: string; + providerCommitMessage: string; + providerCommitUrl: string; + providerBranchUrl: string; }; -export type TagList = { - sum: number; - tags: Tag[]; -} +export type DeploymentList = { + total: number; + deployments: Deployment[]; +}; -export type ExecutionStatus = "waiting" | "processing" | "completed" | "failed"; +/** @deprecated Use Deployment instead */ +export type Tag = Deployment; + +/** @deprecated Use DeploymentList instead */ +export type TagList = DeploymentList; + +export type ExecutionStatus = "waiting" | "processing" | "completed" | "failed" | "scheduled"; export type Execution = { - '$id': string; - functionId: string; - dateCreated: number; - trigger: string; - status: ExecutionStatus; - exitCode: number; - stdout: string; - stderr: string; - time: number; + $id: string; + $createdAt: string; + $updatedAt: string; + $permissions: string[]; + functionId: string; + trigger: string; + status: ExecutionStatus; + requestMethod: string; + requestPath: string; + requestHeaders: Header[]; + responseStatusCode: number; + responseBody: string; + responseHeaders: Header[]; + logs: string; + errors: string; + duration: number; + scheduledAt?: string; +}; + +export type Header = { + name: string; + value: string; }; export type ExecutionList = { - sum: number; + total: number; executions: Execution[]; }; -export type Search = { - search?: string; - limit?: number; - offset?: number; - orderType?: 'ASC' | 'DESC'; +// ============================================================================ +// Client Types +// ============================================================================ + +export type Client = { + setEndpoint: (endpoint: string) => Client; + setProject: (projectId: string) => Client; + setKey: (key: string) => Client; + setSelfSigned: (value?: boolean) => Client; + setJWT: (jwt: string) => Client; + setLocale: (locale: string) => Client; + setSession: (session: string) => Client; + setForwardedUserAgent: (userAgent: string) => Client; +}; + +// ============================================================================ +// Service Client Types +// ============================================================================ + +export type UsersClient = { + // User CRUD + create: (userId: string, email?: string, phone?: string, password?: string, name?: string) => Promise; + get: (userId: string) => Promise; + list: (queries?: string[], search?: string) => Promise; + delete: (userId: string) => Promise; + + // User updates + updateEmail: (userId: string, email: string) => Promise; + updateName: (userId: string, name: string) => Promise; + updatePassword: (userId: string, password: string) => Promise; + updatePhone: (userId: string, number: string) => Promise; + updateStatus: (userId: string, status: boolean) => Promise; + updateLabels: (userId: string, labels: string[]) => Promise; + updateEmailVerification: (userId: string, emailVerification: boolean) => Promise; + updatePhoneVerification: (userId: string, phoneVerification: boolean) => Promise; + updateMfa: (userId: string, mfa: boolean) => Promise; + + // Preferences + getPrefs: (userId: string) => Promise>; + updatePrefs: (userId: string, prefs: Record) => Promise>; + + // Sessions + listSessions: (userId: string) => Promise; + deleteSessions: (userId: string) => Promise; + deleteSession: (userId: string, sessionId: string) => Promise; + createSession: (userId: string) => Promise; + + // Logs + getLogs: (userId: string, queries?: string[]) => Promise; + + // Targets + listTargets: (userId: string, queries?: string[]) => Promise<{ total: number; targets: Target[] }>; +}; + +export type DatabasesClient = { + // Database CRUD + create: (databaseId: string, name: string, enabled?: boolean) => Promise; + get: (databaseId: string) => Promise; + list: (queries?: string[], search?: string) => Promise; + update: (databaseId: string, name: string, enabled?: boolean) => Promise; + delete: (databaseId: string) => Promise; + + // Collection CRUD + createCollection: (databaseId: string, collectionId: string, name: string, permissions?: string[], documentSecurity?: boolean, enabled?: boolean) => Promise; + getCollection: (databaseId: string, collectionId: string) => Promise; + listCollections: (databaseId: string, queries?: string[], search?: string) => Promise; + updateCollection: (databaseId: string, collectionId: string, name: string, permissions?: string[], documentSecurity?: boolean, enabled?: boolean) => Promise; + deleteCollection: (databaseId: string, collectionId: string) => Promise; + + // Document CRUD + createDocument: (databaseId: string, collectionId: string, documentId: string, data: Record, permissions?: string[]) => Promise; + getDocument: (databaseId: string, collectionId: string, documentId: string, queries?: string[]) => Promise; + listDocuments: (databaseId: string, collectionId: string, queries?: string[]) => Promise; + updateDocument: (databaseId: string, collectionId: string, documentId: string, data?: Record, permissions?: string[]) => Promise; + deleteDocument: (databaseId: string, collectionId: string, documentId: string) => Promise; + + // Attributes + createStringAttribute: (databaseId: string, collectionId: string, key: string, size: number, required: boolean, xdefault?: string, array?: boolean, encrypt?: boolean) => Promise; + createIntegerAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, min?: number, max?: number, xdefault?: number, array?: boolean) => Promise; + createFloatAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, min?: number, max?: number, xdefault?: number, array?: boolean) => Promise; + createBooleanAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: boolean, array?: boolean) => Promise; + createEmailAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string, array?: boolean) => Promise; + createUrlAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string, array?: boolean) => Promise; + createIpAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string, array?: boolean) => Promise; + createDatetimeAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string, array?: boolean) => Promise; + createEnumAttribute: (databaseId: string, collectionId: string, key: string, elements: string[], required: boolean, xdefault?: string, array?: boolean) => Promise; + createRelationshipAttribute: (databaseId: string, collectionId: string, relatedCollectionId: string, type: string, twoWay?: boolean, key?: string, twoWayKey?: string, onDelete?: string) => Promise; + getAttribute: (databaseId: string, collectionId: string, key: string) => Promise; + listAttributes: (databaseId: string, collectionId: string, queries?: string[]) => Promise; + updateStringAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string) => Promise; + updateIntegerAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, min?: number, max?: number, xdefault?: number) => Promise; + updateFloatAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, min?: number, max?: number, xdefault?: number) => Promise; + updateBooleanAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: boolean) => Promise; + updateEmailAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string) => Promise; + updateUrlAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string) => Promise; + updateIpAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string) => Promise; + updateDatetimeAttribute: (databaseId: string, collectionId: string, key: string, required: boolean, xdefault?: string) => Promise; + updateEnumAttribute: (databaseId: string, collectionId: string, key: string, elements: string[], required: boolean, xdefault?: string) => Promise; + updateRelationshipAttribute: (databaseId: string, collectionId: string, key: string, onDelete?: string) => Promise; + deleteAttribute: (databaseId: string, collectionId: string, key: string) => Promise; + + // Indexes + createIndex: (databaseId: string, collectionId: string, key: string, type: string, attributes: string[], orders?: string[]) => Promise; + getIndex: (databaseId: string, collectionId: string, key: string) => Promise; + listIndexes: (databaseId: string, collectionId: string, queries?: string[]) => Promise; + deleteIndex: (databaseId: string, collectionId: string, key: string) => Promise; +}; + +/** @deprecated Use DatabasesClient instead */ +export type DatabaseClient = { + listCollections: () => Promise; + listDocuments: (collectionId: string) => Promise; + updateCollection: (collectionId: string, name: string, read: string[], write: string[], rules?: (Rule | CreatedRule)[]) => Promise; + deleteCollection: (collectionId: string) => Promise; + getCollection: (collectionId: string) => Promise; + deleteDocument: (collectionId: string, documentId: string) => Promise; + createCollection: (name: string, read: string[], write: string[], rules: Rule[]) => Promise; +}; + +type GetHealth = () => Promise; +type GetHealthQueue = (threshold?: number) => Promise; + +export type HealthClient = { + get: GetHealth; + getDB: GetHealth; + getCache: GetHealth; + getPubSub: GetHealth; + getTime: () => Promise; + getStorage: GetHealth; + getStorageLocal: GetHealth; + getAntivirus: () => Promise; + getCertificate: (domain?: string) => Promise; + + // Queue health checks + getQueueBuilds: GetHealthQueue; + getQueueCertificates: GetHealthQueue; + getQueueDatabases: (name?: string, threshold?: number) => Promise; + getQueueDeletes: GetHealthQueue; + getQueueFunctions: GetHealthQueue; + getQueueLogs: GetHealthQueue; + getQueueMails: GetHealthQueue; + getQueueMessaging: GetHealthQueue; + getQueueMigrations: GetHealthQueue; + getQueueUsage: GetHealthQueue; + getQueueUsageDump: GetHealthQueue; + getQueueWebhooks: GetHealthQueue; + getFailedJobs: (name: string, threshold?: number) => Promise; +}; + +export type StorageClient = { + // Bucket CRUD + createBucket: (bucketId: string, name: string, permissions?: string[], fileSecurity?: boolean, enabled?: boolean, maximumFileSize?: number, allowedFileExtensions?: string[], compression?: string, encryption?: boolean, antivirus?: boolean) => Promise; + getBucket: (bucketId: string) => Promise; + listBuckets: (queries?: string[], search?: string) => Promise; + updateBucket: (bucketId: string, name: string, permissions?: string[], fileSecurity?: boolean, enabled?: boolean, maximumFileSize?: number, allowedFileExtensions?: string[], compression?: string, encryption?: boolean, antivirus?: boolean) => Promise; + deleteBucket: (bucketId: string) => Promise; + + // File CRUD + createFile: (bucketId: string, fileId: string, file: File | ReadStream | Buffer, permissions?: string[]) => Promise; + getFile: (bucketId: string, fileId: string) => Promise; + listFiles: (bucketId: string, queries?: string[], search?: string) => Promise; + updateFile: (bucketId: string, fileId: string, name?: string, permissions?: string[]) => Promise; + deleteFile: (bucketId: string, fileId: string) => Promise; + + // File operations + getFileDownload: (bucketId: string, fileId: string) => Promise; + getFilePreview: (bucketId: string, fileId: string, width?: number, height?: number, gravity?: string, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: string) => Promise; + getFileView: (bucketId: string, fileId: string) => Promise; }; export type FunctionsClient = { - create: (name: string, execute: string[], env: string, vars?: Vars, events?: string[], schedule?: string, timeout?: number) => Promise; - list: (search?: string, offset?: number, limit?: number, orderType?: 'ASC' | 'DESC') => Promise; - get: (functionId: string) => Promise; - update: (functionId: string, name: string, execute: string[], vars?: Vars, events?: string[], schedule?: string, timeout?: number) => Promise; - updateTag: (functionId: string, tagId: string) => Promise; - delete: (functionId: string) => Promise; - createTag: (id: string, command: string, code: ReadStream) => Promise; - listTags: (id: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC') => Promise; - getTag: (functionId: string, tagId: string) => Promise; - deleteTag: (functionId: string, tagId: string) => Promise; - createExecution: (functionId: string, data?: string) => Promise; - listExecutions: (functionId: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC') => Promise; - getExecution: (functionId: string, executionId: string) => Promise; -} + // Function CRUD + create: (functionId: string, name: string, runtime: string, execute?: string[], events?: string[], schedule?: string, timeout?: number, enabled?: boolean, logging?: boolean, entrypoint?: string, commands?: string, scopes?: string[], installationId?: string, providerRepositoryId?: string, providerBranch?: string, providerSilentMode?: boolean, providerRootDirectory?: string, templateRepository?: string, templateOwner?: string, templateRootDirectory?: string, templateVersion?: string) => Promise; + get: (functionId: string) => Promise; + list: (queries?: string[], search?: string) => Promise; + update: (functionId: string, name: string, runtime?: string, execute?: string[], events?: string[], schedule?: string, timeout?: number, enabled?: boolean, logging?: boolean, entrypoint?: string, commands?: string, scopes?: string[], installationId?: string, providerRepositoryId?: string, providerBranch?: string, providerSilentMode?: boolean, providerRootDirectory?: string) => Promise; + delete: (functionId: string) => Promise; + + // Deployment operations (replaces Tags) + createDeployment: (functionId: string, code: ReadStream | Buffer, activate: boolean, entrypoint?: string, commands?: string) => Promise; + getDeployment: (functionId: string, deploymentId: string) => Promise; + listDeployments: (functionId: string, queries?: string[], search?: string) => Promise; + updateDeployment: (functionId: string, deploymentId: string) => Promise; + deleteDeployment: (functionId: string, deploymentId: string) => Promise; + getDeploymentDownload: (functionId: string, deploymentId: string) => Promise; + + // Execution operations + createExecution: (functionId: string, body?: string, async?: boolean, path?: string, method?: string, headers?: Record, scheduledAt?: string) => Promise; + getExecution: (functionId: string, executionId: string) => Promise; + listExecutions: (functionId: string, queries?: string[]) => Promise; + deleteExecution: (functionId: string, executionId: string) => Promise; + + // Variable operations + createVariable: (functionId: string, key: string, value: string) => Promise; + getVariable: (functionId: string, variableId: string) => Promise; + listVariables: (functionId: string) => Promise; + updateVariable: (functionId: string, variableId: string, key: string, value?: string) => Promise; + deleteVariable: (functionId: string, variableId: string) => Promise; + + /** @deprecated Use createDeployment instead */ + createTag: (id: string, command: string, code: ReadStream) => Promise; + /** @deprecated Use listDeployments instead */ + listTags: (id: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC') => Promise; + /** @deprecated Use getDeployment instead */ + getTag: (functionId: string, tagId: string) => Promise; + /** @deprecated Use deleteDeployment instead */ + deleteTag: (functionId: string, tagId: string) => Promise; + /** @deprecated Use updateDeployment instead */ + updateTag: (functionId: string, tagId: string) => Promise; +}; + +// ============================================================================ +// SDK Type with Helper Classes +// ============================================================================ + +export type PermissionHelper = { + read: (role: string) => string; + write: (role: string) => string; + create: (role: string) => string; + update: (role: string) => string; + delete: (role: string) => string; +}; + +export type RoleHelper = { + any: () => string; + user: (id: string, status?: string) => string; + users: (status?: string) => string; + guests: () => string; + team: (id: string, role?: string) => string; + member: (id: string) => string; + label: (name: string) => string; +}; + +export type QueryHelper = { + equal: (attribute: string, value: unknown) => string; + notEqual: (attribute: string, value: unknown) => string; + lessThan: (attribute: string, value: unknown) => string; + lessThanEqual: (attribute: string, value: unknown) => string; + greaterThan: (attribute: string, value: unknown) => string; + greaterThanEqual: (attribute: string, value: unknown) => string; + search: (attribute: string, value: string) => string; + orderAsc: (attribute: string) => string; + orderDesc: (attribute: string) => string; + cursorAfter: (documentId: string) => string; + cursorBefore: (documentId: string) => string; + limit: (limit: number) => string; + offset: (offset: number) => string; + contains: (attribute: string, value: unknown) => string; + or: (queries: string[]) => string; + and: (queries: string[]) => string; + select: (attributes: string[]) => string; + between: (attribute: string, start: unknown, end: unknown) => string; + startsWith: (attribute: string, value: string) => string; + endsWith: (attribute: string, value: string) => string; + isNull: (attribute: string) => string; + isNotNull: (attribute: string) => string; +}; + +export type IDHelper = { + unique: () => string; + custom: (id: string) => string; +}; export type SDK = { Client: new () => Client; + // Service classes Users: new (client: Client) => UsersClient; Health: new (client: Client) => HealthClient; - Database: new (client: Client) => DatabaseClient; + Databases: new (client: Client) => DatabasesClient; Storage: new (client: Client) => StorageClient; Functions: new (client: Client) => FunctionsClient; + + // Helper classes + Permission: PermissionHelper; + Role: RoleHelper; + Query: QueryHelper; + ID: IDHelper; + + /** @deprecated Use Databases instead */ + Database: new (client: Client) => DatabaseClient; }; diff --git a/src/appwrite/Database.ts b/src/appwrite/Database.ts index 7d5be16..1530bc8 100644 --- a/src/appwrite/Database.ts +++ b/src/appwrite/Database.ts @@ -1,61 +1,297 @@ -import { Client, Collection, CreatedCollection, CreatedRule, DatabaseClient, Rule } from "../appwrite"; -import { AppwriteSDK } from '../constants'; +import { Client, Collection, CreatedCollection, DatabasesClient, Database as DatabaseEntity, DatabasesList, DocumentsList, Attribute, AttributesList } from "../appwrite"; +import { AppwriteSDK, ID, Permission, Role } from '../constants'; import AppwriteCall from "../utils/AppwriteCall"; export class Database { - private readonly database: DatabaseClient; + private readonly databases: DatabasesClient; + private defaultDatabaseId: string | undefined; - constructor(client: Client) { - this.database = new AppwriteSDK.Database(client); + constructor(client: Client, defaultDatabaseId?: string) { + this.databases = new AppwriteSDK.Databases(client); + this.defaultDatabaseId = defaultDatabaseId; } - public async getCollection(collectionId: string): Promise { - return await AppwriteCall(this.database.getCollection(collectionId)); + /** + * Get the database ID, using default if not provided + */ + private getDatabaseId(databaseId?: string): string { + const id = databaseId || this.defaultDatabaseId; + if (!id) { + throw new Error('Database ID is required. Please configure a default database ID in your project settings.'); + } + return id; } - public async deleteDocument(collectionId: string, documentId: string): Promise { - await AppwriteCall(this.database.deleteDocument(collectionId, documentId)); + /** + * Set the default database ID + */ + public setDefaultDatabaseId(databaseId: string): void { + this.defaultDatabaseId = databaseId; } - public async deleteCollection(collectionId: string): Promise { - await AppwriteCall(this.database.deleteCollection(collectionId)); + /** + * Get the current default database ID + */ + public getDefaultDatabaseId(): string | undefined { + return this.defaultDatabaseId; } - public async createCollection(collection: CreatedCollection): Promise { - await AppwriteCall( - this.database.createCollection( + // ========================================================================= + // Database operations + // ========================================================================= + + public async listDatabases(): Promise { + return await AppwriteCall(this.databases.list()); + } + + public async getDatabase(databaseId: string): Promise { + return await AppwriteCall(this.databases.get(databaseId)); + } + + public async createDatabase(name: string, databaseId?: string): Promise { + const id = databaseId || ID.unique(); + return await AppwriteCall(this.databases.create(id, name, true)); + } + + public async deleteDatabase(databaseId: string): Promise { + await AppwriteCall(this.databases.delete(databaseId)); + } + + // ========================================================================= + // Collection operations + // ========================================================================= + + public async getCollection(collectionId: string, databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall(this.databases.getCollection(dbId, collectionId)); + } + + public async listCollections(databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + const result = await AppwriteCall<{ total: number; collections: Collection[] }>( + this.databases.listCollections(dbId) + ); + return result?.collections; + } + + public async createCollection(collection: CreatedCollection, databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + const collectionId = ID.unique(); + + // Convert old permission format to new format if needed + const permissions = this.convertPermissions( + collection.$permissions ?? [] + ); + + return await AppwriteCall( + this.databases.createCollection( + dbId, + collectionId, collection.name, - collection.$permissions?.read ?? [], - collection.$permissions?.write ?? [], - collection.rules ?? [] + permissions, + true, // documentSecurity + true // enabled ) ); } - public async updatePermissions(collection: Collection, read: string[], write: string[]): Promise { - await AppwriteCall(this.database.updateCollection(collection.$id, collection.name, read, write, collection.rules)); + public async deleteCollection(collectionId: string, databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + await AppwriteCall(this.databases.deleteCollection(dbId, collectionId)); } - public async createRule(collection: Collection, newRule: CreatedRule): Promise { - await AppwriteCall( - this.database.updateCollection(collection.$id, collection.name, collection.$permissions.read, collection.$permissions.write, [ - ...collection.rules, - newRule, - ]) + public async updateCollection( + collectionId: string, + name: string, + permissions?: string[], + databaseId?: string + ): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall( + this.databases.updateCollection(dbId, collectionId, name, permissions) ); } - public async removeRule(collection: Collection, ruleToRemove: Rule): Promise { - const rules = collection.rules.filter((rule) => rule.$id !== ruleToRemove.$id); + // ========================================================================= + // Document operations + // ========================================================================= + + public async listDocuments(collectionId: string, databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall(this.databases.listDocuments(dbId, collectionId)); + } + + public async deleteDocument(collectionId: string, documentId: string, databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + await AppwriteCall(this.databases.deleteDocument(dbId, collectionId, documentId)); + } + + // ========================================================================= + // Permission operations + // ========================================================================= + + public async updatePermissions( + collection: Collection, + read: string[], + write: string[], + databaseId?: string + ): Promise { + const dbId = this.getDatabaseId(databaseId); + const permissions = this.convertLegacyPermissions(read, write); await AppwriteCall( - this.database.updateCollection( + this.databases.updateCollection( + dbId, collection.$id, collection.name, - collection.$permissions.read, - collection.$permissions.write, - rules + permissions ) ); } + + // ========================================================================= + // Attribute operations (replaces rules) + // ========================================================================= + + public async listAttributes(collectionId: string, databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall(this.databases.listAttributes(dbId, collectionId)); + } + + public async createStringAttribute( + collectionId: string, + key: string, + size: number, + required: boolean, + defaultValue?: string, + array?: boolean, + databaseId?: string + ): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall( + this.databases.createStringAttribute(dbId, collectionId, key, size, required, defaultValue, array) + ); + } + + public async createIntegerAttribute( + collectionId: string, + key: string, + required: boolean, + min?: number, + max?: number, + defaultValue?: number, + array?: boolean, + databaseId?: string + ): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall( + this.databases.createIntegerAttribute(dbId, collectionId, key, required, min, max, defaultValue, array) + ); + } + + public async createBooleanAttribute( + collectionId: string, + key: string, + required: boolean, + defaultValue?: boolean, + array?: boolean, + databaseId?: string + ): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall( + this.databases.createBooleanAttribute(dbId, collectionId, key, required, defaultValue, array) + ); + } + + public async createEmailAttribute( + collectionId: string, + key: string, + required: boolean, + defaultValue?: string, + array?: boolean, + databaseId?: string + ): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall( + this.databases.createEmailAttribute(dbId, collectionId, key, required, defaultValue, array) + ); + } + + public async createUrlAttribute( + collectionId: string, + key: string, + required: boolean, + defaultValue?: string, + array?: boolean, + databaseId?: string + ): Promise { + const dbId = this.getDatabaseId(databaseId); + return await AppwriteCall( + this.databases.createUrlAttribute(dbId, collectionId, key, required, defaultValue, array) + ); + } + + public async deleteAttribute(collectionId: string, key: string, databaseId?: string): Promise { + const dbId = this.getDatabaseId(databaseId); + await AppwriteCall(this.databases.deleteAttribute(dbId, collectionId, key)); + } + + // ========================================================================= + // Helper methods + // ========================================================================= + + /** + * Convert new permission array format + */ + private convertPermissions(permissions: string[]): string[] { + // If already in new format, return as-is + if (permissions.length === 0 || permissions[0].includes('(')) { + return permissions; + } + // Otherwise, assume it's role strings and convert + return permissions.map(role => Permission.read(this.normalizeRole(role))); + } + + /** + * Convert legacy read/write arrays to new permission format + */ + private convertLegacyPermissions(read: string[], write: string[]): string[] { + const permissions: string[] = []; + + read.forEach(role => { + permissions.push(Permission.read(this.normalizeRole(role))); + }); + + write.forEach(role => { + permissions.push(Permission.write(this.normalizeRole(role))); + permissions.push(Permission.create(this.normalizeRole(role))); + permissions.push(Permission.update(this.normalizeRole(role))); + permissions.push(Permission.delete(this.normalizeRole(role))); + }); + + return Array.from(new Set(permissions)); // Remove duplicates + } + + /** + * Normalize legacy role format to new SDK format + */ + private normalizeRole(role: string): string { + if (role === '*') { + return Role.any(); + } + if (role.startsWith('user:')) { + return Role.user(role.substring(5)); + } + if (role.startsWith('team:')) { + const parts = role.substring(5).split('/'); + return parts.length > 1 ? Role.team(parts[0], parts[1]) : Role.team(parts[0]); + } + if (role === 'guests') { + return Role.guests(); + } + if (role === 'users') { + return Role.users(); + } + return role; + } } diff --git a/src/appwrite/Functions.ts b/src/appwrite/Functions.ts index 1bd8ce9..c3d0a55 100644 --- a/src/appwrite/Functions.ts +++ b/src/appwrite/Functions.ts @@ -1,5 +1,5 @@ -import { Client, Execution, ExecutionList, FunctionsClient, FunctionsList, Tag, TagList, Vars } from "../appwrite"; -import { AppwriteSDK } from '../constants'; +import { Client, Execution, ExecutionList, FunctionsClient, FunctionsList, Deployment, DeploymentList, Variable, VariableList, Function as FunctionEntity } from "../appwrite"; +import { AppwriteSDK, ID, Query } from '../constants'; import AppwriteCall from '../utils/AppwriteCall'; import { ReadStream } from 'node:fs'; @@ -10,43 +10,230 @@ export class Functions { this.functions = new AppwriteSDK.Functions(client); } - public async create(name: string, execute: string[], env: string, vars?: Vars, events?: string[], schedule?: string, timeout?: number): Promise { - return await AppwriteCall(this.functions.create(name, execute, env, vars, events, schedule, timeout)); - } - public async list(search?: string, offset?: number, limit?: number, orderType?: 'ASC' | 'DESC'): Promise { - return await AppwriteCall(this.functions.list(search, offset, limit, orderType)); + // ========================================================================= + // Function CRUD operations + // ========================================================================= + + /** + * Create a new function + * @param name Function name + * @param execute Execution permissions + * @param runtime Runtime environment (e.g., 'node-18.0', 'python-3.11') + */ + public async create( + name: string, + execute: string[], + runtime: string, + events?: string[], + schedule?: string, + timeout?: number, + enabled?: boolean, + logging?: boolean, + entrypoint?: string, + commands?: string, + scopes?: string[] + ): Promise { + const functionId = ID.unique(); + return await AppwriteCall( + this.functions.create( + functionId, + name, + runtime, + execute, + events, + schedule, + timeout, + enabled, + logging, + entrypoint, + commands, + scopes + ) + ); } - public async get(functionId: string): Promise { - return await AppwriteCall(this.functions.get(functionId)); + + public async list(queries?: string[], search?: string): Promise { + // Ensure we pass undefined (not empty string) for search to avoid API validation errors + const validQueries = queries && queries.length > 0 ? queries : undefined; + const validSearch = search && search.length > 0 ? search : undefined; + return await AppwriteCall(this.functions.list(validQueries, validSearch)); } - public async update(functionId: string, name: string, execute: string[], vars?: Vars, events?: string[], schedule?: string, timeout?: number): Promise { - return await AppwriteCall(this.functions.update(functionId, name, execute, vars, events, schedule, timeout)); + + public async get(functionId: string): Promise { + return await AppwriteCall(this.functions.get(functionId)); } - public async updateTag(functionId: string, tagId: string): Promise { - return await AppwriteCall(this.functions.updateTag(functionId, tagId)); + + public async update( + functionId: string, + name: string, + runtime?: string, + execute?: string[], + events?: string[], + schedule?: string, + timeout?: number, + enabled?: boolean, + logging?: boolean, + entrypoint?: string, + commands?: string, + scopes?: string[] + ): Promise { + return await AppwriteCall( + this.functions.update( + functionId, + name, + runtime, + execute, + events, + schedule, + timeout, + enabled, + logging, + entrypoint, + commands, + scopes + ) + ); } + public async delete(functionId: string): Promise { return await AppwriteCall(this.functions.delete(functionId)); } - public async createTag(functionId: string, command: string, code: ReadStream): Promise { - return await AppwriteCall(this.functions.createTag(functionId, command, code)); + + // ========================================================================= + // Deployment operations (replaces Tags) + // ========================================================================= + + /** + * Create a new deployment + */ + public async createDeployment( + functionId: string, + code: ReadStream, + activate: boolean, + entrypoint?: string, + commands?: string + ): Promise { + return await AppwriteCall( + this.functions.createDeployment(functionId, code, activate, entrypoint, commands) + ); } - public async listTags(id: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC'): Promise { - return await AppwriteCall(this.functions.listTags(id, search, offset, limit, orderType)); + + public async listDeployments( + functionId: string, + queries?: string[], + search?: string + ): Promise { + return await AppwriteCall( + this.functions.listDeployments(functionId, queries, search) + ); } - public async getTag(functionId: string, tagId: string): Promise { - return await AppwriteCall(this.functions.getTag(functionId, tagId)); + + public async getDeployment(functionId: string, deploymentId: string): Promise { + return await AppwriteCall(this.functions.getDeployment(functionId, deploymentId)); } - public async deleteTag(functionId: string, tagId: string): Promise { - return await AppwriteCall(this.functions.deleteTag(functionId, tagId)); + + /** + * Activate a deployment (set as active) + */ + public async updateDeployment(functionId: string, deploymentId: string): Promise { + return await AppwriteCall(this.functions.updateDeployment(functionId, deploymentId)); + } + + public async deleteDeployment(functionId: string, deploymentId: string): Promise { + return await AppwriteCall(this.functions.deleteDeployment(functionId, deploymentId)); } - public async createExecution(functionId: string, data?: string): Promise { - return await AppwriteCall(this.functions.createExecution(functionId, data)); + + // ========================================================================= + // Execution operations + // ========================================================================= + + public async createExecution( + functionId: string, + body?: string, + async?: boolean, + path?: string, + method?: string, + headers?: Record + ): Promise { + return await AppwriteCall( + this.functions.createExecution(functionId, body, async, path, method, headers) + ); } - public async listExecutions(functionId: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC'): Promise { - return await AppwriteCall(this.functions.listExecutions(functionId, search, limit, offset, orderType)); + + public async listExecutions(functionId: string, queries?: string[]): Promise { + return await AppwriteCall(this.functions.listExecutions(functionId, queries)); } + public async getExecution(functionId: string, executionId: string): Promise { - return await AppwriteCall(this.functions.getExecution(functionId, executionId)); + return await AppwriteCall(this.functions.getExecution(functionId, executionId)); + } + + public async deleteExecution(functionId: string, executionId: string): Promise { + return await AppwriteCall(this.functions.deleteExecution(functionId, executionId)); + } + + // ========================================================================= + // Variable operations + // ========================================================================= + + public async createVariable(functionId: string, key: string, value: string): Promise { + return await AppwriteCall(this.functions.createVariable(functionId, key, value)); + } + + public async listVariables(functionId: string): Promise { + return await AppwriteCall(this.functions.listVariables(functionId)); + } + + public async getVariable(functionId: string, variableId: string): Promise { + return await AppwriteCall(this.functions.getVariable(functionId, variableId)); + } + + public async updateVariable(functionId: string, variableId: string, key: string, value?: string): Promise { + return await AppwriteCall(this.functions.updateVariable(functionId, variableId, key, value)); + } + + public async deleteVariable(functionId: string, variableId: string): Promise { + return await AppwriteCall(this.functions.deleteVariable(functionId, variableId)); + } + + // ========================================================================= + // Deprecated methods (for backward compatibility) + // ========================================================================= + + /** @deprecated Use createDeployment instead */ + public async createTag(functionId: string, command: string, code: ReadStream): Promise { + return this.createDeployment(functionId, code, true, undefined, command); + } + + /** @deprecated Use listDeployments instead */ + public async listTags( + id: string, + search?: string, + limit?: number, + offset?: number, + orderType?: 'ASC' | 'DESC' + ): Promise { + const queries: string[] = []; + if (limit) queries.push(Query.limit(limit)); + if (offset) queries.push(Query.offset(offset)); + if (orderType === 'DESC') queries.push(Query.orderDesc('$createdAt')); + else if (orderType === 'ASC') queries.push(Query.orderAsc('$createdAt')); + + return this.listDeployments(id, queries.length > 0 ? queries : undefined, search); + } + + /** @deprecated Use getDeployment instead */ + public async getTag(functionId: string, tagId: string): Promise { + return this.getDeployment(functionId, tagId); + } + + /** @deprecated Use deleteDeployment instead */ + public async deleteTag(functionId: string, tagId: string): Promise { + return this.deleteDeployment(functionId, tagId); + } + + /** @deprecated Use updateDeployment instead */ + public async updateTag(functionId: string, tagId: string): Promise { + return this.updateDeployment(functionId, tagId); } } diff --git a/src/appwrite/Health.ts b/src/appwrite/Health.ts index 3863e2a..1e80853 100644 --- a/src/appwrite/Health.ts +++ b/src/appwrite/Health.ts @@ -1,6 +1,7 @@ import { MarkdownString } from 'vscode'; import { AppwriteHealth, Client, HealthClient } from "../appwrite"; import { AppwriteSDK } from '../constants'; + export class Health { private readonly health: HealthClient; @@ -12,36 +13,144 @@ export class Health { * @returns The health of all Appwrite services. */ public async checkup(): Promise> { - return { - HTTP: await this.health.get(), - DB: await this.health.getDB(), - Cache: await this.health.getCache(), - Time: await this.health.getTime(), - QueueWebhooks: await this.health.getQueueWebhooks(), - QueueTasks: await this.health.getQueueTasks(), - QueueLogs: await this.health.getQueueLogs(), - QueueUsage: await this.health.getQueueUsage(), - QueueCertificates: await this.health.getQueueCertificates(), - QueueFunctions: await this.health.getQueueFunctions(), - StorageLocal: await this.health.getStorageLocal(), - AntiVirus: await this.health.getAntiVirus(), - }; + const results: Partial = {}; + + // Core services + try { + results.HTTP = await this.health.get(); + } catch (e) { + results.HTTP = { name: 'HTTP', ping: 0, status: 'error' }; + } + + try { + results.DB = await this.health.getDB(); + } catch (e) { + results.DB = { name: 'DB', ping: 0, status: 'error' }; + } + + try { + results.Cache = await this.health.getCache(); + } catch (e) { + results.Cache = { name: 'Cache', ping: 0, status: 'error' }; + } + + try { + results.PubSub = await this.health.getPubSub(); + } catch (e) { + results.PubSub = { name: 'PubSub', ping: 0, status: 'error' }; + } + + try { + results.Time = await this.health.getTime(); + } catch (e) { + results.Time = { remoteTime: 0, localTime: 0, diff: 0 }; + } + + // Storage + try { + results.Storage = await this.health.getStorage(); + } catch (e) { + results.Storage = { name: 'Storage', ping: 0, status: 'error' }; + } + + try { + results.StorageLocal = await this.health.getStorageLocal(); + } catch (e) { + results.StorageLocal = { name: 'StorageLocal', ping: 0, status: 'error' }; + } + + try { + results.Antivirus = await this.health.getAntivirus(); + } catch (e) { + results.Antivirus = { version: 'unknown', status: 'error' }; + } + + // Queues + try { + results.QueueWebhooks = await this.health.getQueueWebhooks(); + } catch (e) { + results.QueueWebhooks = { size: -1 }; + } + + try { + results.QueueLogs = await this.health.getQueueLogs(); + } catch (e) { + results.QueueLogs = { size: -1 }; + } + + try { + results.QueueUsage = await this.health.getQueueUsage(); + } catch (e) { + results.QueueUsage = { size: -1 }; + } + + try { + results.QueueCertificates = await this.health.getQueueCertificates(); + } catch (e) { + results.QueueCertificates = { size: -1 }; + } + + try { + results.QueueFunctions = await this.health.getQueueFunctions(); + } catch (e) { + results.QueueFunctions = { size: -1 }; + } + + try { + results.QueueBuilds = await this.health.getQueueBuilds(); + } catch (e) { + results.QueueBuilds = { size: -1 }; + } + + try { + results.QueueMails = await this.health.getQueueMails(); + } catch (e) { + results.QueueMails = { size: -1 }; + } + + try { + results.QueueMessaging = await this.health.getQueueMessaging(); + } catch (e) { + results.QueueMessaging = { size: -1 }; + } + + try { + results.QueueMigrations = await this.health.getQueueMigrations(); + } catch (e) { + results.QueueMigrations = { size: -1 }; + } + + try { + results.QueueDeletes = await this.health.getQueueDeletes(); + } catch (e) { + results.QueueDeletes = { size: -1 }; + } + + return results; } } export const healthTooltips: Record = { HTTP: "Check the Appwrite HTTP server is up and responsive.", - DB: "Check the Appwrite in-memory cache server is up and connection is successful.", + DB: "Check the Appwrite database server is up and connection is successful.", Cache: "Check the Appwrite in-memory cache server is up and connection is successful.", - Time: - new MarkdownString("Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet. If your computer sets its own clock, it likely uses NTP."), + PubSub: "Check the Appwrite pub/sub server is up and connection is successful.", + Time: new MarkdownString( + "Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet." + ), + Storage: "Check the Appwrite storage device is up and connection is successful.", + StorageLocal: "Check the Appwrite local storage device is up and connection is successful.", + Antivirus: "Check the Appwrite Anti Virus server is up and connection is successful.", QueueWebhooks: "The number of webhooks that are waiting to be processed in the Appwrite internal queue server.", - QueueTasks: "The number of tasks that are waiting to be processed in the Appwrite internal queue server.", QueueLogs: "The number of logs that are waiting to be processed in the Appwrite internal queue server.", QueueUsage: "The number of usage stats that are waiting to be processed in the Appwrite internal queue server.", - QueueCertificates: - new MarkdownString("The number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server."), + QueueCertificates: new MarkdownString( + "The number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server." + ), QueueFunctions: "The number of functions waiting to be executed.", - StorageLocal: "Check the Appwrite local storage device is up and connection is successful.", - AntiVirus: "Check the Appwrite Anti Virus server is up and connection is successful.", + QueueBuilds: "The number of function builds waiting to be processed.", + QueueMails: "The number of emails waiting to be sent.", + QueueMessaging: "The number of messages waiting to be delivered.", + QueueMigrations: "The number of migrations waiting to be processed.", + QueueDeletes: "The number of delete operations waiting to be processed.", }; diff --git a/src/appwrite/Storage.ts b/src/appwrite/Storage.ts index a27dd4f..ba63552 100644 --- a/src/appwrite/Storage.ts +++ b/src/appwrite/Storage.ts @@ -1,20 +1,142 @@ import { ReadStream } from 'node:fs'; -import { Client, FilesList, StorageClient } from "../appwrite"; -import { AppwriteSDK } from '../constants'; +import { Client, File, FilesList, StorageClient, Bucket, BucketsList } from "../appwrite"; +import { AppwriteSDK, ID } from '../constants'; import AppwriteCall from "../utils/AppwriteCall"; export class Storage { private readonly storage: StorageClient; + private defaultBucketId: string | undefined; - constructor(client: Client) { + constructor(client: Client, defaultBucketId?: string) { this.storage = new AppwriteSDK.Storage(client); + this.defaultBucketId = defaultBucketId; } - public async listFiles(): Promise { - return await AppwriteCall(this.storage.listFiles()); + /** + * Get the bucket ID, using default if not provided + */ + private getBucketId(bucketId?: string): string { + const id = bucketId || this.defaultBucketId; + if (!id) { + throw new Error('Bucket ID is required. Please configure a default bucket ID in your project settings.'); + } + return id; } - public async createFile(file: ReadStream): Promise { - return await AppwriteCall(this.storage.createFile(file)); + /** + * Set the default bucket ID + */ + public setDefaultBucketId(bucketId: string): void { + this.defaultBucketId = bucketId; + } + + /** + * Get the current default bucket ID + */ + public getDefaultBucketId(): string | undefined { + return this.defaultBucketId; + } + + // ========================================================================= + // Bucket operations + // ========================================================================= + + public async listBuckets(): Promise { + return await AppwriteCall(this.storage.listBuckets()); + } + + public async getBucket(bucketId: string): Promise { + return await AppwriteCall(this.storage.getBucket(bucketId)); + } + + public async createBucket( + name: string, + bucketId?: string, + permissions?: string[], + fileSecurity?: boolean, + enabled?: boolean, + maximumFileSize?: number, + allowedFileExtensions?: string[] + ): Promise { + const id = bucketId || ID.unique(); + return await AppwriteCall( + this.storage.createBucket( + id, + name, + permissions, + fileSecurity, + enabled, + maximumFileSize, + allowedFileExtensions + ) + ); + } + + public async deleteBucket(bucketId: string): Promise { + await AppwriteCall(this.storage.deleteBucket(bucketId)); + } + + // ========================================================================= + // File operations + // ========================================================================= + + public async listFiles(bucketId?: string): Promise { + const bId = this.getBucketId(bucketId); + return await AppwriteCall(this.storage.listFiles(bId)); + } + + public async getFile(fileId: string, bucketId?: string): Promise { + const bId = this.getBucketId(bucketId); + return await AppwriteCall(this.storage.getFile(bId, fileId)); + } + + public async createFile( + file: ReadStream | Buffer, + bucketId?: string, + fileId?: string, + permissions?: string[] + ): Promise { + const bId = this.getBucketId(bucketId); + const fId = fileId || ID.unique(); + return await AppwriteCall(this.storage.createFile(bId, fId, file, permissions)); + } + + public async updateFile( + fileId: string, + name?: string, + permissions?: string[], + bucketId?: string + ): Promise { + const bId = this.getBucketId(bucketId); + return await AppwriteCall(this.storage.updateFile(bId, fileId, name, permissions)); + } + + public async deleteFile(fileId: string, bucketId?: string): Promise { + const bId = this.getBucketId(bucketId); + await AppwriteCall(this.storage.deleteFile(bId, fileId)); + } + + // ========================================================================= + // File download/preview operations + // ========================================================================= + + public async getFileDownload(fileId: string, bucketId?: string): Promise { + const bId = this.getBucketId(bucketId); + return await AppwriteCall(this.storage.getFileDownload(bId, fileId)); + } + + public async getFilePreview( + fileId: string, + bucketId?: string, + width?: number, + height?: number + ): Promise { + const bId = this.getBucketId(bucketId); + return await AppwriteCall(this.storage.getFilePreview(bId, fileId, width, height)); + } + + public async getFileView(fileId: string, bucketId?: string): Promise { + const bId = this.getBucketId(bucketId); + return await AppwriteCall(this.storage.getFileView(bId, fileId)); } } diff --git a/src/appwrite/Users.ts b/src/appwrite/Users.ts index 442d01a..de50dff 100644 --- a/src/appwrite/Users.ts +++ b/src/appwrite/Users.ts @@ -1,6 +1,6 @@ import { window } from "vscode"; -import { Client, Log, User, UsersClient } from "../appwrite"; -import { AppwriteSDK } from "../constants"; +import { Client, Log, LogsList, User, UsersList, UsersClient } from "../appwrite"; +import { AppwriteSDK, ID } from "../constants"; import AppwriteCall from "../utils/AppwriteCall"; export class Users { @@ -9,10 +9,30 @@ export class Users { constructor(client: Client) { this.users = new AppwriteSDK.Users(client); } + + /** + * Create a new user + * Note: In SDK v21, userId is the first parameter + */ public async createNewUser(context: CreateUserContext): Promise { - await AppwriteCall(this.users.create(context.email, context.password, context.name), (user) => { - window.showInformationMessage(`Created user with id: ${user.$id}`); - }); + const userId = ID.unique(); + await AppwriteCall( + this.users.create(userId, context.email, undefined, context.password, context.name), + (user) => { + window.showInformationMessage(`Created user with id: ${user.$id}`); + } + ); + } + + public async get(userId: string): Promise { + return await AppwriteCall(this.users.get(userId)); + } + + public async list(queries?: string[], search?: string): Promise { + // Ensure we pass undefined (not empty string) for search to avoid API validation errors + const validQueries = queries && queries.length > 0 ? queries : undefined; + const validSearch = search && search.length > 0 ? search : undefined; + return await AppwriteCall(this.users.list(validQueries, validSearch)); } public async delete(userId: string): Promise { @@ -21,8 +41,37 @@ export class Users { }); } - public async getLogs(userId: string): Promise { - return (await AppwriteCall(this.users.getLogs(userId))) ?? []; + /** + * Get user logs + * Note: In SDK v21, getLogs returns LogList with logs array + */ + public async getLogs(userId: string, queries?: string[]): Promise { + const result = await AppwriteCall(this.users.getLogs(userId, queries)); + return result?.logs ?? []; + } + + public async updateEmail(userId: string, email: string): Promise { + return await AppwriteCall(this.users.updateEmail(userId, email)); + } + + public async updateName(userId: string, name: string): Promise { + return await AppwriteCall(this.users.updateName(userId, name)); + } + + public async updatePassword(userId: string, password: string): Promise { + return await AppwriteCall(this.users.updatePassword(userId, password)); + } + + public async updateStatus(userId: string, status: boolean): Promise { + return await AppwriteCall(this.users.updateStatus(userId, status)); + } + + public async updateEmailVerification(userId: string, emailVerification: boolean): Promise { + return await AppwriteCall(this.users.updateEmailVerification(userId, emailVerification)); + } + + public async updatePhoneVerification(userId: string, phoneVerification: boolean): Promise { + return await AppwriteCall(this.users.updatePhoneVerification(userId, phoneVerification)); } } diff --git a/src/client.ts b/src/client.ts index 5fe9c13..d082220 100644 --- a/src/client.ts +++ b/src/client.ts @@ -8,23 +8,33 @@ import { AppwriteSDK } from "./constants"; import { AppwriteProjectConfiguration } from "./settings"; export let client: Client; -export let clientConfig: { endpoint: string; projectId: string; secret: string }; +export let clientConfig: { + endpoint: string; + projectId: string; + secret: string; + databaseId?: string; + bucketId?: string; +}; export let usersClient: Users | undefined; export let healthClient: Health | undefined; export let databaseClient: Database | undefined; export let storageClient: Storage | undefined; export let functionsClient: Functions | undefined; - -function initAppwriteClient({ endpoint, projectId, secret, selfSigned }: AppwriteProjectConfiguration) { +function initAppwriteClient({ endpoint, projectId, secret, selfSigned, databaseId, bucketId }: AppwriteProjectConfiguration) { client = new AppwriteSDK.Client(); - clientConfig = { endpoint, projectId, secret }; - client.setEndpoint(endpoint).setProject(projectId).setKey(secret).setSelfSigned(selfSigned); + clientConfig = { endpoint, projectId, secret, databaseId, bucketId }; + + client.setEndpoint(endpoint).setProject(projectId).setKey(secret); + + if (selfSigned) { + client.setSelfSigned(true); + } usersClient = new Users(client); healthClient = new Health(client); - databaseClient = new Database(client); - storageClient = new Storage(client); + databaseClient = new Database(client, databaseId); + storageClient = new Storage(client, bucketId); functionsClient = new Functions(client); return client; diff --git a/src/commands/database/createAttribute.ts b/src/commands/database/createAttribute.ts new file mode 100644 index 0000000..ae5a963 --- /dev/null +++ b/src/commands/database/createAttribute.ts @@ -0,0 +1,102 @@ +import { window } from "vscode"; +import { databaseClient } from "../../client"; +import { ext } from "../../extensionVariables"; +import { AttributesTreeItem } from "../../tree/database/settings/AttributesTreeItem"; + +const ATTRIBUTE_TYPES = [ + { label: "String", description: "Text content" }, + { label: "Integer", description: "Whole numbers" }, + { label: "Float", description: "Decimal numbers" }, + { label: "Boolean", description: "True/false values" }, + { label: "Email", description: "Email addresses" }, + { label: "URL", description: "Web URLs" }, + { label: "IP", description: "IP addresses" }, + { label: "Datetime", description: "Date and time values" }, + { label: "Enum", description: "Predefined options" }, +]; + +export async function createAttribute(attributesTreeItem: AttributesTreeItem): Promise { + if (!databaseClient) { + return; + } + + const collectionTreeItem = attributesTreeItem.parent; + const collection = collectionTreeItem.collection; + const databaseId = collectionTreeItem.databaseId; + + // Select attribute type + const typeChoice = await window.showQuickPick(ATTRIBUTE_TYPES, { + placeHolder: "Select attribute type", + }); + + if (!typeChoice) { + return; + } + + // Get attribute key + const key = await window.showInputBox({ + prompt: "Attribute key (name)", + validateInput: (value) => { + if (!value || value.length === 0) return "Key is required"; + if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(value)) return "Key must start with letter/underscore and contain only letters, numbers, underscores"; + return undefined; + }, + }); + + if (!key) { + return; + } + + // Ask if required + const requiredChoice = await window.showQuickPick( + [{ label: "Required", picked: false }, { label: "Optional", picked: true }], + { placeHolder: "Is this attribute required?" } + ); + + if (!requiredChoice) { + return; + } + + const required = requiredChoice.label === "Required"; + + try { + switch (typeChoice.label) { + case "String": { + const sizeStr = await window.showInputBox({ + prompt: "Maximum string length (1-16384)", + value: "255", + }); + const size = parseInt(sizeStr || "255"); + await databaseClient.createStringAttribute(collection.$id, key, size, required, undefined, false, databaseId); + break; + } + case "Integer": { + await databaseClient.createIntegerAttribute(collection.$id, key, required, undefined, undefined, undefined, false, databaseId); + break; + } + case "Boolean": { + await databaseClient.createBooleanAttribute(collection.$id, key, required, undefined, false, databaseId); + break; + } + case "Email": { + await databaseClient.createEmailAttribute(collection.$id, key, required, undefined, false, databaseId); + break; + } + case "URL": { + await databaseClient.createUrlAttribute(collection.$id, key, required, undefined, false, databaseId); + break; + } + default: + window.showWarningMessage(`Attribute type "${typeChoice.label}" is not yet supported in this extension.`); + return; + } + + window.showInformationMessage(`Created ${typeChoice.label.toLowerCase()} attribute "${key}".`); + ext.tree?.database?.refresh(); + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } +} + +// Backward compatibility alias +export { createAttribute as createRule }; diff --git a/src/commands/database/createCollection.ts b/src/commands/database/createCollection.ts index 4973b37..e97877f 100644 --- a/src/commands/database/createCollection.ts +++ b/src/commands/database/createCollection.ts @@ -1,17 +1,44 @@ import { window } from "vscode"; -import { databaseClient } from "../../client"; +import { clientConfig, databaseClient } from "../../client"; +import { DatabaseTreeItem } from "../../tree/database/DatabaseTreeItemProvider"; -export async function createCollection(): Promise { +export async function createCollection(databaseTreeItem?: DatabaseTreeItem): Promise { if (!databaseClient) { return; } + // Get databaseId from tree item, config, or let user select + let databaseId = databaseTreeItem?.database.$id || clientConfig?.databaseId; + + if (!databaseId) { + // List databases and let user select + const databases = await databaseClient.listDatabases(); + if (!databases || databases.databases.length === 0) { + window.showErrorMessage("No databases found. Please create a database first."); + return; + } + + const selected = await window.showQuickPick( + databases.databases.map(db => ({ + label: db.name, + description: db.$id, + id: db.$id + })), + { placeHolder: "Select a database" } + ); + + if (!selected) { + return; + } + databaseId = selected.id; + } + const name = await window.showInputBox({ prompt: "Collection name", }); if (name && name.length > 0) { - await databaseClient.createCollection({ name }); + await databaseClient.createCollection({ name, $permissions: [] }, databaseId); window.showInformationMessage(`Created collection "${name}".`); } } diff --git a/src/commands/database/createRule.ts b/src/commands/database/createRule.ts deleted file mode 100644 index 689611d..0000000 --- a/src/commands/database/createRule.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CreatedRule } from "../../appwrite"; -import { databaseClient } from "../../client"; -import { RulesTreeItem } from "../../tree/database/settings/RulesTreeItem"; -import { createRuleWizard } from "../../ui/createRuleWizard"; -import { refreshTree } from '../../utils/refreshTree'; - -export async function createRule(rulesTreeItem: RulesTreeItem): Promise { - - if (!databaseClient) { - return; - } - - const collection = rulesTreeItem.parent.collection; - const ruleContext = await createRuleWizard(collection); - - if (ruleContext) { - const newRule: CreatedRule = { - ...ruleContext, - type: ruleContext.type, - }; - - databaseClient.createRule(collection, newRule); - - await rulesTreeItem.refresh(); - refreshTree("database"); - } -} diff --git a/src/commands/database/deleteAttribute.ts b/src/commands/database/deleteAttribute.ts new file mode 100644 index 0000000..903e9f6 --- /dev/null +++ b/src/commands/database/deleteAttribute.ts @@ -0,0 +1,35 @@ +import { window } from "vscode"; +import { databaseClient } from "../../client"; +import { ext } from "../../extensionVariables"; +import { AttributeTreeItem } from "../../tree/database/settings/AttributeTreeItem"; +import { confirmDialog } from "../../ui/confirmDialog"; + +export async function deleteAttribute(attributeItem: AttributeTreeItem): Promise { + if (!databaseClient) { + return; + } + + const attribute = attributeItem.attribute; + const collectionTreeItem = attributeItem.parent.parent; + const collection = collectionTreeItem.collection; + const databaseId = collectionTreeItem.databaseId; + + try { + const shouldDelete = await confirmDialog( + `Delete attribute "${attribute.key}" from collection "${collection.name}"?` + ); + + if (!shouldDelete) { + return; + } + + await databaseClient.deleteAttribute(collection.$id, attribute.key, databaseId); + window.showInformationMessage(`Deleted attribute "${attribute.key}".`); + ext.tree?.database?.refresh(); + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } +} + +// Backward compatibility alias +export { deleteAttribute as removeRule }; diff --git a/src/commands/database/deleteCollection.ts b/src/commands/database/deleteCollection.ts index fe1458f..828c652 100644 --- a/src/commands/database/deleteCollection.ts +++ b/src/commands/database/deleteCollection.ts @@ -8,13 +8,15 @@ export async function deleteCollection(collectionTreeItem: CollectionTreeItem): return; } const collection = collectionTreeItem.collection; + const databaseId = collectionTreeItem.databaseId; + try { const shouldDelete = await confirmDialog(`Delete collection "${collection.name}"?`); if (shouldDelete) { - await databaseClient.deleteCollection(collection.$id); + await databaseClient.deleteCollection(collection.$id, databaseId); window.showInformationMessage(`Deleted collection "${collection.name}".`); } } catch (e) { - window.showErrorMessage(e); + window.showErrorMessage(e.message || String(e)); } } diff --git a/src/commands/database/deleteDocument.ts b/src/commands/database/deleteDocument.ts index 996f72f..d2a0aac 100644 --- a/src/commands/database/deleteDocument.ts +++ b/src/commands/database/deleteDocument.ts @@ -8,14 +8,17 @@ export async function deleteDocument(documentTreeItem: DocumentTreeItem): Promis return; } const document = documentTreeItem.document; - const collection = documentTreeItem.parent.parent.collection; + const collectionTreeItem = documentTreeItem.parent.parent; + const collection = collectionTreeItem.collection; + const databaseId = collectionTreeItem.databaseId; + try { const shouldDelete = await confirmDialog(`Delete document "${document["$id"]}" from ${collection.name}?`); if (shouldDelete) { - await databaseClient.deleteDocument(collection.$id, document["$id"]); + await databaseClient.deleteDocument(collection.$id, document["$id"], databaseId); window.showInformationMessage(`Deleted document "${document["$id"]}" from ${collection.name}.`); } } catch (e) { - window.showErrorMessage(e); + window.showErrorMessage(e.message || String(e)); } } diff --git a/src/commands/database/permissions/createPermission.ts b/src/commands/database/permissions/createPermission.ts index bd0929b..7712223 100644 --- a/src/commands/database/permissions/createPermission.ts +++ b/src/commands/database/permissions/createPermission.ts @@ -1,25 +1,61 @@ import { window } from "vscode"; import { databaseClient } from "../../../client"; +import { Permission, Role } from "../../../constants"; +import { ext } from "../../../extensionVariables"; import { PermissionsTreeItem } from "../../../tree/database/settings/PermissionsTreeItem"; +type PermissionType = "read" | "create" | "update" | "delete" | "write"; + export type CreatePermissionWizardContext = { - kind: "read" | "write"; - permission: string; + kind: PermissionType; + role: string; }; -export async function createPermissionWizard(kind?: "read" | "write"): Promise { - const permissionKind = kind ?? (await window.showQuickPick(["read", "write"])); - if (permissionKind && (permissionKind === "read" || permissionKind === "write")) { - const permission = await window.showInputBox({ prompt: "Add * for wildcard access", placeHolder: "User ID, Team ID, or Role" }); - if (permission === undefined) { - return undefined; - } - - return { - kind: permissionKind, - permission, - }; + +export async function createPermissionWizard(): Promise { + const permissionKind = await window.showQuickPick( + ["read", "create", "update", "delete", "write"], + { placeHolder: "Select permission type" } + ) as PermissionType | undefined; + + if (!permissionKind) { + return undefined; + } + + const roleType = await window.showQuickPick( + [ + { label: "any", description: "Anyone (public)" }, + { label: "users", description: "Any authenticated user" }, + { label: "guests", description: "Any unauthenticated user" }, + { label: "user", description: "Specific user by ID" }, + { label: "team", description: "Specific team by ID" }, + ], + { placeHolder: "Select role type" } + ); + + if (!roleType) { + return undefined; + } + + let role: string; + if (roleType.label === "any") { + role = Role.any(); + } else if (roleType.label === "users") { + role = Role.users(); + } else if (roleType.label === "guests") { + role = Role.guests(); + } else if (roleType.label === "user") { + const userId = await window.showInputBox({ prompt: "Enter user ID" }); + if (!userId) return undefined; + role = Role.user(userId); + } else if (roleType.label === "team") { + const teamId = await window.showInputBox({ prompt: "Enter team ID" }); + if (!teamId) return undefined; + role = Role.team(teamId); + } else { + return undefined; } - return undefined; + + return { kind: permissionKind, role }; } export async function createPermission(treeItem: PermissionsTreeItem): Promise { @@ -27,21 +63,43 @@ export async function createPermission(treeItem: PermissionsTreeItem): Promise { if (!databaseClient) { return; } - const collection = treeItem.parent.parent.collection; - const kind = treeItem.kind; - let read = Array.from(collection.$permissions.read); - let write = Array.from(collection.$permissions.write); + const collectionTreeItem = treeItem.parent.parent; + const collection = collectionTreeItem.collection; + const databaseId = collectionTreeItem.databaseId; - if (kind === "read") { - read = read.filter((item) => item !== treeItem.permission); - } else { - write = write.filter((item) => item !== treeItem.permission); - } + // Build the full permission string to remove + const permissionToRemove = `${treeItem.kind}("${treeItem.permission}")`; + + try { + const shouldDelete = await confirmDialog(`Delete ${treeItem.kind} permission for "${treeItem.permission}"?`); + if (!shouldDelete) { + return; + } - await databaseClient.updatePermissions(collection, read, write); + // Remove the permission from the array + const permissions = (collection.$permissions || []).filter( + perm => perm !== permissionToRemove + ); + + await databaseClient.updateCollection(collection.$id, collection.name, permissions, databaseId); + window.showInformationMessage(`Removed ${treeItem.kind} permission for "${treeItem.permission}".`); + ext.tree?.database?.refresh(); + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } } diff --git a/src/commands/database/permissions/editPermission.ts b/src/commands/database/permissions/editPermission.ts index 81f5aa1..1c038bc 100644 --- a/src/commands/database/permissions/editPermission.ts +++ b/src/commands/database/permissions/editPermission.ts @@ -1,32 +1,40 @@ import { window } from "vscode"; import { databaseClient } from "../../../client"; +import { ext } from "../../../extensionVariables"; import { PermissionTreeItem } from "../../../tree/database/settings/PermissionTreeItem"; export async function editPermission(treeItem: PermissionTreeItem): Promise { if (!databaseClient) { return; } - const editedPermission = await window.showInputBox({ + + const editedRole = await window.showInputBox({ value: treeItem.permission, + prompt: `Edit the role for ${treeItem.kind} permission`, }); - if (editedPermission === undefined) { + if (editedRole === undefined || editedRole === treeItem.permission) { return; } - const collection = treeItem.parent.parent.collection; - const kind = treeItem.kind; + const collectionTreeItem = treeItem.parent.parent; + const collection = collectionTreeItem.collection; + const databaseId = collectionTreeItem.databaseId; - let read = Array.from(collection.$permissions.read); - let write = Array.from(collection.$permissions.write); + // Build permission strings + const oldPermission = `${treeItem.kind}("${treeItem.permission}")`; + const newPermission = `${treeItem.kind}("${editedRole}")`; - if (kind === "read") { - read = read.filter((item) => item !== treeItem.permission); - read.push(editedPermission); - } else { - write = write.filter((item) => item !== treeItem.permission); - write.push(editedPermission); - } + try { + // Update permissions: remove old, add new + const permissions = (collection.$permissions || []) + .filter(perm => perm !== oldPermission) + .concat(newPermission); - await databaseClient.updatePermissions(collection, read, write); + await databaseClient.updateCollection(collection.$id, collection.name, permissions, databaseId); + window.showInformationMessage(`Updated ${treeItem.kind} permission to "${editedRole}".`); + ext.tree?.database?.refresh(); + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } } diff --git a/src/commands/database/removeRule.ts b/src/commands/database/removeRule.ts deleted file mode 100644 index 5c455d5..0000000 --- a/src/commands/database/removeRule.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { databaseClient } from '../../client'; -import { RuleTreeItem } from '../../tree/database/settings/RuleTreeItem'; -import { refreshTree } from '../../utils/refreshTree'; - -export async function removeRule(ruleItem: RuleTreeItem): Promise { - if (!databaseClient) { - return; - } - const rule = ruleItem.rule; - const collection = ruleItem.parent.parent.collection; - await databaseClient.removeRule(collection, rule); - refreshTree('database'); -} diff --git a/src/commands/functions/activateDeployment.ts b/src/commands/functions/activateDeployment.ts new file mode 100644 index 0000000..269c10b --- /dev/null +++ b/src/commands/functions/activateDeployment.ts @@ -0,0 +1,34 @@ +import { window } from "vscode"; +import { Deployment } from '../../appwrite'; +import { functionsClient } from '../../client'; +import { DeploymentTreeItem } from '../../tree/functions/deployments/DeploymentTreeItem'; +import { ext } from "../../extensionVariables"; + +export async function activateDeployment(deploymentItem: DeploymentTreeItem | Deployment): Promise { + if (!functionsClient) { + return; + } + + let functionId: string; + let deploymentId: string; + + if (deploymentItem instanceof DeploymentTreeItem) { + functionId = deploymentItem.parent.parent.func.$id; + deploymentId = deploymentItem.deployment.$id; + } else { + // It's a Deployment object - we need the functionId from it + functionId = deploymentItem.resourceId; + deploymentId = deploymentItem.$id; + } + + try { + await functionsClient.updateDeployment(functionId, deploymentId); + window.showInformationMessage(`Activated deployment "${deploymentId}".`); + ext.tree?.functions?.refresh(); + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } +} + +// Backward compatibility alias +export { activateDeployment as activateTag }; diff --git a/src/commands/functions/activateTag.ts b/src/commands/functions/activateTag.ts deleted file mode 100644 index b34a423..0000000 --- a/src/commands/functions/activateTag.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Tag } from '../../appwrite'; -import { functionsClient } from '../../client'; -import { TagTreeItem } from '../../tree/functions/tags/TagTreeItem'; - -export async function activateTag(tagItem: TagTreeItem | Tag): Promise { - const tag = tagItem instanceof TagTreeItem ? tagItem.tag : tagItem; - await functionsClient?.updateTag(tag.functionId, tag.$id); -} diff --git a/src/commands/functions/copyExecutionErrors.ts b/src/commands/functions/copyExecutionErrors.ts index 889bdd0..aacf998 100644 --- a/src/commands/functions/copyExecutionErrors.ts +++ b/src/commands/functions/copyExecutionErrors.ts @@ -7,5 +7,6 @@ export async function copyExecutionErrors(executionItem: ExecutionTreeItem): Pro } const execution = executionItem.execution; - env.clipboard.writeText(execution.stderr); + // SDK v21: stderr renamed to errors + env.clipboard.writeText(execution.errors || ''); } diff --git a/src/commands/functions/copyExecutionOutput.ts b/src/commands/functions/copyExecutionOutput.ts index a1edf27..87084f2 100644 --- a/src/commands/functions/copyExecutionOutput.ts +++ b/src/commands/functions/copyExecutionOutput.ts @@ -7,5 +7,6 @@ export async function copyExecutionOutput(executionItem: ExecutionTreeItem): Pro } const execution = executionItem.execution; - env.clipboard.writeText(execution.stdout); + // SDK v21: stdout renamed to logs + env.clipboard.writeText(execution.logs || ''); } diff --git a/src/commands/functions/createDeployment.ts b/src/commands/functions/createDeployment.ts new file mode 100644 index 0000000..89973c4 --- /dev/null +++ b/src/commands/functions/createDeployment.ts @@ -0,0 +1,183 @@ +import { ProgressLocation, QuickPickItem, Uri, window, workspace } from "vscode"; +import { functionsClient } from "../../client"; +import { getTarReadStream } from "../../utils/tar"; +import { ext } from "../../extensionVariables"; +import * as fs from "fs"; +import { DeploymentsTreeItem } from "../../tree/functions/deployments/DeploymentsTreeItem"; +import { selectWorkspaceFolder } from "../../utils/workspace"; +import { ProgressMessage } from "../../utils/types"; +import { Deployment } from "../../appwrite"; +import { activateDeployment } from "./activateDeployment"; + +export async function createDeployment(item?: DeploymentsTreeItem | Uri): Promise { + if (item instanceof Uri) { + const functions = await functionsClient?.list(); + if (functions === undefined) { + return; + } + const pick = await window.showQuickPick( + functions.functions.map( + (func): QuickPickItem => ({ label: func.name, description: func.runtime, detail: func.$id }) + ), + { placeHolder: "Select a function to create deployment" } + ); + if (pick === undefined || pick.detail === undefined) { + return; + } + const deployments = await functionsClient?.listDeployments(pick.detail); + let value; + if (deployments && deployments.deployments.length > 0) { + value = deployments.deployments[deployments.deployments.length - 1].entrypoint; + } + const entrypoint = await window.showInputBox({ value, prompt: "Entrypoint for your function" }); + if (entrypoint === undefined) { + return; + } + const deployment = await window.withProgress( + { location: ProgressLocation.Notification, title: "Creating deployment..." }, + async (progress, _token) => { + if (pick.detail === undefined) { + return; + } + return await createDeploymentFromUri(pick.detail, entrypoint, item, progress); + } + ); + if (deployment) { + await deploymentNotification(deployment); + } + + return; + } + + if (item instanceof DeploymentsTreeItem) { + const func = item.parent.func; + const folder = await selectWorkspaceFolder("Select folder of your function code."); + if (folder === undefined || folder === "") { + return; + } + const deployments = await functionsClient?.listDeployments(func.$id); + let value; + if (deployments && deployments.deployments.length > 0) { + value = deployments.deployments[deployments.deployments.length - 1].entrypoint; + } + const entrypoint = await window.showInputBox({ value, prompt: "Entrypoint for your function" }); + if (entrypoint === undefined) { + return; + } + const deployment = await window.withProgress( + { location: ProgressLocation.Notification, title: "Creating deployment..." }, + async (progress, _token) => { + return await createDeploymentFromUri(func.$id, entrypoint, Uri.parse(folder), progress); + } + ); + + if (deployment) { + await deploymentNotification(deployment); + return; + } + } + + if (item === undefined) { + const functions = await functionsClient?.list(); + if (functions === undefined) { + return; + } + const pick = await window.showQuickPick( + functions.functions.map( + (func): QuickPickItem => ({ label: func.name, description: func.runtime, detail: func.$id }) + ), + { placeHolder: "Select a function to create deployment" } + ); + if (pick === undefined || pick.detail === undefined) { + return; + } + const funcId = pick.detail; + const folder = await selectWorkspaceFolder("Select folder of your function code."); + const deployments = await functionsClient?.listDeployments(funcId); + let value; + if (deployments && deployments.deployments.length > 0) { + value = deployments.deployments[deployments.deployments.length - 1].entrypoint; + } + const entrypoint = await window.showInputBox({ value, prompt: "Entrypoint for your function" }); + if (entrypoint === undefined) { + return; + } + const deployment = await window.withProgress( + { location: ProgressLocation.Notification, title: "Creating deployment..." }, + async (progress, _token) => { + return await createDeploymentFromUri(funcId, entrypoint, Uri.parse(folder), progress); + } + ); + + if (deployment) { + await deploymentNotification(deployment); + return; + } + } +} + +async function createDeploymentFromUri( + functionId: string, + entrypoint: string, + uri: Uri, + progress: ProgressMessage +): Promise { + progress.report({ message: "Creating tarball", increment: 10 }); + + if (functionsClient === undefined) { + return; + } + + let tarFilePath; + try { + tarFilePath = await getTarReadStream(uri); + } catch (e) { + window.showErrorMessage("Error creating tar file.\n" + e); + return; + } + if (tarFilePath === undefined) { + window.showErrorMessage("Failed to create tar file."); + ext.outputChannel.appendLog("Failed to create tar file."); + return; + } + // somehow makes the upload work + await workspace.fs.readFile(Uri.file(tarFilePath)); + progress.report({ message: "Uploading deployment", increment: 60 }); + try { + return await functionsClient.createDeployment( + functionId, + fs.createReadStream(tarFilePath), + true, // activate + entrypoint + ); + } catch (e) { + ext.outputChannel.appendLog("Creating deployment error: " + e); + } +} + +async function deploymentNotification(deployment: Deployment): Promise { + ext.tree?.functions?.refresh(); + if (deployment) { + const action = await window.showInformationMessage( + `Successfully created deployment with size ${formatSize(deployment.size)}.`, + "Activate deployment", + "View in console" + ); + if (action === "Activate deployment") { + await activateDeployment(deployment); + } + if (action === "View in console") { + // + } + return; + } +} + +function formatSize(bytes: number): string { + if (bytes < 1024) return `${bytes}B`; + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`; + return `${(bytes / (1024 * 1024)).toFixed(1)}MB`; +} + +// Backward compatibility alias +export { createDeployment as createTag }; diff --git a/src/commands/functions/createExecution.ts b/src/commands/functions/createExecution.ts index 76e299f..2b9e795 100644 --- a/src/commands/functions/createExecution.ts +++ b/src/commands/functions/createExecution.ts @@ -13,8 +13,12 @@ export async function createExecution(functionTreeItem: FunctionTreeItem): Promi } export async function executeFunction(functionId: string): Promise { + if (!functionsClient) { + return; + } + ext.outputChannel.appendLog(`Creating execution for function with ID: ${functionId}`); - let execution = await functionsClient?.createExecution(functionId); + let execution = await functionsClient.createExecution(functionId); ext.outputChannel.appendLog(JSON.stringify(execution, null, 2)); await ext.tree?.functions?.refresh(); @@ -22,7 +26,7 @@ export async function executeFunction(functionId: string): Promise { return; } - execution = await waitForExecution(execution); + execution = await waitForExecution(functionId, execution); ext.tree?.functions?.refresh(); if (execution === undefined) { @@ -31,7 +35,10 @@ export async function executeFunction(functionId: string): Promise { const failed = execution.status === "failed"; const item = !failed ? "View output" : "View errors"; - const action = await window.showInformationMessage(`Execution ${failed ? "failed" : "completed"} in ${execution.time.toFixed(2)}s.`, item); + const action = await window.showInformationMessage( + `Execution ${failed ? "failed" : "completed"} in ${execution.duration.toFixed(2)}s.`, + item + ); if (action === item) { if (item === "View output") { await viewExecutionOutput(execution); @@ -42,15 +49,16 @@ export async function executeFunction(functionId: string): Promise { } } -async function waitForExecution(execution: Execution | undefined): Promise { +async function waitForExecution(functionId: string, execution: Execution | undefined): Promise { if (execution === undefined) { return; } - if (execution.status === "processing" || execution.status === "waiting") { + // Handle all non-terminal states + if (execution.status === "processing" || execution.status === "waiting" || execution.status === "scheduled") { await sleep(5000); - ext.outputChannel.appendLog("Execution still ..."); - return await waitForExecution(await functionsClient?.getExecution(execution.functionId, execution.$id)); + ext.outputChannel.appendLog(`Execution still ${execution.status}...`); + return await waitForExecution(functionId, await functionsClient?.getExecution(functionId, execution.$id)); } return execution; diff --git a/src/commands/functions/createFunction.ts b/src/commands/functions/createFunction.ts index c90d48c..1f11bb9 100644 --- a/src/commands/functions/createFunction.ts +++ b/src/commands/functions/createFunction.ts @@ -1,19 +1,33 @@ import { window } from 'vscode'; import { functionsClient } from '../../client'; import { appwriteFunctionRuntimes } from '../../constants'; +import { ext } from '../../extensionVariables'; import { validateFunctionName } from '../../tree/functions/settings/NameTreeItem'; export async function createFunction(): Promise { + if (!functionsClient) { + return; + } const name = await window.showInputBox({ prompt: 'Function name', validateInput: validateFunctionName }); if (name === undefined) { return; } - const env: string | undefined = await window.showQuickPick(appwriteFunctionRuntimes); - if (env === undefined) { + const runtime: string | undefined = await window.showQuickPick(appwriteFunctionRuntimes, { + placeHolder: 'Select runtime environment' + }); + if (runtime === undefined) { return; } - await functionsClient?.create(name, [], env); + try { + const func = await functionsClient.create(name, [], runtime); + if (func) { + window.showInformationMessage(`Created function "${name}" with runtime ${runtime}.`); + ext.tree?.functions?.refresh(); + } + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } } diff --git a/src/commands/functions/createFunctionVar.ts b/src/commands/functions/createFunctionVar.ts index d2d7c77..6ddc7ad 100644 --- a/src/commands/functions/createFunctionVar.ts +++ b/src/commands/functions/createFunctionVar.ts @@ -1,16 +1,23 @@ +import { window } from 'vscode'; import { functionsClient } from '../../client'; +import { ext } from '../../extensionVariables'; import { VarsTreeItem } from '../../tree/functions/settings/VarsTreeItem'; import { keyValuePrompt } from '../../tree/functions/settings/VarTreeItem'; export async function createFunctionVar(treeItem: VarsTreeItem): Promise { - if (treeItem === undefined) { + if (treeItem === undefined || !functionsClient) { return; } const func = treeItem.parent.func; const keyval = await keyValuePrompt(); if (keyval) { - const newVars = {...func.vars}; - newVars[keyval.key] = keyval.value; - await functionsClient?.update(func.$id, func.name, [], newVars, func.events, func.schedule, func.timeout); + try { + // SDK v21: Use createVariable instead of updating func.vars + await functionsClient.createVariable(func.$id, keyval.key, keyval.value); + window.showInformationMessage(`Created variable "${keyval.key}".`); + ext.tree?.functions?.refresh(); + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } } } diff --git a/src/commands/functions/createTag.ts b/src/commands/functions/createTag.ts deleted file mode 100644 index b154d33..0000000 --- a/src/commands/functions/createTag.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { ProgressLocation, QuickPickItem, Uri, window, workspace } from "vscode"; -import { functionsClient } from "../../client"; -import { getTarReadStream } from "../../utils/tar"; -import { ext } from "../../extensionVariables"; -import * as fs from "fs"; -import { TagsTreeItem } from "../../tree/functions/tags/TagsTreeItem"; -import { selectWorkspaceFolder } from "../../utils/workspace"; -import { ProgressMessage } from "../../utils/types"; -import { Tag } from "../../appwrite"; -import { activateTag } from "./activateTag"; - -export async function createTag(item?: TagsTreeItem | Uri): Promise { - if (item instanceof Uri) { - const functions = await functionsClient?.list(); - if (functions === undefined) { - return; - } - const pick = await window.showQuickPick( - functions.functions.map( - (func): QuickPickItem => ({ label: func.name, description: func.env, detail: func.$id }) - ), - { placeHolder: "Select a function to create tag" } - ); - if (pick === undefined || pick.detail === undefined) { - return; - } - const tags = await functionsClient?.listTags(pick.detail); - let value; - if (tags && tags.tags.length > 0) { - value = tags.tags[tags.tags.length - 1].command; - } - const command = await window.showInputBox({ value, prompt: "Command to run your code" }); - if (command === undefined) { - return; - } - const tag = await window.withProgress( - { location: ProgressLocation.Notification, title: "Creating tag..." }, - async (progress, _token) => { - if (pick.detail === undefined) { - return; - } - return await createTagFromUri(pick.detail, command, item, progress); - } - ); - if (tag) { - await tagNotification(tag); - } - - return; - } - - if (item instanceof TagsTreeItem) { - const func = item.parent.func; - const folder = await selectWorkspaceFolder("Select folder of your function code."); - if (folder === undefined || folder === "") { - return; - } - const tags = await functionsClient?.listTags(func.$id); - let value; - if (tags && tags.tags.length > 0) { - value = tags.tags[tags.tags.length - 1].command; - } - const command = await window.showInputBox({ value, prompt: "Command to run your code" }); - if (command === undefined) { - return; - } - const tag = await window.withProgress( - { location: ProgressLocation.Notification, title: "Creating tag..." }, - async (progress, _token) => { - return await createTagFromUri(func.$id, command, Uri.parse(folder), progress); - } - ); - - if (tag) { - await tagNotification(tag); - return; - } - } - - if (item === undefined) { - const functions = await functionsClient?.list(); - if (functions === undefined) { - return; - } - const pick = await window.showQuickPick( - functions.functions.map( - (func): QuickPickItem => ({ label: func.name, description: func.env, detail: func.$id }) - ), - { placeHolder: "Select a function to create tag" } - ); - if (pick === undefined || pick.detail === undefined) { - return; - } - const funcId = pick.detail; - const folder = await selectWorkspaceFolder("Select folder of your function code."); - const tags = await functionsClient?.listTags(funcId); - let value; - if (tags && tags.tags.length > 0) { - value = tags.tags[tags.tags.length - 1].command; - } - const command = await window.showInputBox({ value, prompt: "Command to run your code" }); - if (command === undefined) { - return; - } - const tag = await window.withProgress( - { location: ProgressLocation.Notification, title: "Creating tag..." }, - async (progress, _token) => { - return await createTagFromUri(funcId, command, Uri.parse(folder), progress); - } - ); - - if (tag) { - await tagNotification(tag); - return; - } - } -} - -async function createTagFromUri(functionId: string, command: string, uri: Uri, progress: ProgressMessage): Promise { - progress.report({ message: "Creating tarball", increment: 10 }); - - if (functionsClient === undefined) { - return; - } - - let tarFilePath; - try { - tarFilePath = await getTarReadStream(uri); - } catch (e) { - window.showErrorMessage("Error creating tar file.\n" + e); - return; - } - if (tarFilePath === undefined) { - window.showErrorMessage("Failed to create tar file."); - ext.outputChannel.appendLog("Failed to create tar file."); - return; - } - // somehow makes the upload work - await workspace.fs.readFile(Uri.file(tarFilePath)); - progress.report({ message: "Uploading tag", increment: 60 }); - try { - return await functionsClient.createTag(functionId, command, fs.createReadStream(tarFilePath)); - } catch (e) { - ext.outputChannel.appendLog("Creating tag error: " + e); - } -} - -async function tagNotification(tag: Tag): Promise { - ext.tree?.functions?.refresh(); - if (tag) { - const action = await window.showInformationMessage( - `Successfully created tag with size ${tag.size}B.`, - "Activate tag", - "View in console" - ); - if (action === "Activate tag") { - await activateTag(tag); - } - if (action === "View in console") { - // - } - return; - } -} diff --git a/src/commands/functions/deleteDeployment.ts b/src/commands/functions/deleteDeployment.ts new file mode 100644 index 0000000..98d81f8 --- /dev/null +++ b/src/commands/functions/deleteDeployment.ts @@ -0,0 +1,30 @@ +import { window } from "vscode"; +import { functionsClient } from "../../client"; +import { DeploymentTreeItem } from "../../tree/functions/deployments/DeploymentTreeItem"; +import { confirmDialog } from "../../ui/confirmDialog"; +import { ext } from "../../extensionVariables"; + +export async function deleteDeployment(deploymentItem: DeploymentTreeItem): Promise { + if (deploymentItem === undefined) { + return; + } + + const func = deploymentItem.parent.parent.func; + const deployment = deploymentItem.deployment; + + try { + const shouldDelete = await confirmDialog( + `Delete deployment "${deployment.$id}" from function "${func.name}"?` + ); + if (shouldDelete) { + await functionsClient?.deleteDeployment(func.$id, deployment.$id); + window.showInformationMessage(`Deleted deployment "${deployment.$id}".`); + ext.tree?.functions?.refresh(); + } + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } +} + +// Backward compatibility alias +export { deleteDeployment as deleteTag }; diff --git a/src/commands/functions/deleteFunctionVar.ts b/src/commands/functions/deleteFunctionVar.ts index cac27e3..b0fe9f8 100644 --- a/src/commands/functions/deleteFunctionVar.ts +++ b/src/commands/functions/deleteFunctionVar.ts @@ -1,13 +1,30 @@ +import { window } from 'vscode'; import { functionsClient } from '../../client'; +import { ext } from '../../extensionVariables'; import { VarTreeItem } from '../../tree/functions/settings/VarTreeItem'; +import { confirmDialog } from '../../ui/confirmDialog'; export async function deleteFunctionVar(treeItem: VarTreeItem): Promise { - if (treeItem === undefined) { + if (treeItem === undefined || !functionsClient) { return; } - const func = treeItem.func; - const newVars = {...func.vars}; - delete newVars[treeItem.key]; - await functionsClient?.update(func.$id, func.name, [], newVars, func.events, func.schedule, func.timeout); + const func = treeItem.parent.parent.func; + const variableKey = treeItem.key; + + try { + const shouldDelete = await confirmDialog(`Delete variable "${variableKey}"?`); + if (shouldDelete) { + // SDK v21: Need to get variable ID first, then delete + const variables = await functionsClient.listVariables(func.$id); + const variable = variables?.variables.find(v => v.key === variableKey); + if (variable) { + await functionsClient.deleteVariable(func.$id, variable.$id); + window.showInformationMessage(`Deleted variable "${variableKey}".`); + ext.tree?.functions?.refresh(); + } + } + } catch (e) { + window.showErrorMessage(e.message || String(e)); + } } diff --git a/src/commands/functions/deleteTag.ts b/src/commands/functions/deleteTag.ts deleted file mode 100644 index 1d3b885..0000000 --- a/src/commands/functions/deleteTag.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { functionsClient } from "../../client"; -import { TagTreeItem } from "../../tree/functions/tags/TagTreeItem"; - -export async function deleteTag(tagItem: TagTreeItem): Promise { - if (tagItem === undefined) { - return; - } - - const func = tagItem.parent.parent.func; - await functionsClient?.deleteTag(func.$id, tagItem.tag.$id); -} diff --git a/src/commands/functions/viewExecutionErrors.ts b/src/commands/functions/viewExecutionErrors.ts index 2a79f28..7192227 100644 --- a/src/commands/functions/viewExecutionErrors.ts +++ b/src/commands/functions/viewExecutionErrors.ts @@ -12,5 +12,11 @@ export async function viewExecutionErrors(executionItem: ExecutionTreeItem | Exe if (executionItem instanceof ExecutionTreeItem) { execution = executionItem.execution; } - await openReadOnlyContent({ label: `Execution stderr`, fullId: `${execution.$id}-errors.txt` }, execution.stderr, '.txt'); + + // SDK v21: stderr renamed to errors + await openReadOnlyContent( + { label: `Execution errors`, fullId: `${execution.$id}-errors.txt` }, + execution.errors || '', + '.txt' + ); } diff --git a/src/commands/functions/viewExecutionOutput.ts b/src/commands/functions/viewExecutionOutput.ts index 28088c5..2a41332 100644 --- a/src/commands/functions/viewExecutionOutput.ts +++ b/src/commands/functions/viewExecutionOutput.ts @@ -7,13 +7,16 @@ export async function viewExecutionOutput(executionItem: ExecutionTreeItem | Exe return; } - let execution = executionItem as Execution; if (executionItem instanceof ExecutionTreeItem) { execution = executionItem.execution; } - console.log(execution.dateCreated); - await openReadOnlyContent({ label: `Execution stdout`, fullId: `${execution.$id}-output.txt` }, execution.stdout, '.txt'); + // SDK v21: stdout renamed to logs + await openReadOnlyContent( + { label: `Execution logs`, fullId: `${execution.$id}-logs.txt` }, + execution.logs || '', + '.txt' + ); } diff --git a/src/commands/registerCommands.ts b/src/commands/registerCommands.ts index 4bb1f94..243bea3 100644 --- a/src/commands/registerCommands.ts +++ b/src/commands/registerCommands.ts @@ -4,14 +4,14 @@ import { refreshAllViews, refreshTree } from "../utils/refreshTree"; import { connectAppwrite } from "./connectAppwrite"; import { createCollection } from "./database/createCollection"; import { createPermission } from "./database/permissions/createPermission"; -import { createRule } from "./database/createRule"; +import { createAttribute } from "./database/createAttribute"; import { deleteCollection } from "./database/deleteCollection"; import { deleteDocument } from "./database/deleteDocument"; import { deletePermission } from "./database/permissions/deletePermission"; import { viewDocumentAsJson } from "./database/openDocument"; import { refreshCollection } from "./database/refreshCollection"; import { refreshCollectionsList } from "./database/refreshCollectionsList"; -import { removeRule } from "./database/removeRule"; +import { deleteAttribute } from "./database/deleteAttribute"; import { viewCollectionAsJson } from "./database/viewCollectionAsJson"; import { openDocumentation } from "./openDocumentation"; import { copyUserEmail } from "./users/copyUserEmail"; @@ -25,15 +25,15 @@ import { viewUserPrefs } from "./users/viewUserPrefs"; import { editPermission } from "./database/permissions/editPermission"; import { setActiveProject } from "./project/setActiveProject"; import { removeProject } from "./project/removeProject"; -import { createTag } from './functions/createTag'; +import { createDeployment } from './functions/createDeployment'; import { createExecution } from './functions/createExecution'; -import { activateTag } from './functions/activateTag'; +import { activateDeployment } from './functions/activateDeployment'; import { editValue } from './common/editValue'; import { deleteFunction } from './functions/deleteFunction'; import { createFunction } from './functions/createFunction'; import { createFunctionVar } from './functions/createFunctionVar'; import { deleteFunctionVar } from './functions/deleteFunctionVar'; -import { deleteTag } from './functions/deleteTag'; +import { deleteDeployment } from './functions/deleteDeployment'; import { viewExecutionErrors } from './functions/viewExecutionErrors'; import { viewExecutionOutput } from './functions/viewExecutionOutput'; import { copyExecutionErrors } from './functions/copyExecutionErrors'; @@ -96,8 +96,12 @@ export function registerCommands(context: ExtensionContext): void { registerCommand("OpenDatabaseDocumentation", () => openDocumentation("database")); registerCommand("viewDocumentAsJson", viewDocumentAsJson); registerCommand("viewCollectionAsJson", viewCollectionAsJson); - registerCommand("createRule", createRule); - registerCommand("removeRule", removeRule); + // Attribute commands (replaces Rule commands) + registerCommand("createAttribute", createAttribute, "database"); + registerCommand("deleteAttribute", deleteAttribute, "database"); + // Backward compatibility aliases for Rule commands + registerCommand("createRule", createAttribute, "database"); + registerCommand("removeRule", deleteAttribute, "database"); registerCommand("deleteDocument", deleteDocument, "database"); registerCommand("deleteCollection", deleteCollection, "database"); registerCommand("refreshCollection", refreshCollection); @@ -124,9 +128,14 @@ export function registerCommands(context: ExtensionContext): void { /** Functions **/ registerCommand("refreshFunctions", undefined, "functions"); registerCommand("CreateExecution", createExecution, "functions"); - registerCommand("CreateTag", createTag, "functions"); - registerCommand("activateTag", activateTag, "functions"); - registerCommand("deleteTag", deleteTag, "functions"); + // Deployment commands (replaces Tag commands) + registerCommand("CreateDeployment", createDeployment, "functions"); + registerCommand("activateDeployment", activateDeployment, "functions"); + registerCommand("deleteDeployment", deleteDeployment, "functions"); + // Backward compatibility aliases for Tag commands + registerCommand("CreateTag", createDeployment, "functions"); + registerCommand("activateTag", activateDeployment, "functions"); + registerCommand("deleteTag", deleteDeployment, "functions"); registerCommand("deleteFunction", deleteFunction, "functions"); registerCommand("openFunctionsDocumentation", () => openDocumentation("functions")); registerCommand("createFunction", createFunction, "functions"); diff --git a/src/constants.ts b/src/constants.ts index 40276cc..90cc1a0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,197 +1,330 @@ -import type { SDK } from "./appwrite"; +import type { SDK, PermissionHelper, RoleHelper, QueryHelper, IDHelper } from "./appwrite"; // eslint-disable-next-line @typescript-eslint/no-var-requires -export const AppwriteSDK: SDK = require("node-appwrite") as SDK; +const sdk = require("node-appwrite"); +export const AppwriteSDK: SDK = sdk as SDK; + +// Export helper classes from SDK +export const Permission: PermissionHelper = sdk.Permission; +export const Role: RoleHelper = sdk.Role; +export const Query: QueryHelper = sdk.Query; +export const ID: IDHelper = sdk.ID; + +// System events for Appwrite v1.8.x / SDK v21 +// See: https://appwrite.io/docs/advanced/platform/events export const appwriteSystemEvents = [ + // Users events { - name: "account.create", - description: "This event triggers when the account is created.", + name: "users.*.create", + description: "Triggered when a user is created.", }, { - name: "account.update.email", - description: "This event triggers when the account email address is updated.", + name: "users.*.update", + description: "Triggered when a user is updated.", }, { - name: "account.update.name", - description: "This event triggers when the account name is updated.", + name: "users.*.update.email", + description: "Triggered when a user email is updated.", }, { - name: "account.update.password", - description: "This event triggers when the account password is updated.", + name: "users.*.update.name", + description: "Triggered when a user name is updated.", }, { - name: "account.update.prefs", - description: "This event triggers when the account preferences are updated.", + name: "users.*.update.password", + description: "Triggered when a user password is updated.", }, { - name: "account.recovery.create", - description: "This event triggers when the account recovery token is created.", + name: "users.*.update.status", + description: "Triggered when a user status is updated.", }, { - name: "account.recovery.update", - description: "This event triggers when the account recovery token is validated.", + name: "users.*.update.prefs", + description: "Triggered when user preferences are updated.", }, { - name: "account.verification.create", - description: "This event triggers when the account verification token is created.", + name: "users.*.delete", + description: "Triggered when a user is deleted.", }, { - name: "account.verification.update", - description: "This event triggers when the account verification token is validated.", + name: "users.*.sessions.*.create", + description: "Triggered when a user session is created.", }, { - name: "account.delete", - description: "This event triggers when the account is deleted.", + name: "users.*.sessions.*.delete", + description: "Triggered when a user session is deleted.", }, { - name: "account.sessions.create", - description: "This event triggers when the account session is created.", + name: "users.*.recovery.*.create", + description: "Triggered when a user recovery token is created.", }, { - name: "account.delete", - description: "This event triggers when the account is deleted.", + name: "users.*.recovery.*.update", + description: "Triggered when a user recovery token is validated.", }, { - name: "account.sessions.create", - description: "This event triggers when the account session is created.", + name: "users.*.verification.*.create", + description: "Triggered when a user verification token is created.", }, { - name: "account.sessions.delete", - description: "This event triggers when the account session is deleted.", + name: "users.*.verification.*.update", + description: "Triggered when a user verification token is validated.", }, + + // Databases events (new format with databaseId) { - name: "database.collections.create", - description: "This event triggers when a database collection is created.", + name: "databases.*.create", + description: "Triggered when a database is created.", }, { - name: "database.collections.update", - description: "This event triggers when a database collection is updated.", + name: "databases.*.update", + description: "Triggered when a database is updated.", }, { - name: "database.collections.delete", - description: "This event triggers when a database collection is deleted.", + name: "databases.*.delete", + description: "Triggered when a database is deleted.", }, { - name: "database.documents.create", - description: "This event triggers when a database document is created.", + name: "databases.*.collections.*.create", + description: "Triggered when a collection is created.", }, { - name: "database.documents.update", - description: "This event triggers when a database document is updated.", + name: "databases.*.collections.*.update", + description: "Triggered when a collection is updated.", }, { - name: "database.documents.delete", - description: "This event triggers when a database document is deleted.", + name: "databases.*.collections.*.delete", + description: "Triggered when a collection is deleted.", }, { - name: "functions.create", - description: "This event triggers when a function is created.", + name: "databases.*.collections.*.documents.*.create", + description: "Triggered when a document is created.", }, { - name: "functions.update", - description: "This event triggers when a function is updated.", + name: "databases.*.collections.*.documents.*.update", + description: "Triggered when a document is updated.", }, { - name: "functions.delete", - description: "This event triggers when a function is deleted.", + name: "databases.*.collections.*.documents.*.delete", + description: "Triggered when a document is deleted.", }, { - name: "functions.tags.create", - description: "This event triggers when a function tag is created.", + name: "databases.*.collections.*.attributes.*.create", + description: "Triggered when an attribute is created.", }, { - name: "functions.tags.update", - description: "This event triggers when a function tag is updated.", + name: "databases.*.collections.*.attributes.*.delete", + description: "Triggered when an attribute is deleted.", }, { - name: "functions.tags.delete", - description: "This event triggers when a function tag is deleted.", + name: "databases.*.collections.*.indexes.*.create", + description: "Triggered when an index is created.", }, { - name: "functions.executions.create", - description: "This event triggers when a function execution is created.", + name: "databases.*.collections.*.indexes.*.delete", + description: "Triggered when an index is deleted.", }, + + // Storage events (with bucketId) { - name: "functions.executions.update", - description: "This event triggers when a function execution is updated.", + name: "buckets.*.create", + description: "Triggered when a storage bucket is created.", }, { - name: "storage.files.create", - description: "This event triggers when a storage file is created.", + name: "buckets.*.update", + description: "Triggered when a storage bucket is updated.", }, { - name: "storage.files.update", - description: "This event triggers when a storage file is updated.", + name: "buckets.*.delete", + description: "Triggered when a storage bucket is deleted.", }, { - name: "storage.files.delete", - description: "This event triggers when a storage file is deleted.", + name: "buckets.*.files.*.create", + description: "Triggered when a file is created.", }, { - name: "users.create", - description: "This event triggers when a user is created from the users API.", + name: "buckets.*.files.*.update", + description: "Triggered when a file is updated.", }, { - name: "users.update.prefs", - description: "This event triggers when a user preference is updated from the users API.", + name: "buckets.*.files.*.delete", + description: "Triggered when a file is deleted.", + }, + + // Functions events (with deployments instead of tags) + { + name: "functions.*.create", + description: "Triggered when a function is created.", }, { - name: "users.update.status", - description: "This event triggers when a user status is updated from the users API.", + name: "functions.*.update", + description: "Triggered when a function is updated.", }, { - name: "users.delete", - description: "This event triggers when a user is deleted from users API.", + name: "functions.*.delete", + description: "Triggered when a function is deleted.", }, { - name: "users.sessions.delete", - description: "This event triggers when a user session is deleted from users API.", + name: "functions.*.deployments.*.create", + description: "Triggered when a function deployment is created.", }, { - name: "teams.create", - description: "This event triggers when a team is created.", + name: "functions.*.deployments.*.update", + description: "Triggered when a function deployment is updated.", }, { - name: "teams.update", - description: "This event triggers when a team is updated.", + name: "functions.*.deployments.*.delete", + description: "Triggered when a function deployment is deleted.", }, { - name: "teams.delete", - description: "This event triggers when a team is deleted.", + name: "functions.*.executions.*.create", + description: "Triggered when a function execution is created.", }, { - name: "teams.memberships.create", - description: "This event triggers when a team memberships is created.", + name: "functions.*.executions.*.update", + description: "Triggered when a function execution is updated.", }, { - name: "teams.memberships.update", - description: "This event triggers when a team membership is updated.", + name: "functions.*.executions.*.delete", + description: "Triggered when a function execution is deleted.", + }, + + // Teams events + { + name: "teams.*.create", + description: "Triggered when a team is created.", + }, + { + name: "teams.*.update", + description: "Triggered when a team is updated.", + }, + { + name: "teams.*.delete", + description: "Triggered when a team is deleted.", + }, + { + name: "teams.*.memberships.*.create", + description: "Triggered when a team membership is created.", + }, + { + name: "teams.*.memberships.*.update", + description: "Triggered when a team membership is updated.", + }, + { + name: "teams.*.memberships.*.update.status", + description: "Triggered when a team membership status is updated.", + }, + { + name: "teams.*.memberships.*.delete", + description: "Triggered when a team membership is deleted.", + }, + + // Messaging events + { + name: "providers.*.create", + description: "Triggered when a messaging provider is created.", }, { - name: "teams.memberships.update.status", - description: "This event triggers when a team memberships status is updated.", + name: "providers.*.update", + description: "Triggered when a messaging provider is updated.", }, { - name: "teams.memberships.delete", - description: "This event triggers when a team memberships is deleted.", + name: "providers.*.delete", + description: "Triggered when a messaging provider is deleted.", + }, + { + name: "topics.*.create", + description: "Triggered when a messaging topic is created.", + }, + { + name: "topics.*.update", + description: "Triggered when a messaging topic is updated.", + }, + { + name: "topics.*.delete", + description: "Triggered when a messaging topic is deleted.", + }, + { + name: "messages.*.create", + description: "Triggered when a message is created.", + }, + { + name: "messages.*.update", + description: "Triggered when a message is updated.", + }, + { + name: "messages.*.delete", + description: "Triggered when a message is deleted.", }, ]; +// Function runtimes for Appwrite v1.8.x / SDK v21 +// See: https://appwrite.io/docs/products/functions/runtimes export const appwriteFunctionRuntimes = [ - "dotnet-3.1", - "dotnet-5.0", - "dart-2.10", - "dart-2.12", - "deno-1.5", - "deno-1.6", - "deno-1.8", - "python-3.8", + // Node.js + "node-18.0", + "node-20.0", + "node-21.0", + "node-22.0", + + // Python "python-3.9", - "ruby-2.7", - "ruby-3.0", - "php-7.4", + "python-3.10", + "python-3.11", + "python-3.12", + + // PHP "php-8.0", - "node-14.5", - "node-15.5", + "php-8.1", + "php-8.2", + "php-8.3", + + // Ruby + "ruby-3.1", + "ruby-3.2", + "ruby-3.3", + + // Dart + "dart-2.17", + "dart-2.18", + "dart-3.0", + "dart-3.1", + "dart-3.3", + + // Deno + "deno-1.35", + "deno-1.40", + "deno-2.0", + + // Bun + "bun-1.0", + + // .NET + "dotnet-6.0", + "dotnet-7.0", + "dotnet-8.0", + + // Java + "java-8.0", + "java-11.0", + "java-17.0", + "java-18.0", + "java-21.0", + + // Swift + "swift-5.8", + "swift-5.9", + + // Kotlin + "kotlin-1.8", + "kotlin-1.9", + + // C++ + "cpp-17", + "cpp-20", + + // Go + "go-1.22", + "go-1.23", ]; diff --git a/src/settings.ts b/src/settings.ts index 72a7474..7792327 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -8,6 +8,10 @@ export type AppwriteProjectConfiguration = { projectId: string; selfSigned: boolean; secret: string; + /** Default database ID for database operations (required for SDK v21+) */ + databaseId?: string; + /** Default storage bucket ID for file operations (required for SDK v21+) */ + bucketId?: string; }; export async function getDefaultProject(): Promise { diff --git a/src/tree/ChildTreeItem.ts b/src/tree/ChildTreeItem.ts index 97a2c44..4bc329f 100644 --- a/src/tree/ChildTreeItem.ts +++ b/src/tree/ChildTreeItem.ts @@ -1,8 +1,11 @@ import { TreeItem } from "vscode"; export class ChildTreeItem extends TreeItem { - constructor(public readonly parent: Parent, item: TreeItem) { - super(item.label || 'Please provide label'); - Object.assign(this, item); + constructor(public readonly parent: Parent, item: Partial & { label: string }) { + super(item.label); + this.label = item.label; + if (item.description !== undefined) { + this.description = item.description; + } } } diff --git a/src/tree/CollapsableTreeItem.ts b/src/tree/CollapsableTreeItem.ts index 6eeeb7b..058bc99 100644 --- a/src/tree/CollapsableTreeItem.ts +++ b/src/tree/CollapsableTreeItem.ts @@ -4,7 +4,9 @@ import { AppwriteTreeItemBase } from "../ui/AppwriteTreeItemBase"; export class CollapsableTreeItem extends AppwriteTreeItemBase { constructor(parent: Parent, item: Partial & { label: string }, private readonly children: TreeItem[], public readonly brand?: string) { super(parent, item.label); - Object.assign(this, item); + if (item.description !== undefined) { + this.description = item.description; + } } public async getChildren(): Promise { diff --git a/src/tree/database/CollectionTreeItem.ts b/src/tree/database/CollectionTreeItem.ts index 22c3a02..52a40a2 100644 --- a/src/tree/database/CollectionTreeItem.ts +++ b/src/tree/database/CollectionTreeItem.ts @@ -5,22 +5,28 @@ import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase"; import { DatabaseTreeItemProvider } from "./DatabaseTreeItemProvider"; import { DocumentsTreeItem } from "./DocumentsTreeItem"; import { PermissionsTreeItem } from "./settings/PermissionsTreeItem"; -import { RulesTreeItem } from "./settings/RulesTreeItem"; +import { AttributesTreeItem } from "./settings/AttributesTreeItem"; export class CollectionTreeItem extends AppwriteTreeItemBase { - constructor(public collection: Collection, public readonly provider: DatabaseTreeItemProvider) { + constructor( + public collection: Collection, + public readonly databaseId: string, + public readonly provider: DatabaseTreeItemProvider + ) { super(undefined, collection.name); + this.description = collection.$id; + this.tooltip = `Collection: ${collection.name}\nID: ${collection.$id}\nDatabase: ${databaseId}`; } public async getChildren(): Promise { - return [new RulesTreeItem(this), new PermissionsTreeItem(this), new DocumentsTreeItem(this)]; + return [new AttributesTreeItem(this), new PermissionsTreeItem(this), new DocumentsTreeItem(this)]; } public async refresh(): Promise { if (!databaseClient) { return; } - this.collection = (await databaseClient.getCollection(this.collection.$id)) ?? this.collection; + this.collection = (await databaseClient.getCollection(this.collection.$id, this.databaseId)) ?? this.collection; this.provider.refreshChild(this); } diff --git a/src/tree/database/DatabaseTreeItemProvider.ts b/src/tree/database/DatabaseTreeItemProvider.ts index 9d92c16..80ed18a 100644 --- a/src/tree/database/DatabaseTreeItemProvider.ts +++ b/src/tree/database/DatabaseTreeItemProvider.ts @@ -1,15 +1,59 @@ import * as vscode from "vscode"; -import { client } from "../../client"; -import AppwriteCall from "../../utils/AppwriteCall"; -import { Collection, CollectionsList } from "../../appwrite"; +import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; +import { databaseClient } from "../../client"; +import { Collection, Database } from "../../appwrite"; import { CollectionTreeItem } from "./CollectionTreeItem"; -import { AppwriteSDK } from "../../constants"; import { ext } from '../../extensionVariables'; import { AppwriteTreeItemBase } from '../../ui/AppwriteTreeItemBase'; +/** + * Tree item representing a database in the tree view + */ +export class DatabaseTreeItem extends AppwriteTreeItemBase { + constructor( + public database: Database, + public readonly provider: DatabaseTreeItemProvider + ) { + super(undefined, database.name); + this.description = database.$id; + this.tooltip = `Database: ${database.name}\nID: ${database.$id}\nEnabled: ${database.enabled}`; + } + + public async getChildren(): Promise { + if (!databaseClient) { + return []; + } + + const collections = await databaseClient.listCollections(this.database.$id); + if (!collections || collections.length === 0) { + return [{ label: "No collections found" }]; + } + + const collectionTreeItems = collections.map( + (collection: Collection) => new CollectionTreeItem(collection, this.database.$id, this.provider) + ); + const headerItem: TreeItem = { + label: `Total collections: ${collections.length}`, + }; + return [headerItem, ...collectionTreeItems]; + } + + public async refresh(): Promise { + if (!databaseClient) { + return; + } + this.database = (await databaseClient.getDatabase(this.database.$id)) ?? this.database; + this.provider.refreshChild(this); + } + + collapsibleState = TreeItemCollapsibleState.Collapsed; + contextValue = "database"; + iconPath = new ThemeIcon("database"); +} + export class DatabaseTreeItemProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter< - CollectionTreeItem | undefined | void + vscode.TreeItem | undefined | void >(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; @@ -29,25 +73,32 @@ export class DatabaseTreeItemProvider implements vscode.TreeDataProvider { ext.outputChannel?.appendLine('getChildren for: ' + parent?.label); - if (client === undefined) { - return Promise.resolve([]); + if (databaseClient === undefined) { + return []; } - if (parent instanceof AppwriteTreeItemBase) { - return await parent.getChildren?.() ?? []; - } + try { + if (parent instanceof AppwriteTreeItemBase) { + return await parent.getChildren?.() ?? []; + } - const databaseSdk = new AppwriteSDK.Database(client); + // Root level: show databases + const databasesList = await databaseClient.listDatabases(); + if (databasesList && databasesList.databases.length > 0) { + const databaseTreeItems = databasesList.databases.map( + (database: Database) => new DatabaseTreeItem(database, this) + ); + const headerItem: vscode.TreeItem = { + label: `Total databases: ${databasesList.total}`, + }; + return [headerItem, ...databaseTreeItems]; + } - const collectionsList = await AppwriteCall(databaseSdk.listCollections()); - if (collectionsList) { - const collectionTreeItems = collectionsList.collections.map((collection: Collection) => new CollectionTreeItem(collection, this)) ?? []; - const headerItem: vscode.TreeItem = { - label: `Total collections: ${collectionsList.sum}`, - }; - return [headerItem, ...collectionTreeItems]; + return [{ label: "No databases found" }]; + } catch (error: unknown) { + const message = error instanceof Error ? error.message : String(error); + ext.outputChannel?.appendLog(`Error in database tree: ${message}`); + return [{ label: `Error: ${message}` }]; } - - return [{ label: "No collections found" }]; } } diff --git a/src/tree/database/DocumentTreeItem.ts b/src/tree/database/DocumentTreeItem.ts index fe420ee..07e59d6 100644 --- a/src/tree/database/DocumentTreeItem.ts +++ b/src/tree/database/DocumentTreeItem.ts @@ -1,14 +1,29 @@ -import { ThemeIcon } from 'vscode'; -import { ChildTreeItem } from '../ChildTreeItem'; +import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; +import { AppwriteTreeItemBase } from '../../ui/AppwriteTreeItemBase'; import { DocumentsTreeItem } from './DocumentsTreeItem'; -export class DocumentTreeItem extends ChildTreeItem { +export class DocumentTreeItem extends AppwriteTreeItemBase { // eslint-disable-next-line @typescript-eslint/no-explicit-any - constructor(parent: DocumentsTreeItem, public readonly document: Record) { - super(parent, { - label: document['$id'], - }); + constructor(public readonly parent: DocumentsTreeItem, public readonly document: Record) { + super(parent, document['$id']); + this.description = document['name'] || document['$collectionId']; + this.tooltip = `Document ID: ${document['$id']}\nCreated: ${document['$createdAt']}\nUpdated: ${document['$updatedAt']}`; } + + public async getChildren(): Promise { + return Object.entries(this.document) + .filter(([key]) => !key.startsWith('$')) + .map(([key, value]) => { + const displayValue = value === null ? 'null' : typeof value === 'object' ? JSON.stringify(value) : String(value); + const item = new TreeItem(key); + item.description = displayValue; + item.iconPath = new ThemeIcon('symbol-field'); + item.contextValue = 'documentField'; + return item; + }); + } + + collapsibleState = TreeItemCollapsibleState.Collapsed; iconPath = new ThemeIcon('json'); contextValue = 'document'; } diff --git a/src/tree/database/DocumentsTreeItem.ts b/src/tree/database/DocumentsTreeItem.ts index 314c58c..929f8b2 100644 --- a/src/tree/database/DocumentsTreeItem.ts +++ b/src/tree/database/DocumentsTreeItem.ts @@ -1,32 +1,39 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; -import { DocumentsList } from "../../appwrite"; -import { client } from "../../client"; -import { AppwriteSDK } from "../../constants"; +import { databaseClient } from "../../client"; import { ext } from "../../extensionVariables"; import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase"; -import AppwriteCall from "../../utils/AppwriteCall"; import { CollectionTreeItem } from "./CollectionTreeItem"; import { DocumentTreeItem } from "./DocumentTreeItem"; export class DocumentsTreeItem extends AppwriteTreeItemBase { - constructor(parent: CollectionTreeItem) { + constructor(public readonly parent: CollectionTreeItem) { super(parent, "Documents"); } public async getChildren(): Promise { - const databaseSdk = new AppwriteSDK.Database(client); - const documentList = await AppwriteCall(databaseSdk.listDocuments(this.parent.collection.$id)); - if (documentList === undefined) { + if (!databaseClient || !this.parent?.collection) { return []; } - ext.outputChannel?.append(JSON.stringify(documentList, null, 4)); + try { + const documentList = await databaseClient.listDocuments( + this.parent.collection.$id, + this.parent.databaseId + ); + if (documentList === undefined) { + return [{ label: "Failed to load documents" }]; + } - const documentTreeItems = documentList.documents.map((document) => new DocumentTreeItem(this, document)); - const headerItem: TreeItem = { - label: `Total documents: ${documentTreeItems.length}`, - }; - return [headerItem, ...documentTreeItems]; + const documentTreeItems = documentList.documents.map((document) => new DocumentTreeItem(this, document)); + const headerItem: TreeItem = { + label: `Total documents: ${documentList.total}`, + }; + return [headerItem, ...documentTreeItems]; + } catch (error: unknown) { + const message = error instanceof Error ? error.message : String(error); + ext.outputChannel?.appendLog(`Error loading documents: ${message}`); + return [{ label: `Error: ${message}` }]; + } } collapsibleState = TreeItemCollapsibleState.Collapsed; diff --git a/src/tree/database/settings/AttributeTreeItem.ts b/src/tree/database/settings/AttributeTreeItem.ts new file mode 100644 index 0000000..3b50b86 --- /dev/null +++ b/src/tree/database/settings/AttributeTreeItem.ts @@ -0,0 +1,46 @@ +import { ThemeIcon } from "vscode"; +import { Attribute } from "../../../appwrite"; +import { ChildTreeItem } from "../../ChildTreeItem"; +import { AttributesTreeItem } from "./AttributesTreeItem"; + +export class AttributeTreeItem extends ChildTreeItem { + constructor(parent: AttributesTreeItem, public readonly attribute: Attribute) { + super(parent, { + label: attribute.key, + description: `${attribute.type}${attribute.required ? ' (required)' : ''}`, + }); + this.label = attribute.key; + this.description = `${attribute.type}${attribute.required ? ' (required)' : ''}`; + this.tooltip = `Key: ${attribute.key}\nType: ${attribute.type}\nRequired: ${attribute.required}\nStatus: ${attribute.status}`; + } + + iconPath = new ThemeIcon(this.getIconForType()); + contextValue = "collection.attribute"; + + private getIconForType(): string { + switch (this.attribute.type) { + case 'string': + return 'symbol-string'; + case 'integer': + case 'float': + case 'double': + return 'symbol-number'; + case 'boolean': + return 'symbol-boolean'; + case 'datetime': + return 'calendar'; + case 'email': + return 'mail'; + case 'url': + return 'link'; + case 'ip': + return 'globe'; + case 'enum': + return 'symbol-enum'; + case 'relationship': + return 'references'; + default: + return 'symbol-field'; + } + } +} diff --git a/src/tree/database/settings/AttributesTreeItem.ts b/src/tree/database/settings/AttributesTreeItem.ts new file mode 100644 index 0000000..e5aaf1c --- /dev/null +++ b/src/tree/database/settings/AttributesTreeItem.ts @@ -0,0 +1,41 @@ +import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; +import { Attribute } from "../../../appwrite"; +import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase"; +import { CommandTreeItem } from "../../CommandTreeItem"; +import { CollectionTreeItem } from "../CollectionTreeItem"; +import { AttributeTreeItem } from "./AttributeTreeItem"; + +export class AttributesTreeItem extends AppwriteTreeItemBase { + constructor(public readonly parent: CollectionTreeItem) { + super(parent, "Attributes"); + } + + public async getChildren(): Promise { + // Read attributes directly from the collection object (same pattern as PermissionsTreeItem) + const attributes: Attribute[] = this.parent?.collection?.attributes ?? []; + + if (attributes.length === 0) { + const addAttributeItem = new CommandTreeItem( + { label: "Add attribute", iconPath: new ThemeIcon("add") }, + { + command: "vscode-appwrite.createAttribute", + arguments: [this], + title: "Create attribute", + tooltip: "Create collection attribute" + } + ); + return [addAttributeItem]; + } + return attributes.map((attribute: Attribute) => new AttributeTreeItem(this, attribute)); + } + + public async refresh(): Promise { + if (this.parent?.refresh) { + await this.parent.refresh(); + } + } + + iconPath = new ThemeIcon("symbol-property"); + contextValue = "collection.attributes"; + collapsibleState = TreeItemCollapsibleState.Collapsed; +} diff --git a/src/tree/database/settings/PermissionTreeItem.ts b/src/tree/database/settings/PermissionTreeItem.ts index d4c76a5..804d687 100644 --- a/src/tree/database/settings/PermissionTreeItem.ts +++ b/src/tree/database/settings/PermissionTreeItem.ts @@ -1,10 +1,36 @@ +import { ThemeIcon } from "vscode"; import { ChildTreeItem } from "../../ChildTreeItem"; import { PermissionsTreeItem } from "./PermissionsTreeItem"; +type PermissionType = 'read' | 'create' | 'update' | 'delete' | 'write'; + export class PermissionTreeItem extends ChildTreeItem { - constructor(parent: PermissionsTreeItem, public readonly permission: string, public readonly kind: "read" | "write") { + constructor( + parent: PermissionsTreeItem, + public readonly permission: string, + public readonly kind: PermissionType + ) { super(parent, { label: permission }); + this.label = permission; } + iconPath = new ThemeIcon(this.getIconForKind()); contextValue = 'permission'; + + private getIconForKind(): string { + switch (this.kind) { + case 'read': + return 'eye'; + case 'create': + return 'add'; + case 'update': + return 'edit'; + case 'delete': + return 'trash'; + case 'write': + return 'pencil'; + default: + return 'key'; + } + } } diff --git a/src/tree/database/settings/PermissionsTreeItem.ts b/src/tree/database/settings/PermissionsTreeItem.ts index 64788fd..fa9ae59 100644 --- a/src/tree/database/settings/PermissionsTreeItem.ts +++ b/src/tree/database/settings/PermissionsTreeItem.ts @@ -1,25 +1,70 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; -import { Permissions } from "../../../appwrite"; import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase"; import { CollapsableTreeItem } from "../../CollapsableTreeItem"; import { CollectionTreeItem } from "../CollectionTreeItem"; import { PermissionTreeItem } from "./PermissionTreeItem"; +/** + * Permission types in SDK v21 + */ +type PermissionType = 'read' | 'create' | 'update' | 'delete' | 'write'; + export class PermissionsTreeItem extends AppwriteTreeItemBase { - public readonly permissions: Permissions; + public readonly permissions: string[]; - constructor(parent: CollectionTreeItem) { + constructor(public readonly parent: CollectionTreeItem) { super(parent, "Permissions"); - this.permissions = parent.collection.$permissions; + // In SDK v21, $permissions is a flat array of permission strings + this.permissions = parent?.collection?.$permissions ?? []; } public async getChildren(): Promise { - const readPermissions = this.permissions.read.map((perm) => new PermissionTreeItem(this, perm, "read")); - const writePermissions = this.permissions.write.map((perm) => new PermissionTreeItem(this, perm, "write")); - return [ - new CollapsableTreeItem(this, { label: "Read" }, readPermissions, "read"), - new CollapsableTreeItem(this, { label: "Write" }, writePermissions, "write"), - ]; + if (this.permissions.length === 0) { + return [{ label: "No permissions configured" }]; + } + + // Group permissions by type (read, create, update, delete, write) + const grouped = this.groupPermissions(); + + const children: TreeItem[] = []; + + for (const [type, perms] of Object.entries(grouped)) { + if (perms.length > 0) { + const permItems = perms.map((perm) => new PermissionTreeItem(this, perm, type as PermissionType)); + children.push(new CollapsableTreeItem(this, { label: this.capitalizeFirst(type) }, permItems, type)); + } + } + + return children; + } + + /** + * Group permissions by type (read, create, update, delete, write) + * Permissions are in format: "read(\"any\")", "create(\"users\")", etc. + */ + private groupPermissions(): Record { + const grouped: Record = { + read: [], + create: [], + update: [], + delete: [], + write: [], + }; + + for (const perm of this.permissions) { + const match = perm.match(/^(read|create|update|delete|write)\((.+)\)$/); + if (match) { + const type = match[1] as PermissionType; + const role = match[2].replace(/"/g, ''); // Remove quotes + grouped[type].push(role); + } + } + + return grouped; + } + + private capitalizeFirst(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); } iconPath = new ThemeIcon("shield"); diff --git a/src/tree/database/settings/RuleTreeItem.ts b/src/tree/database/settings/RuleTreeItem.ts deleted file mode 100644 index 7d635ac..0000000 --- a/src/tree/database/settings/RuleTreeItem.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Rule } from "../../../appwrite"; -import { ChildTreeItem } from "../../ChildTreeItem"; -import { RulesTreeItem } from "./RulesTreeItem"; - -export class RuleTreeItem extends ChildTreeItem { - constructor(parent: RulesTreeItem, public readonly rule: Rule) { - super(parent, { label: rule.label, description: rule.type }); - } - contextValue = "collection.rule"; -} diff --git a/src/tree/database/settings/RulesTreeItem.ts b/src/tree/database/settings/RulesTreeItem.ts deleted file mode 100644 index d4722e7..0000000 --- a/src/tree/database/settings/RulesTreeItem.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; -import { Rule } from "../../../appwrite"; -import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase"; -import { CommandTreeItem } from "../../CommandTreeItem"; -import { CollectionTreeItem } from "../CollectionTreeItem"; -import { RuleTreeItem } from "./RuleTreeItem"; - -export class RulesTreeItem extends AppwriteTreeItemBase { - public readonly rules: Rule[]; - - constructor(parent: CollectionTreeItem) { - super(parent, "Rules"); - this.rules = parent.collection.rules; - } - - public async getChildren(): Promise { - if (this.rules.length === 0) { - const addRuleItem = new CommandTreeItem( - { label: "Add rule", iconPath: new ThemeIcon("add") }, - { command: "vscode-appwrite.createRule", arguments: [this], title: "Create rule", tooltip: "Create collection rule" } - ); - return [addRuleItem]; - } - return this.rules.map((rule) => new RuleTreeItem(this, rule)); - } - - public async refresh(): Promise { - await this.parent.refresh(); - } - - iconPath = new ThemeIcon("symbol-property"); - contextValue = "collection.rules"; - collapsibleState = TreeItemCollapsibleState.Collapsed; -} diff --git a/src/tree/functions/FunctionTreeItem.ts b/src/tree/functions/FunctionTreeItem.ts index ae5e1ed..d553517 100644 --- a/src/tree/functions/FunctionTreeItem.ts +++ b/src/tree/functions/FunctionTreeItem.ts @@ -5,17 +5,23 @@ import { msToDate } from '../../utils/date'; import { ExecutionsTreeItem } from './executions/ExecutionsTreeItem'; import { FunctionsTreeItemProvider } from './FunctionsTreeItemProvider'; import { FunctionSettingsTreeItem } from './settings/FunctionSettingsTreeItem'; -import { TagsTreeItem } from './tags/TagsTreeItem'; +import { DeploymentsTreeItem } from './deployments/DeploymentsTreeItem'; export class FunctionTreeItem extends AppwriteTreeItemBase { constructor(public func: Function, public readonly provider: FunctionsTreeItemProvider) { super(undefined, func.name); - this.tooltip = new MarkdownString(`ID: ${func.$id} \nLast updated: ${msToDate(func.dateUpdated)} \nCreated: ${msToDate(func.dateCreated)}`); - this.description = func.env; + this.tooltip = new MarkdownString( + `**ID:** ${func.$id} \n` + + `**Runtime:** ${func.runtime} \n` + + `**Last updated:** ${msToDate(func.$updatedAt)} \n` + + `**Created:** ${msToDate(func.$createdAt)} \n` + + `**Enabled:** ${func.enabled}` + ); + this.description = func.runtime; } public async getChildren(): Promise { - return [new FunctionSettingsTreeItem(this), new TagsTreeItem(this), new ExecutionsTreeItem(this)]; + return [new FunctionSettingsTreeItem(this), new DeploymentsTreeItem(this), new ExecutionsTreeItem(this)]; } public async refresh(): Promise { diff --git a/src/tree/functions/FunctionsTreeItemProvider.ts b/src/tree/functions/FunctionsTreeItemProvider.ts index 6713b71..0445807 100644 --- a/src/tree/functions/FunctionsTreeItemProvider.ts +++ b/src/tree/functions/FunctionsTreeItemProvider.ts @@ -1,7 +1,6 @@ import * as vscode from "vscode"; -import { client } from "../../client"; -import { Function, FunctionsList } from "../../appwrite"; -import { AppwriteSDK } from "../../constants"; +import { functionsClient } from "../../client"; +import { Function } from "../../appwrite"; import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase"; import { ext } from "../../extensionVariables"; import { EventEmitter, TreeItem } from "vscode"; @@ -26,18 +25,19 @@ export class FunctionsTreeItemProvider implements vscode.TreeDataProvider { - if (client === undefined) { + if (functionsClient === undefined) { return Promise.resolve([]); } if (parent === undefined) { - const functionsSdk = new AppwriteSDK.Functions(client); - - const list: FunctionsList = await functionsSdk.list(); - - if (list) { - const functionTreeItems = list.functions.map((func: Function) => new FunctionTreeItem(func, this)) ?? []; - return functionTreeItems; + const list = await functionsClient.list(); + + if (list && list.functions.length > 0) { + const functionTreeItems = list.functions.map((func: Function) => new FunctionTreeItem(func, this)); + const headerItem: TreeItem = { + label: `Total functions: ${list.total}`, + }; + return [headerItem, ...functionTreeItems]; } return [{ label: "No functions found" }]; diff --git a/src/tree/functions/deployments/DeploymentTreeItem.ts b/src/tree/functions/deployments/DeploymentTreeItem.ts new file mode 100644 index 0000000..0885cc0 --- /dev/null +++ b/src/tree/functions/deployments/DeploymentTreeItem.ts @@ -0,0 +1,47 @@ +import { MarkdownString, ThemeIcon, TreeItem } from "vscode"; +import { Deployment } from '../../../appwrite'; +import { msToDate } from '../../../utils/date'; +import { DeploymentsTreeItem } from './DeploymentsTreeItem'; + +export class DeploymentTreeItem extends TreeItem { + constructor(public readonly parent: DeploymentsTreeItem, public readonly deployment: Deployment) { + super(deployment.$id); + const func = parent.parent.func; + const active = func.deployment === deployment.$id; + this.label = `${msToDate(deployment.$createdAt)}${active ? ' (Active)' : ''}`; + this.description = `${deployment.status} - ${deployment.$id}`; + this.iconPath = new ThemeIcon(this.getStatusIcon(deployment.status, active)); + this.contextValue = `deployment${active ? '_active' : ''}`; + this.tooltip = new MarkdownString( + `**ID:** ${deployment.$id} \n` + + `**Created:** ${msToDate(deployment.$createdAt)} \n` + + `**Status:** ${deployment.status} \n` + + `**Size:** ${this.formatSize(deployment.size)} \n` + + `**Build Time:** ${deployment.buildTime}ms \n` + + `**Entrypoint:** ${deployment.entrypoint || 'N/A'}` + ); + } + + private getStatusIcon(status: string, active: boolean): string { + if (active) { + return 'circle-large-filled'; + } + switch (status) { + case 'ready': + return 'check'; + case 'processing': + case 'building': + return 'sync~spin'; + case 'failed': + return 'error'; + default: + return 'circle-large-outline'; + } + } + + private formatSize(bytes: number): string { + if (bytes < 1024) return `${bytes}B`; + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`; + return `${(bytes / (1024 * 1024)).toFixed(1)}MB`; + } +} diff --git a/src/tree/functions/deployments/DeploymentsTreeItem.ts b/src/tree/functions/deployments/DeploymentsTreeItem.ts new file mode 100644 index 0000000..82bb587 --- /dev/null +++ b/src/tree/functions/deployments/DeploymentsTreeItem.ts @@ -0,0 +1,42 @@ +import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; +import { functionsClient } from "../../../client"; +import { AppwriteTreeItemBase } from '../../../ui/AppwriteTreeItemBase'; +import { FunctionTreeItem } from '../FunctionTreeItem'; +import { DeploymentTreeItem } from './DeploymentTreeItem'; + +export class DeploymentsTreeItem extends AppwriteTreeItemBase { + constructor(public readonly parent: FunctionTreeItem) { + super(parent, "Deployments"); + } + + public async getChildren(): Promise { + if (!functionsClient || !this.parent?.func) { + return []; + } + const deployments = await functionsClient.listDeployments(this.parent.func.$id); + const children = deployments?.deployments + .sort((a, b) => new Date(b.$createdAt).getTime() - new Date(a.$createdAt).getTime()) + .map((deployment) => new DeploymentTreeItem(this, deployment)) ?? []; + + if (children.length === 0) { + const noDeploymentsItem: TreeItem = { + command: { + command: "vscode-appwrite.CreateDeployment", + title: "Create deployment", + arguments: [this], + tooltip: "Create a deployment" + }, + label: "Create a deployment", + iconPath: new ThemeIcon("cloud-upload"), + }; + return [noDeploymentsItem]; + } + return children; + } + + collapsibleState = TreeItemCollapsibleState.Collapsed; + + contextValue = "deployments"; + + iconPath = new ThemeIcon("package"); +} diff --git a/src/tree/functions/executions/ExecutionTreeItem.ts b/src/tree/functions/executions/ExecutionTreeItem.ts index 622486c..7fe7787 100644 --- a/src/tree/functions/executions/ExecutionTreeItem.ts +++ b/src/tree/functions/executions/ExecutionTreeItem.ts @@ -4,8 +4,9 @@ import { msToDate } from "../../../utils/date"; import { ExecutionsTreeItem } from "./ExecutionsTreeItem"; const executionStatusIcons: Record = { - processing: new ThemeIcon("loading"), + processing: new ThemeIcon("loading~spin"), waiting: new ThemeIcon("circle-outline"), + scheduled: new ThemeIcon("clock"), completed: new ThemeIcon("circle-filled", new ThemeColor("testing.iconPassed")), failed: new ThemeIcon("circle-filled", new ThemeColor("testing.iconFailed")), }; @@ -17,40 +18,21 @@ export class ExecutionTreeItem extends TreeItem { constructor(public readonly parent: ExecutionsTreeItem, public execution: Execution) { super(execution.$id); this.label = this.getLabel(execution); - this.iconPath = executionStatusIcons[execution.status]; - const md = `Id: ${execution.$id} \nCreated: ${this.getCreated(execution)} \nTrigger: ${execution.trigger}`; - this.tooltip = new MarkdownString(md); + this.iconPath = executionStatusIcons[execution.status] ?? new ThemeIcon("circle-outline"); + const md = new MarkdownString( + `**ID:** ${execution.$id} \n` + + `**Created:** ${this.getCreated(execution)} \n` + + `**Trigger:** ${execution.trigger} \n` + + `**Status:** ${execution.status} \n` + + `**Duration:** ${execution.duration}s \n` + + `**Status Code:** ${execution.responseStatusCode}` + ); + this.tooltip = md; this.description = execution.trigger; this.contextValue = this.getContextValue(execution); - this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting"; - // if (this.isAutoRefreshing) { - // this.autoRefresh(); - // } + this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting" || execution.status === "scheduled"; } - // async autoRefresh(): Promise { - // if (!this.isAutoRefreshing && this.refreshCount < 5) { - // return; - // } - // this.refreshCount++; - // ext.outputChannel.appendLog("Refreshing execution."); - // const execution = await functionsClient?.getExecution(this.parent.parent.func.$id, this.execution.$id); - - // if (!execution) { - // ext.outputChannel.appendLog("Execution is undefined"); - // this.isAutoRefreshing = false; - // return; - // } - // this.execution = execution; - // this.contextValue = this.getContextValue(execution); - // this.iconPath = executionStatusIcons[execution.status]; - // this.label = this.getLabel(execution); - // this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting"; - // ext.tree?.functions?.refreshChild(this); - // await sleep(1000); - // this.autoRefresh(); - // } - getLabel(execution: Execution): string { if (execution.status === "completed" || execution.status === "failed") { return `${this.getCreated(execution)} (${this.getExecutionTime(execution)}s)`; @@ -59,18 +41,21 @@ export class ExecutionTreeItem extends TreeItem { } getExecutionTime(execution: Execution): string { - return execution.time.toPrecision(2); + return execution.duration.toPrecision(2); } getContextValue(execution: Execution): string { if (execution.status === "completed" || execution.status === "failed") { - if (execution.stderr === "" && execution.stdout === "") { + const hasLogs = execution.logs && execution.logs.length > 0; + const hasErrors = execution.errors && execution.errors.length > 0; + + if (!hasErrors && !hasLogs) { return "execution_noErrorOrOutput"; } - if (execution.stderr === "") { + if (!hasErrors) { return "execution_outputOnly"; } - if (execution.stdout === "") { + if (!hasLogs) { return "execution_errorOnly"; } } @@ -78,6 +63,6 @@ export class ExecutionTreeItem extends TreeItem { } getCreated(execution: Execution): string { - return msToDate(execution.dateCreated); + return msToDate(execution.$createdAt); } } diff --git a/src/tree/functions/executions/ExecutionsTreeItem.ts b/src/tree/functions/executions/ExecutionsTreeItem.ts index 148409b..e866586 100644 --- a/src/tree/functions/executions/ExecutionsTreeItem.ts +++ b/src/tree/functions/executions/ExecutionsTreeItem.ts @@ -1,6 +1,7 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; import { Execution, ExecutionList } from "../../../appwrite"; import { functionsClient } from "../../../client"; +import { Query } from "../../../constants"; import { ExecutionTreeItem } from "./ExecutionTreeItem"; import { FunctionTreeItem } from "../FunctionTreeItem"; import { ext } from "../../../extensionVariables"; @@ -14,24 +15,29 @@ export class ExecutionsTreeItem extends AppwriteTreeItemBase { private executionsToShow = 10; public async getChildren(): Promise { - if (!functionsClient) { + if (!functionsClient || !this.parent?.func) { return []; } + + // Use Query helpers for pagination and sorting + const queries = [ + Query.limit(this.executionsToShow), + Query.orderDesc('$createdAt') + ]; + const executions: ExecutionList | undefined = await functionsClient.listExecutions( this.parent.func.$id, - undefined, - this.executionsToShow, - undefined, - "DESC" + queries ); + const children = executions?.executions.map((execution: Execution) => new ExecutionTreeItem(this, execution)) ?? [ new TreeItem("No executions."), ]; if (children.length === 0) { children.push(new TreeItem("No executions.")); } - ext.outputChannel.appendLog(`Found ${executions?.sum} executions`); - if (executions?.sum ?? (0 > this.executionsToShow && this.executionsToShow !== 100)) { + ext.outputChannel.appendLog(`Found ${executions?.total} executions`); + if ((executions?.total ?? 0) > this.executionsToShow && this.executionsToShow !== 100) { const viewMoreItem: TreeItem = { command: { command: "vscode-appwrite.viewMore", diff --git a/src/tree/functions/settings/EventsTreeItem.ts b/src/tree/functions/settings/EventsTreeItem.ts index 89bf252..fc35594 100644 --- a/src/tree/functions/settings/EventsTreeItem.ts +++ b/src/tree/functions/settings/EventsTreeItem.ts @@ -25,7 +25,20 @@ export class EventsTreeItem extends EnumEditableTreeItemBase { } public async setValue(value: string[]): Promise { - await functionsClient?.update(this.func.$id, this.func.name, [], this.func.vars, value, this.func.schedule, this.func.timeout); + await functionsClient?.update( + this.func.$id, + this.func.name, + this.func.runtime, + this.func.execute, + value, + this.func.schedule, + this.func.timeout, + this.func.enabled, + this.func.logging, + this.func.entrypoint, + this.func.commands, + this.func.scopes + ); ext.tree?.functions?.refresh(); } } diff --git a/src/tree/functions/settings/NameTreeItem.ts b/src/tree/functions/settings/NameTreeItem.ts index 25f6c30..55e1686 100644 --- a/src/tree/functions/settings/NameTreeItem.ts +++ b/src/tree/functions/settings/NameTreeItem.ts @@ -31,7 +31,20 @@ export class NameTreeItem extends StringEditableTreeItemBase { if (value.length === 0) { return; } - await functionsClient?.update(this.func.$id, value, [], this.func.vars, this.func.events, this.func.schedule, this.func.timeout); + await functionsClient?.update( + this.func.$id, + value, + this.func.runtime, + this.func.execute, + this.func.events, + this.func.schedule, + this.func.timeout, + this.func.enabled, + this.func.logging, + this.func.entrypoint, + this.func.commands, + this.func.scopes + ); ext.tree?.functions?.refresh(); } diff --git a/src/tree/functions/settings/ScheduleTreeItem.ts b/src/tree/functions/settings/ScheduleTreeItem.ts index 10a2e15..9ce5871 100644 --- a/src/tree/functions/settings/ScheduleTreeItem.ts +++ b/src/tree/functions/settings/ScheduleTreeItem.ts @@ -25,7 +25,20 @@ export class ScheduleTreeItem extends StringEditableTreeItemBase { }; public async setValue(value: string): Promise { - await functionsClient?.update(this.func.$id, this.func.name, [], this.func.vars, this.func.events, value === "" ? undefined : value, this.func.timeout); + await functionsClient?.update( + this.func.$id, + this.func.name, + this.func.runtime, + this.func.execute, + this.func.events, + value === "" ? undefined : value, + this.func.timeout, + this.func.enabled, + this.func.logging, + this.func.entrypoint, + this.func.commands, + this.func.scopes + ); ext.tree?.functions?.refresh(); } diff --git a/src/tree/functions/settings/TimeoutTreeItem.ts b/src/tree/functions/settings/TimeoutTreeItem.ts index b2e8a62..9549fd5 100644 --- a/src/tree/functions/settings/TimeoutTreeItem.ts +++ b/src/tree/functions/settings/TimeoutTreeItem.ts @@ -5,7 +5,6 @@ import { ext } from "../../../extensionVariables"; import { StringEditableTreeItemBase } from "../../common/editable/StringEditableTreeItem"; function isNumeric(str: string) { - console.log("here"); return !isNaN(+str); } @@ -31,11 +30,16 @@ export class TimeoutTreeItem extends StringEditableTreeItemBase { await functionsClient?.update( this.func.$id, this.func.name, - [], - this.func.vars, + this.func.runtime, + this.func.execute, this.func.events, this.func.schedule, - parseInt(value) + parseInt(value), + this.func.enabled, + this.func.logging, + this.func.entrypoint, + this.func.commands, + this.func.scopes ); ext.tree?.functions?.refresh(); } diff --git a/src/tree/functions/settings/VarTreeItem.ts b/src/tree/functions/settings/VarTreeItem.ts index cd64572..c48c0a2 100644 --- a/src/tree/functions/settings/VarTreeItem.ts +++ b/src/tree/functions/settings/VarTreeItem.ts @@ -5,16 +5,15 @@ import { ext } from "../../../extensionVariables"; import { StringEditableTreeItemBase } from "../../common/editable/StringEditableTreeItem"; import { VarsTreeItem } from "./VarsTreeItem"; -const tooltip = "Environment var"; -const description = "Function name. Max length: 128 chars."; -const tooLongInvalid = "Value exceeds maximum length of 128 characters."; +const tooltip = "Environment variable"; +const description = "Variable value"; export async function keyValuePrompt(keyInit?: string, valueInit?: string): Promise<{ key: string; value: string } | undefined> { - const key = await window.showInputBox({ value: keyInit, prompt: "Environment variable name" }); + const key = await window.showInputBox({ value: keyInit, prompt: "Variable name" }); if (key === undefined) { return; } - const value = await window.showInputBox({ value: valueInit, prompt: "Environment variable value" }); + const value = await window.showInputBox({ value: valueInit, prompt: "Variable value" }); if (value === undefined) { return; } @@ -25,26 +24,32 @@ export class VarTreeItem extends StringEditableTreeItemBase { public readonly func: Function; inputBoxOptions: InputBoxOptions = { - validateInput: (value) => { - if (value.length > 128) { - return tooLongInvalid; - } - }, prompt: description, }; public async setValue(value: string, key?: string): Promise { - if (value.length === 0) { + if (value.length === 0 || !functionsClient) { return; } - const newVars = { ...this.func.vars }; - newVars[this.key] = value; - if (key) { - delete newVars[this.key]; - newVars[key] = value; + + try { + // SDK v21: Use updateVariable to change value + // First get the variable ID + const variables = await functionsClient.listVariables(this.func.$id); + const variable = variables?.variables.find(v => v.key === this.key); + if (variable) { + // If key changed, we need to delete and recreate + if (key && key !== this.key) { + await functionsClient.deleteVariable(this.func.$id, variable.$id); + await functionsClient.createVariable(this.func.$id, key, value); + } else { + await functionsClient.updateVariable(this.func.$id, variable.$id, this.key, value); + } + ext.tree?.functions?.refresh(); + } + } catch (e) { + window.showErrorMessage(e.message || String(e)); } - await functionsClient?.update(this.func.$id, this.func.name, [], newVars, this.func.events, this.func.schedule, this.func.timeout); - ext.tree?.functions?.refresh(); } constructor(public readonly parent: VarsTreeItem, public readonly key: string, value: string) { @@ -58,7 +63,7 @@ export class VarTreeItem extends StringEditableTreeItemBase { public async prompt(): Promise { const keyval = await keyValuePrompt(this.key, this.value); if (keyval) { - this.setValue(keyval.value, keyval.key); + await this.setValue(keyval.value, keyval.key); } } } diff --git a/src/tree/functions/settings/VarsTreeItem.ts b/src/tree/functions/settings/VarsTreeItem.ts index 165b8dc..dcdd263 100644 --- a/src/tree/functions/settings/VarsTreeItem.ts +++ b/src/tree/functions/settings/VarsTreeItem.ts @@ -1,21 +1,33 @@ -import { TreeItem, TreeItemCollapsibleState } from "vscode"; -import { Vars } from "../../../appwrite"; +import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; +import { functionsClient } from "../../../client"; import { AppwriteTreeItemBase } from '../../../ui/AppwriteTreeItemBase'; import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem"; import { VarTreeItem } from "./VarTreeItem"; export class VarsTreeItem extends AppwriteTreeItemBase { - public readonly vars: Vars; - constructor(parent: FunctionSettingsTreeItem) { - super(parent, "Environment variables"); - this.vars = parent.func.vars; + super(parent, "Variables"); this.description = undefined; } public async getChildren(): Promise { - return Object.keys(this.vars).map((key) => new VarTreeItem(this, key, this.vars[key])); + if (!functionsClient || !this.parent?.func) { + return []; + } + + const variablesList = await functionsClient.listVariables(this.parent.func.$id); + const variables = variablesList?.variables ?? []; + + if (variables.length === 0) { + return [{ + label: "No variables", + iconPath: new ThemeIcon("info") + }]; + } + + return variables.map((variable) => new VarTreeItem(this, variable.key, variable.value)); } + contextValue = "vars"; collapsibleState = TreeItemCollapsibleState.Collapsed; } diff --git a/src/tree/functions/tags/TagTreeItem.ts b/src/tree/functions/tags/TagTreeItem.ts deleted file mode 100644 index b34208a..0000000 --- a/src/tree/functions/tags/TagTreeItem.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { MarkdownString, ThemeIcon, TreeItem } from "vscode"; -import { Tag } from '../../../appwrite'; -import { msToDate } from '../../../utils/date'; -import { TagsTreeItem } from './TagsTreeItem'; - -export class TagTreeItem extends TreeItem { - constructor(public readonly parent: TagsTreeItem, public readonly tag: Tag) { - super(tag.$id); - const func = parent.parent.func; - const active = func.tag === tag.$id; - this.label = `${msToDate(tag.dateCreated)}${active ? ' (Active)' : ''}`; - this.description = tag.$id; - this.iconPath = new ThemeIcon(active ? 'circle-large-filled' : 'circle-large-outline'); - this.contextValue = `tag${active ? '_active' : ''}`; - this.tooltip = new MarkdownString(`ID: ${tag.$id} \nCreated: ${msToDate(tag.dateCreated)} \nCommand: ${tag.command} \nSize: ${tag.size}B`); - } -} diff --git a/src/tree/functions/tags/TagsTreeItem.ts b/src/tree/functions/tags/TagsTreeItem.ts deleted file mode 100644 index e9f7f4a..0000000 --- a/src/tree/functions/tags/TagsTreeItem.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; -import { functionsClient } from "../../../client"; -import { AppwriteTreeItemBase } from '../../../ui/AppwriteTreeItemBase'; -import { FunctionTreeItem } from '../FunctionTreeItem'; -import { TagTreeItem } from './TagTreeItem'; - -export class TagsTreeItem extends AppwriteTreeItemBase { - constructor(public readonly parent: FunctionTreeItem) { - super(parent, "Tags"); - } - - public async getChildren(): Promise { - if (!functionsClient) { - return []; - } - const tags = await functionsClient.listTags(this.parent.func.$id); - const children = tags?.tags.sort((a, b) => b.dateCreated - a.dateCreated).map((tag) => new TagTreeItem(this, tag)) ?? [new TreeItem('No tags.')]; - - if (children.length === 0) { - const noTagsItem: TreeItem = { - command: { - command: "vscode-appwrite.CreateTag", - title: "Create tag", - arguments: [this], - tooltip: "Create a tag" - }, - label: "Create a tag", - iconPath: new ThemeIcon("cloud-upload"), - }; - children.push(noTagsItem); - } - return children; - } - - collapsibleState = TreeItemCollapsibleState.Collapsed; - - contextValue = "tags"; - - iconPath = new ThemeIcon("tag"); -} diff --git a/src/tree/projects/ProjectTreeItem.ts b/src/tree/projects/ProjectTreeItem.ts index 1ea1976..f6b18e3 100644 --- a/src/tree/projects/ProjectTreeItem.ts +++ b/src/tree/projects/ProjectTreeItem.ts @@ -3,10 +3,12 @@ import { AppwriteProjectConfiguration } from "../../settings"; export class ProjectTreeItem extends TreeItem { constructor(public readonly project: AppwriteProjectConfiguration, active: boolean) { - super("Project"); + super(project.nickname || project.projectId); + const name = project.nickname || project.projectId; + this.label = `${name}${active ? " (Active)" : ""}`; + this.description = project.endpoint; + this.tooltip = `Project: ${name}\nID: ${project.projectId}\nEndpoint: ${project.endpoint}`; this.iconPath = new ThemeIcon("rocket"); - const name = project.nickname ?? "Project"; - this.label = `${name} ${active ? "(Active)" : ""}`; this.contextValue = `appwriteProject${active ? "_active" : ""}`; if (!active) { this.command = { command: "vscode-appwrite.setActiveProject", title: "Set active", arguments: [this] }; diff --git a/src/tree/storage/FileTreeItem.ts b/src/tree/storage/FileTreeItem.ts index a88f0c7..4f5edb8 100644 --- a/src/tree/storage/FileTreeItem.ts +++ b/src/tree/storage/FileTreeItem.ts @@ -1,12 +1,43 @@ -import { ThemeIcon, TreeItem } from "vscode"; +import { MarkdownString, ThemeIcon, TreeItem } from "vscode"; import { File } from "../../appwrite"; export class FileTreeItem extends TreeItem { - constructor(public readonly file: File) { + constructor( + public readonly file: File, + public readonly bucketId: string + ) { super(file.name); + this.description = this.formatSize(file.sizeOriginal); + this.tooltip = new MarkdownString( + `**Name:** ${file.name} \n` + + `**ID:** ${file.$id} \n` + + `**Size:** ${this.formatSize(file.sizeOriginal)} \n` + + `**MIME Type:** ${file.mimeType} \n` + + `**Bucket:** ${bucketId}` + ); } - iconPath = new ThemeIcon("file"); + private formatSize(bytes: number): string { + if (bytes < 1024) return `${bytes}B`; + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`; + if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`; + return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}GB`; + } + + private getIconForMimeType(): string { + const mimeType = this.file.mimeType.toLowerCase(); + if (mimeType.startsWith('image/')) return 'file-media'; + if (mimeType.startsWith('video/')) return 'play'; + if (mimeType.startsWith('audio/')) return 'play'; + if (mimeType.includes('pdf')) return 'file-pdf'; + if (mimeType.includes('json')) return 'json'; + if (mimeType.includes('xml')) return 'file-code'; + if (mimeType.includes('text/')) return 'file-text'; + if (mimeType.includes('zip') || mimeType.includes('tar') || mimeType.includes('gzip')) return 'file-zip'; + return 'file'; + } + + iconPath = new ThemeIcon(this.getIconForMimeType()); contextValue = "file"; } diff --git a/src/tree/storage/StorageTreeItemProvider.ts b/src/tree/storage/StorageTreeItemProvider.ts index 42877c0..66d3c20 100644 --- a/src/tree/storage/StorageTreeItemProvider.ts +++ b/src/tree/storage/StorageTreeItemProvider.ts @@ -1,7 +1,60 @@ import * as vscode from "vscode"; +import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; import { storageClient } from "../../client"; +import { Bucket, File } from "../../appwrite"; +import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase"; import { FileTreeItem } from "./FileTreeItem"; +/** + * Tree item representing a storage bucket + */ +export class BucketTreeItem extends AppwriteTreeItemBase { + constructor( + public bucket: Bucket, + public readonly provider: StorageTreeItemProvider + ) { + super(undefined, bucket.name); + this.description = bucket.$id; + this.tooltip = `Bucket: ${bucket.name}\nID: ${bucket.$id}\nEnabled: ${bucket.enabled}\nMax File Size: ${this.formatSize(bucket.maximumFileSize)}`; + } + + public async getChildren(): Promise { + if (!storageClient) { + return []; + } + + const files = await storageClient.listFiles(this.bucket.$id); + if (!files || files.files.length === 0) { + return [{ label: "No files found" }]; + } + + const fileTreeItems = files.files.map((file: File) => new FileTreeItem(file, this.bucket.$id)); + const headerItem: TreeItem = { + label: `Total files: ${files.total}`, + }; + return [headerItem, ...fileTreeItems]; + } + + public async refresh(): Promise { + if (!storageClient) { + return; + } + this.bucket = (await storageClient.getBucket(this.bucket.$id)) ?? this.bucket; + this.provider.refreshChild(this); + } + + private formatSize(bytes: number): string { + if (bytes < 1024) return `${bytes}B`; + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`; + if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`; + return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}GB`; + } + + collapsibleState = TreeItemCollapsibleState.Collapsed; + contextValue = "bucket"; + iconPath = new ThemeIcon("archive"); +} + export class StorageTreeItemProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter< vscode.TreeItem | undefined | void @@ -13,20 +66,33 @@ export class StorageTreeItemProvider implements vscode.TreeDataProvider { + async getChildren(parent?: vscode.TreeItem): Promise { if (storageClient === undefined) { return []; } - const files = await storageClient.listFiles(); - if (files === undefined || files?.files.length === 0) { - const noStorage = new vscode.TreeItem("No files found"); - return [noStorage]; + if (parent instanceof AppwriteTreeItemBase) { + return await parent.getChildren?.() ?? []; } - return files.files.map((file) => new FileTreeItem(file)); + + // Root level: show buckets + const buckets = await storageClient.listBuckets(); + if (buckets && buckets.buckets.length > 0) { + const bucketTreeItems = buckets.buckets.map((bucket: Bucket) => new BucketTreeItem(bucket, this)); + const headerItem: TreeItem = { + label: `Total buckets: ${buckets.total}`, + }; + return [headerItem, ...bucketTreeItems]; + } + + return [{ label: "No buckets found" }]; } } diff --git a/src/tree/users/UserTreeItemProvider.ts b/src/tree/users/UserTreeItemProvider.ts index f2d73ff..a86b7cc 100644 --- a/src/tree/users/UserTreeItemProvider.ts +++ b/src/tree/users/UserTreeItemProvider.ts @@ -1,13 +1,10 @@ import * as vscode from "vscode"; -import { client } from "../../client"; -import AppwriteCall from "../../utils/AppwriteCall"; -import { User, UsersList } from "../../appwrite"; +import { usersClient } from "../../client"; +import { User } from "../../appwrite"; import { ThemeIcon } from "vscode"; import { UserPrefsTreeItem } from "./properties/UserPrefsTreeItem"; import { ChildTreeItem } from "../ChildTreeItem"; import { UserTreeItem } from "./UserTreeItem"; -// eslint-disable-next-line @typescript-eslint/no-var-requires -const sdk = require("node-appwrite"); export class UserTreeItemProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter< @@ -25,13 +22,13 @@ export class UserTreeItemProvider implements vscode.TreeDataProvider { - if (client === undefined) { + if (usersClient === undefined) { return Promise.resolve([]); } if (element instanceof UserTreeItem) { - const regDate = new Date(); - regDate.setMilliseconds(element.user.registration); + // SDK v21: registration is now an ISO date string + const regDate = new Date(element.user.registration); const items: vscode.TreeItem[] = [ new ChildTreeItem(element, { contextValue: "user.name", @@ -62,12 +59,12 @@ export class UserTreeItemProvider implements vscode.TreeDataProvider(usersSdk.list()); + const usersList = await usersClient.list(); if (usersList) { const userTreeItems = usersList.users.map((user: User) => new UserTreeItem(user)) ?? []; const headerItem: vscode.TreeItem = { - label: `Total users: ${usersList.sum}`, + // SDK v21: sum renamed to total + label: `Total users: ${usersList.total}`, }; return [headerItem, ...userTreeItems]; } diff --git a/src/ui/AddProjectWizard.ts b/src/ui/AddProjectWizard.ts index 8e4d84e..b86345f 100644 --- a/src/ui/AddProjectWizard.ts +++ b/src/ui/AddProjectWizard.ts @@ -47,8 +47,30 @@ export async function addProjectWizard(): Promise extends TreeItem { constructor(public readonly parent: Parent, label: string) { super(label); + this.label = label; } abstract getChildren?(): Promise; diff --git a/src/ui/createRuleWizard.ts b/src/ui/createRuleWizard.ts deleted file mode 100644 index c53bd44..0000000 --- a/src/ui/createRuleWizard.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { QuickPickItem, window } from "vscode"; -import { Collection, CollectionsList } from "../appwrite"; -import { client } from "../client"; -import { AppwriteSDK } from "../constants"; -import AppwriteCall from "../utils/AppwriteCall"; - -export type CreateRuleWizardContext = { - label: string; - key: string; - type: keyof typeof ruleTypes; - default: any; - required: boolean; - array: boolean; - list?: string[]; -}; - -const ruleTypes = { - text: "Any string value.", - numeric: "Any integer or float value.", - boolean: "Any boolean value.", - wildcard: "Accept any value.", - url: "Any valid URL.", - email: "Any valid email address.", - ip: "Any valid IP v4 or v6 address.", - document: "Accept a valid child document from specified collection(s).", -}; - -type RuleType = keyof typeof ruleTypes; - -export async function createRuleWizard(collection: Collection): Promise { - const label = await window.showInputBox({ - placeHolder: "Attribute label", - prompt: "Attribute internal display name", - validateInput: (value) => { - if (value === "") { - return "Label cannot be empty."; - } - }, - }); - if (label === undefined) { - return; - } - const key = await window.showInputBox({ - placeHolder: "Attribute key name", - prompt: "Attribute key name. Used as the document JSON key in the Database API.", - ignoreFocusOut: true, - validateInput: (value) => { - if (value === "") { - return "Key name cannot be empty."; - } - }, - }); - if (key === undefined) { - return; - } - const ruleTypeItems: QuickPickItem[] = Object.entries(ruleTypes).map(([label, description]) => ({ - label, - detail: description, - })); - - const typeItem = await window.showQuickPick(ruleTypeItems, { placeHolder: "Rule value type." }); - const type: RuleType | undefined = (typeItem?.label as RuleType) ?? undefined; - - if (typeItem === undefined || type === undefined) { - return; - } - - let list: string[] | undefined = undefined; - - if (type === "document") { - const databaseSdk = new AppwriteSDK.Database(client); - const collectionsList = await AppwriteCall(databaseSdk.listCollections()); - - if (collectionsList === undefined) { - window.showErrorMessage("Could not get collections list."); - return; - } - - if (collectionsList) { - const collections = collectionsList.collections.filter((c) => c.$id !== collection.$id); - const qpItems: QuickPickItem[] = collections.map((collection) => ({ - label: collection.name, - description: collection.$id, - })); - - const listInput = await window.showQuickPick(qpItems, { - canPickMany: true, - placeHolder: "Collections which contain valid child documents for this document attribute.", - ignoreFocusOut: true, - }); - list = listInput?.map((item) => item.description as string) ?? []; - } - } - - if (label === "document" && list === undefined) { - return; - } - - const array = await window.showQuickPick(["Primitive", "Array"], { - placeHolder: "Decide if this rule is a primitive or an array of values.", - ignoreFocusOut: true, - }); - - if (array === undefined) { - return; - } - - const required = await window.showQuickPick(["Required", "Optional"], { - placeHolder: "Decide if this rule value is required in order to pass document validation.", - ignoreFocusOut: true, - }); - - if (required === undefined) { - return; - } - - const defaultValue = await window.showInputBox({ - placeHolder: "Default value (press Enter to skip)", - prompt: "Default value for this rule type. Make sure that the default value is able to pass validation in order to avoid errors when skipping optional values.", - ignoreFocusOut: true, - }); - - if (defaultValue === undefined) { - return; - } - - if (label && key && type) { - return { - label, - key, - type, - default: defaultValue, - array: array === "Array", - required: required === "Required", - list, - }; - } - - return undefined; -} diff --git a/src/utils/AppwriteCall.ts b/src/utils/AppwriteCall.ts index 7101e5b..89bdeb8 100644 --- a/src/utils/AppwriteCall.ts +++ b/src/utils/AppwriteCall.ts @@ -1,29 +1,43 @@ /* eslint-disable @typescript-eslint/ban-types */ import { window } from "vscode"; -import { Error } from "../appwrite"; +import { Error as AppwriteError } from "../appwrite"; import { ext } from "../extensionVariables"; export default function AppwriteCall( - promise: Promise, + promise: Promise, onSuccess?: (success: T) => R, - onError?: (error: Error) => R + onError?: (error: AppwriteError) => R ): Promise { return promise.then( (successResp) => { - ext.outputChannel?.appendLog(`Appwrite call success:`); if (onSuccess) { return onSuccess((successResp as unknown) as T); } return successResp as unknown as R; }, - (errResp: Error) => { - if (onError) { - onError(errResp as Error); - return undefined; - } + (errResp: unknown) => { + try { + const err = errResp as AppwriteError; + const message = err?.message || String(errResp); + + console.error(`[Appwrite] API error:`, errResp); + ext.outputChannel?.appendLog(`Appwrite API error: ${message}`); + if (err?.code) { + ext.outputChannel?.appendLog(`Error code: ${err.code}`); + } + if (err?.type) { + ext.outputChannel?.appendLog(`Error type: ${err.type}`); + } - window.showErrorMessage(errResp.message); - ext.outputChannel?.appendLog(errResp.message); + if (onError) { + onError(err); + return undefined; + } + + window.showErrorMessage(message); + } catch (handlerError) { + console.error(`[Appwrite] Error in error handler:`, handlerError); + } return undefined; } ); diff --git a/src/utils/date.ts b/src/utils/date.ts index adad317..31bb271 100644 --- a/src/utils/date.ts +++ b/src/utils/date.ts @@ -4,6 +4,15 @@ import timezone = require("dayjs/plugin/timezone"); // dependent on utc plugin dayjs.extend(utc); dayjs.extend(timezone); -export function msToDate(ms: number): string { - return dayjs(ms * 1000).tz(dayjs.tz.guess()).format("LTS"); +/** + * Convert a timestamp to localized time string + * @param dateValue - Can be a Unix timestamp (number) or ISO date string + */ +export function msToDate(dateValue: number | string): string { + if (typeof dateValue === 'string') { + // ISO date string (SDK v21+) + return dayjs(dateValue).tz(dayjs.tz.guess()).format("LTS"); + } + // Legacy: Unix timestamp in seconds + return dayjs(dateValue * 1000).tz(dayjs.tz.guess()).format("LTS"); } diff --git a/webpack.config.js b/webpack.config.js index 538f0ac..8d7a612 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,22 +6,31 @@ const path = require('path'); /**@type {import('webpack').Configuration}*/ const config = { - target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ - mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') + target: 'node', // vscode extensions run in a Node.js-context + mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') - entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ + entry: './src/extension.ts', // the entry point of this extension output: { - // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ + // the bundle is stored in the 'dist' folder (check package.json) path: path.resolve(__dirname, 'dist'), filename: 'extension.js', libraryTarget: 'commonjs2' }, devtool: 'nosources-source-map', - externals: { - vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ - }, + externals: [ + { vscode: 'commonjs vscode' }, + // Externalize node-appwrite SDK (uses modern JS features) + /^node-appwrite/, + // Handle node: protocol imports + ({ request }, callback) => { + if (request && request.startsWith('node:')) { + return callback(null, 'commonjs ' + request.slice(5)); + } + callback(); + } + ], resolve: { - // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader + // support reading TypeScript and JavaScript files extensions: ['.ts', '.js'] }, module: {