diff --git a/.nx/version-plans/version-plan-1764807248032.md b/.nx/version-plans/version-plan-1764807248032.md new file mode 100644 index 0000000..7ab510d --- /dev/null +++ b/.nx/version-plans/version-plan-1764807248032.md @@ -0,0 +1,20 @@ +--- +nx-cdk: patch +--- + +This is the initial release of `@aligent/nx-cdk`, an Nx plugin for AWS CDK development that helps scaffold and manage CDK projects within an Nx monorepo structure. + +### Preset Generator: + +- Initialize new AWS CDK projects with complete Nx workspace structure +- Creates root configuration files (ESLint, Prettier, Rolldown, Vitest, TypeScript) +- Scaffolds CDK application with bin/main.ts entry point and service stacks +- Configurable Node.js version support (default: 24.11.0) +- Includes CDK configuration files (cdk.json, cdk.context.json) + +### Service Generator: + +- Create new CDK services within existing projects +- Generates service structure in `services//` directory +- Includes build configuration (Rolldown), testing setup (Vitest), and linting (ESLint) +- Auto-registers stacks to main CDK application diff --git a/README.md b/README.md index df89abc..6033803 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Aligent's monorepo for Microservice Development Utilities. For more details abou # Packages - [Microservice Util Lib](/packages/microservice-util-lib/README.md) +- [Nx CDK](/packages/nx-cdk/README.md) - [Nx Openapi](/packages/nx-openapi/README.md) - [Nx Serverless](/packages/nx-serverless/README.md) (obsoleted) @@ -100,16 +101,14 @@ To test packages locally before publishing, you can use the local `verdaccio` re ```bash # Start local registry -npx nx start-local-registry +npx nx start-local-registry microservice-development-utilities # In another terminal, publish packages locally -npx nx run-many -t publish +npx nx release publish # Stop local registry when done -npx nx stop-local-registry +npx nx stop-local-registry microservice-development-utilities ``` -### Note -- At the moment, we do not include `verdaccio` in our dev dependencies yet because of [CVE-2025-56200]https://github.com/advisories/GHSA-9965-vmph-33xx vulnerable in one of Verdaccio v6.2.1 dependencies. It will be added back once they resolve the issue. For now, we will need to add it in when we use it and remove it before making a PR. ## Project Structure @@ -117,6 +116,7 @@ npx nx stop-local-registry microservice-development-utilities/ ├── packages/ │ ├── microservice-util-lib/ # Utility library for microservices +│ ├── nx-cdk/ # Nx plugin for CDK project generation │ ├── nx-openapi/ # Nx plugin for OpenAPI code generation │ └── nx-serverless/ # Nx plugin for Serverless project generation (obsoleted) └── package.json # Root package configuration diff --git a/package-lock.json b/package-lock.json index fecae86..7df4672 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "@aws-sdk/client-ssm": "^3.922.0", "@redocly/openapi-core": "^1.34.2", "object-hash": "^3.0.0", - "openapi-typescript": "7.7.3" + "openapi-typescript": "7.7.3", + "ts-morph": "^27.0.2" }, "devDependencies": { "@aligent/ts-code-standards": "^3.0.0", @@ -45,6 +46,7 @@ "typedoc": "^0.28.14", "typedoc-plugin-markdown": "^4.9.0", "typescript": "^5.9.3", + "verdaccio": "^6.2.4", "vite": "^6.4.1", "vitest": "3.1.2" } @@ -53,6 +55,10 @@ "resolved": "packages/microservice-util-lib", "link": true }, + "node_modules/@aligent/nx-cdk": { + "resolved": "packages/nx-cdk", + "link": true + }, "node_modules/@aligent/nx-openapi": { "resolved": "packages/nx-openapi", "link": true @@ -2890,6 +2896,36 @@ "dev": true, "license": "MIT" }, + "node_modules/@cypress/request": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.9.tgz", + "integrity": "sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~4.0.4", + "http-signature": "~1.4.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.14.0", + "safe-buffer": "^5.1.2", + "tough-cookie": "^5.0.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@emnapi/core": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", @@ -3639,6 +3675,27 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -4509,7 +4566,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4523,7 +4579,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4537,7 +4592,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4551,7 +4605,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4565,7 +4618,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4579,7 +4631,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4593,7 +4644,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4607,7 +4657,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4621,7 +4670,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4635,7 +4683,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4649,7 +4696,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4663,7 +4709,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4677,7 +4722,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4691,7 +4735,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4705,7 +4748,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4719,7 +4761,6 @@ "cpu": [ "wasm32" ], - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4733,7 +4774,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4746,7 +4786,6 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4760,7 +4799,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4774,7 +4812,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4788,7 +4825,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4808,6 +4844,13 @@ "typescript": "^3 || ^4 || ^5" } }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -5264,6 +5307,19 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -6256,7 +6312,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/@swc-node/core/-/core-1.14.1.tgz", "integrity": "sha512-jrt5GUaZUU6cmMS+WTJEvGvaB6j1YNKPHPzC2PUi2BjaFbtxURHj6641Az6xN7b665hNniAIdvjxWcRml5yCnw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 10" @@ -6274,7 +6330,7 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/@swc-node/register/-/register-1.11.1.tgz", "integrity": "sha512-VQ0hJ5jX31TVv/fhZx4xJRzd8pwn6VvzYd2tGOHHr2TfXGCBixZoqdPDXTiEoJLCTS2MmvBf6zyQZZ0M8aGQCQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@swc-node/core": "^1.14.1", @@ -6298,14 +6354,14 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@swc-node/sourcemap-support": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/@swc-node/sourcemap-support/-/sourcemap-support-0.6.1.tgz", "integrity": "sha512-ovltDVH5QpdHXZkW138vG4+dgcNsxfwxHVoV6BtmTbz2KKl1A8ZSlbdtxzzfNjCjbpayda8Us9eMtcHobm38dA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "source-map-support": "^0.5.21", @@ -6316,7 +6372,7 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -6327,7 +6383,7 @@ "version": "1.15.2", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.2.tgz", "integrity": "sha512-OQm+yJdXxvSjqGeaWhP6Ia264ogifwAO7Q12uTDVYj/Ks4jBTI4JknlcjDRAXtRhqbWsfbZyK/5RtuIPyptk3w==", - "dev": true, + "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -6369,7 +6425,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6386,7 +6441,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6403,7 +6457,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -6420,7 +6473,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6437,7 +6489,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6454,7 +6505,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6471,7 +6521,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6488,7 +6537,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6505,7 +6553,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6522,7 +6569,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -6536,14 +6582,14 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0" }, "node_modules/@swc/helpers": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -6553,12 +6599,51 @@ "version": "0.1.25", "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz", "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" } }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ts-morph/common": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.28.1.tgz", + "integrity": "sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==", + "license": "MIT", + "dependencies": { + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1", + "tinyglobby": "^0.2.14" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", @@ -6685,7 +6770,7 @@ "version": "22.19.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz", "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -6704,6 +6789,16 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "license": "MIT" }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/sinon": { "version": "17.0.4", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", @@ -7013,172 +7108,688 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@vitest/coverage-v8": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.2.tgz", - "integrity": "sha512-XDdaDOeaTMAMYW7N63AqoK32sYUWbXnTkC6tEbVcu3RlU1bB9of32T+PGf8KZvxqLNqeXhafDFqCkwpf2+dyaQ==", - "dev": true, + "node_modules/@verdaccio/auth": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/auth/-/auth-8.0.0-next-8.28.tgz", + "integrity": "sha512-tM0URyKFq1dGFaoBN0whT1SDur1lBKG+pkQwxgJIXgH04DmefLCH63pn/K1iDDfLwqyxMewpmvMTBS390SSR+A==", + "devOptional": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@bcoe/v8-coverage": "^1.0.2", - "debug": "^4.4.0", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^5.0.6", - "istanbul-reports": "^3.1.7", - "magic-string": "^0.30.17", - "magicast": "^0.3.5", - "std-env": "^3.9.0", - "test-exclude": "^7.0.1", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@verdaccio/config": "8.0.0-next-8.28", + "@verdaccio/core": "8.0.0-next-8.28", + "@verdaccio/loaders": "8.0.0-next-8.18", + "@verdaccio/signature": "8.0.0-next-8.20", + "debug": "4.4.3", + "lodash": "4.17.21", + "verdaccio-htpasswd": "13.0.0-next-8.28" }, - "peerDependencies": { - "@vitest/browser": "3.1.2", - "vitest": "3.1.2" + "engines": { + "node": ">=18" }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" } }, - "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", - "dev": true, + "node_modules/@verdaccio/config": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/config/-/config-8.0.0-next-8.28.tgz", + "integrity": "sha512-yl7lcSOzT9y7EgUald4bZXIKxhZdAPRvtDZwmsPL433bc+CInyriqYCo6L4fZgFxYAdj9iDzvZIJtCtsFc+8NA==", + "devOptional": true, "license": "MIT", + "dependencies": { + "@verdaccio/core": "8.0.0-next-8.28", + "debug": "4.4.3", + "js-yaml": "4.1.1", + "lodash": "4.17.21" + }, "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" } }, - "node_modules/@vitest/coverage-v8/node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/@verdaccio/core": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/core/-/core-8.0.0-next-8.28.tgz", + "integrity": "sha512-W/wBvgF53CLr7m2zDV4QnHGYh0M/D3HTm5OuTxIjeclwDZGH2UHSdiI2BFFhvW7zt6MQVjfTQdgtcH4cmLGXhQ==", + "devOptional": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" + "ajv": "8.17.1", + "http-errors": "2.0.0", + "http-status-codes": "2.3.0", + "minimatch": "7.4.6", + "process-warning": "1.0.0", + "semver": "7.7.3" }, "engines": { - "node": ">=10" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" } }, - "node_modules/@vitest/expect": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.2.tgz", - "integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==", - "dev": true, + "node_modules/@verdaccio/core/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "devOptional": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.1.2", - "@vitest/utils": "3.1.2", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@vitest/mocker": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.2.tgz", - "integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==", - "dev": true, - "license": "MIT", + "node_modules/@verdaccio/core/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "devOptional": true, + "license": "ISC", "dependencies": { - "@vitest/spy": "3.1.2", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "brace-expansion": "^2.0.1" }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0" + "engines": { + "node": ">=10" }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@vitest/pretty-format": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", - "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", - "dev": true, + "node_modules/@verdaccio/file-locking": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@verdaccio/file-locking/-/file-locking-10.3.1.tgz", + "integrity": "sha512-oqYLfv3Yg3mAgw9qhASBpjD50osj2AX4IwbkUtyuhhKGyoFU9eZdrbeW6tpnqUnj6yBMtAPm2eGD4BwQuX400g==", + "devOptional": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^2.0.0" + "lockfile": "1.0.4" + }, + "engines": { + "node": ">=12" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" } }, - "node_modules/@vitest/runner": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.2.tgz", - "integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==", - "dev": true, + "node_modules/@verdaccio/hooks": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/hooks/-/hooks-8.0.0-next-8.28.tgz", + "integrity": "sha512-K+Cu9Pls8G2Wvu6pOYuelCTNBLpSOpmodJaPbUVv/kkhsTphgRiRENhOZGbiPhfVKehQeUCj9WiF8C7xzTf2Vg==", + "devOptional": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.1.2", - "pathe": "^2.0.3" + "@verdaccio/core": "8.0.0-next-8.28", + "@verdaccio/logger": "8.0.0-next-8.28", + "debug": "4.4.3", + "got-cjs": "12.5.4", + "handlebars": "4.7.8" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" } }, - "node_modules/@vitest/snapshot": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.2.tgz", - "integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==", - "dev": true, + "node_modules/@verdaccio/loaders": { + "version": "8.0.0-next-8.18", + "resolved": "https://registry.npmjs.org/@verdaccio/loaders/-/loaders-8.0.0-next-8.18.tgz", + "integrity": "sha512-p8o/DST+TPLz1pTqnduYKMggNxYO5ET+3a4UXLArVDWbhqNnYFRmZVyIW8r0JFOuRwUKdpcJMkXefufMRm8B8g==", + "devOptional": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.1.2", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" + "@verdaccio/core": "8.0.0-next-8.28", + "debug": "4.4.3", + "lodash": "4.17.21" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" } }, - "node_modules/@vitest/spy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz", - "integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", - "dev": true, + "node_modules/@verdaccio/local-storage-legacy": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@verdaccio/local-storage-legacy/-/local-storage-legacy-11.1.1.tgz", + "integrity": "sha512-P6ahH2W6/KqfJFKP+Eid7P134FHDLNvHa+i8KVgRVBeo2/IXb6FEANpM1mCVNvPANu0LCAmNJBOXweoUKViaoA==", + "devOptional": true, "license": "MIT", "dependencies": { - "tinyspy": "^3.0.2" + "@verdaccio/core": "8.0.0-next-8.21", + "@verdaccio/file-locking": "10.3.1", + "@verdaccio/streams": "10.2.1", + "async": "3.2.6", + "debug": "4.4.1", + "lodash": "4.17.21", + "lowdb": "1.0.0", + "mkdirp": "1.0.4" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" } }, - "node_modules/@vitest/ui": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.1.2.tgz", - "integrity": "sha512-+YPgKiLpFEyBVJNHDkRcSDcLrrnr20lyU4HQoI9Jtq1MdvoX8usql9h38mQw82MBU1Zo5BPC6sw+sXZ6NS18CQ==", - "dev": true, + "node_modules/@verdaccio/local-storage-legacy/node_modules/@verdaccio/core": { + "version": "8.0.0-next-8.21", + "resolved": "https://registry.npmjs.org/@verdaccio/core/-/core-8.0.0-next-8.21.tgz", + "integrity": "sha512-n3Y8cqf84cwXxUUdTTfEJc8fV55PONPKijCt2YaC0jilb5qp1ieB3d4brqTOdCdXuwkmnG2uLCiGpUd/RuSW0Q==", + "devOptional": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.1.2", - "fflate": "^0.8.2", - "flatted": "^3.3.3", + "ajv": "8.17.1", + "http-errors": "2.0.0", + "http-status-codes": "2.3.0", + "minimatch": "7.4.6", + "process-warning": "1.0.0", + "semver": "7.7.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/local-storage-legacy/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@verdaccio/local-storage-legacy/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@verdaccio/local-storage-legacy/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "devOptional": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@verdaccio/local-storage-legacy/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@verdaccio/logger": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/logger/-/logger-8.0.0-next-8.28.tgz", + "integrity": "sha512-Iss+5mUJSvkDIwOWv6lk9OZjHl9PKHXf4FwM/YI5a77B06r5LYvdpppKVwGxBFn8jFcyGBl97zz8uqz6uD/rhQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/logger-commons": "8.0.0-next-8.28", + "pino": "9.14.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/logger-commons": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/logger-commons/-/logger-commons-8.0.0-next-8.28.tgz", + "integrity": "sha512-GlIpSCKC6uKR4D9BZFbCiiJHeAaZ/n8izYqMKqFV5RKOrdMaMmYKjVFLvjGDpd22AFnCvSUfgrKCX1FXe8ZFqw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/core": "8.0.0-next-8.28", + "@verdaccio/logger-prettify": "8.0.0-next-8.4", + "colorette": "2.0.20", + "debug": "4.4.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/logger-commons/node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@verdaccio/logger-prettify": { + "version": "8.0.0-next-8.4", + "resolved": "https://registry.npmjs.org/@verdaccio/logger-prettify/-/logger-prettify-8.0.0-next-8.4.tgz", + "integrity": "sha512-gjI/JW29fyalutn/X1PQ0iNuGvzeVWKXRmnLa7gXVKhdi4p37l/j7YZ7n44XVbbiLIKAK0pbavEg9Yr66QrYaA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "colorette": "2.0.20", + "dayjs": "1.11.13", + "lodash": "4.17.21", + "on-exit-leak-free": "2.1.2", + "pino-abstract-transport": "1.2.0", + "sonic-boom": "3.8.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/logger-prettify/node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@verdaccio/middleware": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/middleware/-/middleware-8.0.0-next-8.28.tgz", + "integrity": "sha512-L2PL4JJQ6dKipNrA/weWTEw47ZUgiJrvKb7g/z3yuDR5O/C7AJ+mOxqsWww0kgq0cvQm+kOXMVY9Oq1g9a+Agw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/config": "8.0.0-next-8.28", + "@verdaccio/core": "8.0.0-next-8.28", + "@verdaccio/url": "13.0.0-next-8.28", + "debug": "4.4.3", + "express": "4.21.2", + "express-rate-limit": "5.5.1", + "lodash": "4.17.21", + "lru-cache": "7.18.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/middleware/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "devOptional": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@verdaccio/search-indexer": { + "version": "8.0.0-next-8.5", + "resolved": "https://registry.npmjs.org/@verdaccio/search-indexer/-/search-indexer-8.0.0-next-8.5.tgz", + "integrity": "sha512-0GC2tJKstbPg/W2PZl2yE+hoAxffD2ZWilEnEYSEo2e9UQpNIy2zg7KE/uMUq2P72Vf5EVfVzb8jdaH4KV4QeA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/signature": { + "version": "8.0.0-next-8.20", + "resolved": "https://registry.npmjs.org/@verdaccio/signature/-/signature-8.0.0-next-8.20.tgz", + "integrity": "sha512-1kwO+l7cLiDjXUwqVTvaKXvcI4C23u4cZCVnGGKXRcahrbVm7Hdh12wSIX5V9gV6O3VlWH458JxoimpPAo4Oxw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/config": "8.0.0-next-8.28", + "@verdaccio/core": "8.0.0-next-8.28", + "debug": "4.4.3", + "jsonwebtoken": "9.0.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/streams": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/@verdaccio/streams/-/streams-10.2.1.tgz", + "integrity": "sha512-OojIG/f7UYKxC4dYX8x5ax8QhRx1b8OYUAMz82rUottCuzrssX/4nn5QE7Ank0DUSX3C9l/HPthc4d9uKRJqJQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/tarball": { + "version": "13.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/tarball/-/tarball-13.0.0-next-8.28.tgz", + "integrity": "sha512-89FHelT4xsrBeAk6WYhhUR6cgpky1IAgBiN3VtWs2b3KA8XesZeG7G0UDygTVEe2O0etXYtrz9vlqZ9nYEaAGA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/core": "8.0.0-next-8.28", + "@verdaccio/url": "13.0.0-next-8.28", + "debug": "4.4.3", + "gunzip-maybe": "1.4.2", + "tar-stream": "3.1.7" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/tarball/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/@verdaccio/ui-theme": { + "version": "8.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/ui-theme/-/ui-theme-8.0.0-next-8.28.tgz", + "integrity": "sha512-TzhdphchcvsI38UPP5hdNJh+LAFvRhYlfrtBuqlZy0BHeGM2i2MNioGl2il2NLVteqXAK9MqnuC5WGxCFXoDYw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@verdaccio/url": { + "version": "13.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/url/-/url-13.0.0-next-8.28.tgz", + "integrity": "sha512-42wA5LkXWpY42pONEHQhAC5h8nFXdDHChP22swOitTp1xzvAs+PmwUlrol7kMXMWO04skDCSSW1Q54eNkTx/rA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/core": "8.0.0-next-8.28", + "debug": "4.4.3", + "validator": "13.15.23" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/utils": { + "version": "8.1.0-next-8.28", + "resolved": "https://registry.npmjs.org/@verdaccio/utils/-/utils-8.1.0-next-8.28.tgz", + "integrity": "sha512-/AYNGafG9T90NPGsq6eDMuXx+41tlWfiYsCchgwz074GWEitZ2nAZQWWNvYvFVB2hXzord52muEVTWjgaZPOdQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/core": "8.0.0-next-8.28", + "lodash": "4.17.21", + "minimatch": "7.4.6" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/utils/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "devOptional": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.2.tgz", + "integrity": "sha512-XDdaDOeaTMAMYW7N63AqoK32sYUWbXnTkC6tEbVcu3RlU1bB9of32T+PGf8KZvxqLNqeXhafDFqCkwpf2+dyaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^1.0.2", + "debug": "^4.4.0", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "std-env": "^3.9.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "3.1.2", + "vitest": "3.1.2" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@vitest/coverage-v8/node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@vitest/expect": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.2.tgz", + "integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.2", + "@vitest/utils": "3.1.2", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.2.tgz", + "integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.2", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", + "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.2.tgz", + "integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.1.2", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.2.tgz", + "integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.2", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz", + "integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/ui": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.1.2.tgz", + "integrity": "sha512-+YPgKiLpFEyBVJNHDkRcSDcLrrnr20lyU4HQoI9Jtq1MdvoX8usql9h38mQw82MBU1Zo5BPC6sw+sXZ6NS18CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.1.2", + "fflate": "^0.8.2", + "flatted": "^3.3.3", "pathe": "^2.0.3", "sirv": "^3.0.1", "tinyglobby": "^0.2.13", @@ -7259,6 +7870,43 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -7400,6 +8048,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/apache-md5": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.8.tgz", + "integrity": "sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -7433,6 +8091,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/array-includes": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", @@ -7576,6 +8241,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -7615,6 +8300,16 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -7643,6 +8338,23 @@ "tslib": "^2.1.0" } }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "devOptional": true, + "license": "MIT" + }, "node_modules/axe-core": { "version": "4.11.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", @@ -7674,6 +8386,21 @@ "node": ">= 0.4" } }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "devOptional": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -7931,6 +8658,21 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "devOptional": true, + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -7973,6 +8715,23 @@ "node": ">= 0.8" } }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "devOptional": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -7984,6 +8743,77 @@ "readable-stream": "^3.4.0" } }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "devOptional": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/bowser": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.12.1.tgz", @@ -8012,6 +8842,16 @@ "node": ">=8" } }, + "node_modules/browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "pako": "~0.2.0" + } + }, "node_modules/browserslist": { "version": "4.28.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", @@ -8079,12 +8919,29 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "devOptional": true, + "license": "BSD-3-Clause" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -8095,6 +8952,62 @@ "node": ">=8" } }, + "node_modules/cacheable-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", + "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -8131,7 +9044,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -8183,6 +9096,13 @@ ], "license": "CC-BY-4.0" }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "devOptional": true, + "license": "Apache-2.0" + }, "node_modules/chai": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", @@ -8289,6 +9209,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clipanion": { + "version": "4.0.0-rc.4", + "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-4.0.0-rc.4.tgz", + "integrity": "sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q==", + "devOptional": true, + "license": "MIT", + "workspaces": [ + "website" + ], + "dependencies": { + "typanion": "^3.8.0" + }, + "peerDependencies": { + "typanion": "*" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -8312,6 +9248,19 @@ "node": ">=0.8" } }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -8323,6 +9272,12 @@ "node": ">= 0.12.0" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "license": "MIT" + }, "node_modules/collect-v8-coverage": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", @@ -8379,6 +9334,76 @@ "node": ">= 0.8" } }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/compression/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==", + "devOptional": 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" + } + ], + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -8393,12 +9418,73 @@ "dev": true, "license": "MIT" }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/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==", + "devOptional": 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" + } + ], + "license": "MIT" + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "license": "MIT" }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/core-js-compat": { "version": "3.46.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", @@ -8412,6 +9498,27 @@ "url": "https://opencollective.com/core-js" } }, + "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": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/corser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", @@ -8469,6 +9576,19 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -8523,6 +9643,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -8540,6 +9667,35 @@ } } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", @@ -8594,6 +9750,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -8648,6 +9814,27 @@ "node": ">=0.4.0" } }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -8748,6 +9935,52 @@ "node": ">= 0.4" } }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexify/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==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -8755,6 +9988,34 @@ "dev": true, "license": "MIT" }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "devOptional": true, + "license": "MIT" + }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -8796,6 +10057,16 @@ "dev": true, "license": "MIT" }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -8830,6 +10101,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/envinfo": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.15.0.tgz", + "integrity": "sha512-chR+t7exF6y59kelhXw5I3849nTy7KIRO+ePdLMhCD+JRP/JvmkenDWP7QSFGlsHX+kxGxdDutOPrmj5j1HR6g==", + "devOptional": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", @@ -9070,6 +10354,13 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "devOptional": true, + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -9721,6 +11012,26 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -9728,6 +11039,26 @@ "dev": true, "license": "MIT" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -9764,6 +11095,138 @@ "node": ">=12.0.0" } }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz", + "integrity": "sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/express/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "devOptional": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/express/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==", + "devOptional": 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" + } + ], + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "devOptional": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -9777,6 +11240,13 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -9970,6 +11440,42 @@ "node": ">=8" } }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "devOptional": true, + "license": "MIT" + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -10080,6 +11586,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, "node_modules/form-data": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", @@ -10096,6 +11612,33 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/front-matter": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", @@ -10270,6 +11813,19 @@ "node": ">= 0.4" } }, + "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==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -10288,6 +11844,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -10389,11 +11955,38 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got-cjs": { + "version": "12.5.4", + "resolved": "https://registry.npmjs.org/got-cjs/-/got-cjs-12.5.4.tgz", + "integrity": "sha512-Uas6lAsP8bRCt5WXGMhjFf/qEHTrm4v4qxGR02rLG2kdG9qedctvlkdwXVcDJ7Cs84X+r4dPU7vdwGjCaspXug==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "4.6.0", + "@szmarczak/http-timer": "4.0.6", + "@types/responselike": "1.0.0", + "cacheable-lookup": "6.1.0", + "cacheable-request": "7.0.2", + "decompress-response": "^6.0.0", + "form-data-encoder": "1.7.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "2.0.0", + "p-cancelable": "2.1.1", + "responselike": "2.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/graphemer": { @@ -10403,6 +11996,46 @@ "dev": true, "license": "MIT" }, + "node_modules/gunzip-maybe": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", + "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "browserify-zlib": "^0.1.4", + "is-deflate": "^1.0.0", + "is-gzip": "^1.0.0", + "peek-stream": "^1.1.0", + "pumpify": "^1.3.3", + "through2": "^2.0.3" + }, + "bin": { + "gunzip-maybe": "bin.js" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/harmony-reflect": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", @@ -10548,6 +12181,30 @@ "dev": true, "license": "MIT" }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "devOptional": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", @@ -10591,6 +12248,42 @@ "node": ">=12" } }, + "node_modules/http-signature": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", + "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/http-status-codes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", + "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -10739,6 +12432,16 @@ "node": ">= 0.4" } }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -10879,6 +12582,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-deflate": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", + "integrity": "sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -10972,6 +12682,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-gzip": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", + "integrity": "sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -11034,6 +12754,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -11133,6 +12860,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -11217,6 +12951,13 @@ "dev": true, "license": "ISC" }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "devOptional": true, + "license": "MIT" + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -11891,6 +13632,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -11907,7 +13655,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/json-parse-even-better-errors": { @@ -11916,6 +13664,13 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "devOptional": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -11929,6 +13684,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "devOptional": true, + "license": "ISC" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -11984,6 +13746,72 @@ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "license": "MIT" }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "devOptional": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "devOptional": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "devOptional": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -12007,11 +13835,34 @@ "dev": true, "license": "MIT" }, + "node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", + "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "jwa": "^1.4.2", + "safe-buffer": "^5.0.1" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -12093,12 +13944,71 @@ "node": ">=8" } }, + "node_modules/lockfile": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", + "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "devOptional": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^3.0.2" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "devOptional": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -12106,6 +14016,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -12142,6 +14059,33 @@ "dev": true, "license": "MIT" }, + "node_modules/lowdb": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", + "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.3", + "is-promise": "^2.1.0", + "lodash": "4", + "pify": "^3.0.0", + "steno": "^0.4.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -12240,6 +14184,26 @@ "dev": true, "license": "MIT" }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "devOptional": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -12257,6 +14221,16 @@ "node": ">= 8" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -12288,7 +14262,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "mime": "cli.js" @@ -12327,6 +14301,16 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -12361,6 +14345,19 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "devOptional": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -12403,6 +14400,23 @@ "dev": true, "license": "MIT" }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "devOptional": true, + "license": "MIT" + }, "node_modules/nise": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", @@ -12427,6 +14441,27 @@ "@sinonjs/commons": "^3.0.1" } }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -12456,6 +14491,19 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npm-package-arg": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.1.tgz", @@ -12567,7 +14615,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12586,7 +14634,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12695,6 +14743,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -12884,7 +14965,7 @@ "version": "11.13.2", "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.13.2.tgz", "integrity": "sha512-1SXVyYQ9bqMX3uZo8Px81EG7jhZkO9PvvR5X9roY5TLYVm4ZA7pbPDNlYaDBBeF9U+YO3OeMNoHde52hrcCu8w==", - "dev": true, + "devOptional": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" @@ -12911,6 +14992,16 @@ "@oxc-resolver/binding-win32-x64-msvc": "11.13.2" } }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -12973,6 +15064,13 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -13009,6 +15107,22 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -13105,6 +15219,25 @@ "node": ">= 14.16" } }, + "node_modules/peek-stream": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", + "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "duplexify": "^3.5.0", + "through2": "^2.0.3" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "devOptional": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -13123,11 +15256,141 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pino": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", + "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "devOptional": 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" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/pino/node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino/node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "devOptional": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/pino/node_modules/sonic-boom": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", + "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 6" @@ -13373,6 +15636,30 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "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==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/process-warning": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz", + "integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==", + "devOptional": true, + "license": "MIT" + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -13392,12 +15679,49 @@ "dev": true, "license": "MIT" }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -13439,7 +15763,7 @@ "version": "6.14.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -13472,6 +15796,65 @@ ], "license": "MIT" }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -13492,6 +15875,16 @@ "node": ">= 6" } }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -13634,6 +16027,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "devOptional": true, + "license": "MIT" + }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -13653,6 +16053,19 @@ "node": ">=10" } }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -13767,7 +16180,7 @@ "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, + "devOptional": true, "license": "MIT" }, "node_modules/safe-push-apply": { @@ -13805,11 +16218,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/secure-compare": { @@ -13828,7 +16251,75 @@ "semver": "bin/semver.js" }, "engines": { - "node": ">=10" + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" } }, "node_modules/set-function-length": { @@ -13880,6 +16371,13 @@ "node": ">= 0.4" } }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "devOptional": true, + "license": "ISC" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -13907,7 +16405,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -13927,7 +16425,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -13944,7 +16442,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -13963,7 +16461,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -14046,6 +16544,16 @@ "node": ">=8" } }, + "node_modules/sonic-boom": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -14075,12 +16583,48 @@ "source-map": "^0.6.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "devOptional": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -14111,6 +16655,16 @@ "dev": true, "license": "MIT" }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", @@ -14118,6 +16672,16 @@ "dev": true, "license": "MIT" }, + "node_modules/steno": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", + "integrity": "sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.3" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -14132,6 +16696,25 @@ "node": ">= 0.4" } }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -14464,9 +17047,9 @@ } }, "node_modules/test-exclude/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -14500,6 +17083,77 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/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==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -14572,6 +17226,26 @@ "node": ">=14.0.0" } }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -14601,6 +17275,16 @@ "node": ">=8.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", @@ -14611,6 +17295,26 @@ "node": ">=6" } }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "devOptional": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "devOptional": true, + "license": "MIT" + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -14624,6 +17328,16 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-morph": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-27.0.2.tgz", + "integrity": "sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.28.1", + "code-block-writer": "^13.0.3" + } + }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -14653,6 +17367,36 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "devOptional": true, + "license": "Unlicense" + }, + "node_modules/typanion": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", + "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==", + "devOptional": true, + "license": "MIT", + "workspaces": [ + "website" + ] + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14689,6 +17433,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -14864,6 +17622,20 @@ "dev": true, "license": "MIT" }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -14887,7 +17659,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -14942,6 +17714,23 @@ "node": ">= 0.8.0" } }, + "node_modules/unix-crypt-td-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", @@ -14995,6 +17784,26 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "devOptional": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -15019,6 +17828,201 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/validator": { + "version": "13.15.23", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", + "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verdaccio": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/verdaccio/-/verdaccio-6.2.4.tgz", + "integrity": "sha512-1riItDS5ZmkLVclEOI4ibmJPCTfg1f8iEbdZWo7mgaEDHs1KS2JJnGq+dnoDlbo4efJ5mCyy1g7p32k/xx2+wg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@cypress/request": "3.0.9", + "@verdaccio/auth": "8.0.0-next-8.28", + "@verdaccio/config": "8.0.0-next-8.28", + "@verdaccio/core": "8.0.0-next-8.28", + "@verdaccio/hooks": "8.0.0-next-8.28", + "@verdaccio/loaders": "8.0.0-next-8.18", + "@verdaccio/local-storage-legacy": "11.1.1", + "@verdaccio/logger": "8.0.0-next-8.28", + "@verdaccio/middleware": "8.0.0-next-8.28", + "@verdaccio/search-indexer": "8.0.0-next-8.5", + "@verdaccio/signature": "8.0.0-next-8.20", + "@verdaccio/streams": "10.2.1", + "@verdaccio/tarball": "13.0.0-next-8.28", + "@verdaccio/ui-theme": "8.0.0-next-8.28", + "@verdaccio/url": "13.0.0-next-8.28", + "@verdaccio/utils": "8.1.0-next-8.28", + "async": "3.2.6", + "clipanion": "4.0.0-rc.4", + "compression": "1.8.1", + "cors": "2.8.5", + "debug": "4.4.3", + "envinfo": "7.15.0", + "express": "4.21.2", + "JSONStream": "1.3.5", + "lodash": "4.17.21", + "lru-cache": "7.18.3", + "mime": "3.0.0", + "semver": "7.7.3", + "verdaccio-audit": "13.0.0-next-8.28", + "verdaccio-htpasswd": "13.0.0-next-8.28" + }, + "bin": { + "verdaccio": "bin/verdaccio" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio-audit": { + "version": "13.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/verdaccio-audit/-/verdaccio-audit-13.0.0-next-8.28.tgz", + "integrity": "sha512-vcl+V4R43QFSrch0QggG92hEd+aGh7fGBqkA1pcF/m4eJ2JQw7+/8JD5VJ/qCnt7Udnz9Jmey6SvgFgxsB6ODA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/config": "8.0.0-next-8.28", + "@verdaccio/core": "8.0.0-next-8.28", + "express": "4.21.2", + "https-proxy-agent": "5.0.1", + "node-fetch": "cjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio-audit/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==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/verdaccio-audit/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/verdaccio-htpasswd": { + "version": "13.0.0-next-8.28", + "resolved": "https://registry.npmjs.org/verdaccio-htpasswd/-/verdaccio-htpasswd-13.0.0-next-8.28.tgz", + "integrity": "sha512-iAkhusaNUEvBeq+7Xn8YUqq4hXoVuAteZPrG4dwsqSjVliS7YQGdysQKYG89QnN9iMKAEvuSzhb+GP0c5dbL0g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@verdaccio/core": "8.0.0-next-8.28", + "@verdaccio/file-locking": "13.0.0-next-8.6", + "apache-md5": "1.1.8", + "bcryptjs": "2.4.3", + "debug": "4.4.3", + "http-errors": "2.0.0", + "unix-crypt-td-js": "1.1.4" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio-htpasswd/node_modules/@verdaccio/file-locking": { + "version": "13.0.0-next-8.6", + "resolved": "https://registry.npmjs.org/@verdaccio/file-locking/-/file-locking-13.0.0-next-8.6.tgz", + "integrity": "sha512-F6xQWvsZnEyGjugrYfe+D/ChSVudXmBFWi8xuTIX6PAdp7dk9x9biOGQFW8O3GSAK8UhJ6WlRisQKJeYRa6vWQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "lockfile": "1.0.4" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "devOptional": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/verdaccio/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "devOptional": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "devOptional": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "node_modules/vite": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", @@ -15207,6 +18211,13 @@ "defaults": "^1.0.3" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "devOptional": true, + "license": "BSD-2-Clause" + }, "node_modules/whatwg-encoding": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", @@ -15220,6 +18231,17 @@ "node": ">=12" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -15352,6 +18374,13 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "devOptional": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -15408,6 +18437,16 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -15493,6 +18532,15 @@ "openapi-fetch": "^0.15.0" } }, + "packages/nx-cdk": { + "name": "@aligent/nx-cdk", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "@nx/devkit": "20.8.1", + "ts-morph": "^27.0.2" + } + }, "packages/nx-openapi": { "name": "@aligent/nx-openapi", "version": "2.0.0", diff --git a/package.json b/package.json index 743c123..9bbc3f2 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "@aws-sdk/client-ssm": "^3.922.0", "@redocly/openapi-core": "^1.34.2", "object-hash": "^3.0.0", - "openapi-typescript": "7.7.3" + "openapi-typescript": "7.7.3", + "ts-morph": "^27.0.2" }, "devDependencies": { "@aligent/ts-code-standards": "^3.0.0", @@ -53,6 +54,7 @@ "typedoc": "^0.28.14", "typedoc-plugin-markdown": "^4.9.0", "typescript": "^5.9.3", + "verdaccio": "^6.2.4", "vite": "^6.4.1", "vitest": "3.1.2" }, diff --git a/packages/nx-cdk/README.md b/packages/nx-cdk/README.md new file mode 100644 index 0000000..cca1970 --- /dev/null +++ b/packages/nx-cdk/README.md @@ -0,0 +1,130 @@ +# Nx Cloud Development Kit + +The `@aligent/nx-cdk` package provides Nx generators for AWS CDK development. It helps you scaffold new CDK projects and services within an Nx monorepo structure. + +## Generators + +### Preset Generator + +The preset generator initializes a new CDK project with a complete workspace structure, including configuration files, build tools, and an application scaffold. + +#### Usage + +```bash +npx create-nx-workspace@latest --preset=@aligent/nx-cdk +``` + +#### Options + +| Option | Type | Required | Default | Description | +| ------------- | ------ | -------- | --------- | -------------------------------------------------------------------------------- | +| `name` | string | Yes | - | The name of the project/application (alphanumeric and dashes only) | +| `nodeVersion` | string | No | `24.11.0` | The target Node.js version for the project (must be valid semver, e.g., 22.10.0) | + +#### What it creates + +The preset generator scaffolds: + +- **Root configuration files**: + - `eslint.config.mjs` - ESLint configuration + - `prettier.config.mjs` - Prettier configuration + - `rolldown.config.base.mjs` - Base Rolldown configuration + - `vitest.config.base.mjs` - Base Vitest configuration + - `vitest.global.setup.mjs` - Global Vitest setup + - `tsconfig.json` - Root TypeScript configuration + - `nx.json` - Nx workspace configuration + - `package.json` - Project dependencies and scripts + - `cdk-config.yml` - CDK configuration + - `LICENSE` - Project license + +- **Application folder** (`application/`): + - `cdk.json` - CDK app configuration + - `cdk.context.json` - CDK context + - `bin/main.ts` - CDK app entry point + - `lib/service-stacks.ts` - Service stacks definition + - TypeScript configurations (`tsconfig.json`, `tsconfig.lib.json`, `tsconfig.spec.json`) + +### Service Generator + +The service generator creates a new CDK service within the `services/` folder of your existing CDK project. Each service is configured as a separate package with its own build configuration and testing setup. + +#### Usage + +```bash +npx nx g @aligent/nx-cdk:service +``` + +#### Options + +| Option | Type | Required | Description | +| ------ | ------ | -------- | ------------------------------------------------------------------------- | +| `name` | string | Yes | The name of the service (cannot contain 'Stack' or 'Service' in the name) | + +#### What it creates + +The service generator creates a new service in `services//` with: + +- **Service files**: + - `src/index.ts` - Service entry point + - `package.json` - Service-specific dependencies + - `README.md` - Service documentation + - `eslint.config.mjs` - ESLint configuration + - `rolldown.config.mjs` - Rolldown configuration + - `vitest.config.mjs` - Vitest configuration + - TypeScript configurations (`tsconfig.json`, `tsconfig.lib.json`, `tsconfig.spec.json`) + +- **Root updates**: + - Adds the service to the root `tsconfig.json` references for proper TypeScript project references + +- **Application updates**: + - Adds the stack to the main CDK application + +#### Example + +```bash +# Create a new service named "user-management" +npx nx g @aligent/nx-cdk:service user-management + +# Create a new service named "payment-processing" +npx nx g @aligent/nx-cdk:service payment-processing +``` + +## Project Structure + +After using both generators, your project structure will look like: + +``` +my-cdk-app/ +├── application/ +│ ├── bin/ +│ │ └── main.ts +│ ├── lib/ +│ │ └── service-stacks.ts +│ ├── _internal/ +│ │ ├── version-functions-aspect.ts +│ │ ├── nodejs-function-defaults-injector.ts +│ │ ├── step-function-defaults-injector.ts +│ │ ├── log-group-defaults-injector.ts +│ │ └── microservice-checks.ts +│ ├── cdk.json +│ ├── cdk.context.json +│ └── package.json +├── services/ +│ ├── user-management/ +│ │ ├── src/ +│ │ │ └── index.ts +│ │ ├── package.json +│ │ └── ... +│ └── payment-processing/ +│ ├── src/ +│ │ └── index.ts +│ ├── package.json +│ └── ... +├── nx.json +├── package.json +└── tsconfig.json +``` + +## License + +MIT diff --git a/packages/nx-cdk/eslint.config.mjs b/packages/nx-cdk/eslint.config.mjs new file mode 100644 index 0000000..40f2223 --- /dev/null +++ b/packages/nx-cdk/eslint.config.mjs @@ -0,0 +1,21 @@ +import nxEslintPlugin from '@nx/eslint-plugin'; +import jsonParser from 'jsonc-eslint-parser'; +import baseConfig from '../../eslint.config.mjs'; + +export default [ + ...baseConfig, + { + files: ['./package.json'], + plugins: { '@nx': nxEslintPlugin }, + rules: { + '@nx/dependency-checks': ['error', { ignoredFiles: ['{projectRoot}/*.{js,cjs,mjs}'] }], + }, + languageOptions: { parser: jsonParser }, + }, + { + files: ['./package.json', './generators.json'], + plugins: { '@nx': nxEslintPlugin }, + rules: { '@nx/nx-plugin-checks': 'error' }, + languageOptions: { parser: jsonParser }, + }, +]; diff --git a/packages/nx-cdk/generators.json b/packages/nx-cdk/generators.json new file mode 100644 index 0000000..7b9eaf2 --- /dev/null +++ b/packages/nx-cdk/generators.json @@ -0,0 +1,15 @@ +{ + "generators": { + "preset": { + "factory": "./src/generators/preset/preset", + "schema": "./src/generators/preset/schema.json", + "description": "preset generator", + "x-use-standalone-layout": true + }, + "service": { + "factory": "./src/generators/service/generator", + "schema": "./src/generators/service/schema.json", + "description": "Generate a new service" + } + } +} diff --git a/packages/nx-cdk/package.json b/packages/nx-cdk/package.json new file mode 100644 index 0000000..49f2a6d --- /dev/null +++ b/packages/nx-cdk/package.json @@ -0,0 +1,19 @@ +{ + "name": "@aligent/nx-cdk", + "version": "0.0.0", + "type": "commonjs", + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/aligent/microservice-development-utilities.git", + "directory": "packages/nx-cdk" + }, + "dependencies": { + "@nx/devkit": "20.8.1", + "ts-morph": "^27.0.2" + }, + "generators": "./generators.json", + "author": "Aligent", + "license": "MIT" +} diff --git a/packages/nx-cdk/project.json b/packages/nx-cdk/project.json new file mode 100644 index 0000000..73ee101 --- /dev/null +++ b/packages/nx-cdk/project.json @@ -0,0 +1,46 @@ +{ + "name": "nx-cdk", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/nx-cdk/src", + "projectType": "library", + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/nx-cdk", + "main": "{projectRoot}/src/index.ts", + "tsConfig": "{projectRoot}/tsconfig.lib.json", + "assets": [ + "{projectRoot}/*.md", + { + "input": "./{projectRoot}/src", + "glob": "**/!(*.ts)", + "output": "./src" + }, + { + "input": "./{projectRoot}/src", + "glob": "**/*.d.ts", + "output": "./src" + }, + { + "input": "./{projectRoot}", + "glob": "generators.json", + "output": "." + }, + { + "input": "./{projectRoot}", + "glob": "executors.json", + "output": "." + } + ] + } + }, + "nx-release-publish": { + "options": { + "packageRoot": "dist/nx-cdk" + } + } + }, + "tags": ["nx", "plugin", "cdk"] +} diff --git a/packages/nx-cdk/src/generators/helpers/configs/nxJson.ts b/packages/nx-cdk/src/generators/helpers/configs/nxJson.ts new file mode 100644 index 0000000..8eb73fb --- /dev/null +++ b/packages/nx-cdk/src/generators/helpers/configs/nxJson.ts @@ -0,0 +1,51 @@ +import { NxJsonConfiguration } from '@nx/devkit'; + +export const NX_JSON: NxJsonConfiguration & { $schema: string } = { + $schema: './node_modules/nx/schemas/nx-schema.json', + defaultBase: 'origin/staging', + plugins: [ + { plugin: '@nx/eslint/plugin', options: {} }, + { plugin: '@nx/vite/plugin', options: {} }, + { plugin: '@nx/js/typescript', options: { build: false } }, + ], + namedInputs: { + default: ['{projectRoot}/**/*', 'sharedGlobals'], + production: [ + 'default', + '!{projectRoot}/.eslintrc.json', + '!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)', + '!{projectRoot}/tsconfig.spec.json', + '!{projectRoot}/vitest.config.m[jt]s', + '!{projectRoot}/src/test-setup.[jt]s', + ], + sharedGlobals: [], + }, + targetDefaults: { + build: { + cache: true, + dependsOn: ['^build'], + inputs: ['production', '^production'], + outputs: ['{projectRoot}/dist'], + }, + cdk: { dependsOn: ['^build', '^build:lambda'], inputs: ['production', '^production'] }, + lint: { cache: true, inputs: ['default'] }, + test: { + cache: true, + inputs: ['default', '^production'], + outputs: ['{projectRoot}/coverage'], + // Stack tests may require lambda handlers to be built first + dependsOn: ['^build', 'build:lambda'], + configurations: { coverage: { coverage: true } }, + }, + typecheck: { cache: true, dependsOn: ['^build'], inputs: ['production', '^production'] }, + parameters: { + executor: 'nx:run-commands', + options: { color: true, cwd: '{projectRoot}/parameters', file: '.env.csv' }, + defaultConfiguration: 'export', + configurations: { + import: { command: 'store-parameters import {args.file}' }, + export: { command: 'store-parameters export {args.file} --path={args.path}' }, + }, + }, + }, +} as const; diff --git a/packages/nx-cdk/src/generators/helpers/configs/packageJson.ts b/packages/nx-cdk/src/generators/helpers/configs/packageJson.ts new file mode 100644 index 0000000..5d90343 --- /dev/null +++ b/packages/nx-cdk/src/generators/helpers/configs/packageJson.ts @@ -0,0 +1,63 @@ +export const PACKAGE_JSON = { + author: 'Aligent', + private: true, + license: 'MIT', + type: 'module', + scripts: { + test: 'nx affected -t test --coverage', + 'test:all': 'nx run-many -t test --coverage', + lint: 'nx affected -t lint', + 'lint:all': 'nx run-many -t lint', + typecheck: 'nx affected -t typecheck', + 'typecheck:all': 'nx run-many -t typecheck', + postinstall: `[ -d .git ] && git config core.hooksPath '.git-hooks' && chmod +x .git-hooks/* || true`, + 'pg:synth': `nx run application:cdk synth 'development/**' --exclusively --profile playground`, + 'pg:deploy': `nx run application:cdk deploy --method 'direct' 'development/**' --exclusively --require-approval never --profile playground`, + 'pg:destroy': "nx run application:cdk destroy 'development/**' --profile playground", + audit: 'nx run-many -t lint typecheck test --configuration coverage --skip-nx-cache', + }, + dependencies: { + '@aligent/microservice-util-lib': '^1.2.0', + }, + devDependencies: { + '@aligent/cdk-step-function-from-file': '^0.3.2', + '@aligent/nx-openapi': '^1.0.0', + '@aligent/ts-code-standards': '^4.1.0', + '@nx/eslint': '22.1.3', + '@nx/eslint-plugin': '22.1.3', + '@nx/js': '22.1.3', + '@nx/vite': '22.1.3', + '@swc-node/register': '^1.10.10', + '@swc/core': '^1.13.3', + '@swc/helpers': '^0.5.17', + '@types/aws-lambda': '^8.10.152', + '@types/node': '^22.17.0', + '@typescript-eslint/eslint-plugin': '8.44.0', + '@typescript-eslint/parser': '8.44.0', + '@vitest/coverage-v8': '^3.2.4', + '@vitest/ui': '^3.2.4', + 'aws-cdk': '^2.1033.0', + 'aws-cdk-lib': '^2.230.0', + 'cdk-nag': '^2.37.55', + constructs: '^10.4.3', + eslint: '^9.32.0', + 'eslint-config-prettier': '^10.1.8', + 'eslint-plugin-import': '^2.32.0', + 'fast-glob': '^3.3.3', + jiti: '2.5.1', + 'jsonc-eslint-parser': '^2.4.0', + nx: '22.1.3', + prettier: '^3.6.2', + // FIXME: [MI-251] Rolldown is still in beta. We pin the version and can upgrade with precaution. + rolldown: '1.0.0-beta.53', + 'store-parameters': '^1.1.3', + tslib: '^2.8.1', + tsx: '^4.21.0', + typescript: '~5.9.2', + vite: '^7.2.6', + vitest: '^3.2.4', + }, + workspaces: ['application', 'clients', 'libs/*', 'services/*'], + packageManager: + 'yarn@4.12.0+sha512.f45ab632439a67f8bc759bf32ead036a1f413287b9042726b7cc4818b7b49e14e9423ba49b18f9e06ea4941c1ad062385b1d8760a8d5091a1a31e5f6219afca8', +} as const; diff --git a/packages/nx-cdk/src/generators/helpers/configs/tsConfigs.ts b/packages/nx-cdk/src/generators/helpers/configs/tsConfigs.ts new file mode 100644 index 0000000..71c478d --- /dev/null +++ b/packages/nx-cdk/src/generators/helpers/configs/tsConfigs.ts @@ -0,0 +1,49 @@ +interface TsConfig { + extends: string; + compilerOptions?: Record; + files?: string[]; + include: string[]; + exclude?: string[]; + references: Array>; +} + +const BASE_CONFIG = '@aligent/ts-code-standards/tsconfigs-extend'; + +export const TS_CONFIG_JSON: TsConfig = { + extends: BASE_CONFIG, + files: [], + include: [], + references: [], +} as const; + +export const TS_CONFIG_LIB_JSON: TsConfig = { + extends: BASE_CONFIG, + compilerOptions: { + baseUrl: '.', + rootDir: 'src', + outDir: 'dist', + tsBuildInfoFile: 'dist/tsconfig.lib.tsbuildinfo', + types: ['node'], + }, + include: ['src/**/*.ts'], + exclude: ['vite.config.mjs', 'src/**/*.spec.ts', 'src/**/*.test.ts'], + references: [], +} as const; + +export const TS_CONFIG_SPEC_JSON: TsConfig = { + extends: BASE_CONFIG, + compilerOptions: { + outDir: './out-tsc/vitest', + types: ['vitest/globals', 'vitest/importMeta', 'vite/client', 'node', 'vitest'], + }, + include: [ + 'vite.config.mjs', + 'src/**/*.test.ts', + 'src/**/*.spec.ts', + 'src/**/*.d.ts', + 'tests/**/*.test.ts', + 'tests/**/*.spec.ts', + 'tests/**/*.d.ts', + ], + references: [{ path: './tsconfig.lib.json' }], +}; diff --git a/packages/nx-cdk/src/generators/helpers/utilities.ts b/packages/nx-cdk/src/generators/helpers/utilities.ts new file mode 100644 index 0000000..ad4c9f5 --- /dev/null +++ b/packages/nx-cdk/src/generators/helpers/utilities.ts @@ -0,0 +1,138 @@ +/* v8 ignore start */ +import { readJsonFile, readProjectConfiguration, Tree } from '@nx/devkit'; +import { existsSync } from 'fs'; +import { join } from 'path'; +import { Project } from 'ts-morph'; +import { PACKAGE_JSON } from './configs/packageJson'; +import { TS_CONFIG_JSON, TS_CONFIG_LIB_JSON, TS_CONFIG_SPEC_JSON } from './configs/tsConfigs'; + +interface PackageJsonInput { + name: string; + projectName: string; + version: string; + nodeVersion: string; +} + +interface Service { + name: string; + constant: string; + stack: string; +} + +export function constructPackageJsonFile(input: PackageJsonInput) { + const devDependencies = Object.fromEntries( + Object.entries({ + '@aligent/nx-cdk': input.version, + ...PACKAGE_JSON.devDependencies, + }).sort() + ); + + const packageJson = Object.fromEntries( + Object.entries({ + name: `@${input.name}/integrations`, + description: `${input.projectName} integrations mono-repository`, + version: input.version, + ...PACKAGE_JSON, + devDependencies, + engines: { node: `^${input.nodeVersion}` }, + }) + ); + + return packageJson; +} + +export function constructProjectTsConfigFiles(type: 'application' | 'service') { + const tsConfig = { ...TS_CONFIG_JSON }; + if (type === 'service') { + tsConfig.references = [{ path: './tsconfig.lib.json' }, { path: './tsconfig.spec.json' }]; + } + + return { + tsConfig, + tsConfigLib: { ...TS_CONFIG_LIB_JSON }, + tsConfigSpec: { ...TS_CONFIG_SPEC_JSON }, + }; +} + +function isPackageJsonWithVersion(obj: unknown): obj is { version: string } { + return ( + typeof obj === 'object' && + obj !== null && + 'version' in obj && + typeof obj.version === 'string' + ); +} + +export function getGeneratorVersion() { + const packagePath = join(__dirname, '../../../package.json'); + const packageJson = readJsonFile(packagePath); + + if (isPackageJsonWithVersion(packageJson)) { + return packageJson.version; + } + + throw new Error(`Unable to get generator version from ${packagePath}`); +} + +/** + * Automatically registers a service stack to the main CDK application's ApplicationStage. + * + * This function modifies the service-stacks.ts file by: + * 1. Adding import statements for the service's stack class and constants + * 2. Instantiating the stack within the ApplicationStage constructor + * + * @param tree - The Nx virtual file system tree + * @param service - Service information containing name, constant, and stack class names + * @param projectName - The name of the main application project to register the service to + * + * @throws {Error} If the ApplicationStage constructor cannot be found in service-stacks.ts + */ +export async function addServiceStackToMainApplication( + tree: Tree, + service: Service, + projectName: string +) { + const application = readProjectConfiguration(tree, projectName); + + if (application.root.includes('..')) { + throw new Error('Invalid application root path'); + } + + const stacksPath = join(tree.root, application.root, 'lib/service-stacks.ts'); + + if (!existsSync(stacksPath)) { + console.log('Service Stacks does not exist, skipping service stacks registration.'); + return; + } + + const project = new Project(); + const stackSource = project.addSourceFileAtPath(stacksPath); + + const applicationStage = stackSource.getClassOrThrow('ApplicationStage'); + const stageConstructors = applicationStage?.getConstructors(); + + if (!stageConstructors?.length) { + throw new Error('Unable to find main application stage constructor'); + } + + stackSource.addImportDeclaration({ + moduleSpecifier: `@services/${service.name}`, + namedImports: [service.constant, service.stack], + }); + + stageConstructors[0]?.addStatements( + `new ${service.stack}(this, ${service.constant}.NAME, { ...props, description: ${service.constant}.DESCRIPTION });` + ); + + await stackSource?.save(); +} + +/** + * Splits a kebab-case name into an array of capitalized parts. + * + * @param name - The kebab-case string to split (e.g., "my-service-name") + * @returns An array of strings with each part capitalized (e.g., ["My", "Service", "Name"]) + */ +export function splitInputName(name: string) { + return name.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)); +} diff --git a/packages/nx-cdk/src/generators/preset/files/.editorconfig.template b/packages/nx-cdk/src/generators/preset/files/.editorconfig.template new file mode 100644 index 0000000..24b98c1 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.editorconfig.template @@ -0,0 +1,18 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 100 + +[{package.json,*.yml,*.md}] +indent_size = 2 +indent_style = space + +[*.md] +trim_trailing_whitespace = false diff --git a/packages/nx-cdk/src/generators/preset/files/.git-hooks/pre-push.template b/packages/nx-cdk/src/generators/preset/files/.git-hooks/pre-push.template new file mode 100755 index 0000000..b99870a --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.git-hooks/pre-push.template @@ -0,0 +1,68 @@ +#!/bin/bash +# Script adapted from https://github.com/kaczor6418/git-hooks-example/blob/master/git-hooks/pre-commit + +# Support using VSCode to commit +# This loads nvm.sh and sets the correct PATH before running hook +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + +# Define colours for nicer CLI output +RED="\033[1;31m" +GREEN="\033[1;32m" +NO_COLOUR="\033[0m" + +echo -e "${GREEN}Executing git hook $0 $@${NO_COLOUR}" + +# Use the current Node version explicitly +nvm use + +# Get the list of staged changes +STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM) + +# Exclude files that shouldn't trigger pre-commit checks +# This is done here because `nx affected` doesn't look at task inputs +# when determining if a project is affected +EXCLUDED_FILES_REGEX='.*\.md$' # Ignore markdown files +EXCLUDED_FILES_REGEX+='|.*\/step-functions\/.*\.(yml|yaml)$' # Ignore step function yaml files +EXCLUDED_FILES_REGEX+='|^\/?([^\/]*)$' # Ignore all root-level files +AFFECTED_FILES=$(echo "$STAGED_FILES" | \ + grep -vE "$EXCLUDED_FILES_REGEX" | \ + paste -sd,) + +echo -e "${GREEN}\nAffected files: $AFFECTED_FILES\n${NO_COLOUR}" + +# Exit early if there are no affected files +if [ -z "$AFFECTED_FILES" ]; then + echo -e "${GREEN}No affected files found. Exiting pre-commit hook.${NO_COLOUR}" + exit 0 +fi + +# Prepare the affected commands for static analysis targets +AFFECTED_COMMAND="yarn nx affected --files=$AFFECTED_FILES --nxBail --tui=false" +commands=("$AFFECTED_COMMAND -t lint typecheck --parallel=3", "$AFFECTED_COMMAND -t test --configuration coverage") +failures=() + +# Loop over commands, execute and push failure message if we see one +for cmd in "${commands[@]}"; do + $cmd + exit_code=$? + + if [ "$exit_code" -eq 1 ]; then + failures+=("✖ Command ${RED}'${cmd}'${NO_COLOUR} failed with exit code ${exit_code} - see CLI output for errors") + elif [ "$exit_code" -eq 127 ]; then + failures+=("✖ Command ${RED}'${cmd}'${NO_COLOUR} failed with exit code ${exit_code} - check that the script exists in package.json") + elif [ "$exit_code" -ne 0 ]; then + failures+=("✖ Command ${RED}'${cmd}'${NO_COLOUR} failed with unexpected exit code ${exit_code}") + fi +done + +# Report overall success or failure +if [ ${#failures[@]} -ne 0 ]; then + echo -e "\n🚩${RED} Couldn't commit changes dues to the following errors: ${NO_COLOUR}" + + for report in "${failures[@]}"; do + echo -e $report; + done + + exit 1 +fi diff --git a/packages/nx-cdk/src/generators/preset/files/.github/CODEOWNERS.template b/packages/nx-cdk/src/generators/preset/files/.github/CODEOWNERS.template new file mode 100644 index 0000000..261386d --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.github/CODEOWNERS.template @@ -0,0 +1,3 @@ +# Both Microservice and DevOps teams own everything in this repo +# We'll review this in few months time and adjust when needed +* @aligent/microservices @aligent/devops diff --git a/packages/nx-cdk/src/generators/preset/files/.github/dependabot.yml.template b/packages/nx-cdk/src/generators/preset/files/.github/dependabot.yml.template new file mode 100644 index 0000000..439d325 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.github/dependabot.yml.template @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: 'npm' + directory: '/' + schedule: + interval: 'monthly' + open-pull-requests-limit: 10 diff --git a/packages/nx-cdk/src/generators/preset/files/.github/workflows/ci-cd.yml.template b/packages/nx-cdk/src/generators/preset/files/.github/workflows/ci-cd.yml.template new file mode 100644 index 0000000..bd61d2a --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.github/workflows/ci-cd.yml.template @@ -0,0 +1,27 @@ +name: CI/CD Pipeline + +on: + pull_request: + branches: + - '**' + push: + branches: + - staging + - production + +jobs: + code-quality: + name: 🕵️‍♀️ Code Quality Check + uses: aligent/workflows/.github/workflows/node-pr.yml@main + with: + skip-format: false + + deploy: + name: Deploy to AWS + uses: aligent/workflows/.github/workflows/aws-cdk-deploy.yml@main + with: + cdk-stack-name: ${{ vars.STACK_NAME }} + aws-access-key-id: ${{ vars.AWS_ACCESS_KEY_ID }} + deploy: true + secrets: + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/packages/nx-cdk/src/generators/preset/files/.gitignore.template b/packages/nx-cdk/src/generators/preset/files/.gitignore.template new file mode 100644 index 0000000..f4350b8 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.gitignore.template @@ -0,0 +1,62 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# Ignore everything by default +* + +# Project standard configurations +!**/*.md +!.git-hooks +!.git-hooks/* +!.github +!.github/* +!.github/**/* +!.editorconfig +!.gitignore +!.nvmrc +!.prettierignore +!cdk-config.yml +!eslint.config.mjs +!LICENSE +!nx.json +!package.json +!prettier.config.mjs +!rolldown.config.base.mjs +!tsconfig.json +!vitest.global.setup.mjs +!vitest.config.base.mjs + +# Package manager +!.yarn +!.yarn/patches +!.yarn/plugins +!.yarn/plugins/* +!.yarn/plugins/**/* +!.yarn/releases +!.yarn/sdks +!.yarn/versions +!.yarnrc.yml +!yarn.lock + +# Application +!application +!application/* +!application/**/* +!collection +!collection/* +!collection/**/* +!docs +!docs/* +!docs/**/* +!libs +!libs/* +!libs/**/* +!services +!services/* +!services/**/* + +# Test and bundle artifacts +**/cdk.out +**/dist +**/coverage + +# Environment files +*.env diff --git a/packages/nx-cdk/src/generators/preset/files/.nvmrc.template b/packages/nx-cdk/src/generators/preset/files/.nvmrc.template new file mode 100644 index 0000000..1b29d17 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.nvmrc.template @@ -0,0 +1 @@ +v<%= nodeVersion %> diff --git a/packages/nx-cdk/src/generators/preset/files/.prettierignore.template b/packages/nx-cdk/src/generators/preset/files/.prettierignore.template new file mode 100644 index 0000000..4bf4836 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.prettierignore.template @@ -0,0 +1,10 @@ +# Add files here to ignore them from prettier formatting + +# Build and test artifacts +**/dist +**/coverage + +# Tools, misc and autogenerated files +.nx +**/tsconfig.* +yarn.lock diff --git a/packages/nx-cdk/src/generators/preset/files/.yarnrc.yml.template b/packages/nx-cdk/src/generators/preset/files/.yarnrc.yml.template new file mode 100644 index 0000000..f3a90a9 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/.yarnrc.yml.template @@ -0,0 +1,6 @@ +nodeLinker: node-modules + +plugins: + - checksum: e5e6e2885ab0e6521b70b0af7c6d8ca2c75dcae2403706fc4600a783b339a6530a476dafb9450c9436ca4050eb6bdee9b62e6e2cebfecf1e81dd709a2480dc07 + path: .yarn/plugins/@yarnpkg/plugin-engines.cjs + spec: 'https://raw.githubusercontent.com/devoto13/yarn-plugin-engines/main/bundles/%40yarnpkg/plugin-engines.js' diff --git a/packages/nx-cdk/src/generators/preset/files/LICENSE.template b/packages/nx-cdk/src/generators/preset/files/LICENSE.template new file mode 100644 index 0000000..26f3f77 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/LICENSE.template @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Aligent + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/nx-cdk/src/generators/preset/files/README.md.template b/packages/nx-cdk/src/generators/preset/files/README.md.template new file mode 100644 index 0000000..fb145b3 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/README.md.template @@ -0,0 +1,77 @@ +# <%= projectName %> Integrations + +A monorepo containing integration services that support the <%= projectName %> project. This repository manages the deployment of microservices and their shared infrastructure using AWS CDK. + +## Overview + + + +## Services + +Services deployment are managed by the main [CDK Application](./application/README.md) + + + + +## Project Structure + +``` +<%= folderName %>/ +├── application/ # CDK Application & orchestration +│ ├── bin/main.ts # CDK App entry point (development/staging/production stages) +│ ├── lib/ # Service stack composition +│ └── cdk.json # CDK configuration +│ +├── services/ # Microservices workspace +│ +├── nx.json # Nx monorepo configuration +├── rolldown.config.base.mjs # Base Lambda bundling config +├── vitest.config.base.mjs # Base test configuration +└── eslint.config.mjs # ESLint configuration +``` + +## Getting Started + +### Prerequisites + +- Node.js <%= nodeVersion %> (see [.nvmrc](.nvmrc)) +- Yarn 4.12.0+ +- AWS CLI configured with appropriate credentials + +### Installation + +```bash +# Use correct Node version +nvm use + +# Install dependencies +yarn install +``` + +## Contributing + +We follow [trunk-based development framework](https://trunkbaseddevelopment.com/) as a start and will evolve depending on our need. + +1. Create new branch from `main` +2. Make your changes following code standards +3. Ensure your changes pass linting, type checks and testes +4. Submit a pull request back to `main` +5. For deployment, submit a pull request from `main` to `staging` or `production` + +## Adding New Services + +To add a new service to the monorepo: + +1. Use the Aligent CDK generator `@aligent/nx-cdk` +2. Add service infrastructure in + - `services/{service-name}/src/index.ts` + - `services/{service-name}/src/infra/` +3. Add Lambda handlers in `services/{service-name}/src/runtime/handlers/` + +## License + +MIT + +## Support + +For questions or issues, please contact the Aligent Microservices guild. diff --git a/packages/nx-cdk/src/generators/preset/files/application/README.md.template b/packages/nx-cdk/src/generators/preset/files/application/README.md.template new file mode 100644 index 0000000..dd1eadb --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/README.md.template @@ -0,0 +1,61 @@ +# Application + +This application manages the deployment of microservices and their shared infrastructure. + +## Configuration + +### Environment Parameters + +Parameters are managed through the `parameters/.env.csv` file by default + +```bash +# Pull down parameters from the playground environment to .env.csv +yarn nx run application:parameters + +# Update parameters from .env.csv +yarn nx run application:parameters:import + +# Custom filename and parameter path can be passed in as arguments +yarn nx run application:parameters --file .env.dev.csv --path /my/dev/path +``` + +## Deployment + +### Using yarn script from workspace root (Recommended) + +```bash +# Synthesize templates +yarn pg:synth + +# Deploy to playground +yarn pg:deploy +``` + +### Direct Nx Commands + +```bash +yarn nx run application:cdk +``` + +## Testing + +### Mock Services + +The application may include mock services for testing integrations without external dependencies. + + + +Change the value of the `/application/dev/url` SSM Parameter to switch between real and mock endpoints + +### Local Development + +```bash +# Type checking +yarn typecheck + +# Testing +yarn test + +# Linting +yarn lint +``` diff --git a/packages/nx-cdk/src/generators/preset/files/application/_internal/log-group-defaults-injector.ts.template b/packages/nx-cdk/src/generators/preset/files/application/_internal/log-group-defaults-injector.ts.template new file mode 100644 index 0000000..c20552d --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/_internal/log-group-defaults-injector.ts.template @@ -0,0 +1,100 @@ +import { RemovalPolicy, type IPropertyInjector } from 'aws-cdk-lib'; +import { LogGroup, RetentionDays, type LogGroupProps } from 'aws-cdk-lib/aws-logs'; + +interface Config { + duration: 'SHORT' | 'MEDIUM' | 'LONG'; +} + +/** + * Property injector for CloudWatch Log Groups with configuration-aware defaults + * + * Applies configuration-specific retention policies and removal settings to log groups. + * Different configurations balance between cost optimization and data retention needs. + * + * @example + * ```typescript + * // Apply configuration-specific defaults + * PropertyInjectors.of(scope).add( + * new LogGroupDefaultsInjector({ duration: 'SHORT' }).withProps({ + * logGroupName: '/custom/log/group', + * }) + * ); + * + * // Log groups automatically inherit configuration defaults + * new LogGroup(stack, 'MyLogGroup', { + * // retention and removal policy applied automatically + * }); + * ``` + * + * @see https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_logs.LogGroup.html + */ +export class LogGroupDefaultsInjector implements IPropertyInjector { + readonly constructUniqueId = LogGroup.PROPERTY_INJECTION_ID; + private readonly config: Config; + private defaultProps: LogGroupProps; + + /** + * Creates a new LogGroupDefaultsInjector + * + * @param config - Configuration identifier used to select appropriate defaults. + */ + constructor(config: Config) { + const props = retentionProperties(config.duration); + this.config = { ...config }; + this.defaultProps = { ...props }; + } + + /** + * Creates a new injector instance with additional properties + * + * Returns a new injector that inherits the current configuration but includes + * additional properties that override the configuration defaults. + * + * @param props - Additional properties to merge with configuration defaults + * @returns A new injector instance with merged properties + * + * @example + * ```typescript + * const customInjector = new LogGroupDefaultsInjector({ duration: 'SHORT' }) + * .withProps({ + * logGroupName: '/aws/lambda/custom', + * retention: RetentionDays.ONE_MONTH, + * }); + * ``` + */ + public withProps(props: LogGroupProps) { + const modifiedInjector = new LogGroupDefaultsInjector(this.config); + modifiedInjector.defaultProps = { ...this.defaultProps, ...props }; + return modifiedInjector; + } + + /** + * Injects configuration-appropriate defaults into log group properties + * + * Merges configuration-specific retention and removal policies with user-provided properties. + * + * @param originalProps - Properties provided when creating the log group + * @param context - CDK injection context containing construct information + * @returns Merged properties with injected defaults + */ + public inject(originalProps: LogGroupProps) { + return { ...this.defaultProps, ...originalProps }; + } +} + +/** + * Get duration-specific log group properties + * + * @param duration - The duration to get the log group properties for + * @returns The log group properties for the duration + */ +function retentionProperties(duration: 'SHORT' | 'MEDIUM' | 'LONG') { + switch (duration) { + case 'SHORT': + return { retention: RetentionDays.ONE_WEEK, removalPolicy: RemovalPolicy.DESTROY }; + case 'MEDIUM': + return { retention: RetentionDays.SIX_MONTHS, removalPolicy: RemovalPolicy.DESTROY }; + default: + return { retention: RetentionDays.TWO_YEARS, removalPolicy: RemovalPolicy.RETAIN }; + } +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/_internal/microservice-checks.ts.template b/packages/nx-cdk/src/generators/preset/files/application/_internal/microservice-checks.ts.template new file mode 100644 index 0000000..79c7151 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/_internal/microservice-checks.ts.template @@ -0,0 +1,58 @@ +import { CfnResource } from 'aws-cdk-lib'; +import { NagMessageLevel, NagPack, rules, type NagPackProps } from 'cdk-nag'; +import type { IConstruct } from 'constructs'; + +/** + * Microservice Checks are a compilation of rules to validate infrastructure-as-code template + * against recommended practices using the cdk-nag library. + * + * @see https://github.com/cdk-patterns/cdk-nag/ + * + * @example + * const app = new App(); + * const stack = new Stack(app, 'MyStack'); + * Aspects.of(stack).add(new MicroservicesChecks()); + */ +export class MicroserviceChecks extends NagPack { + constructor(props?: NagPackProps) { + super(props); + this.packName = 'Microservices'; + } + + public visit(node: IConstruct) { + if (node instanceof CfnResource) { + this.applyRule({ + info: 'The Lambda function does not have an explicit memory value configured.', + explanation: + "Lambda allocates CPU power in proportion to the amount of memory configured. By default, your functions have 128 MB of memory allocated. You can increase that value up to 10 GB. With more CPU resources, your Lambda function's duration might decrease. You can use tools such as AWS Lambda Power Tuning to test your function at different memory settings to find the one that matches your cost and performance requirements the best.", + level: NagMessageLevel.ERROR, + rule: rules.lambda.LambdaDefaultMemorySize, + node: node, + }); + this.applyRule({ + info: 'The Lambda function does not have an explicitly defined timeout value.', + explanation: + 'Lambda functions have a default timeout of 3 seconds. If your timeout value is too short, Lambda might terminate invocations prematurely. On the other side, setting the timeout much higher than the average execution may cause functions to execute for longer upon code malfunction, resulting in higher costs and possibly reaching concurrency limits depending on how such functions are invoked. You can also use AWS Lambda Power Tuning to test your function at different timeout settings to find the one that matches your cost and performance requirements the best.', + level: NagMessageLevel.ERROR, + rule: rules.lambda.LambdaDefaultTimeout, + node: node, + }); + this.applyRule({ + info: 'The Lambda function does not have tracing set to Tracing.ACTIVE.', + explanation: + 'When a Lambda function has ACTIVE tracing, Lambda automatically samples invocation requests, based on the sampling algorithm specified by X-Ray.', + level: NagMessageLevel.ERROR, + rule: rules.lambda.LambdaTracing, + node: node, + }); + this.applyRule({ + info: 'The CloudWatch Log Group does not have an explicit retention policy defined.', + explanation: + 'By default, logs are kept indefinitely and never expire. You can adjust the retention policy for each log group, keeping the indefinite retention, or choosing a retention period between one day and 10 years. For Lambda functions, this applies to their automatically created CloudWatch Log Groups.', + level: NagMessageLevel.ERROR, + rule: rules.cloudwatch.CloudWatchLogGroupRetentionPeriod, + node: node, + }); + } + } +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/_internal/nodejs-function-defaults-injector.ts.template b/packages/nx-cdk/src/generators/preset/files/application/_internal/nodejs-function-defaults-injector.ts.template new file mode 100644 index 0000000..da6391c --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/_internal/nodejs-function-defaults-injector.ts.template @@ -0,0 +1,110 @@ +import { type IPropertyInjector } from 'aws-cdk-lib'; +import { Runtime, Tracing } from 'aws-cdk-lib/aws-lambda'; +import { NodejsFunction, type NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs'; + +interface Config { + runtime: Runtime; + sourceMap?: boolean; +} + +/** + * Property injector for Node.js Lambda functions with configuration-aware defaults + * + * Applies configuration-specific bundling and runtime settings to Lambda functions. + * Different configurations can optimize for different priorities such as build speed, + * bundle size, or debugging capabilities. + * + * @example + * ```typescript + * // Apply configuration-specific defaults + * PropertyInjectors.of(scope).add( + * new NodeJsFunctionDefaultsInjector({ + * sourceMaps: true, + * esm: true, + * minify: true, + * }).withProps({ + * timeout: Duration.seconds(30), + * memorySize: 256, + * }) + * ); + * + * // Functions automatically inherit configuration defaults + * new Function(stack, 'MyFunction', { + * code: Code.fromAsset('src/lambda'), + * handler: 'index.handler', + * // bundling and runtime config applied automatically + * }); + * ``` + * + * @see https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.NodejsFunction.html + */ +export class NodeJsFunctionDefaultsInjector implements IPropertyInjector { + public readonly constructUniqueId = NodejsFunction.PROPERTY_INJECTION_ID; + private readonly config: Required; + private defaultProps: NodejsFunctionProps; + + /** + * Creates a new NodeJsFunctionDefaultsInjector + * + * @param config - Configuration identifier used to select appropriate defaults. Uses production defaults if not specified. + */ + constructor(config: Config) { + this.config = { ...config, sourceMap: config.sourceMap || true }; + this.defaultProps = { runtime: config.runtime, tracing: Tracing.ACTIVE }; + } + + /** + * Creates a new injector instance with additional properties + * + * Returns a new injector that inherits the current configuration but includes + * additional properties that override the configuration defaults. + * + * @param props - Additional properties to merge with configuration defaults + * @returns A new injector instance with merged properties + * + * @example + * ```typescript + * const customInjector = new NodeJsFunctionDefaultsInjector({ + * sourceMaps: false, + * }) + * .withProps({ + * timeout: Duration.minutes(5), + * memorySize: 1024, + * }); + * ``` + * + * TODO: Provide a nice way to inherit global properties from previous injectors + */ + public withProps(props: NodejsFunctionProps) { + const modifiedInjector = new NodeJsFunctionDefaultsInjector(this.config); + modifiedInjector.defaultProps = { ...this.defaultProps, ...props }; + return modifiedInjector; + } + + /** + * Injects configuration-appropriate defaults into Lambda function properties + * + * Merges configuration-specific defaults with user-provided properties, + * automatically configuring bundling options and runtime settings. + * + * @param originalProps - Properties provided when creating the function + * @returns Merged properties with injected defaults + */ + public inject(originalProps: NodejsFunctionProps) { + // The NodeJsFunction constructor pre-sets runtime to 16.x or LATEST depending on feature flags + // We assume that using this injector means you want to standardise the runtime across all lambdas + const props = { + ...this.defaultProps, + ...originalProps, + runtime: this.defaultProps.runtime, + }; + + // If source maps are enabled in our bundling, add the required NODE_OPTIONS flag to the environment + const environment = { + ...props.environment, + ...(this.config.sourceMap ? { NODE_OPTIONS: '--enable-source-maps' } : {}), + }; + + return { ...props, environment }; + } +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/_internal/step-function-defaults-injector.ts.template b/packages/nx-cdk/src/generators/preset/files/application/_internal/step-function-defaults-injector.ts.template new file mode 100644 index 0000000..03b2380 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/_internal/step-function-defaults-injector.ts.template @@ -0,0 +1,126 @@ +import { type InjectionContext, type IPropertyInjector } from 'aws-cdk-lib'; +import { LogGroup } from 'aws-cdk-lib/aws-logs'; +import { + LogLevel, + StateMachine, + StateMachineType, + type StateMachineProps, +} from 'aws-cdk-lib/aws-stepfunctions'; +import type { Construct } from 'constructs'; + +type StepFunctionDefaults = Omit; + +/** + * Property injector for Step Functions with configuration-aware defaults + * + * Applies configuration-specific settings to Step Functions. All configurations enable + * X-Ray tracing by default for observability. For EXPRESS state machines, automatically + * creates log groups and configures comprehensive logging. + * + * @example + * ```typescript + * // Apply configuration-specific defaults + * PropertyInjectors.of(scope).add( + * new StepFunctionDefaultsInjector('dev').withProps({ + * timeout: Duration.minutes(30), + * }) + * ); + * + * // Step Functions automatically inherit defaults + * new StateMachine(stack, 'MyWorkflow', { + * stateMachineType: StateMachineType.EXPRESS, + * definitionBody: DefinitionBody.fromFile('workflow.asl.yaml'), + * // tracing enabled and logging configured automatically for EXPRESS + * }); + * ``` + * + * @see https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_stepfunctions.StateMachine.html + */ +export class StepFunctionDefaultsInjector implements IPropertyInjector { + public readonly constructUniqueId = StateMachine.PROPERTY_INJECTION_ID; + private readonly config: Record; + private defaultProps: StateMachineProps; + + /** + * Creates a new StepFunctionDefaultsInjector + * + * @param config - Configuration identifier (currently unused but maintained for consistency). + * All configurations enable tracing by default. + */ + constructor(config: Record = {}) { + this.config = { ...config }; + this.defaultProps = { tracingEnabled: true }; + } + + /** + * Creates a new injector instance with additional properties + * + * Returns a new injector that inherits the current configuration but includes + * additional properties that override the configuration defaults. + * + * @param props - Additional properties to merge with configuration defaults + * @returns A new injector instance with merged properties + * + * @example + * ```typescript + * const customInjector = new StepFunctionDefaultsInjector('prod') + * .withProps({ + * timeout: Duration.hours(1), + * stateMachineName: 'custom-workflow', + * }); + * ``` + */ + public withProps(props: StateMachineProps) { + const modifiedInjector = new StepFunctionDefaultsInjector(this.config); + modifiedInjector.defaultProps = { ...this.defaultProps, ...props }; + return modifiedInjector; + } + + /** + * Injects configuration-appropriate defaults into Step Function properties + * + * Enables X-Ray tracing for all state machines. For EXPRESS state machines, + * automatically creates log groups and configures comprehensive logging. + * + * @param originalProps - Properties provided when creating the state machine + * @param context - CDK injection context containing construct information + * @returns Merged properties with injected defaults and logging configuration + */ + public inject(originalProps: StateMachineProps, context: InjectionContext) { + // Prepare logging configuration for EXPRESS step functions + const logging = expressLogProperties(context.scope, context.id, originalProps); + return { ...this.defaultProps, ...originalProps, ...logging }; + } +} + +/** + * Build the logging configuration for an express step function, respecting + * existing logging configuration. + * + * @param machineScope - The scope of the step function. + * @param machineId - The id of the step function. + * @param props - The properties for the step function. + * @returns The logging configuration for an express step function + */ +function expressLogProperties( + machineScope: Construct, + machineId: string, + props: StepFunctionDefaults +) { + if (props.stateMachineType !== StateMachineType.EXPRESS) { + return {}; + } + + // Create a new log group if one is not provided + const logGroup = + props.logs?.destination ?? new LogGroup(machineScope, `/aws/states/${machineId}`); + + return { + logs: { + destination: logGroup, + level: LogLevel.ALL, + includeExecutionData: true, + ...props.logs, + }, + }; +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/_internal/version-functions-aspect.ts.template b/packages/nx-cdk/src/generators/preset/files/application/_internal/version-functions-aspect.ts.template new file mode 100644 index 0000000..11983a7 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/_internal/version-functions-aspect.ts.template @@ -0,0 +1,74 @@ +import type { IAspect } from 'aws-cdk-lib'; +import { Function } from 'aws-cdk-lib/aws-lambda'; +import { + CfnStateMachineAlias, + CfnStateMachineVersion, + StateMachine, +} from 'aws-cdk-lib/aws-stepfunctions'; +import { IConstruct } from 'constructs'; + +/** + * Aspect that automatically adds versioning and aliases to Lambda and Step Functions + * + * Visits all constructs in the scope and automatically creates versions and aliases + * for supported resource types. This enables blue-green deployments, traffic shifting, + * and provides stable ARNs for external integrations. + * + * Currently supports: + * - Lambda Functions: Creates function aliases + * - Step Functions: Creates versions and aliases with 100% traffic routing + * + * @example + * ```typescript + * // Apply to entire app for automatic versioning + * Aspects.of(app).add(new VersionFunctionsAspect()); + * + * // Or with custom alias name + * Aspects.of(app).add(new VersionFunctionsAspect({ alias: 'PROD' })); + * ``` + */ +export class VersionFunctionsAspect implements IAspect { + /** + * Creates a new VersionFunctionsAspect + * + * @param props - Configuration for the aspect + * @param props.alias - Name for the alias to create. Defaults to 'LATEST' + */ + constructor( + private readonly props: { + alias: string; + } = { + alias: 'LATEST', + } + ) {} + + /** + * Visits a construct and applies versioning if it's a supported resource type + * + * For Lambda Functions: Adds a function alias pointing to $LATEST + * For Step Functions: Creates a version and alias with 100% traffic routing + * + * @param node - The construct to potentially add versioning to + */ + visit(node: IConstruct): void { + if (node instanceof StateMachine) { + const version = new CfnStateMachineVersion(node, `Version`, { + stateMachineArn: node.stateMachineArn, + }); + + new CfnStateMachineAlias(node, `Alias`, { + name: this.props.alias, + routingConfiguration: [ + { + stateMachineVersionArn: version.attrArn, + weight: 100, + }, + ], + }); + } + + if (node instanceof Function) { + node.addAlias(this.props.alias); + } + } +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/bin/main.ts.template b/packages/nx-cdk/src/generators/preset/files/application/bin/main.ts.template new file mode 100644 index 0000000..e42fea6 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/bin/main.ts.template @@ -0,0 +1,72 @@ +#!/usr/bin/env node +import { App, Aspects, Tags } from 'aws-cdk-lib'; +import { Runtime } from 'aws-cdk-lib/aws-lambda'; +import { ApplicationStage } from '../lib/service-stacks.js'; + +// TODO [MI-277] Pull this out to constructs repo so we can import and use later +import { LogGroupDefaultsInjector } from '../_internal/log-group-defaults-injector.js'; +import { MicroserviceChecks } from '../_internal/microservice-checks.js'; +import { NodeJsFunctionDefaultsInjector } from '../_internal/nodejs-function-defaults-injector.js'; +import { StepFunctionDefaultsInjector } from '../_internal/step-function-defaults-injector.ts'; +import { VersionFunctionsAspect } from '../_internal/version-functions-aspect.js'; + +const APPLICATION_CONTEXT = { APPLICATION_OWNER: 'aligent' } as const; + +const app = new App({ + context: APPLICATION_CONTEXT, + propertyInjectors: [ + new NodeJsFunctionDefaultsInjector({ runtime: <%= nodeRuntime %> }), + new StepFunctionDefaultsInjector(), + ], +}); +Tags.of(app).add('OWNER', APPLICATION_CONTEXT.APPLICATION_OWNER); + +/** + * Static Stage Creation Approach + * + * We use static stage creation (explicitly defining development, staging, production) for several reasons: + * + * 1. **Predictability**: All stages are known at synthesis time, making the CDK app + * behavior deterministic and easier to reason about. + * + * 2. **Type Safety**: Static definitions provide better IDE support, autocompletion, + * and compile-time type checking for stage-specific configurations. + * + * 3. **Explicit Configuration**: Each stage's unique settings (e.g., log retention + * durations, aspects, property injectors) are clearly visible in the code without + * needing to trace through dynamic logic. + * + * 4. **Simpler Deployment**: CDK can synthesize all stages in a single pass without + * requiring runtime context lookups or conditional logic. + * + * 5. **CI/CD Integration**: Static stages integrate seamlessly with standard CI/CD + * pipelines where environment configuration is managed externally. + * + * @see {@link https://dev.to/aws-heroes/how-to-use-aws-cdk-stage-and-when-to-choose-static-vs-dynamic-stack-creation-35h|Static vs Dynamic Stack Creation} + * + * @remarks Property Injector Behavior + * Property injectors are applied based on their class type and will only execute once per + * construct tree. When the same injector type is defined at both app and stage levels, the + * stage-level injector takes precedence and overrides the app-level configuration. + */ +const development = new ApplicationStage(app, 'development', { + propertyInjectors: [new LogGroupDefaultsInjector({ duration: 'SHORT' })], +}); +Aspects.of(development).add(new MicroserviceChecks()); + +const staging = new ApplicationStage(app, 'staging', { + propertyInjectors: [new LogGroupDefaultsInjector({ duration: 'MEDIUM' })], +}); +Aspects.of(staging).add(new MicroserviceChecks()); + +const production = new ApplicationStage(app, 'production', { + propertyInjectors: [new LogGroupDefaultsInjector({ duration: 'LONG' })], +}); +Aspects.of(production).add(new MicroserviceChecks()); + +/** + * This aspect ensures all Lambda functions and Step Functions in production + * are automatically versioned and have a stable 'live' alias pointing to the + * current version, enabling zero-downtime deployments. + */ +Aspects.of(production).add(new VersionFunctionsAspect()); diff --git a/packages/nx-cdk/src/generators/preset/files/application/cdk.context.json.template b/packages/nx-cdk/src/generators/preset/files/application/cdk.context.json.template new file mode 100644 index 0000000..349dbe6 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/cdk.context.json.template @@ -0,0 +1,4 @@ +{ + "cli-telemetry": false, + "acknowledged-issue-numbers": [34892] +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/cdk.json.template b/packages/nx-cdk/src/generators/preset/files/application/cdk.json.template new file mode 100644 index 0000000..38e1a3a --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/cdk.json.template @@ -0,0 +1,92 @@ +{ + "app": "npx tsx bin/main.ts", + "watch": { + "include": ["**"], + "exclude": [ + "README.md", + "cdk*.json", + "**/*.d.ts", + "**/*.js", + "tsconfig.json", + "package*.json", + "yarn.lock", + "node_modules", + "test" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": ["aws", "aws-cn"], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": true, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true, + "@aws-cdk/core:enableAdditionalMetadataCollection": true, + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": false, + "@aws-cdk/aws-s3:setUniqueReplicationRoleName": true, + "@aws-cdk/aws-events:requireEventBusPolicySid": true, + "@aws-cdk/core:aspectPrioritiesMutating": true, + "@aws-cdk/aws-dynamodb:retainTableReplica": true, + "@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": true, + "@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": true, + "@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": true, + "@aws-cdk/aws-s3:publicAccessBlockedByDefault": true, + "@aws-cdk/aws-lambda:useCdkManagedLogGroup": true + } +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/eslint.config.mjs.template b/packages/nx-cdk/src/generators/preset/files/application/eslint.config.mjs.template new file mode 100644 index 0000000..fef103b --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/eslint.config.mjs.template @@ -0,0 +1,3 @@ +import baseConfig from '../eslint.config.mjs'; + +export default [...baseConfig]; diff --git a/packages/nx-cdk/src/generators/preset/files/application/lib/service-stacks.ts.template b/packages/nx-cdk/src/generators/preset/files/application/lib/service-stacks.ts.template new file mode 100644 index 0000000..f3a481d --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/lib/service-stacks.ts.template @@ -0,0 +1,21 @@ +import { Stage, Tags, type StageProps } from 'aws-cdk-lib'; +import type { Construct } from 'constructs'; + +/** + * Application Stage + * + * This is the main entry point for the application. + * It is used to define context and compose service stacks. + * + * Service stacks are automatically instantiated here when generated using the service generator. + * Each service stack will be initialized with this stage as the parent scope, ensuring proper + * stack composition and resource organization within the CDK application. + */ +export class ApplicationStage extends Stage { + constructor(scope: Construct, id: string, props?: StageProps) { + super(scope, id, props); + Tags.of(this).add('STAGE', id); + + // Service stacks initialization + } +} diff --git a/packages/nx-cdk/src/generators/preset/files/application/package.json.template b/packages/nx-cdk/src/generators/preset/files/application/package.json.template new file mode 100644 index 0000000..288ed69 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/application/package.json.template @@ -0,0 +1,27 @@ +{ + "name": "application", + "type": "module", + "main": "./bin/main.ts", + "types": "./bin/main.ts", + "nx": { + "tags": [ + "scope:application" + ], + "targets": { + "cdk": { + "executor": "nx:run-commands", + "options": { + "color": true, + "command": "cdk", + "cwd": "{projectRoot}" + } + }, + "parameters": { + "executor": "nx:run-commands", + "options": { + "path": "/application/dev" + } + } + } + } +} diff --git a/packages/nx-cdk/src/generators/preset/files/cdk-config.yml.template b/packages/nx-cdk/src/generators/preset/files/cdk-config.yml.template new file mode 100644 index 0000000..067c911 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/cdk-config.yml.template @@ -0,0 +1,16 @@ +cdk-pipe: + commands: + cdk: + bootstrap: yarn nx run application:cdk bootstrap + deploy: yarn nx run application:cdk deploy + synth: yarn nx run application:cdk synth + diff: yarn nx run application:cdk diff + npm: + checks: + lint: yarn lint + format: yarn lint # Formatting is controlled by the lint step, we turn this off in the pipeline anyway + install: yarn install --immutable + beforeScripts: + - yarn --version + afterScripts: + - echo "Deployment is completed" diff --git a/packages/nx-cdk/src/generators/preset/files/eslint.config.mjs.template b/packages/nx-cdk/src/generators/preset/files/eslint.config.mjs.template new file mode 100644 index 0000000..9e0486e --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/eslint.config.mjs.template @@ -0,0 +1,54 @@ +import { eslintConfigs } from '@aligent/ts-code-standards'; +import nxEslintPlugin from '@nx/eslint-plugin'; +import jsonParser from 'jsonc-eslint-parser'; + +const eslintBaseConfig = [ + ...eslintConfigs.base, + { + ignores: [ + '**/*.js', + '**/*.cjs', + '**/*.mjs', + '**/coverage', + '**/cdk.out', + '**/dist', + '**/out-tsc', + '**/vite.config.*.timestamp*', + '**/vitest.config.*.timestamp*', + ], + }, + { + files: ['**/*.ts'], + plugins: { '@nx': nxEslintPlugin }, + rules: { + '@nx/enforce-module-boundaries': [ + 'error', + { + allow: ['^.*/eslint(\\.base)?\\.config\\.[cm]?[jt]s$'], + enforceBuildableLibDependency: true, + depConstraints: [ + { + sourceTag: 'scope:application', + onlyDependOnLibsWithTags: ['scope:libs', 'scope:services'], + }, + { + sourceTag: 'scope:services', + onlyDependOnLibsWithTags: ['scope:libs', 'scope:services'], + }, + { + sourceTag: 'scope:libs', + onlyDependOnLibsWithTags: ['scope:libs'], + }, + ], + }, + ], + 'no-console': 'warn', + }, + }, + { + files: ['**/*.json'], + languageOptions: { parser: jsonParser }, + }, +]; + +export default eslintBaseConfig; diff --git a/packages/nx-cdk/src/generators/preset/files/prettier.config.mjs.template b/packages/nx-cdk/src/generators/preset/files/prettier.config.mjs.template new file mode 100644 index 0000000..1ed145e --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/prettier.config.mjs.template @@ -0,0 +1,3 @@ +import { prettierConfig } from '@aligent/ts-code-standards'; + +export default prettierConfig; diff --git a/packages/nx-cdk/src/generators/preset/files/rolldown.config.base.mjs.template b/packages/nx-cdk/src/generators/preset/files/rolldown.config.base.mjs.template new file mode 100644 index 0000000..725f4d4 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/rolldown.config.base.mjs.template @@ -0,0 +1,46 @@ +import fg from 'fast-glob'; +import { builtinModules } from 'node:module'; +import { extname, resolve } from 'node:path'; +import { defineConfig } from 'rolldown'; + +/** + * Prepare Rolldown config that bundles all typescript files in a single directory in to separate files + * This is used to bundle lambda handlers with their own dependencies for separate upload to AWS Lambda + * + * @param {string} subPath Relative path to the handlers directory + * @returns Rolldown config for multiple lambda handlers + */ +export function defineLambdaConfig(subPath) { + if (subPath.includes('..')) throw new Error('Invalid path provided'); + const handlersPath = resolve(process.cwd(), subPath); + const handlers = fg.sync(`${handlersPath}/**/*.ts`); + + return handlers.map(handler => { + const bundledPath = handler.replace(`${handlersPath}/`, ''); + const entryName = bundledPath.replace(extname(bundledPath), ''); + + return defineConfig({ + input: { [entryName]: handler }, + platform: 'node', + tsconfig: 'tsconfig.lib.json', + logLevel: 'info', + watch: false, + external: [...builtinModules], + output: { + entryFileNames: '[name]/index.mjs', + format: 'esm', + // TODO: [MI-251] Support sourcemap enable/disable base on environment + sourcemap: true, + // FIXME: [MI-251] Rolldown is still in Beta and built-in minification is not production ready yet + minify: false, + legalComments: 'none', + inlineDynamicImports: true, + // TODO: [MI-251] Support shims only when needed instead consider looking at tsup, tsdown and rollup shims plugins + banner: `import { fileURLToPath } from 'node:url'; +import { dirname } from 'node:path'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename);`, + }, + }); + }); +} diff --git a/packages/nx-cdk/src/generators/preset/files/tsconfig.json.template b/packages/nx-cdk/src/generators/preset/files/tsconfig.json.template new file mode 100644 index 0000000..ad107c5 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/tsconfig.json.template @@ -0,0 +1,6 @@ +{ + "extends": "@aligent/ts-code-standards/tsconfigs-extend", + "compileOnSave": false, + "files": [], + "references": [{"path": "./application"}] +} diff --git a/packages/nx-cdk/src/generators/preset/files/vitest.config.base.mjs.template b/packages/nx-cdk/src/generators/preset/files/vitest.config.base.mjs.template new file mode 100644 index 0000000..9f64862 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/vitest.config.base.mjs.template @@ -0,0 +1,39 @@ +import { resolve } from 'node:path'; +import { defineConfig } from 'vitest/config'; + +// More information about mode: https://vite.dev/guide/env-and-mode.html#node-env-and-modes +export const vitestBaseConfig = defineConfig(({ command, mode }) => { + return { + test: { + globals: true, + watch: false, + environment: 'node', + reporters: ['default'], + coverage: { + provider: 'v8', + exclude: [ + 'node_modules/', + '**/types', + '*.mjs', + '**/__data__', + '**/dist', + '**/out-tsc', + ], + thresholds: { + branches: 80, + functions: 80, + lines: 80, + statements: 80, + }, + }, + include: [ + 'src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', + 'tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', + ], + setupFiles: [ + // Include the root setup file in all tests that extend this config + resolve(import.meta.dirname, './vitest.global.setup.mjs'), + ], + }, + }; +}); diff --git a/packages/nx-cdk/src/generators/preset/files/vitest.global.setup.mjs.template b/packages/nx-cdk/src/generators/preset/files/vitest.global.setup.mjs.template new file mode 100644 index 0000000..6fef67a --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/files/vitest.global.setup.mjs.template @@ -0,0 +1,109 @@ +import { beforeAll } from 'vitest' + +beforeAll(() => { + expect.addSnapshotSerializer( + replaceProperties({ property: [ + // Replace asset storage locations in Lambda function snapshots + 'Code.S3Bucket', + 'Code.S3Key', + // Replace asset storage locations in Step Function snapshots + 'DefinitionS3Location.Bucket', + 'DefinitionS3Location.Key' + ] }) + ); +}) + +const PLACEHOLDER = '[SNAPSHOT_PLACEHOLDER]'; +const isObject = (val) => !!val && typeof val === 'object'; + +// Helper function to traverse object and find properties to replace +const findPropertiesToReplace = ( + obj, + property, + path = [] +) => { + const results = []; + + for (const [key, value] of Object.entries(obj)) { + const currentPath = [...path, key]; + const fullPath = currentPath.join('.'); + + let shouldReplace = false; + + if (property instanceof RegExp) { + shouldReplace = property.test(fullPath); + } else if (Array.isArray(property)) { + shouldReplace = property.includes(fullPath); + } else { + shouldReplace = fullPath === property; + } + + if (shouldReplace && value !== PLACEHOLDER) { + results.push({ path: currentPath, value }); + } + + if (isObject(value)) { + results.push(...findPropertiesToReplace(value, property, currentPath)); + } + } + + return results; +}; + +// Helper function to set value at nested path +const setValueAtPath = (obj, path, value) => { + let current = obj; + + for (let i = 0; i < path.length - 1; i++) { + const key = path[i]; + if (!isObject(current[key])) { + current[key] = {}; + } + current = current[key]; + } + + current[path[path.length - 1]] = value; +}; + +/** + * Custom serializer for vitest snapshot tests + * Allows replacing properties in a snapshot with placeholder values. + * + * Properties to replace can be specified as a string, array of strings, or a single regular expression + * Nested properties can be specified using dot notation. + * + * @example + * ``` + * beforeAll(() => { + * expect.addSnapshotSerializer( + * // Will replace the value of Code: { S3Bucket: '...', S3Key: '...' } anywhere in the object structure + * replaceProperties({ property: ['Code.S3Bucket', 'Code.S3Key'] }) + * ); + * }) + * ``` + * + * @param {{ property: string | string[] | RegExp, placeholder?: string }} input + * @returns + */ +export const replaceProperties = ({ + property, + placeholder = PLACEHOLDER, +}) => { + return { + test(val) { + if (!isObject(val)) return false; + const propertiesToReplace = findPropertiesToReplace(val, property); + return propertiesToReplace.length > 0; + }, + serialize(val, config, indentation, depth, refs, printer) { + const clone = { ...val }; + const propertiesToReplace = findPropertiesToReplace(clone, property); + + for (const { path } of propertiesToReplace) { + setValueAtPath(clone, path, placeholder); + } + + return printer(clone, config, indentation, depth, refs); + }, + } +}; diff --git a/packages/nx-cdk/src/generators/preset/preset.spec.ts b/packages/nx-cdk/src/generators/preset/preset.spec.ts new file mode 100644 index 0000000..67218c9 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/preset.spec.ts @@ -0,0 +1,20 @@ +import { Tree, readNxJson } from '@nx/devkit'; +import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; + +import { presetGenerator } from './preset'; +import { PresetGeneratorSchema } from './schema'; + +describe('preset generator', () => { + let tree: Tree; + const options: PresetGeneratorSchema = { name: 'test', nodeVersion: '24.11.0' }; + + beforeEach(() => { + tree = createTreeWithEmptyWorkspace(); + }); + + it('should run successfully', async () => { + await presetGenerator(tree, options); + const config = readNxJson(tree); + expect(config).toBeDefined(); + }); +}); diff --git a/packages/nx-cdk/src/generators/preset/preset.ts b/packages/nx-cdk/src/generators/preset/preset.ts new file mode 100644 index 0000000..4c8f27b --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/preset.ts @@ -0,0 +1,45 @@ +import { formatFiles, generateFiles, Tree, updateNxJson, writeJson } from '@nx/devkit'; +import { join } from 'path'; +import { NX_JSON } from '../helpers/configs/nxJson'; +import { + constructPackageJsonFile, + constructProjectTsConfigFiles, + getGeneratorVersion, + splitInputName, +} from '../helpers/utilities'; +import { PresetGeneratorSchema } from './schema'; + +export async function presetGenerator(tree: Tree, options: PresetGeneratorSchema) { + const { name, destination, nodeVersion } = options; + const [nodeVersionMajor] = nodeVersion.split('.'); + const nameParts = splitInputName(name); + const projectName = nameParts.join(' '); + + generateFiles(tree, join(__dirname, 'files'), '.', { + ...options, + projectName, + folderName: destination || name, + nodeRuntime: `Runtime.NODEJS_${nodeVersionMajor}_X`, + template: '', + }); + + updateNxJson(tree, { ...NX_JSON }); + + const packageJson = constructPackageJsonFile({ + name: options.name, + projectName, + version: getGeneratorVersion(), + nodeVersion, + }); + writeJson(tree, 'package.json', packageJson); + + // Generate application's tsconfigs + const { tsConfig, tsConfigLib, tsConfigSpec } = constructProjectTsConfigFiles('application'); + writeJson(tree, 'application/tsconfig.json', tsConfig); + writeJson(tree, 'application/tsconfig.lib.json', tsConfigLib); + writeJson(tree, 'application/tsconfig.spec.json', tsConfigSpec); + + await formatFiles(tree); +} + +export default presetGenerator; diff --git a/packages/nx-cdk/src/generators/preset/schema.d.ts b/packages/nx-cdk/src/generators/preset/schema.d.ts new file mode 100644 index 0000000..931bf3f --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/schema.d.ts @@ -0,0 +1,7 @@ +/* v8 ignore start */ +export interface PresetGeneratorSchema { + name: string; + nodeVersion: string; + // FIXME: [MI-281] Add this into schema.json once we move to our own cli tool + destination?: string; +} diff --git a/packages/nx-cdk/src/generators/preset/schema.json b/packages/nx-cdk/src/generators/preset/schema.json new file mode 100644 index 0000000..1602429 --- /dev/null +++ b/packages/nx-cdk/src/generators/preset/schema.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/schema", + "$id": "Preset", + "title": "", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the project/application", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "What is the name of the project?", + "pattern": "^[a-z0-9-]+$", + "patternErrorMessage": "Project name must contain only lowercase alphanumeric characters and dashes" + }, + "nodeVersion": { + "type": "string", + "description": "The target Node.js version", + "$default": { + "$source": "argv", + "index": 1 + }, + "default": "24.11.0", + "x-prompt": "What is the target Node.js version the project?", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$", + "patternErrorMessage": "Node.js version must be a valid semantic version (semver), e.g. 22.10.0 or 24.10.0" + } + }, + "required": ["name"] +} diff --git a/packages/nx-cdk/src/generators/service/files/README.md.template b/packages/nx-cdk/src/generators/service/files/README.md.template new file mode 100644 index 0000000..f3d4fc2 --- /dev/null +++ b/packages/nx-cdk/src/generators/service/files/README.md.template @@ -0,0 +1,29 @@ +# <%= serviceName %> + +This is a CDK service generated using `@aligent/nx-cdk` for Nx. + +## Architecture + + + +# Technical Decisions + + + +## Development + +### Type Checking + +```bash +npx nx check-types <%= name %> +``` + +### Testing + +```bash +npx nx test <%= name %> +``` + +## Deployment + +This service is deployed as part of the CDK application. See the main README for deployment instructions. diff --git a/packages/nx-cdk/src/generators/service/files/eslint.config.mjs.template b/packages/nx-cdk/src/generators/service/files/eslint.config.mjs.template new file mode 100644 index 0000000..7577373 --- /dev/null +++ b/packages/nx-cdk/src/generators/service/files/eslint.config.mjs.template @@ -0,0 +1,20 @@ +import eslintPluginImport from 'eslint-plugin-import'; +import baseConfig from '../../eslint.config.mjs'; + +export default [ + ...baseConfig, + { + files: ['**/*.ts'], + plugins: { import: eslintPluginImport }, + rules: { + 'import/no-extraneous-dependencies': [ + 'warn', + { + optionalDependencies: false, + peerDependencies: false, + packageDir: ['.', '..', '../..'], + }, + ], + }, + }, +]; diff --git a/packages/nx-cdk/src/generators/service/files/package.json.template b/packages/nx-cdk/src/generators/service/files/package.json.template new file mode 100644 index 0000000..e439c3d --- /dev/null +++ b/packages/nx-cdk/src/generators/service/files/package.json.template @@ -0,0 +1,32 @@ +{ + "name": "<%= name %>", + "type": "module", + "main": "./src/index.ts", + "types": "./src/index.ts", + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts", + "default": "./src/index.ts" + }, + "./package.json": "./package.json" + }, + "bundleDependencies": [ + "clients" + ], + "nx": { + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "rolldown -c rolldown.config.mjs", + "color": true, + "cwd": "{projectRoot}" + } + } + }, + "tags": [ + "scope:services" + ] + } +} diff --git a/packages/nx-cdk/src/generators/service/files/rolldown.config.mjs.template b/packages/nx-cdk/src/generators/service/files/rolldown.config.mjs.template new file mode 100644 index 0000000..c76585c --- /dev/null +++ b/packages/nx-cdk/src/generators/service/files/rolldown.config.mjs.template @@ -0,0 +1,3 @@ +import { defineLambdaConfig } from '../../rolldown.config.base.mjs'; + +export default defineLambdaConfig('src/runtime/handlers'); diff --git a/packages/nx-cdk/src/generators/service/files/src/index.ts.template b/packages/nx-cdk/src/generators/service/files/src/index.ts.template new file mode 100644 index 0000000..7cdf080 --- /dev/null +++ b/packages/nx-cdk/src/generators/service/files/src/index.ts.template @@ -0,0 +1,75 @@ +import { Stack, StackProps, Stage, Tags } from 'aws-cdk-lib'; +import { Code } from 'aws-cdk-lib/aws-lambda'; +import { Construct } from 'constructs'; +import path from 'node:path'; + +/** +* @important +* Due to the immutable nature of CloudFormation, +* CDK will generate new CloudFormation template and deploy if you change stack name +*/ +export const <%= constant %> = { + NAME: '<%= name %>', + DESCRIPTION: '<%= name %> service description' +} as const; + +type Id = typeof <%= constant %>.NAME | (string & {}); +interface Props extends StackProps { + description: string; +} + +/** + * Entrypoint for the <%= name %> service + * + * Instantiate in a CDK Application Stage to deploy to AWS. + * + * Use 'resolve' helpers below when referencing lambda handlers, step function files etc. + */ +export class <%= stack %> extends Stack { + constructor(scope: Construct, id: Id, props?: Props) { + super(scope, id, props); + + const STAGE = Stage.of(this)?.stageName; + if (!STAGE) { + throw new Error('This construct must be used within a CDK Stage'); + } + + Tags.of(this).add('SERVICE', id); + } +} + +/** + * Resolves a path to infra assets relative to this stack + * + * @param assetPath - The path to the asset. + * @returns The resolved path. + */ +export function resolveAssetPath(assetPath: `${'infra/'}${string}`) { + return path.resolve(import.meta.dirname, assetPath); +} + +/** + * Return an object with the default bundled code asset and + * handler property for use with the NodejsFunction construct. + * + * @example + * ```ts + * new NodejsFunction(this, 'FetchData', { + * ...resolveLambdaHandler('runtime/handlers/fetch-data.ts'), + * }); + * ``` + * + * @param assetPath - The path to the typescript handler file. + * @returns The resolved bundled code path and handler name. + */ +export function resolveLambdaHandler(assetPath: `${'runtime/handlers/'}${string}${'.ts'}`) { + // Replace 'runtime/handlers/' with '..dist/' and remove the file extension + const bundledPath = assetPath.replace( + /^runtime\/handlers\/(?.*)\.ts$/, + '../dist/$' + ); + return { + code: Code.fromAsset(path.resolve(import.meta.dirname, bundledPath)), + handler: 'index.handler', + }; +} diff --git a/packages/nx-cdk/src/generators/service/files/src/infra/.gitkeep.template b/packages/nx-cdk/src/generators/service/files/src/infra/.gitkeep.template new file mode 100644 index 0000000..e69de29 diff --git a/packages/nx-cdk/src/generators/service/files/src/runtime/handlers/.gitkeep.template b/packages/nx-cdk/src/generators/service/files/src/runtime/handlers/.gitkeep.template new file mode 100644 index 0000000..e69de29 diff --git a/packages/nx-cdk/src/generators/service/files/src/runtime/lib/utils/.gitkeep.template b/packages/nx-cdk/src/generators/service/files/src/runtime/lib/utils/.gitkeep.template new file mode 100644 index 0000000..e69de29 diff --git a/packages/nx-cdk/src/generators/service/files/tests/__data__/.gitkeep.template b/packages/nx-cdk/src/generators/service/files/tests/__data__/.gitkeep.template new file mode 100644 index 0000000..e69de29 diff --git a/packages/nx-cdk/src/generators/service/files/vitest.config.mjs.template b/packages/nx-cdk/src/generators/service/files/vitest.config.mjs.template new file mode 100644 index 0000000..67fc241 --- /dev/null +++ b/packages/nx-cdk/src/generators/service/files/vitest.config.mjs.template @@ -0,0 +1,18 @@ +import { defineConfig, mergeConfig } from 'vitest/config'; +import { vitestBaseConfig } from '../../vitest.config.base.mjs'; + +export default defineConfig(configEnv => { + return mergeConfig( + vitestBaseConfig(configEnv), + defineConfig({ + cacheDir: '../../node_modules/.vite/<%= name %>', + test: { + env: { + NODE_ENV: 'test', + YOUR_ENV_VAR: 'environment-variable', + }, + unstubEnvs: true, + }, + }) + ); +}); diff --git a/packages/nx-cdk/src/generators/service/generator.spec.ts b/packages/nx-cdk/src/generators/service/generator.spec.ts new file mode 100644 index 0000000..b2c982a --- /dev/null +++ b/packages/nx-cdk/src/generators/service/generator.spec.ts @@ -0,0 +1,48 @@ +import { Tree } from '@nx/devkit'; +import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; +import { serviceGenerator } from './generator'; +import { ServiceGeneratorSchema } from './schema'; + +const application = { + name: 'application', + type: 'module', + main: './bin/main.ts', + types: './bin/main.ts', + nx: { tags: ['scope:application'] }, +}; + +describe('service generator', () => { + let tree: Tree; + beforeEach(() => { + tree = createTreeWithEmptyWorkspace(); + tree.write( + 'tsconfig.json', + `{ + "extends": "./tsconfig.base.json", + "compileOnSave": false, + "files": [], + "references": [] + }` + ); + tree.write('application/package.json', JSON.stringify(application)); + }); + + it('should run successfully', async () => { + const options: ServiceGeneratorSchema = { name: 'test' }; + await expect(serviceGenerator(tree, options)).resolves.not.toThrow(); + }); + + it('should add the project reference to tsconfig.json', async () => { + const options: ServiceGeneratorSchema = { name: 'test' }; + + await serviceGenerator(tree, options); + + const tsconfig = tree.read('tsconfig.json', 'utf-8'); + + assert.isNotNull(tsconfig); + + const references = JSON.parse(tsconfig).references; + + expect(references).toEqual([{ path: './services/test' }]); + }); +}); diff --git a/packages/nx-cdk/src/generators/service/generator.ts b/packages/nx-cdk/src/generators/service/generator.ts new file mode 100644 index 0000000..8c12dbc --- /dev/null +++ b/packages/nx-cdk/src/generators/service/generator.ts @@ -0,0 +1,60 @@ +import { formatFiles, generateFiles, Tree, updateJson, writeJson } from '@nx/devkit'; +import { join } from 'path'; +import { + addServiceStackToMainApplication, + constructProjectTsConfigFiles, + splitInputName, +} from '../helpers/utilities'; +import { ServiceGeneratorSchema } from './schema'; + +const SERVICES_FOLDER = 'services'; + +function addTsConfigReference(tree: Tree, referencePath: string) { + updateJson(tree, 'tsconfig.json', json => { + json.references ??= []; + + if (json.references.some((r: { path: string }) => r.path === referencePath)) { + throw new Error( + `You already have a library using the import path "${referencePath}". Make sure to specify a unique one.` + ); + } + + json.references.push({ path: referencePath }); + + return json; + }); +} + +export async function serviceGenerator(tree: Tree, options: ServiceGeneratorSchema) { + const projectRoot = `${SERVICES_FOLDER}/${options.name}`; + const nameParts = splitInputName(options.name); + + const constant = nameParts.map(name => name.toUpperCase()).join('_'); + const stack = `${nameParts.join('')}Stack`; + + if (!tree.exists(SERVICES_FOLDER)) { + tree.write(`${SERVICES_FOLDER}/.gitkeep`, ''); + } + + generateFiles(tree, join(__dirname, 'files'), projectRoot, { + ...options, + serviceName: nameParts.join(' '), + constant, + stack, + template: '', + }); + + // Generate service's tsconfigs + const { tsConfig, tsConfigLib, tsConfigSpec } = constructProjectTsConfigFiles('service'); + writeJson(tree, `${projectRoot}/tsconfig.json`, tsConfig); + writeJson(tree, `${projectRoot}/tsconfig.lib.json`, tsConfigLib); + writeJson(tree, `${projectRoot}/tsconfig.spec.json`, tsConfigSpec); + + // Integrate the new service with the root application + addTsConfigReference(tree, `./${projectRoot}`); + addServiceStackToMainApplication(tree, { name: options.name, constant, stack }, 'application'); + + await formatFiles(tree); +} + +export default serviceGenerator; diff --git a/packages/nx-cdk/src/generators/service/schema.d.ts b/packages/nx-cdk/src/generators/service/schema.d.ts new file mode 100644 index 0000000..f8c9385 --- /dev/null +++ b/packages/nx-cdk/src/generators/service/schema.d.ts @@ -0,0 +1,4 @@ +/* v8 ignore start */ +export interface ServiceGeneratorSchema { + name: string; +} diff --git a/packages/nx-cdk/src/generators/service/schema.json b/packages/nx-cdk/src/generators/service/schema.json new file mode 100644 index 0000000..013051f --- /dev/null +++ b/packages/nx-cdk/src/generators/service/schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/schema", + "$id": "ServiceGenerator", + "title": "Nx Generator for bootstrapping Serverless Framework services", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the service", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "What is the name of the service?", + "pattern": "^(?!.*[Ss]tack|.*[Ss]ervice).*$", + "patternErrorMessage": "Service name cannot contain '[Ss]tack' or '[Ss]ervice'" + } + }, + "required": ["name"] +} diff --git a/packages/nx-cdk/src/index.ts b/packages/nx-cdk/src/index.ts new file mode 100644 index 0000000..18e56bb --- /dev/null +++ b/packages/nx-cdk/src/index.ts @@ -0,0 +1,3 @@ +/* v8 ignore next 2 */ +export * from './generators/preset/preset'; +export * from './generators/service/generator'; diff --git a/packages/nx-cdk/tsconfig.json b/packages/nx-cdk/tsconfig.json new file mode 100644 index 0000000..9fa1b41 --- /dev/null +++ b/packages/nx-cdk/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": {}, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/nx-cdk/tsconfig.lib.json b/packages/nx-cdk/tsconfig.lib.json new file mode 100644 index 0000000..d7f7e3e --- /dev/null +++ b/packages/nx-cdk/tsconfig.lib.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.mjs", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/nx-cdk/tsconfig.spec.json b/packages/nx-cdk/tsconfig.spec.json new file mode 100644 index 0000000..bc3aad4 --- /dev/null +++ b/packages/nx-cdk/tsconfig.spec.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc" + }, + "include": ["vite.config.mjs", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/packages/nx-cdk/vite.config.mjs b/packages/nx-cdk/vite.config.mjs new file mode 100644 index 0000000..debc737 --- /dev/null +++ b/packages/nx-cdk/vite.config.mjs @@ -0,0 +1,9 @@ +import { defineConfig, mergeConfig } from 'vitest/config'; +import { viteBaseConfig } from '../../vite.config.base.mjs'; + +export default mergeConfig( + viteBaseConfig, + defineConfig({ + cacheDir: '../../node_modules/.vite/packages/nx-cdk', + }) +);