From e1191f73033c1f1670b51b6ae902b8af9e3b8ccb Mon Sep 17 00:00:00 2001 From: Gilbert Holland-Lloyd Date: Mon, 22 Jun 2026 17:02:11 +0100 Subject: [PATCH] feat: configurable HTTP proxy image, Node 22 support, and 100% unit test coverage Allow overriding the built-in HTTP proxy image via NAVY_HTTP_PROXY_IMAGE or Navyfile httpProxyImage, and forward custom env via httpProxyEnv / NAVY_HTTP_PROXY_ENV. Fix navyFile propagation when toggling HTTPS or destroying one Navy while others remain. Modernise for Node 22: dependency updates, audit remediation, Flow/lint fixes. CI uses Moneyhub runners and routes dockerode through DOCKER_HOST so it matches docker compose. Integration tests updated for commander v12 and rimraf v5. Add c8 with 100% unit test coverage, CLI fixes (-e/--navy ordering, reject unknown subcommand options), and docs (http-proxy, navyfile-config, intent doc). --- .c8rc.json | 24 + .eslintignore | 1 + .eslintrc.yml | 5 +- .flowconfig | 3 +- .github/workflows/build.yaml | 48 +- .gitignore | 4 +- babel.config.js | 12 +- docs/http-proxy.md | 60 + docs/intent/make-proxy-image-configurable.md | 152 + docs/navyfile-config.md | 10 + flow-libs/node-globals.js | 13 + flow-libs/node-modules.js | 51 + flow-libs/npm-modules.js | 3 + lerna.json | 9 +- package-lock.json | 23157 ++++++++++------ package.json | 58 +- packages/navy-plugin-nodejs/package-lock.json | 33 - packages/navy-plugin-nodejs/package.json | 7 +- .../navy-plugin-nodejs/src/__tests__/index.js | 59 + .../__tests__/rewrite-linked-node-modules.js | 115 + .../src/hooks/rewrite-linked-node-modules.js | 4 +- .../middleware/__tests__/mount-user-home.js | 113 + packages/navy/package-lock.json | 842 - packages/navy/package.json | 27 +- .../navy/src/__tests__/config-provider.js | 95 + packages/navy/src/__tests__/config.js | 145 + packages/navy/src/__tests__/driver-logging.js | 191 + packages/navy/src/__tests__/driver.js | 22 + packages/navy/src/__tests__/errors.js | 60 + packages/navy/src/__tests__/http-proxy.js | 431 + packages/navy/src/__tests__/index.js | 28 + packages/navy/src/__tests__/service.js | 19 + packages/navy/src/cli/__tests__/develop.js | 225 + .../navy/src/cli/__tests__/external-ip.js | 76 + packages/navy/src/cli/__tests__/health.js | 230 + packages/navy/src/cli/__tests__/https.js | 217 + packages/navy/src/cli/__tests__/import.js | 103 + packages/navy/src/cli/__tests__/index.js | 130 + packages/navy/src/cli/__tests__/lan-ip.js | 98 + packages/navy/src/cli/__tests__/launch.js | 170 + packages/navy/src/cli/__tests__/live.js | 143 + packages/navy/src/cli/__tests__/local-ip.js | 82 + packages/navy/src/cli/__tests__/logs.js | 57 + packages/navy/src/cli/__tests__/open.js | 70 + .../cli/__tests__/program-unknown-options.js | 97 + packages/navy/src/cli/__tests__/program.js | 602 + packages/navy/src/cli/__tests__/ps.js | 312 + .../navy/src/cli/__tests__/refresh-config.js | 104 + packages/navy/src/cli/__tests__/run.js | 60 + packages/navy/src/cli/__tests__/status.js | 201 + packages/navy/src/cli/__tests__/updates.js | 268 + .../src/cli/__tests__/wait-for-healthy.js | 151 + .../navy/src/cli/config/__tests__/index.js | 305 + .../navy/src/cli/config/__tests__/wrapper.js | 64 + packages/navy/src/cli/config/index.js | 24 +- packages/navy/src/cli/config/wrapper.js | 3 +- packages/navy/src/cli/develop.js | 11 +- .../doctor/__tests__/clean-compose-files.js | 81 + .../navy/src/cli/doctor/__tests__/index.js | 83 + .../__tests__/invalid-compose-config.js | 111 + .../src/cli/doctor/__tests__/invalid-state.js | 91 + .../navy/src/cli/doctor/__tests__/util.js | 116 + .../src/cli/doctor/clean-compose-files.js | 14 +- packages/navy/src/cli/doctor/index.js | 2 +- .../src/cli/doctor/invalid-compose-config.js | 4 +- packages/navy/src/cli/doctor/invalid-state.js | 4 +- packages/navy/src/cli/external-ip.js | 4 +- packages/navy/src/cli/health.js | 6 +- packages/navy/src/cli/https.js | 23 +- packages/navy/src/cli/import.js | 6 +- packages/navy/src/cli/index.js | 2 +- packages/navy/src/cli/lan-ip.js | 6 +- packages/navy/src/cli/launch.js | 4 +- packages/navy/src/cli/live.js | 6 +- packages/navy/src/cli/local-ip.js | 4 +- packages/navy/src/cli/logs.js | 2 +- packages/navy/src/cli/open.js | 4 +- packages/navy/src/cli/program.js | 59 +- packages/navy/src/cli/ps.js | 11 +- packages/navy/src/cli/refresh-config.js | 4 +- packages/navy/src/cli/run.js | 2 +- packages/navy/src/cli/status.js | 4 +- packages/navy/src/cli/updates.js | 8 +- .../util/__tests__/get-or-initialise-navy.js | 72 + .../navy/src/cli/util/__tests__/import.js | 152 + packages/navy/src/cli/util/__tests__/index.js | 20 + .../util/__tests__/merge-action-options.js | 56 + .../src/cli/util/__tests__/reconfigure.js | 86 + .../src/cli/util/get-or-initialise-navy.js | 8 +- packages/navy/src/cli/util/import.js | 8 +- packages/navy/src/cli/util/index.js | 4 +- .../navy/src/cli/util/merge-action-options.js | 26 + packages/navy/src/cli/util/reconfigure.js | 4 +- packages/navy/src/cli/wait-for-healthy.js | 6 +- .../registry/__tests__/get-credentials.js | 57 + .../client/registry/__tests__/get-endpoint.js | 125 + .../registry/__tests__/get-fat-manifest.js | 56 + .../client/registry/__tests__/get-token.js | 75 + .../src/client/registry/__tests__/helpers.js | 27 + .../src/client/registry/get-credentials.js | 10 +- .../navy/src/client/registry/get-endpoint.js | 78 +- .../src/client/registry/get-fat-manifest.js | 4 +- .../navy/src/client/registry/get-token.js | 2 +- packages/navy/src/client/registry/helpers.js | 2 +- packages/navy/src/config-provider.js | 8 +- .../filesystem/__tests__/index.js | 162 + .../src/config-providers/filesystem/index.js | 22 +- .../config-providers/npm/__tests__/index.js | 195 + .../config-providers/npm/__tests__/util.js | 4 +- .../navy/src/config-providers/npm/index.js | 32 +- packages/navy/src/config.js | 16 +- .../src/domain/__tests__/container-image.js | 123 + .../domain/__tests__/oci-api-specification.js | 35 + packages/navy/src/driver-logging.js | 2 +- packages/navy/src/driver.js | 4 +- .../docker-compose/__tests__/client.js | 291 + .../drivers/docker-compose/__tests__/index.js | 421 + .../navy/src/drivers/docker-compose/client.js | 11 +- .../navy/src/drivers/docker-compose/index.js | 26 +- packages/navy/src/errors.js | 2 +- packages/navy/src/http-proxy.js | 87 +- packages/navy/src/index.js | 6 +- .../__tests__/add-service-proxy-config.js | 226 + .../navy/src/middleware/__tests__/develop.js | 78 + .../navy/src/middleware/__tests__/helpers.js | 133 + .../src/middleware/__tests__/port-override.js | 73 + .../src/middleware/__tests__/set-env-vars.js | 49 + .../src/middleware/__tests__/set-image.js | 44 + .../__tests__/set-logging-driver.js | 48 + .../src/middleware/__tests__/tag-override.js | 54 + .../middleware/add-service-proxy-config.js | 22 +- packages/navy/src/middleware/develop.js | 6 +- packages/navy/src/middleware/helpers.js | 10 +- packages/navy/src/middleware/port-override.js | 11 +- packages/navy/src/middleware/set-env-vars.js | 4 +- packages/navy/src/middleware/set-image.js | 4 +- .../navy/src/middleware/set-logging-driver.js | 4 +- packages/navy/src/middleware/tag-override.js | 2 +- .../src/navy/__tests__/default-middleware.js | 37 + packages/navy/src/navy/__tests__/index.js | 1165 + .../navy/src/navy/__tests__/middleware.js | 62 + .../src/navy/__tests__/plugin-interface.js | 105 + packages/navy/src/navy/__tests__/state.js | 141 + packages/navy/src/navy/__tests__/util.js | 30 + packages/navy/src/navy/default-middleware.js | 2 +- packages/navy/src/navy/index.js | 113 +- packages/navy/src/navy/middleware.js | 6 +- packages/navy/src/navy/plugin-interface.js | 6 +- packages/navy/src/navy/state.js | 11 +- .../navy/src/util/__tests__/exec-async.js | 98 + .../navy/src/util/__tests__/external-ip.js | 131 +- .../navy/src/util/__tests__/get-lan-ip.js | 56 + .../navy/src/util/__tests__/has-update.js | 111 + packages/navy/src/util/__tests__/https.js | 325 + packages/navy/src/util/__tests__/navyrc.js | 53 + .../navy/src/util/__tests__/service-host.js | 89 +- packages/navy/src/util/__tests__/table.js | 68 + packages/navy/src/util/docker-client.js | 5 +- packages/navy/src/util/exec-async.js | 2 +- packages/navy/src/util/external-ip.js | 2 +- packages/navy/src/util/get-lan-ip.js | 2 +- packages/navy/src/util/has-update.js | 4 +- packages/navy/src/util/https.js | 12 +- packages/navy/src/util/service-host.js | 14 +- packages/navy/src/util/table.js | 2 +- scripts/integration.sh | 93 +- scripts/test.sh | 2 +- test/integration/README.md | 32 +- test/integration/chai.js | 4 +- .../plugins/step_definitions/commands.js | 4 +- .../plugins/step_definitions/middleware.js | 10 +- .../features/step_definitions/config.js | 28 +- .../features/step_definitions/develop.js | 8 +- .../features/step_definitions/http-proxy.js | 8 +- .../features/step_definitions/https-proxy.js | 14 +- .../features/step_definitions/launch-cli.js | 6 +- .../features/step_definitions/launch.js | 8 +- .../features/step_definitions/port-cli.js | 13 +- .../features/step_definitions/port.js | 6 +- .../step_definitions/start-stop-cli.js | 14 +- .../features/step_definitions/use-tag.js | 6 +- test/integration/hooks.js | 10 +- test/integration/runner/Dockerfile | 36 - test/integration/runner/docker-entrypoint.sh | 11 - test/integration/runner/docker-login.sh | 6 - test/integration/steps/develop.js | 6 +- test/integration/steps/navy.js | 6 +- .../http-proxy-https-enabled/Navyfile.js | 2 +- .../middleware-plugin.js | 2 +- test/integration/util/cli-automator.js | 23 +- test/integration/util/setup-navy.js | 23 +- website/Gulpfile.js | 2 +- website/index.js | 2 +- website/util/pipeline.js | 2 +- 194 files changed, 26047 insertions(+), 10350 deletions(-) create mode 100644 .c8rc.json create mode 100644 docs/intent/make-proxy-image-configurable.md create mode 100644 flow-libs/node-globals.js create mode 100644 flow-libs/node-modules.js create mode 100644 flow-libs/npm-modules.js delete mode 100644 packages/navy-plugin-nodejs/package-lock.json create mode 100644 packages/navy-plugin-nodejs/src/__tests__/index.js create mode 100644 packages/navy-plugin-nodejs/src/hooks/__tests__/rewrite-linked-node-modules.js create mode 100644 packages/navy-plugin-nodejs/src/middleware/__tests__/mount-user-home.js delete mode 100644 packages/navy/package-lock.json create mode 100644 packages/navy/src/__tests__/config-provider.js create mode 100644 packages/navy/src/__tests__/config.js create mode 100644 packages/navy/src/__tests__/driver-logging.js create mode 100644 packages/navy/src/__tests__/driver.js create mode 100644 packages/navy/src/__tests__/errors.js create mode 100644 packages/navy/src/__tests__/http-proxy.js create mode 100644 packages/navy/src/__tests__/index.js create mode 100644 packages/navy/src/__tests__/service.js create mode 100644 packages/navy/src/cli/__tests__/develop.js create mode 100644 packages/navy/src/cli/__tests__/external-ip.js create mode 100644 packages/navy/src/cli/__tests__/health.js create mode 100644 packages/navy/src/cli/__tests__/https.js create mode 100644 packages/navy/src/cli/__tests__/import.js create mode 100644 packages/navy/src/cli/__tests__/index.js create mode 100644 packages/navy/src/cli/__tests__/lan-ip.js create mode 100644 packages/navy/src/cli/__tests__/launch.js create mode 100644 packages/navy/src/cli/__tests__/live.js create mode 100644 packages/navy/src/cli/__tests__/local-ip.js create mode 100644 packages/navy/src/cli/__tests__/logs.js create mode 100644 packages/navy/src/cli/__tests__/open.js create mode 100644 packages/navy/src/cli/__tests__/program-unknown-options.js create mode 100644 packages/navy/src/cli/__tests__/program.js create mode 100644 packages/navy/src/cli/__tests__/ps.js create mode 100644 packages/navy/src/cli/__tests__/refresh-config.js create mode 100644 packages/navy/src/cli/__tests__/run.js create mode 100644 packages/navy/src/cli/__tests__/status.js create mode 100644 packages/navy/src/cli/__tests__/updates.js create mode 100644 packages/navy/src/cli/__tests__/wait-for-healthy.js create mode 100644 packages/navy/src/cli/config/__tests__/index.js create mode 100644 packages/navy/src/cli/config/__tests__/wrapper.js create mode 100644 packages/navy/src/cli/doctor/__tests__/clean-compose-files.js create mode 100644 packages/navy/src/cli/doctor/__tests__/index.js create mode 100644 packages/navy/src/cli/doctor/__tests__/invalid-compose-config.js create mode 100644 packages/navy/src/cli/doctor/__tests__/invalid-state.js create mode 100644 packages/navy/src/cli/doctor/__tests__/util.js create mode 100644 packages/navy/src/cli/util/__tests__/get-or-initialise-navy.js create mode 100644 packages/navy/src/cli/util/__tests__/import.js create mode 100644 packages/navy/src/cli/util/__tests__/index.js create mode 100644 packages/navy/src/cli/util/__tests__/merge-action-options.js create mode 100644 packages/navy/src/cli/util/__tests__/reconfigure.js create mode 100644 packages/navy/src/cli/util/merge-action-options.js create mode 100644 packages/navy/src/client/registry/__tests__/get-credentials.js create mode 100644 packages/navy/src/client/registry/__tests__/get-endpoint.js create mode 100644 packages/navy/src/client/registry/__tests__/get-fat-manifest.js create mode 100644 packages/navy/src/client/registry/__tests__/get-token.js create mode 100644 packages/navy/src/client/registry/__tests__/helpers.js create mode 100644 packages/navy/src/config-providers/filesystem/__tests__/index.js create mode 100644 packages/navy/src/config-providers/npm/__tests__/index.js create mode 100644 packages/navy/src/domain/__tests__/container-image.js create mode 100644 packages/navy/src/domain/__tests__/oci-api-specification.js create mode 100644 packages/navy/src/drivers/docker-compose/__tests__/client.js create mode 100644 packages/navy/src/drivers/docker-compose/__tests__/index.js create mode 100644 packages/navy/src/middleware/__tests__/add-service-proxy-config.js create mode 100644 packages/navy/src/middleware/__tests__/develop.js create mode 100644 packages/navy/src/middleware/__tests__/helpers.js create mode 100644 packages/navy/src/middleware/__tests__/port-override.js create mode 100644 packages/navy/src/middleware/__tests__/set-env-vars.js create mode 100644 packages/navy/src/middleware/__tests__/set-image.js create mode 100644 packages/navy/src/middleware/__tests__/set-logging-driver.js create mode 100644 packages/navy/src/middleware/__tests__/tag-override.js create mode 100644 packages/navy/src/navy/__tests__/default-middleware.js create mode 100644 packages/navy/src/navy/__tests__/index.js create mode 100644 packages/navy/src/navy/__tests__/middleware.js create mode 100644 packages/navy/src/navy/__tests__/plugin-interface.js create mode 100644 packages/navy/src/navy/__tests__/state.js create mode 100644 packages/navy/src/navy/__tests__/util.js create mode 100644 packages/navy/src/util/__tests__/exec-async.js create mode 100644 packages/navy/src/util/__tests__/get-lan-ip.js create mode 100644 packages/navy/src/util/__tests__/has-update.js create mode 100644 packages/navy/src/util/__tests__/https.js create mode 100644 packages/navy/src/util/__tests__/navyrc.js create mode 100644 packages/navy/src/util/__tests__/table.js delete mode 100644 test/integration/runner/Dockerfile delete mode 100644 test/integration/runner/docker-entrypoint.sh delete mode 100644 test/integration/runner/docker-login.sh diff --git a/.c8rc.json b/.c8rc.json new file mode 100644 index 0000000..49b2e33 --- /dev/null +++ b/.c8rc.json @@ -0,0 +1,24 @@ +{ + "all": true, + "include": [ + "packages/*/src/**/*.js" + ], + "exclude": [ + "**/__tests__/**", + "**/node_modules/**", + "**/*.d.ts", + "packages/*/src/**/index.d.ts" + ], + "reporter": [ + "text", + "text-summary", + "html", + "lcov" + ], + "report-dir": "./coverage", + "check-coverage": true, + "lines": 100, + "branches": 100, + "functions": 100, + "statements": 100 +} diff --git a/.eslintignore b/.eslintignore index dd9c390..d01be05 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ node_modules lib website/build +flow-libs diff --git a/.eslintrc.yml b/.eslintrc.yml index c4102a6..4d28e5c 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -3,7 +3,7 @@ extends: "standard" - plugins: ["flowtype", "import", "chai-friendly"] + plugins: ["import", "chai-friendly"] rules: space-before-function-paren: [2, {"anonymous": "always", "named": "never"}] @@ -22,8 +22,5 @@ no-return-await: "off" - flowtype/define-flow-type: 2 - flowtype/use-flow-type: 2 - import/no-duplicates: "off" diff --git a/.flowconfig b/.flowconfig index 552bcdd..e464110 100644 --- a/.flowconfig +++ b/.flowconfig @@ -3,7 +3,6 @@ [include] [libs] +flow-libs/ [options] -esproposal.export_star_as=enable -suppress_comment= \\(.\\|\n\\)*\\$FlowIgnore diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9f5c2d1..b7b325b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -6,35 +6,45 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: node-${{ matrix.node-version }} docker-${{ matrix.docker }} compose-${{ matrix.docker_compose }} env: - DEBUG: 'navy:*' - NAVY_DEBUG: 'navy:*' + DEBUG: "navy:*" + NAVY_DEBUG: "navy:*" strategy: fail-fast: false matrix: - node-version: [14.x, 16.x] - docker: [18.06-dind, 20.10.5-dind] - docker_compose: [1.14.0, 1.29.2, v2.10.2] + node-version: [22.x, 24.x] + docker: [v24.0.7, v27.3.1] + docker_compose: [v2.20.3, v2.29.7] steps: - - uses: actions/checkout@v2 - - name: Use Node.js - uses: actions/setup-node@v1 - env: - DOCKER_TAG: ${{matrix.docker}} - DOCKER_COMPOSE_VERSION: ${{matrix.docker_compose}} - GITHUB_NODE_VERSION: ${{matrix.node-version}} + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: ${{ matrix.node-version }} - - name: Before tests - run: node --version + + - name: Setup Docker + uses: docker/setup-docker-action@b2189fbf2a6592b51fee7cdd93ee2bfaeba733db # v5.1.0 + with: + version: ${{ matrix.docker }} + # Export DOCKER_HOST so the dockerode client used by navy and the + # `docker compose` CLI invoked by the navy driver both target the + # daemon installed by this action. Without this the action only + # configures a Docker CLI context (consumed by `docker compose`), + # while dockerode falls back to /var/run/docker.sock and ends up + # querying a different daemon, returning no matching containers. + set-host: true + + - name: Setup Docker Compose + uses: docker/setup-compose-action@8cccb8c14b6500aaffebff1aa49c502c34d2e5e6 # v2.1.0 + with: + version: ${{ matrix.docker_compose }} + - name: Install dependencies run: npm ci - - name: Bostrap lerna - run: npm run bootstrap + - name: Test run: npm test - - diff --git a/.gitignore b/.gitignore index df75276..ad33f5e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ npm-debug.log lib website/build .vscode -.node-version \ No newline at end of file +.node-version +coverage +.nyc_output diff --git a/babel.config.js b/babel.config.js index 4876e27..6404750 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,23 +1,23 @@ module.exports = { - 'presets': [ + presets: [ '@babel/preset-typescript', [ '@babel/preset-env', { - 'targets': { - 'node': '10', + targets: { + node: '22', }, }, ], ], - 'plugins': [ + plugins: [ '@babel/plugin-proposal-function-bind', 'add-module-exports', '@babel/transform-flow-strip-types', '@babel/transform-runtime', './resources/babel/transform-error-codes.js', ], - 'parserOpts': { - 'allowReturnOutsideFunction': true, + parserOpts: { + allowReturnOutsideFunction: true, }, } diff --git a/docs/http-proxy.md b/docs/http-proxy.md index d64f680..5009052 100644 --- a/docs/http-proxy.md +++ b/docs/http-proxy.md @@ -17,3 +17,63 @@ This takes advantage of the [nip.io](http://nip.io) service, which provides a UR This allows Navy to easily proxy all of your HTTP services by using virtual hosts in nginx, and also allows for you to quickly reconfigure Navy so it is using your external LAN IP for nip.io domains so you can easily test your services on other devices on your LAN. Navy will automatically pick up and proxy any services which publish port 80, but if your service uses another port then you will need to [explicitly configure it in `Navyfile.js`](navyfile-config.md). + +## Customising the proxy image + +By default, Navy uses the `navycloud/navy-proxy` Docker image for the HTTP proxy. You can override this to use a custom image. + +The image is resolved in the following order of precedence: + +1. **`NAVY_HTTP_PROXY_IMAGE` environment variable** - highest precedence. Set this in your shell environment to override the proxy image globally. +2. **`httpProxyImage` property in `Navyfile.js`** - per-project override. See the [Navyfile.js reference](navyfile-config.md) for details. +3. **Default (`navycloud/navy-proxy`)** - used when neither of the above is set, preserving backwards-compatible behaviour. + +### Examples + +Override via environment variable: + +```bash +export NAVY_HTTP_PROXY_IMAGE=myregistry/custom-proxy:latest +navy launch +``` + +Override via `Navyfile.js`: + +```js +module.exports = { + httpProxyImage: 'myregistry/custom-proxy:latest', +} +``` + +## Passing environment variables to the proxy + +Custom proxy images often need runtime configuration. Navy provides two complementary surfaces for forwarding environment variables to the `nginx-proxy` container, with a clear precedence rule so static project defaults can be overridden from the operator's shell at run time. + +The forwarded environment is built from: + +1. **`NAVY_HTTP_PROXY_ENV` environment variable** - highest precedence. A comma-separated allowlist of names. For each name listed, Navy reads the matching value from its own process environment and forwards it to the proxy container. Names with no value (or an empty value) in the navy process env are silently skipped. +2. **`httpProxyEnv` property in `Navyfile.js`** - per-project map of `NAME -> value` pairs. Values are coerced to strings; entries with `null`, `undefined`, or empty-string values are dropped. See the [Navyfile.js reference](navyfile-config.md) for the property definition. + +When both are configured, the two sources are merged. On key collisions the `NAVY_HTTP_PROXY_ENV` allowlist wins, so an operator can always override a project default from their shell. When neither is configured, no `environment:` block is written to the generated compose config and the proxy container starts with no extra environment variables. + +### Examples + +Forward shell variables via the allowlist: + +```bash +export MY_PROXY_TOKEN=secret +export NAVY_HTTP_PROXY_ENV=MY_PROXY_TOKEN +navy launch +``` + +Set per-project defaults in `Navyfile.js`: + +```js +module.exports = { + httpProxyImage: 'myregistry/custom-proxy:latest', + httpProxyEnv: { + FEATURE_FLAG: 'on', + UPSTREAM_TIMEOUT: '30', + }, +} +``` diff --git a/docs/intent/make-proxy-image-configurable.md b/docs/intent/make-proxy-image-configurable.md new file mode 100644 index 0000000..f417a32 --- /dev/null +++ b/docs/intent/make-proxy-image-configurable.md @@ -0,0 +1,152 @@ +--- +title: Make Navy proxy image configurable +branch: make-proxy-image-configurable +baseline: origin/master +--- + +# Make Navy proxy image configurable + +This document captures the intent behind the work on the `make-proxy-image-configurable` branch and provides a high-level map of where each change lives. It is written for reviewers and future maintainers who need to understand why this branch is so large and how the changes group together, without reading every line of the diff. + +## Snapshot + +| Item | Value | +| --- | --- | +| Branch | `make-proxy-image-configurable` | +| Default branch in this repository | `master` (no `main` exists, so the diff is taken against `origin/master`) | +| Merge baseline (`origin/master`) | `035ecc9fc9fdf25f88cd4d90172cf68ebf7b7983` | +| Branch head | `3d64bfc1ebf3c27181f950f93d183adfe29ae68c` | +| Commits ahead of `master` | 17 | +| Files changed | 190 | +| Approximate line delta | `+25,163 / -10,345` | + +## Headline intent + +The branch began as a focused product change: allow consumers of Navy to override the Docker image used by the built-in HTTP reverse proxy, instead of being hard-coded to `navycloud/navy-proxy`. While delivering that, the toolchain and continuous-integration setup turned out to be too stale to support a clean release on modern Node, so the work expanded to cover dependency modernisation, a CI overhaul, and a substantial unit-test backfill. There are therefore two distinct strands of intent in this branch: + +1. **Product and operations intent.** Make the HTTP proxy image configurable per project and per environment, with a clear precedence order, while preserving the existing default so no consumer is forced to change anything. +2. **Engineering intent.** Bring the repository onto Node 22 and a current dependency set, fix npm-audit findings, stabilise CI so it works reliably with both the `dockerode` client and the `docker compose` CLI, and lift unit-test coverage to a level that lets future changes be made with confidence. + +## Configurable proxy image + +The user-facing change is the ability to override the proxy image either by setting the `NAVY_HTTP_PROXY_IMAGE` environment variable or by adding an `httpProxyImage` property to `Navyfile.js`. The environment variable wins if both are set, and the historical default `navycloud/navy-proxy` is used when neither is provided, so existing setups are unaffected. + +The resolution logic and the related Docker socket helper now live in: + +- `packages/navy/src/http-proxy.js` - new `resolveProxyImage` and `resolveDockerSocketPath` helpers, used when generating the proxy compose config. +- `packages/navy/src/__tests__/http-proxy.js` - covers the precedence order, empty-string fall-through, and `reconfigureHTTPProxy` plumbing. +- `packages/navy/src/middleware/add-service-proxy-config.js` - knock-on changes to keep `navyFile` available where it now matters. + +The behaviour and precedence rules are documented for end users in: + +- `docs/http-proxy.md` - new "Customising the proxy image" section with worked examples. +- `docs/navyfile-config.md` - new `httpProxyImage` entry in the `Navyfile.js` reference, cross-linked from the proxy guide. + +A follow-up commit renamed the environment variable from `NAVY_PROXY_IMAGE` to `NAVY_HTTP_PROXY_IMAGE` so it sits alongside the rest of the HTTP proxy surface area. + +The branch also adds a generic environment-variable passthrough for the proxy image, on the same precedence model as the image override. Consumers can declare a static map of variables in `Navyfile.js` via `httpProxyEnv`, or forward names from the navy process env via the `NAVY_HTTP_PROXY_ENV` allowlist. The two sources are merged when both are set, with the env-var allowlist winning on key collisions, and the generated compose config omits the `environment:` block entirely when nothing is configured so existing setups are unaffected. This keeps navy agnostic of any specific consumer while letting downstream projects (e.g. those running a customised proxy image) wire in whatever runtime configuration they need. + +## HTTPS and proxy reconfiguration correctness + +While testing the configurable image, a latent bug surfaced: the HTTPS CLI path called `reconfigureHTTPProxy` without forwarding the resolved `navyFile`, which meant a custom `httpProxyImage` was silently dropped whenever HTTPS was toggled. The fix threads `navyFile` through the call chain and is covered by edge-case tests. + +Primary locations: + +- `packages/navy/src/cli/https.js` - propagates `navyFile` through `reconfigureHTTPProxy`. +- `packages/navy/src/cli/__tests__/https.js` - new tests for the propagation path. +- `packages/navy/src/__tests__/http-proxy.js` - asserts that `httpProxyImage` survives reconfiguration. + +## Toolchain and monorepo modernisation + +To get the proxy change to build and test on a current developer environment, the toolchain was lifted to Node 22 and the dependency tree was refreshed. The bulk of the line-count in the diff comes from the regenerated `package-lock.json`, but the meaningful edits are concentrated in: + +- `package.json` - `engines.node` set to `>=22`, npm workspaces left in place, new `coverage` and `coverage-no-check` scripts wired up to `c8`. +- `lerna.json`, `babel.config.js`, `.flowconfig`, `flow-libs/` - Babel, Lerna and Flow configuration brought in line with the new toolchain, including refreshed Flow library definitions for current Node and npm modules. +- `.eslintrc.yml`, `.eslintignore` - lint configuration adjusted for the new parser and ignored paths. +- `.c8rc.json` - new coverage configuration enforcing the high coverage thresholds used by the test suite. +- `packages/navy/package.json`, `packages/navy-plugin-nodejs/package.json` - per-package dependency bumps to match the root. + +Two commits in this strand are worth calling out: `chore(deps): remediate npm audit vulnerabilities` and `Fix vulnerabilities`, which together clear the audit output that the modernisation initially exposed. + +## Unit-test expansion and coverage tooling + +The final commit on the branch (`test: add c8 coverage tooling and 100% unit test coverage`) adds `c8` to the toolchain and lifts unit-test coverage close to 100% across the `navy` package. Most of the new test files do not change runtime behaviour, but they pin behaviour that was previously untested and would have made the modernisation risky to land. The new tests sit next to the modules they exercise, in a consistent `__tests__` layout: + +- `packages/navy/src/__tests__/` - core flows: `config-provider.js`, `config.js`, `driver-logging.js`, `driver.js`, `errors.js`, `http-proxy.js`, `index.js`, `service.js`. +- `packages/navy/src/cli/__tests__/` - one test file per CLI command (`develop`, `external-ip`, `health`, `https`, `import`, `index`, `lan-ip`, `launch`, `live`, `local-ip`, `logs`, `open`, `program`, `ps`, `refresh-config`, `run`, `status`, `updates`, `wait-for-healthy`). +- `packages/navy/src/cli/config/__tests__/` and `packages/navy/src/cli/doctor/__tests__/` - configuration wrapper and doctor sub-commands. +- `packages/navy/src/cli/util/__tests__/` - shared CLI helpers (`get-or-initialise-navy`, `import`, `index`, `reconfigure`). +- `packages/navy/src/client/registry/__tests__/` - registry client (`get-credentials`, `get-endpoint`, `get-fat-manifest`, `get-token`, `helpers`). +- `packages/navy/src/config-providers/{filesystem,npm}/__tests__/` - configuration providers. +- `packages/navy/src/domain/__tests__/` - new domain helpers for `container-image` and `oci-api-specification`. +- `packages/navy/src/drivers/docker-compose/__tests__/` - driver client and entry point. +- `packages/navy/src/middleware/__tests__/` - all middleware modules (`add-service-proxy-config`, `develop`, `helpers`, `port-override`, `set-env-vars`, `set-image`, `set-logging-driver`, `tag-override`). +- `packages/navy/src/navy/__tests__/` - core orchestration (`default-middleware`, `index`, `middleware`, `plugin-interface`, `state`, `util`). +- `packages/navy/src/util/__tests__/` - utilities (`exec-async`, `external-ip`, `get-lan-ip`, `has-update`, `https`, `navyrc`, `service-host`, `table`). +- `packages/navy-plugin-nodejs/src/{hooks,middleware}/__tests__/` - plugin-side coverage for `rewrite-linked-node-modules` and `mount-user-home`. + +The implementation files alongside these tests received small edits in the same commit to make them more easily testable and to address issues uncovered while writing the tests. These edits are deliberately narrow and do not change public behaviour. + +## Integration tests and harness + +Several integration-test fixes accompany the toolchain change, mostly to keep the suite working after `commander`, `rimraf`, and `nip.io`-style DNS behaviour shifted under newer dependencies. The Docker-based runner under `test/integration/runner/` was retired because the workflow now provisions Docker directly on the runner. + +Primary locations: + +- `test/integration/` - step definitions and helpers updated for new dependency versions; debug output silenced in spawned CLI processes to stop noisy logs masking failures. +- `scripts/integration.sh` - aligned with the new test layout. +- `test/integration/runner/Dockerfile`, `docker-entrypoint.sh`, `docker-login.sh` - removed; the workflow no longer needs an in-repo container to host the suite. + +Relevant commits: `fix: align integration tests with rimraf v5 and commander v12`, `fix: pin dnsLookup to IPv4 to prevent macOS resolver flake`, `fix(test): silence navy CLI debug output in integration spawns`, `fix(test): always silence navy CLI debug in integration spawns`, and `Fix integration tests`. + +## Continuous integration + +CI now runs on a Node 22 and 24 matrix against two Docker and two Docker Compose versions, using pinned action SHAs. The most subtle change is the routing of `dockerode` and the `docker compose` CLI through the same daemon: `docker/setup-docker-action` is invoked with `set-host: true`, and a runtime helper honours `DOCKER_HOST` when it points at a unix socket so both clients agree on which daemon to talk to. Without this, `dockerode` would silently fall back to `/var/run/docker.sock` and query a different daemon than `docker compose`, producing empty container listings. + +Primary locations: + +- `.github/workflows/build.yaml` - Node matrix, Docker / Compose matrix, pinned action SHAs, and the `set-host: true` configuration with an explanatory comment. +- `packages/navy/src/http-proxy.js` - `resolveDockerSocketPath` ensures the proxy container mounts the same socket the rest of Navy uses. + +Related commits: `Use Moneyhub runners for CICD` and `fix: route navy through DOCKER_HOST socket on setup-docker-action`. + +## Commit narrative + +The commits below are listed in chronological order and group naturally into the strands above. + +- `de29042` chore: modernize dependencies for Node 22 support +- `c01d440` Make Navy proxy image configurable +- `264846b` Fix navyFile propagation and add edge-case tests +- `f374e83` rename NAVY_PROXY_IMAGE env var to NAVY_HTTP_PROXY_IMAGE +- `5f0bd5c` Use Moneyhub runners for CICD +- `453c1a7` style: fix linting issues across navy packages +- `610a66c` fix: restore Flow type-checking under flow-bin 0.311 +- `dd504ac` fix: pin dnsLookup to IPv4 to prevent macOS resolver flake +- `310b6ab` fix: align integration tests with rimraf v5 and commander v12 +- `abcdf6e` Fix integration tests +- `1680372` fix(test): silence navy CLI debug output in integration spawns +- `a8fe75e` fix(test): always silence navy CLI debug in integration spawns +- `777eb1b` fix: route navy through DOCKER_HOST socket on setup-docker-action +- `70a2d20` Fix vulnerabilities +- `18da0bf` chore(deps): remediate npm audit vulnerabilities +- `13dc678` fix: propagate navyFile through https CLI reconfigureHTTPProxy calls +- `3d64bfc` test: add c8 coverage tooling and 100% unit test coverage +- `feat(http-proxy): allow forwarding custom env vars to the proxy container` - generic `httpProxyEnv` / `NAVY_HTTP_PROXY_ENV` passthrough on the proxy compose service, with the allowlist taking precedence on key collisions. + +## Scope appendix - changed files by area + +Counts come from `git diff --name-only origin/master...HEAD` aggregated by top-level area, and are useful for orienting reviewers before they open the diff. + +| Area | Files changed | +| --- | --- | +| `packages/navy` | 140 | +| `test/integration` | 24 | +| Repository root (config, lockfile, etc.) | 9 | +| `packages/navy-plugin-nodejs` | 6 | +| `website` | 3 | +| `flow-libs` | 3 | +| `scripts` | 2 | +| `docs` | 2 | +| `.github` | 1 | + +The heavy concentration in `packages/navy` reflects the unit-test backfill more than any sprawling refactor; the production source changes are narrowly scoped to the proxy-image feature, the HTTPS propagation fix, and small consistency edits that fell out of bringing the test suite to green. diff --git a/docs/navyfile-config.md b/docs/navyfile-config.md index f35ba59..4da798d 100644 --- a/docs/navyfile-config.md +++ b/docs/navyfile-config.md @@ -21,6 +21,8 @@ module.exports = { httpProxyAutoPorts: [ 4080, ], + httpProxyImage: 'myregistry/custom-proxy:latest', + httpProxyEnv: { FOO: 'bar' }, httpProxy: { myotherservice: { port: 8080 } }, @@ -45,6 +47,14 @@ A list of service names in the compose configuration which should be selected by If using the [built in HTTP proxy](http-proxy.md), you can tell Navy to automatically register a service with the HTTP proxy, if it publishes any port in this list. This overrides port 80 for automatic registration. +### `httpProxyImage: ?string` + +Overrides the Docker image used for the [built in HTTP proxy](http-proxy.md). Defaults to `navycloud/navy-proxy` if not set. The `NAVY_HTTP_PROXY_IMAGE` environment variable takes precedence over this property if both are set. + +### `httpProxyEnv: ?{[key: string]: string}` + +A per-project map of environment variables to forward into the [built in HTTP proxy](http-proxy.md) container. Useful when running a custom proxy image that needs runtime configuration. Values are coerced to strings; entries with `null`, `undefined`, or empty-string values are dropped. The `NAVY_HTTP_PROXY_ENV` environment variable (a comma-separated allowlist of names from the navy process env) takes precedence over this property on key collisions. Example: `httpProxyEnv: { FOO: 'bar' }`. + ### `httpProxy: ?{[key: string]: { port: Number, enableHttps: Boolean }}` If using the [built in HTTP proxy](http-proxy.md), you can tell Navy what port a service listens for HTTP connections here. If a service publishes port 80, or alternatively a port specified in `httpProxyAutoPorts`, it will automatically be registered with the HTTP proxy, so configuration here is unnecessary. diff --git a/flow-libs/node-globals.js b/flow-libs/node-globals.js new file mode 100644 index 0000000..88d5288 --- /dev/null +++ b/flow-libs/node-globals.js @@ -0,0 +1,13 @@ +declare var process: { + env: {[key: string]: ?string}, + argv: Array, + stdout: any, + stderr: any, + cwd(): string, + on(event: string, listener: (...args: Array) => mixed): any, + exit(code?: number): void, + ... +}; + +declare var __dirname: string; +declare var __filename: string; diff --git a/flow-libs/node-modules.js b/flow-libs/node-modules.js new file mode 100644 index 0000000..02c8759 --- /dev/null +++ b/flow-libs/node-modules.js @@ -0,0 +1,51 @@ +declare module 'path' { + declare module.exports: any; +} + +declare module 'fs' { + declare module.exports: any; +} + +declare module 'child_process' { + declare module.exports: any; +} + +declare module 'readline' { + declare module.exports: any; +} + +declare module 'os' { + declare module.exports: any; +} + +declare module 'dns' { + declare module.exports: any; +} + +declare module 'util' { + declare module.exports: any; +} + +declare module 'http' { + declare module.exports: any; +} + +declare module 'https' { + declare module.exports: any; +} + +declare module 'stream' { + declare module.exports: any; +} + +declare module 'events' { + declare module.exports: any; +} + +declare module 'url' { + declare module.exports: any; +} + +declare module 'crypto' { + declare module.exports: any; +} diff --git a/flow-libs/npm-modules.js b/flow-libs/npm-modules.js new file mode 100644 index 0000000..7811eee --- /dev/null +++ b/flow-libs/npm-modules.js @@ -0,0 +1,3 @@ +declare module 'pad' { + declare module.exports: any; +} diff --git a/lerna.json b/lerna.json index 0b2e105..7c4f493 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,5 @@ { - "packages": [ - "packages/*" - ], - "version": "5.0.1" -} + "$schema": "node_modules/lerna/schemas/lerna-schema.json", + "version": "7.0.0-alpha.3", + "npmClient": "npm" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index afe527c..3798bcc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10760 +1,16213 @@ { "name": "navy-monorepo", + "lockfileVersion": 3, "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@babel/cli": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.15.7.tgz", - "integrity": "sha512-YW5wOprO2LzMjoWZ5ZG6jfbY9JnkDxuHDwvnrThnuYtByorova/I0HNXJedrUfwuXFQfYOjcqDA4PU3qlZGZjg==", - "dev": true, - "requires": { - "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", - "chokidar": "^3.4.0", - "commander": "^4.0.1", - "convert-source-map": "^1.1.0", + "packages": { + "": { + "name": "navy-monorepo", + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "devDependencies": { + "@babel/cli": "^7", + "@babel/core": "^7", + "@babel/eslint-parser": "^7", + "@babel/plugin-proposal-function-bind": "7.14.5", + "@babel/plugin-transform-flow-strip-types": "^7", + "@babel/plugin-transform-runtime": "^7", + "@babel/preset-env": "^7", + "@babel/preset-typescript": "^7", + "@babel/register": "^7", + "@babel/runtime": "^7", + "@cucumber/cucumber": "^12.8.2", + "babel-plugin-add-module-exports": "^1.0.4", + "c8": "^11.0.0", + "chai": "^4.3.4", + "chai-like": "^1.1.1", + "chai-properties": "^1.4.0", + "chai-things": "^0.2.0", + "core-js": "^3", + "eslint": "^8.57.1", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-chai-friendly": "^1.2.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-promise": "^6.6.0", + "flow-bin": "^0.311.0", + "lerna": "^9.0.7", + "lodash": "^4.17.21", + "mocha": "^11.0.0", + "nock": "^14.0.13", + "node-fetch": "^2.6.5", + "node-pty": "^1.0.0", + "proxyquire": "^2.1.3", + "regenerator-runtime": "^0.14.1", + "rimraf": "^5.0.10", + "sinon": "^21.1.2", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@babel/cli": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.28.6.tgz", + "integrity": "sha512-6EUNcuBbNkj08Oj4gAZ+BUU8yLCgKzgVX4gaTh09Ya2C8ICM4P+G30g4m3akRxSYAp3A/gnWchrNst7px4/nUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.28", + "commander": "^6.2.0", + "convert-source-map": "^2.0.0", "fs-readdir-recursive": "^1.1.0", - "glob": "^7.0.0", + "glob": "^7.2.0", "make-dir": "^2.1.0", - "slash": "^2.0.0", - "source-map": "^0.5.0" - } - }, - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", - "dev": true - }, - "@babel/core": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "slash": "^2.0.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.6.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/eslint-parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz", - "integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==", + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, - "requires": { - "eslint-scope": "^5.1.1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, - "requires": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-annotate-as-pure": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", - "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", + "node_modules/@babel/eslint-parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.6.tgz", + "integrity": "sha512-QGmsKi2PBO/MHSQk+AAgA9R6OHQr+VqnniFE0eMWZcVcfBZoA2dKn2hUsl3Csg/Plt9opRUWdY7//VXsrIlEiA==", "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.15.4", - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, - "@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-create-class-features-plugin": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", - "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "regexpu-core": "^4.7.1" + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-define-polyfill-provider": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", - "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-explode-assignable-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", - "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", - "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-wrap-function": "^7.15.4", - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", - "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, - "requires": { - "@babel/types": "^7.15.4" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", - "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, - "requires": { - "@babel/helper-function-name": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", "dev": true, - "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", - "dev": true - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz", - "integrity": "sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog==", + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", - "@babel/plugin-proposal-optional-chaining": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz", - "integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.15.4", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-proposal-class-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", - "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz", - "integrity": "sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", - "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", - "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-proposal-function-bind": { + "node_modules/@babel/plugin-proposal-function-bind": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.14.5.tgz", "integrity": "sha512-PSQk5JImi81nFAzIebCEqkd0aiP9LDVKLCIH+0yR66JV8cQ1oZ8IRK9NNaA5nw9sjo0cPXxuBPCqgqcpugR8tA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-function-bind": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-json-strings": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", - "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.28.6.tgz", + "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "node_modules/@babel/plugin-syntax-function-bind": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.28.6.tgz", + "integrity": "sha512-fyZHTDBJIv9Tyr+r43EKXVg9YunTAf1DZlsxl8bzcSecAFDOoBbO9g/I+UOMWwR71OvfWTPChKY+zxqAcnnaBg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", - "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-private-methods": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", - "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", - "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", - "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" } }, - "@babel/plugin-syntax-flow": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", - "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-function-bind": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.14.5.tgz", - "integrity": "sha512-gstAIrKtlPwrQaRz4uK+kT7zI2p5MQqX41SeO+kZKH1XGO1jL0nLZBWznRigPpkem6LfIoG2EduQZmPBcUwEmg==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", + "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-flow": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-typescript": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-block-scoping": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", - "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-classes": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", - "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "globals": "^11.1.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-computed-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-destructuring": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", - "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", - "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", - "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-flow": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-for-of": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", - "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", - "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, - "requires": { - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "@babel/plugin-transform-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", - "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-amd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", - "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "babel-plugin-dynamic-import-node": "^2.3.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", - "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.15.4", - "babel-plugin-dynamic-import-node": "^2.3.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", - "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", - "babel-plugin-dynamic-import-node": "^2.3.3" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-umd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", - "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", - "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-new-target": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", - "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-object-super": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-parameters": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", - "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-transform-property-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-regenerator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz", + "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==", "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-reserved-words": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", - "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-runtime": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.8.tgz", - "integrity": "sha512-+6zsde91jMzzvkzuEA3k63zCw+tm/GvuuabkpisgbDMTPQsIMHllE3XczJFFtEHLjjhKQFZmGQVRdELetlWpVw==", + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "babel-plugin-polyfill-corejs2": "^0.2.2", - "babel-plugin-polyfill-corejs3": "^0.2.5", - "babel-plugin-polyfill-regenerator": "^0.2.2", - "semver": "^6.3.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-spread": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz", - "integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==", + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz", + "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-template-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-typescript": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", - "integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", - "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", + "node_modules/@babel/preset-env": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", + "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.29.0", + "@babel/plugin-transform-async-to-generator": "^7.28.6", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.28.6", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.29.0", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.29.0", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/preset-env": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz", - "integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==", + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4", - "@babel/plugin-proposal-async-generator-functions": "^7.15.8", - "@babel/plugin-proposal-class-properties": "^7.14.5", - "@babel/plugin-proposal-class-static-block": "^7.15.4", - "@babel/plugin-proposal-dynamic-import": "^7.14.5", - "@babel/plugin-proposal-export-namespace-from": "^7.14.5", - "@babel/plugin-proposal-json-strings": "^7.14.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", - "@babel/plugin-proposal-numeric-separator": "^7.14.5", - "@babel/plugin-proposal-object-rest-spread": "^7.15.6", - "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", - "@babel/plugin-proposal-optional-chaining": "^7.14.5", - "@babel/plugin-proposal-private-methods": "^7.14.5", - "@babel/plugin-proposal-private-property-in-object": "^7.15.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.14.5", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/plugin-transform-block-scoped-functions": "^7.14.5", - "@babel/plugin-transform-block-scoping": "^7.15.3", - "@babel/plugin-transform-classes": "^7.15.4", - "@babel/plugin-transform-computed-properties": "^7.14.5", - "@babel/plugin-transform-destructuring": "^7.14.7", - "@babel/plugin-transform-dotall-regex": "^7.14.5", - "@babel/plugin-transform-duplicate-keys": "^7.14.5", - "@babel/plugin-transform-exponentiation-operator": "^7.14.5", - "@babel/plugin-transform-for-of": "^7.15.4", - "@babel/plugin-transform-function-name": "^7.14.5", - "@babel/plugin-transform-literals": "^7.14.5", - "@babel/plugin-transform-member-expression-literals": "^7.14.5", - "@babel/plugin-transform-modules-amd": "^7.14.5", - "@babel/plugin-transform-modules-commonjs": "^7.15.4", - "@babel/plugin-transform-modules-systemjs": "^7.15.4", - "@babel/plugin-transform-modules-umd": "^7.14.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9", - "@babel/plugin-transform-new-target": "^7.14.5", - "@babel/plugin-transform-object-super": "^7.14.5", - "@babel/plugin-transform-parameters": "^7.15.4", - "@babel/plugin-transform-property-literals": "^7.14.5", - "@babel/plugin-transform-regenerator": "^7.14.5", - "@babel/plugin-transform-reserved-words": "^7.14.5", - "@babel/plugin-transform-shorthand-properties": "^7.14.5", - "@babel/plugin-transform-spread": "^7.15.8", - "@babel/plugin-transform-sticky-regex": "^7.14.5", - "@babel/plugin-transform-template-literals": "^7.14.5", - "@babel/plugin-transform-typeof-symbol": "^7.14.5", - "@babel/plugin-transform-unicode-escapes": "^7.14.5", - "@babel/plugin-transform-unicode-regex": "^7.14.5", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.15.6", - "babel-plugin-polyfill-corejs2": "^0.2.2", - "babel-plugin-polyfill-corejs3": "^0.2.5", - "babel-plugin-polyfill-regenerator": "^0.2.2", - "core-js-compat": "^3.16.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "@babel/preset-typescript": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", - "integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.15.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/register": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.15.3.tgz", - "integrity": "sha512-mj4IY1ZJkorClxKTImccn4T81+UKTo4Ux0+OFSV9hME1ooqS9UV+pJ6BjD0qXPK4T3XW/KNa79XByjeEMZz+fw==", + "node_modules/@babel/register": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.28.6.tgz", + "integrity": "sha512-pgcbbEl/dWQYb6L6Yew6F94rdwygfuv+vJ/tXfwIOYAfPB6TNWpXUMEtEq3YuTeHRdvMIhvz13bkT9CNaS+wqA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", "make-dir": "^2.1.0", - "pirates": "^4.0.0", + "pirates": "^4.0.6", "source-map-support": "^0.5.16" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", - "debug": "^4.1.0", - "globals": "^11.1.0" + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "node_modules/@balena/dockerignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", + "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==", + "license": "Apache-2.0" + }, + "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, - "requires": { - "@babel/helper-validator-identifier": "^7.14.9", - "to-fast-properties": "^2.0.0" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "@cucumber/create-meta": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/create-meta/-/create-meta-5.0.0.tgz", - "integrity": "sha512-Z5kMZkUff00S3/KSnKzB/KOm2UIxMXY1xXmj2dQMlD49lV6v/W8EEvgDMNtQotQNSOQU5bDupmWQpk+o16tXIw==", - "dev": true, - "requires": { - "@cucumber/messages": "^16.0.0" - } - }, - "@cucumber/cucumber": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-7.3.1.tgz", - "integrity": "sha512-x1+/AvouZy205ZvfYbeEVat5aBAj4EeLt9TZfD7pO9j+tQ3W6uxSuDB1TKfxAXFU3WYrswor0CXoJBYOIZhzMw==", - "dev": true, - "requires": { - "@cucumber/create-meta": "^5.0.0", - "@cucumber/cucumber-expressions": "^12.1.1", - "@cucumber/gherkin": "^19.0.3", - "@cucumber/gherkin-streams": "^2.0.2", - "@cucumber/html-formatter": "^15.0.2", - "@cucumber/messages": "^16.0.1", - "@cucumber/tag-expressions": "^3.0.1", + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cucumber/ci-environment": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-13.0.0.tgz", + "integrity": "sha512-cs+3NzfNkGbcmHPddjEv4TKFiBpZRQ6WJEEufB9mw+ExS22V/4R/zpDSEG+fsJ/iSNCd6A2sATdY8PFOyY3YnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cucumber/cucumber": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-12.8.2.tgz", + "integrity": "sha512-IvprstODr0JYTtVG7CQbphN6AGRpzzAQ1EjG7TSumuS15uvVt0inWm8/9uzX8oJwEv5ReU7JruDFim4938omog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cucumber/ci-environment": "13.0.0", + "@cucumber/cucumber-expressions": "19.0.0", + "@cucumber/gherkin": "38.0.0", + "@cucumber/gherkin-streams": "6.0.0", + "@cucumber/gherkin-utils": "11.0.0", + "@cucumber/html-formatter": "23.1.0", + "@cucumber/junit-xml-formatter": "0.13.3", + "@cucumber/message-streams": "4.1.1", + "@cucumber/messages": "32.3.1", + "@cucumber/pretty-formatter": "1.0.1", + "@cucumber/tag-expressions": "9.1.0", "assertion-error-formatter": "^3.0.0", - "bluebird": "^3.7.2", "capital-case": "^1.0.4", - "cli-table3": "^0.6.0", - "colors": "^1.4.0", - "commander": "^7.0.0", - "create-require": "^1.1.1", - "duration": "^0.2.2", - "durations": "^3.4.2", + "chalk": "^4.1.2", + "cli-table3": "0.6.5", + "commander": "^14.0.0", + "debug": "^4.3.4", + "error-stack-parser": "^2.1.4", "figures": "^3.2.0", - "glob": "^7.1.6", + "glob": "^13.0.0", + "has-ansi": "^4.0.1", "indent-string": "^4.0.0", - "is-generator": "^1.0.3", + "is-installed-globally": "^0.4.0", "is-stream": "^2.0.0", "knuth-shuffle-seeded": "^1.0.6", - "lodash": "^4.17.21", + "lodash.merge": "^4.6.2", + "lodash.mergewith": "^4.6.2", + "luxon": "3.7.2", + "mkdirp": "^3.0.0", "mz": "^2.7.0", "progress": "^2.0.3", - "resolve": "^1.19.0", - "resolve-pkg": "^2.0.0", - "stack-chain": "^2.0.0", - "stacktrace-js": "^2.0.2", - "string-argv": "^0.3.1", - "tmp": "^0.2.1", + "read-package-up": "^12.0.0", + "semver": "7.7.4", + "string-argv": "0.3.1", + "supports-color": "^8.1.1", + "type-fest": "^4.41.0", "util-arity": "^1.1.0", - "verror": "^1.10.0" + "yaml": "^2.2.2", + "yup": "1.7.1" }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } + "bin": { + "cucumber-js": "bin/cucumber.js" + }, + "engines": { + "node": "20 || 22 || >=24" + }, + "funding": { + "url": "https://opencollective.com/cucumber" } }, - "@cucumber/cucumber-expressions": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-12.1.3.tgz", - "integrity": "sha512-LB8MAzE4F/t2KIgsDEz4gZH0xSI4aG0/LmYUPyISPPjUS1pI/yGWWyeX2WsiUQxpSs765WcNIq5Bggt7gGGO3Q==", + "node_modules/@cucumber/cucumber-expressions": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-19.0.0.tgz", + "integrity": "sha512-4FKoOQh2Uf6F6/Ln+1OxuK8LkTg6PyAqekhf2Ix8zqV2M54sH+m7XNJNLhOFOAW/t9nxzRbw2CcvXbCLjcvHZg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "regexp-match-indices": "1.0.2" } }, - "@cucumber/gherkin": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-19.0.3.tgz", - "integrity": "sha512-gWdMm8mfRk3P+VugJWvNALaQV5QnT+5RkqWy3tO+4NsMSQZPo5p4V4vXwriQZ/sZR1Wni5TDRztuRsKLgZ3XHA==", + "node_modules/@cucumber/cucumber/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "requires": { - "@cucumber/message-streams": "^2.0.0", - "@cucumber/messages": "^16.0.1" - } - }, - "@cucumber/gherkin-streams": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin-streams/-/gherkin-streams-2.0.2.tgz", - "integrity": "sha512-cKmXOBz4OwGlrHMBCc4qCC3KzLaqcEZ11nWWskIbv6jyfvlIRuM2OgEF6VLcNVewczifW1p6DrDj0OO+BeXocA==", - "dev": true, - "requires": { - "@cucumber/gherkin": "^19.0.1", - "@cucumber/message-streams": "^2.0.0", - "@cucumber/messages": "^16.0.0", - "commander": "7.2.0", - "source-map-support": "0.5.19" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, - "@cucumber/html-formatter": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-15.0.2.tgz", - "integrity": "sha512-j+YGY4ytj78G/v1gZo53D+vuKXlTg/oxNwSCCGvRQo75+AqYDJSkm/vexXJQ5lY1rXAvlbZ9KI6jhg6LDs0YdQ==", + "node_modules/@cucumber/cucumber/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, - "requires": { - "@cucumber/messages": "^16.0.1", - "commander": "7.2.0", - "source-map-support": "0.5.19" - }, + "license": "MIT", "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "@cucumber/message-streams": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@cucumber/message-streams/-/message-streams-2.1.0.tgz", - "integrity": "sha512-Yh3mw3qv6QL9NI/ihkZF8V9MX2GbnR6oktv34kC3uAbrQy9d/b2SZ3HNjG3J9JQqpV4B7Om3SPElJYIeo66TrA==", + "node_modules/@cucumber/cucumber/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "dev": true, - "requires": { - "@cucumber/messages": "^16.0.1" + "license": "MIT", + "engines": { + "node": ">=20" } }, - "@cucumber/messages": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-16.0.1.tgz", - "integrity": "sha512-80JcaAfQragFqR1rMhRwiqWL9HcR6Z4LDD2mfF0Lxg/lFkCNvmWa9Jl10NUNfFXYD555NKPzP/8xFo55abw8TQ==", + "node_modules/@cucumber/cucumber/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, - "requires": { - "@types/uuid": "8.3.0", - "class-transformer": "0.4.0", - "reflect-metadata": "0.1.13", - "uuid": "8.3.2" + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@cucumber/tag-expressions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-3.0.1.tgz", - "integrity": "sha512-OGCXaJ1BQXmQ5b9pw+JYsBGumK2/LPZiLmbj1o1JFVeSNs2PY8WPQFSyXrskhrHz5Nd/6lYg7lvGMtFHOncC4w==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "node_modules/@cucumber/cucumber/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, + "license": "BlueOak-1.0.0", "dependencies": { - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - } + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "node_modules/@cucumber/cucumber/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true - }, - "@isaacs/string-locale-compare": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", - "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", - "dev": true - }, - "@lerna/add": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/add/-/add-5.6.2.tgz", - "integrity": "sha512-NHrm7kYiqP+EviguY7/NltJ3G9vGmJW6v2BASUOhP9FZDhYbq3O+rCDlFdoVRNtcyrSg90rZFMOWHph4KOoCQQ==", - "dev": true, - "requires": { - "@lerna/bootstrap": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/filter-options": "5.6.2", - "@lerna/npm-conf": "5.6.2", - "@lerna/validation-error": "5.6.2", - "dedent": "^0.7.0", - "npm-package-arg": "8.1.1", - "p-map": "^4.0.0", - "pacote": "^13.6.1", - "semver": "^7.3.4" - }, - "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "@lerna/bootstrap": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-5.6.2.tgz", - "integrity": "sha512-S2fMOEXbef7nrybQhzBywIGSLhuiQ5huPp1sU+v9Y6XEBsy/2IA+lb0gsZosvPqlRfMtiaFstL+QunaBhlWECA==", - "dev": true, - "requires": { - "@lerna/command": "5.6.2", - "@lerna/filter-options": "5.6.2", - "@lerna/has-npm-version": "5.6.2", - "@lerna/npm-install": "5.6.2", - "@lerna/package-graph": "5.6.2", - "@lerna/pulse-till-done": "5.6.2", - "@lerna/rimraf-dir": "5.6.2", - "@lerna/run-lifecycle": "5.6.2", - "@lerna/run-topologically": "5.6.2", - "@lerna/symlink-binary": "5.6.2", - "@lerna/symlink-dependencies": "5.6.2", - "@lerna/validation-error": "5.6.2", - "@npmcli/arborist": "5.3.0", - "dedent": "^0.7.0", - "get-port": "^5.1.1", - "multimatch": "^5.0.0", - "npm-package-arg": "8.1.1", - "npmlog": "^6.0.2", - "p-map": "^4.0.0", - "p-map-series": "^2.1.0", - "p-waterfall": "^2.1.1", - "semver": "^7.3.4" - }, - "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "node_modules/@cucumber/gherkin": { + "version": "38.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-38.0.0.tgz", + "integrity": "sha512-duEXK+KDfQUzu3vsSzXjkxQ2tirF5PRsc1Xrts6THKHJO6mjw4RjM8RV+vliuDasmhhrmdLcOcM7d9nurNTJKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cucumber/messages": ">=31.0.0 <33" } }, - "@lerna/changed": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-5.6.2.tgz", - "integrity": "sha512-uUgrkdj1eYJHQGsXXlpH5oEAfu3x0qzeTjgvpdNrxHEdQWi7zWiW59hRadmiImc14uJJYIwVK5q/QLugrsdGFQ==", + "node_modules/@cucumber/gherkin-streams": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-streams/-/gherkin-streams-6.0.0.tgz", + "integrity": "sha512-HLSHMmdDH0vCr7vsVEURcDA4WwnRLdjkhqr6a4HQ3i4RFK1wiDGPjBGVdGJLyuXuRdJpJbFc6QxHvT8pU4t6jw==", "dev": true, - "requires": { - "@lerna/collect-updates": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/listable": "5.6.2", - "@lerna/output": "5.6.2" + "license": "MIT", + "dependencies": { + "commander": "14.0.0", + "source-map-support": "0.5.21" + }, + "bin": { + "gherkin-javascript": "bin/gherkin" + }, + "peerDependencies": { + "@cucumber/gherkin": ">=22.0.0", + "@cucumber/message-streams": ">=4.0.0", + "@cucumber/messages": ">=17.1.1" } }, - "@lerna/check-working-tree": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-5.6.2.tgz", - "integrity": "sha512-6Vf3IB6p+iNIubwVgr8A/KOmGh5xb4SyRmhFtAVqe33yWl2p3yc+mU5nGoz4ET3JLF1T9MhsePj0hNt6qyOTLQ==", + "node_modules/@cucumber/gherkin-streams/node_modules/commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", "dev": true, - "requires": { - "@lerna/collect-uncommitted": "5.6.2", - "@lerna/describe-ref": "5.6.2", - "@lerna/validation-error": "5.6.2" + "license": "MIT", + "engines": { + "node": ">=20" } }, - "@lerna/child-process": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-5.6.2.tgz", - "integrity": "sha512-QIOQ3jIbWdduHd5892fbo3u7/dQgbhzEBB7cvf+Ys/iCPP8UQrBECi1lfRgA4kcTKC2MyMz0SoyXZz/lFcXc3A==", + "node_modules/@cucumber/gherkin-utils": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-11.0.0.tgz", + "integrity": "sha512-LJ+s4+TepHTgdKWDR4zbPyT7rQjmYIcukTwNbwNwgqr6i8Gjcmzf6NmtbYDA19m1ZFg6kWbFsmHnj37ZuX+kZA==", "dev": true, - "requires": { - "chalk": "^4.1.0", - "execa": "^5.0.0", - "strong-log-transformer": "^2.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "license": "MIT", + "dependencies": { + "@cucumber/gherkin": "^38.0.0", + "@cucumber/messages": "^32.0.0", + "@teppeis/multimaps": "3.0.0", + "commander": "14.0.2", + "source-map-support": "^0.5.21" + }, + "bin": { + "gherkin-utils": "bin/gherkin-utils" } }, - "@lerna/clean": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-5.6.2.tgz", - "integrity": "sha512-A7j8r0Hk2pGyLUyaCmx4keNHen1L/KdcOjb4nR6X8GtTJR5AeA47a8rRKOCz9wwdyMPlo2Dau7d3RV9viv7a5g==", + "node_modules/@cucumber/gherkin-utils/node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", "dev": true, - "requires": { - "@lerna/command": "5.6.2", - "@lerna/filter-options": "5.6.2", - "@lerna/prompt": "5.6.2", - "@lerna/pulse-till-done": "5.6.2", - "@lerna/rimraf-dir": "5.6.2", - "p-map": "^4.0.0", - "p-map-series": "^2.1.0", - "p-waterfall": "^2.1.1" + "license": "MIT", + "engines": { + "node": ">=20" } }, - "@lerna/cli": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-5.6.2.tgz", - "integrity": "sha512-w0NRIEqDOmYKlA5t0iyqx0hbY7zcozvApmfvwF0lhkuhf3k6LRAFSamtimGQWicC779a7J2NXw4ASuBV47Fs1Q==", + "node_modules/@cucumber/html-formatter": { + "version": "23.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-23.1.0.tgz", + "integrity": "sha512-DcCSFoGs6jbwzXPgX1CwgJKEE+ZMcIEzq/0Memg0o24maNn9NJizBFHmoFWG4iv/OxHza+mvc+56cTHetfHndw==", "dev": true, - "requires": { - "@lerna/global-options": "5.6.2", - "dedent": "^0.7.0", - "npmlog": "^6.0.2", - "yargs": "^16.2.0" + "license": "MIT", + "peerDependencies": { + "@cucumber/messages": ">=18" } }, - "@lerna/collect-uncommitted": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-5.6.2.tgz", - "integrity": "sha512-i0jhxpypyOsW2PpPwIw4xg6EPh7/N3YuiI6P2yL7PynZ8nOv8DkIdoyMkhUP4gALjBfckH8Bj94eIaKMviqW4w==", + "node_modules/@cucumber/junit-xml-formatter": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/@cucumber/junit-xml-formatter/-/junit-xml-formatter-0.13.3.tgz", + "integrity": "sha512-w9ujOxiuKDtU6fLzJz+wp4Sgp5Xu6ba7ls00LHJccVmQU0Ba7zs+AHnv3iIgPjKZAQe1w8x93dr8Gaubh7Vqkg==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "chalk": "^4.1.0", - "npmlog": "^6.0.2" - }, + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "@cucumber/query": "^15.0.1", + "@teppeis/multimaps": "^3.0.0", + "luxon": "^3.5.0", + "xmlbuilder": "^15.1.1" + }, + "peerDependencies": { + "@cucumber/messages": "*" } }, - "@lerna/collect-updates": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-5.6.2.tgz", - "integrity": "sha512-DdTK13X6PIsh9HINiMniFeiivAizR/1FBB+hDVe6tOhsXFBfjHMw1xZhXlE+mYIoFmDm1UFK7zvQSexoaxRqFA==", + "node_modules/@cucumber/message-streams": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@cucumber/message-streams/-/message-streams-4.1.1.tgz", + "integrity": "sha512-QCAntLajesWMyX+mZKrj63YghVAts7yKFlZe46XprLbdJZN0ddB+f/Mr9OnyWKC2DHhJ18jzCfKIFCaqpAmUxg==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/describe-ref": "5.6.2", - "minimatch": "^3.0.4", - "npmlog": "^6.0.2", - "slash": "^3.0.0" - }, + "license": "MIT", "dependencies": { - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } + "mime": "^3.0.0" + }, + "peerDependencies": { + "@cucumber/messages": ">=17.1.1" } }, - "@lerna/command": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/command/-/command-5.6.2.tgz", - "integrity": "sha512-eLVGI9TmxcaGt1M7TXGhhBZoeWOtOedMiH7NuCGHtL6TMJ9k+SCExyx+KpNmE6ImyNOzws6EvYLPLjftiqmoaA==", + "node_modules/@cucumber/messages": { + "version": "32.3.1", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-32.3.1.tgz", + "integrity": "sha512-yNQq1KoXRYaEKrWMFmpUQX7TdeQuU9jeGgJAZ3dArTsC/T4NpJ6DnqaJIIgwPnz/wtQIQTNX7/h0rOuF5xY4qQ==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/package-graph": "5.6.2", - "@lerna/project": "5.6.2", - "@lerna/validation-error": "5.6.2", - "@lerna/write-log-file": "5.6.2", - "clone-deep": "^4.0.1", - "dedent": "^0.7.0", - "execa": "^5.0.0", - "is-ci": "^2.0.0", - "npmlog": "^6.0.2" - } - }, - "@lerna/conventional-commits": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-5.6.2.tgz", - "integrity": "sha512-fPrJpYJhxCgY2uyOCTcAAC6+T6lUAtpEGxLbjWHWTb13oKKEygp9THoFpe6SbAD0fYMb3jeZCZCqNofM62rmuA==", - "dev": true, - "requires": { - "@lerna/validation-error": "5.6.2", - "conventional-changelog-angular": "^5.0.12", - "conventional-changelog-core": "^4.2.4", - "conventional-recommended-bump": "^6.1.0", - "fs-extra": "^9.1.0", - "get-stream": "^6.0.0", - "npm-package-arg": "8.1.1", - "npmlog": "^6.0.2", - "pify": "^5.0.0", - "semver": "^7.3.4" - }, + "license": "MIT", "dependencies": { - "pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "dev": true - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@lerna/create": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-5.6.2.tgz", - "integrity": "sha512-+Y5cMUxMNXjTTU9IHpgRYIwKo39w+blui1P+s+qYlZUSCUAew0xNpOBG8iN0Nc5X9op4U094oIdHxv7Dyz6tWQ==", - "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/npm-conf": "5.6.2", - "@lerna/validation-error": "5.6.2", - "dedent": "^0.7.0", - "fs-extra": "^9.1.0", - "init-package-json": "^3.0.2", - "npm-package-arg": "8.1.1", - "p-reduce": "^2.1.0", - "pacote": "^13.6.1", - "pify": "^5.0.0", - "semver": "^7.3.4", - "slash": "^3.0.0", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^4.0.0", - "yargs-parser": "20.2.4" - }, - "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "dev": true - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } + "class-transformer": "0.5.1", + "reflect-metadata": "0.2.2" } }, - "@lerna/create-symlink": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-5.6.2.tgz", - "integrity": "sha512-0WIs3P6ohPVh2+t5axrLZDE5Dt7fe3Kv0Auj0sBiBd6MmKZ2oS76apIl0Bspdbv8jX8+TRKGv6ib0280D0dtEw==", + "node_modules/@cucumber/pretty-formatter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cucumber/pretty-formatter/-/pretty-formatter-1.0.1.tgz", + "integrity": "sha512-A1lU4VVP0aUWdOTmpdzvXOyEYuPtBDI0xYwYJnmoMDplzxMdhcHk86lyyvYDoMoPzzq6OkOE3isuosvUU4X7IQ==", "dev": true, - "requires": { - "cmd-shim": "^5.0.0", - "fs-extra": "^9.1.0", - "npmlog": "^6.0.2" + "license": "MIT", + "dependencies": { + "ansi-styles": "^5.0.0", + "cli-table3": "^0.6.0", + "figures": "^3.2.0", + "ts-dedent": "^2.0.0" + }, + "peerDependencies": { + "@cucumber/cucumber": ">=7.0.0", + "@cucumber/messages": "*" } }, - "@lerna/describe-ref": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-5.6.2.tgz", - "integrity": "sha512-UqU0N77aT1W8duYGir7R+Sk3jsY/c4lhcCEcnayMpFScMbAp0ETGsW04cYsHK29sgg+ZCc5zEwebBqabWhMhnA==", + "node_modules/@cucumber/query": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-15.0.1.tgz", + "integrity": "sha512-FMfT3orJblRsOxvU2doECBvQmauizYlj+5JsM8atAKKPbnQTj7v2/OrnuykvQpfZNBf19DYbRq1e832vllRP/g==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "npmlog": "^6.0.2" + "license": "MIT", + "dependencies": { + "@teppeis/multimaps": "3.0.0", + "lodash.sortby": "^4.7.0" + }, + "peerDependencies": { + "@cucumber/messages": "*" } }, - "@lerna/diff": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-5.6.2.tgz", - "integrity": "sha512-aHKzKvUvUI8vOcshC2Za/bdz+plM3r/ycqUrPqaERzp+kc1pYHyPeXezydVdEmgmmwmyKI5hx4+2QNnzOnun2A==", + "node_modules/@cucumber/tag-expressions": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-9.1.0.tgz", + "integrity": "sha512-bvHjcRFZ+J1TqIa9eFNO1wGHqwx4V9ZKV3hYgkuK/VahHx73uiP4rKV3JVrvWSMrwrFvJG6C8aEwnCWSvbyFdQ==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/validation-error": "5.6.2", - "npmlog": "^6.0.2" - } + "license": "MIT" }, - "@lerna/exec": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-5.6.2.tgz", - "integrity": "sha512-meZozok5stK7S0oAVn+kdbTmU+kHj9GTXjW7V8kgwG9ld+JJMTH3nKK1L3mEKyk9TFu9vFWyEOF7HNK6yEOoVg==", + "node_modules/@emnapi/core": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", + "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/filter-options": "5.6.2", - "@lerna/profiler": "5.6.2", - "@lerna/run-topologically": "5.6.2", - "@lerna/validation-error": "5.6.2", - "p-map": "^4.0.0" + "license": "MIT", + "dependencies": { + "@emnapi/wasi-threads": "1.0.4", + "tslib": "^2.4.0" } }, - "@lerna/filter-options": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-5.6.2.tgz", - "integrity": "sha512-4Z0HIhPak2TabTsUqEBQaQeOqgqEt0qyskvsY0oviYvqP/nrJfJBZh4H93jIiNQF59LJCn5Ce3KJJrLExxjlzw==", + "node_modules/@emnapi/runtime": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", + "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", "dev": true, - "requires": { - "@lerna/collect-updates": "5.6.2", - "@lerna/filter-packages": "5.6.2", - "dedent": "^0.7.0", - "npmlog": "^6.0.2" + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" } }, - "@lerna/filter-packages": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-5.6.2.tgz", - "integrity": "sha512-el9V2lTEG0Bbz+Omo45hATkRVnChCTJhcTpth19cMJ6mQ4M5H4IgbWCJdFMBi/RpTnOhz9BhJxDbj95kuIvvzw==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", + "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", "dev": true, - "requires": { - "@lerna/validation-error": "5.6.2", - "multimatch": "^5.0.0", - "npmlog": "^6.0.2" + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" } }, - "@lerna/get-npm-exec-opts": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-5.6.2.tgz", - "integrity": "sha512-0RbSDJ+QC9D5UWZJh3DN7mBIU1NhBmdHOE289oHSkjDY+uEjdzMPkEUy+wZ8fCzMLFnnNQkAEqNaOAzZ7dmFLA==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, - "requires": { - "npmlog": "^6.0.2" + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "@lerna/get-packed": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-5.6.2.tgz", - "integrity": "sha512-pp5nNDmtrtd21aKHjwwOY5CS7XNIHxINzGa+Jholn1jMDYUtdskpN++ZqYbATGpW831++NJuiuBVyqAWi9xbXg==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "requires": { - "fs-extra": "^9.1.0", - "ssri": "^9.0.1", - "tar": "^6.1.0" + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "@lerna/github-client": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-5.6.2.tgz", - "integrity": "sha512-pjALazZoRZtKqfwLBwmW3HPptVhQm54PvA8s3qhCQ+3JkqrZiIFwkkxNZxs3jwzr+aaSOzfhSzCndg0urb0GXA==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@octokit/plugin-enterprise-rest": "^6.0.1", - "@octokit/rest": "^19.0.3", - "git-url-parse": "^13.1.0", - "npmlog": "^6.0.2" + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "@lerna/gitlab-client": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/gitlab-client/-/gitlab-client-5.6.2.tgz", - "integrity": "sha512-TInJmbrsmYIwUyrRxytjO82KjJbRwm67F7LoZs1shAq6rMvNqi4NxSY9j+hT/939alFmEq1zssoy/caeLXHRfQ==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "requires": { - "node-fetch": "^2.6.1", - "npmlog": "^6.0.2" - } - }, - "@lerna/global-options": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-5.6.2.tgz", - "integrity": "sha512-kaKELURXTlczthNJskdOvh6GGMyt24qat0xMoJZ8plYMdofJfhz24h1OFcvB/EwCUwP/XV1+ohE5P+vdktbrEg==", - "dev": true + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } }, - "@lerna/has-npm-version": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-5.6.2.tgz", - "integrity": "sha512-kXCnSzffmTWsaK0ol30coyCfO8WH26HFbmJjRBzKv7VGkuAIcB6gX2gqRRgNLLlvI+Yrp+JSlpVNVnu15SEH2g==", + "node_modules/@gar/promise-retry": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@gar/promise-retry/-/promise-retry-1.0.3.tgz", + "integrity": "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "semver": "^7.3.4" + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", + "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "license": "Apache-2.0", "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.3", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" } }, - "@lerna/import": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/import/-/import-5.6.2.tgz", - "integrity": "sha512-xQUE49mtcP0z3KUdXBsyvp8rGDz6phuYUoQbhcFRJ7WPcQKzMvtm0XYrER6c2YWEX7QOuDac6tU82P8zTrTBaA==", - "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/prompt": "5.6.2", - "@lerna/pulse-till-done": "5.6.2", - "@lerna/validation-error": "5.6.2", - "dedent": "^0.7.0", - "fs-extra": "^9.1.0", - "p-map-series": "^2.1.0" - } - }, - "@lerna/info": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/info/-/info-5.6.2.tgz", - "integrity": "sha512-MPjY5Olj+fiZHgfEdwXUFRKamdEuLr9Ob/qut8JsB/oQSQ4ALdQfnrOcMT8lJIcC2R67EA5yav2lHPBIkezm8A==", - "dev": true, - "requires": { - "@lerna/command": "5.6.2", - "@lerna/output": "5.6.2", - "envinfo": "^7.7.4" - } - }, - "@lerna/init": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/init/-/init-5.6.2.tgz", - "integrity": "sha512-ahU3/lgF+J8kdJAQysihFJROHthkIDXfHmvhw7AYnzf94HjxGNXj7nz6i3At1/dM/1nQhR+4/uNR1/OU4tTYYQ==", - "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/project": "5.6.2", - "fs-extra": "^9.1.0", - "p-map": "^4.0.0", - "write-json-file": "^4.3.0" - } - }, - "@lerna/link": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/link/-/link-5.6.2.tgz", - "integrity": "sha512-hXxQ4R3z6rUF1v2x62oIzLyeHL96u7ZBhxqYMJrm763D1VMSDcHKF9CjJfc6J9vH5Z2ZbL6CQg50Hw5mUpJbjg==", - "dev": true, - "requires": { - "@lerna/command": "5.6.2", - "@lerna/package-graph": "5.6.2", - "@lerna/symlink-dependencies": "5.6.2", - "@lerna/validation-error": "5.6.2", - "p-map": "^4.0.0", - "slash": "^3.0.0" - }, - "dependencies": { - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" } }, - "@lerna/list": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/list/-/list-5.6.2.tgz", - "integrity": "sha512-WjE5O2tQ3TcS+8LqXUaxi0YdldhxUhNihT5+Gg4vzGdIlrPDioO50Zjo9d8jOU7i3LMIk6EzCma0sZr2CVfEGg==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, - "requires": { - "@lerna/command": "5.6.2", - "@lerna/filter-options": "5.6.2", - "@lerna/listable": "5.6.2", - "@lerna/output": "5.6.2" + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" } }, - "@lerna/listable": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-5.6.2.tgz", - "integrity": "sha512-8Yp49BwkY/5XqVru38Zko+6Wj/sgbwzJfIGEPy3Qu575r1NA/b9eI1gX22aMsEeXUeGOybR7nWT5ewnPQHjqvA==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "requires": { - "@lerna/query-graph": "5.6.2", - "chalk": "^4.1.0", - "columnify": "^1.6.0" + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "@lerna/log-packed": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-5.6.2.tgz", - "integrity": "sha512-O9GODG7tMtWk+2fufn2MOkIDBYMRoKBhYMHshO5Aw/VIsH76DIxpX1koMzWfUngM/C70R4uNAKcVWineX4qzIw==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", "dev": true, - "requires": { - "byte-size": "^7.0.0", - "columnify": "^1.6.0", - "has-unicode": "^2.0.1", - "npmlog": "^6.0.2" + "license": "Apache-2.0", + "engines": { + "node": ">=6.9.0" } }, - "@lerna/npm-conf": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-5.6.2.tgz", - "integrity": "sha512-gWDPhw1wjXYXphk/PAghTLexO5T6abVFhXb+KOMCeem366mY0F5bM88PiorL73aErTNUoR8n+V4X29NTZzDZpQ==", + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", "dev": true, - "requires": { - "config-chain": "^1.1.12", - "pify": "^5.0.0" - }, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, + "license": "MIT", "dependencies": { - "pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "dev": true + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "@lerna/npm-dist-tag": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-5.6.2.tgz", - "integrity": "sha512-t2RmxV6Eog4acXkUI+EzWuYVbeVVY139pANIWS9qtdajfgp4GVXZi1S8mAIb70yeHdNpCp1mhK0xpCrFH9LvGQ==", + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "dev": true, - "requires": { - "@lerna/otplease": "5.6.2", - "npm-package-arg": "8.1.1", - "npm-registry-fetch": "^13.3.0", - "npmlog": "^6.0.2" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "@lerna/npm-install": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-5.6.2.tgz", - "integrity": "sha512-AT226zdEo+uGENd37jwYgdALKJAIJK4pNOfmXWZWzVb9oMOr8I2YSjPYvSYUNG7gOo2YJQU8x5Zd7OShv2924Q==", + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/get-npm-exec-opts": "5.6.2", - "fs-extra": "^9.1.0", - "npm-package-arg": "8.1.1", - "npmlog": "^6.0.2", - "signal-exit": "^3.0.3", - "write-pkg": "^4.0.0" - } - }, - "@lerna/npm-publish": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-5.6.2.tgz", - "integrity": "sha512-ldSyewCfv9fAeC5xNjL0HKGSUxcC048EJoe/B+KRUmd+IPidvZxMEzRu08lSC/q3V9YeUv9ZvRnxATXOM8CffA==", - "dev": true, - "requires": { - "@lerna/otplease": "5.6.2", - "@lerna/run-lifecycle": "5.6.2", - "fs-extra": "^9.1.0", - "libnpmpublish": "^6.0.4", - "npm-package-arg": "8.1.1", - "npmlog": "^6.0.2", - "pify": "^5.0.0", - "read-package-json": "^5.0.1" - }, - "dependencies": { - "pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "dev": true + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "@lerna/npm-run-script": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-5.6.2.tgz", - "integrity": "sha512-MOQoWNcAyJivM8SYp0zELM7vg/Dj07j4YMdxZkey+S1UO0T4/vKBxb575o16hH4WeNzC3Pd7WBlb7C8dLOfNwQ==", + "node_modules/@inquirer/core/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "@lerna/get-npm-exec-opts": "5.6.2", - "npmlog": "^6.0.2" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@lerna/otplease": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/otplease/-/otplease-5.6.2.tgz", - "integrity": "sha512-dGS4lzkEQVTMAgji82jp8RK6UK32wlzrBAO4P4iiVHCUTuwNLsY9oeBXvVXSMrosJnl6Hbe0NOvi43mqSucGoA==", + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dev": true, - "requires": { - "@lerna/prompt": "5.6.2" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "@lerna/output": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/output/-/output-5.6.2.tgz", - "integrity": "sha512-++d+bfOQwY66yo7q1XuAvRcqtRHCG45e/awP5xQomTZ6R1rhWiZ3whWdc9Z6lF7+UtBB9toSYYffKU/xc3L0yQ==", + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "dev": true, - "requires": { - "npmlog": "^6.0.2" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "@lerna/pack-directory": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-5.6.2.tgz", - "integrity": "sha512-w5Jk5fo+HkN4Le7WMOudTcmAymcf0xPd302TqAQncjXpk0cb8tZbj+5bbNHsGb58GRjOIm5icQbHXooQUxbHhA==", + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, - "requires": { - "@lerna/get-packed": "5.6.2", - "@lerna/package": "5.6.2", - "@lerna/run-lifecycle": "5.6.2", - "@lerna/temp-write": "5.6.2", - "npm-packlist": "^5.1.1", - "npmlog": "^6.0.2", - "tar": "^6.1.0" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "@lerna/package": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/package/-/package-5.6.2.tgz", - "integrity": "sha512-LaOC8moyM5J9WnRiWZkedjOninSclBOJyPqhif6mHb2kCFX6jAroNYzE8KM4cphu8CunHuhI6Ixzswtv+Dultw==", + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dev": true, - "requires": { - "load-json-file": "^6.2.0", - "npm-package-arg": "8.1.1", - "write-pkg": "^4.0.0" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "@lerna/package-graph": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-5.6.2.tgz", - "integrity": "sha512-TmL61qBBvA3Tc4qICDirZzdFFwWOA6qicIXUruLiE2PblRowRmCO1bKrrP6XbDOspzwrkPef6N2F2/5gHQAnkQ==", + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dev": true, - "requires": { - "@lerna/prerelease-id-from-version": "5.6.2", - "@lerna/validation-error": "5.6.2", - "npm-package-arg": "8.1.1", - "npmlog": "^6.0.2", - "semver": "^7.3.4" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", + "dev": true, + "license": "MIT", "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "@lerna/prerelease-id-from-version": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-5.6.2.tgz", - "integrity": "sha512-7gIm9fecWFVNy2kpj/KbH11bRcpyANAwpsft3X5m6J7y7A6FTUscCbEvl3ZNdpQKHNuvnHgCtkm3A5PMSCEgkA==", + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dev": true, - "requires": { - "semver": "^7.3.4" + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", + "dev": true, + "license": "MIT", "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "@lerna/profiler": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/profiler/-/profiler-5.6.2.tgz", - "integrity": "sha512-okwkagP5zyRIOYTceu/9/esW7UZFt7lyL6q6ZgpSG3TYC5Ay+FXLtS6Xiha/FQdVdumFqKULDWTGovzUlxcwaw==", + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "dev": true, - "requires": { - "fs-extra": "^9.1.0", - "npmlog": "^6.0.2", - "upath": "^2.0.1" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "@lerna/project": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/project/-/project-5.6.2.tgz", - "integrity": "sha512-kPIMcIy/0DVWM91FPMMFmXyAnCuuLm3NdhnA8NusE//VuY9wC6QC/3OwuCY39b2dbko/fPZheqKeAZkkMH6sGg==", + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dev": true, - "requires": { - "@lerna/package": "5.6.2", - "@lerna/validation-error": "5.6.2", - "cosmiconfig": "^7.0.0", - "dedent": "^0.7.0", - "dot-prop": "^6.0.1", - "glob-parent": "^5.1.1", - "globby": "^11.0.2", - "js-yaml": "^4.1.0", - "load-json-file": "^6.2.0", - "npmlog": "^6.0.2", - "p-map": "^4.0.0", - "resolve-from": "^5.0.0", - "write-json-file": "^4.3.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "@lerna/prompt": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-5.6.2.tgz", - "integrity": "sha512-4hTNmVYADEr0GJTMegWV+GW6n+dzKx1vN9v2ISqyle283Myv930WxuyO0PeYGqTrkneJsyPreCMovuEGCvZ0iQ==", - "dev": true, - "requires": { - "inquirer": "^8.2.4", - "npmlog": "^6.0.2" - } - }, - "@lerna/publish": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-5.6.2.tgz", - "integrity": "sha512-QaW0GjMJMuWlRNjeDCjmY/vjriGSWgkLS23yu8VKNtV5U3dt5yIKA3DNGV3HgZACuu45kQxzMDsfLzgzbGNtYA==", - "dev": true, - "requires": { - "@lerna/check-working-tree": "5.6.2", - "@lerna/child-process": "5.6.2", - "@lerna/collect-updates": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/describe-ref": "5.6.2", - "@lerna/log-packed": "5.6.2", - "@lerna/npm-conf": "5.6.2", - "@lerna/npm-dist-tag": "5.6.2", - "@lerna/npm-publish": "5.6.2", - "@lerna/otplease": "5.6.2", - "@lerna/output": "5.6.2", - "@lerna/pack-directory": "5.6.2", - "@lerna/prerelease-id-from-version": "5.6.2", - "@lerna/prompt": "5.6.2", - "@lerna/pulse-till-done": "5.6.2", - "@lerna/run-lifecycle": "5.6.2", - "@lerna/run-topologically": "5.6.2", - "@lerna/validation-error": "5.6.2", - "@lerna/version": "5.6.2", - "fs-extra": "^9.1.0", - "libnpmaccess": "^6.0.3", - "npm-package-arg": "8.1.1", - "npm-registry-fetch": "^13.3.0", - "npmlog": "^6.0.2", - "p-map": "^4.0.0", - "p-pipe": "^3.1.0", - "pacote": "^13.6.1", - "semver": "^7.3.4" - }, - "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "@lerna/pulse-till-done": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-5.6.2.tgz", - "integrity": "sha512-eA/X1RCxU5YGMNZmbgPi+Kyfx1Q3bn4P9jo/LZy+/NRRr1po3ASXP2GJZ1auBh/9A2ELDvvKTOXCVHqczKC6rA==", + "node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", "dev": true, - "requires": { - "npmlog": "^6.0.2" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, - "@lerna/query-graph": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-5.6.2.tgz", - "integrity": "sha512-KRngr96yBP8XYDi9/U62fnGO+ZXqm04Qk6a2HtoTr/ha8QvO1s7Tgm0xs/G7qWXDQHZgunWIbmK/LhxM7eFQrw==", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, - "requires": { - "@lerna/package-graph": "5.6.2" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" } }, - "@lerna/resolve-symlink": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-5.6.2.tgz", - "integrity": "sha512-PDQy+7M8JEFtwIVHJgWvSxHkxJf9zXCENkvIWDB+SsoDPhw9+caewt46bTeP5iGm9pOMu3oZukaWo/TvF7sNjg==", + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", + "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", "dev": true, - "requires": { - "fs-extra": "^9.1.0", - "npmlog": "^6.0.2", - "read-cmd-shim": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "@lerna/rimraf-dir": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-5.6.2.tgz", - "integrity": "sha512-jgEfzz7uBUiQKteq3G8MtJiA2D2VoKmZSSY3VSiW/tPOSXYxxSHxEsClQdCeNa6+sYrDNDT8fP6MJ3lPLjDeLA==", + "node_modules/@jest/diff-sequences": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true, - "requires": { - "@lerna/child-process": "5.6.2", - "npmlog": "^6.0.2", - "path-exists": "^4.0.0", - "rimraf": "^3.0.2" - }, - "dependencies": { - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@lerna/run": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/run/-/run-5.6.2.tgz", - "integrity": "sha512-c2kJxdFrNg5KOkrhmgwKKUOsfSrGNlFCe26EttufOJ3xfY0VnXlEw9rHOkTgwtu7969rfCdyaVP1qckMrF1Dgw==", + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", "dev": true, - "requires": { - "@lerna/command": "5.6.2", - "@lerna/filter-options": "5.6.2", - "@lerna/npm-run-script": "5.6.2", - "@lerna/output": "5.6.2", - "@lerna/profiler": "5.6.2", - "@lerna/run-topologically": "5.6.2", - "@lerna/timer": "5.6.2", - "@lerna/validation-error": "5.6.2", - "fs-extra": "^9.1.0", - "p-map": "^4.0.0" + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@lerna/run-lifecycle": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-5.6.2.tgz", - "integrity": "sha512-u9gGgq/50Fm8dvfcc/TSHOCAQvzLD7poVanDMhHYWOAqRDnellJEEmA1K/Yka4vZmySrzluahkry9G6jcREt+g==", + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, - "requires": { - "@lerna/npm-conf": "5.6.2", - "@npmcli/run-script": "^4.1.7", - "npmlog": "^6.0.2", - "p-queue": "^6.6.2" + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@lerna/run-topologically": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-5.6.2.tgz", - "integrity": "sha512-QQ/jGOIsVvUg3izShWsd67RlWYh9UOH2yw97Ol1zySX9+JspCMVQrn9eKq1Pk8twQOFhT87LpT/aaxbTBgREPw==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, - "requires": { - "@lerna/query-graph": "5.6.2", - "p-queue": "^6.6.2" + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "@lerna/symlink-binary": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-5.6.2.tgz", - "integrity": "sha512-Cth+miwYyO81WAmrQbPBrLHuF+F0UUc0el5kRXLH6j5zzaRS3kMM68r40M7MmfH8m3GPi7691UARoWFEotW5jw==", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, - "requires": { - "@lerna/create-symlink": "5.6.2", - "@lerna/package": "5.6.2", - "fs-extra": "^9.1.0", - "p-map": "^4.0.0" + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "@lerna/symlink-dependencies": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-5.6.2.tgz", - "integrity": "sha512-dUVNQLEcjVOIQiT9OlSAKt0ykjyJPy8l9i4NJDe2/0XYaUjo8PWsxJ0vrutz27jzi2aZUy07ASmowQZEmnLHAw==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "requires": { - "@lerna/create-symlink": "5.6.2", - "@lerna/resolve-symlink": "5.6.2", - "@lerna/symlink-binary": "5.6.2", - "fs-extra": "^9.1.0", - "p-map": "^4.0.0", - "p-map-series": "^2.1.0" + "license": "MIT", + "engines": { + "node": ">=6.0.0" } }, - "@lerna/temp-write": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/temp-write/-/temp-write-5.6.2.tgz", - "integrity": "sha512-S5ZNVTurSwWBmc9kh5alfSjmO3+BnRT6shYtOlmVIUYqWeYVYA5C1Htj322bbU4CSNCMFK6NQl4qGKL17HMuig==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "is-stream": "^2.0.0", - "make-dir": "^3.0.0", - "temp-dir": "^1.0.0", - "uuid": "^8.3.2" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@lerna/timer": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-5.6.2.tgz", - "integrity": "sha512-AjMOiLc2B+5Nzdd9hNORetAdZ/WK8YNGX/+2ypzM68TMAPfIT5C40hMlSva9Yg4RsBz22REopXgM5s2zQd5ZQA==", - "dev": true - }, - "@lerna/validation-error": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-5.6.2.tgz", - "integrity": "sha512-4WlDUHaa+RSJNyJRtX3gVIAPVzjZD2tle8AJ0ZYBfdZnZmG0VlB2pD1FIbOQPK8sY2h5m0cHLRvfLoLncqHvdQ==", - "dev": true, - "requires": { - "npmlog": "^6.0.2" - } - }, - "@lerna/version": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-5.6.2.tgz", - "integrity": "sha512-odNSR2rTbHW++xMZSQKu/F6Syrd/sUvwDLPaMKktoOSPKmycHt/eWcuQQyACdtc43Iqeu4uQd7PCLsniqOVFrw==", - "dev": true, - "requires": { - "@lerna/check-working-tree": "5.6.2", - "@lerna/child-process": "5.6.2", - "@lerna/collect-updates": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/conventional-commits": "5.6.2", - "@lerna/github-client": "5.6.2", - "@lerna/gitlab-client": "5.6.2", - "@lerna/output": "5.6.2", - "@lerna/prerelease-id-from-version": "5.6.2", - "@lerna/prompt": "5.6.2", - "@lerna/run-lifecycle": "5.6.2", - "@lerna/run-topologically": "5.6.2", - "@lerna/temp-write": "5.6.2", - "@lerna/validation-error": "5.6.2", - "@nrwl/devkit": ">=14.8.1 < 16", - "chalk": "^4.1.0", - "dedent": "^0.7.0", - "load-json-file": "^6.2.0", - "minimatch": "^3.0.4", - "npmlog": "^6.0.2", - "p-map": "^4.0.0", - "p-pipe": "^3.1.0", - "p-reduce": "^2.1.0", - "p-waterfall": "^2.1.1", - "semver": "^7.3.4", - "slash": "^3.0.0", - "write-json-file": "^4.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" } }, - "@lerna/write-log-file": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-5.6.2.tgz", - "integrity": "sha512-J09l18QnWQ3sXIRwuJkjXY3+KwPR2uO5NgbZGE3GXJK1V/LzOBRMvjGAIbuQHXw25uqe7vpLUpB8drtnFrubCQ==", + "node_modules/@mswjs/interceptors": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.41.7.tgz", + "integrity": "sha512-D0nkS5+sx87mYpxFqASImCineYoEl9wGlUPrzkuS0ohzG8wfophLpE+I76qGJ0slLAVI19do5SI9pWJNCVf4fg==", "dev": true, - "requires": { - "npmlog": "^6.0.2", - "write-file-atomic": "^4.0.1" + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", + "integrity": "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==", + "dev": true, + "license": "MIT", "dependencies": { - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - } + "@emnapi/core": "^1.1.0", + "@emnapi/runtime": "^1.1.0", + "@tybys/wasm-util": "^0.9.0" } }, - "@nicolo-ribaudo/chokidar-2": { + "node_modules/@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", "dev": true, + "license": "MIT", "optional": true }, - "@nodelib/fs.scandir": { + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "@nodelib/fs.stat": { + "node_modules/@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } }, - "@nodelib/fs.walk": { + "node_modules/@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "@npmcli/arborist": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-5.3.0.tgz", - "integrity": "sha512-+rZ9zgL1lnbl8Xbb1NQdMjveOMwj4lIYfcDtyJHHi5x4X8jtR6m8SXooJMZy5vmFVZ8w7A2Bnd/oX9eTuU8w5A==", + "node_modules/@npmcli/agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", + "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@npmcli/arborist": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-9.1.6.tgz", + "integrity": "sha512-c5Pr3EG8UP5ollkJy2x+UdEQC5sEHe3H9whYn6hb2HJimAKS4zmoJkx5acCiR/g4P38RnCSMlsYQyyHnKYeLvQ==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/metavuln-calculator": "^3.0.1", - "@npmcli/move-file": "^2.0.0", - "@npmcli/name-from-folder": "^1.0.1", - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/package-json": "^2.0.0", - "@npmcli/run-script": "^4.1.3", - "bin-links": "^3.0.0", - "cacache": "^16.0.6", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/metavuln-calculator": "^9.0.2", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^10.0.0", + "bin-links": "^5.0.0", + "cacache": "^20.0.1", "common-ancestor-path": "^1.0.1", - "json-parse-even-better-errors": "^2.3.1", + "hosted-git-info": "^9.0.0", "json-stringify-nice": "^1.1.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^5.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.0.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "parse-conflict-json": "^2.0.1", - "proc-log": "^2.0.0", + "lru-cache": "^11.2.1", + "minimatch": "^10.0.3", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^13.0.0", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "pacote": "^21.0.2", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.1", - "read-package-json-fast": "^2.0.2", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", + "promise-call-limit": "^3.0.1", "semver": "^7.3.7", - "ssri": "^9.0.0", - "treeverse": "^2.0.0", - "walk-up-path": "^1.0.0" - }, - "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "npm-package-arg": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz", - "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - } + "ssri": "^12.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^4.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "node_modules/@npmcli/arborist/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "requires": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, - "@npmcli/git": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.2.tgz", - "integrity": "sha512-CAcd08y3DWBJqJDpfuVL0uijlq5oaXaOJEKHKc4wqrjd00gkvTZB+nFuLn+doOOKddaQS9JfqtNoFCO2LCvA3w==", - "dev": true, - "requires": { - "@npmcli/promise-spawn": "^3.0.0", - "lru-cache": "^7.4.4", - "mkdirp": "^1.0.4", - "npm-pick-manifest": "^7.0.0", - "proc-log": "^2.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^2.0.2" - }, + "node_modules/@npmcli/arborist/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - } + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "@npmcli/installed-package-contents": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", - "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", + "node_modules/@npmcli/arborist/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, - "requires": { - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "@npmcli/map-workspaces": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-2.0.4.tgz", - "integrity": "sha512-bMo0aAfwhVwqoVM5UzX1DJnlvVvzDCHae821jv48L1EsrYwfOZChlqWYXEtto/+BkBXetPbEWgau++/brh4oVg==", - "dev": true, - "requires": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^8.0.1", - "minimatch": "^5.0.1", - "read-package-json-fast": "^2.0.3" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "@npmcli/metavuln-calculator": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.1.tgz", - "integrity": "sha512-n69ygIaqAedecLeVH3KnO39M6ZHiJ2dEv5A7DGvcqCB8q17BGUgW8QaanIkbWUo2aYGZqJaOORTLAlIvKjNDKA==", + "node_modules/@npmcli/arborist/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "requires": { - "cacache": "^16.0.0", - "json-parse-even-better-errors": "^2.3.1", - "pacote": "^13.0.3", - "semver": "^7.3.5" - }, + "license": "BlueOak-1.0.0", "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "node_modules/@npmcli/arborist/node_modules/npm-bundled": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", + "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, + "license": "ISC", "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@npmcli/name-from-folder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz", - "integrity": "sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA==", - "dev": true - }, - "@npmcli/node-gyp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz", - "integrity": "sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A==", - "dev": true - }, - "@npmcli/package-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-2.0.0.tgz", - "integrity": "sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA==", + "node_modules/@npmcli/arborist/node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.1" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@npmcli/promise-spawn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz", - "integrity": "sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g==", + "node_modules/@npmcli/arborist/node_modules/pacote": { + "version": "21.5.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.5.0.tgz", + "integrity": "sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ==", "dev": true, - "requires": { - "infer-owner": "^1.0.4" + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@npmcli/run-script": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-4.2.1.tgz", - "integrity": "sha512-7dqywvVudPSrRCW5nTHpHgeWnbBtz8cFkOuKrecm6ih+oO9ciydhWt6OF7HlqupRRmB8Q/gECVdB9LMfToJbRg==", + "node_modules/@npmcli/arborist/node_modules/pacote/node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", + "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", "dev": true, - "requires": { - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/promise-spawn": "^3.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^2.0.3", - "which": "^2.0.2" + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@nrwl/cli": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@nrwl/cli/-/cli-15.0.13.tgz", - "integrity": "sha512-w0oOP4v176CbD34+VytiAItIH3fOeiaccq7T2Un/hhx+/Q9mdO/VWyYZOKmp85uGodx/yZ6LyGW6rX0BjM0Rsg==", + "node_modules/@npmcli/arborist/node_modules/pacote/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, - "requires": { - "nx": "15.0.13" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@nrwl/devkit": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-15.0.13.tgz", - "integrity": "sha512-/8k7wbBRFf2UC+T4F+vWMy3bfSGi+uK6RwXk53moLq3nxehXaQhRiCqasC6VJFUw3zK6luu2T7xkPUlA9K9l4w==", + "node_modules/@npmcli/arborist/node_modules/pacote/node_modules/ssri": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", "dev": true, - "requires": { - "@phenomnomnominal/tsquery": "4.1.1", - "ejs": "^3.1.7", - "ignore": "^5.0.4", - "semver": "7.3.4", - "tslib": "^2.3.0" - }, + "license": "ISC", "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@nrwl/tao": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-15.0.13.tgz", - "integrity": "sha512-z55RKnVOYsiABKFUIj+QBf6I4fUwTlObxJpgUJp0i3E97P3BgbzhTG1EhuBxLH8fGKrbOAPs0ct38Asl+zGZfQ==", + "node_modules/@npmcli/arborist/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "requires": { - "nx": "15.0.13" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "@octokit/auth-token": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.2.tgz", - "integrity": "sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q==", + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", "dev": true, - "requires": { - "@octokit/types": "^8.0.0" + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@octokit/core": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.1.0.tgz", - "integrity": "sha512-Czz/59VefU+kKDy+ZfDwtOIYIkFjExOKf+HA92aiTZJ6EfWpFzYQWw0l54ji8bVmyhc+mGaLUbSUmXazG7z5OQ==", - "dev": true, - "requires": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^8.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "@octokit/endpoint": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.3.tgz", - "integrity": "sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw==", + "node_modules/@npmcli/git": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.2.tgz", + "integrity": "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==", "dev": true, - "requires": { - "@octokit/types": "^8.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - }, + "license": "ISC", "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } + "@gar/promise-retry": "^1.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@octokit/graphql": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.4.tgz", - "integrity": "sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A==", + "node_modules/@npmcli/git/node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", "dev": true, - "requires": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^8.0.0", - "universal-user-agent": "^6.0.0" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@octokit/openapi-types": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", - "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==", - "dev": true - }, - "@octokit/plugin-enterprise-rest": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", - "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", - "dev": true + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } }, - "@octokit/plugin-paginate-rest": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz", - "integrity": "sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw==", + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, - "requires": { - "@octokit/types": "^8.0.0" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true + "node_modules/@npmcli/git/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz", - "integrity": "sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw==", + "node_modules/@npmcli/git/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "requires": { - "@octokit/types": "^8.0.0", - "deprecation": "^2.3.1" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "@octokit/request": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz", - "integrity": "sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==", - "dev": true, - "requires": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^8.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" + "node_modules/@npmcli/git/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "license": "ISC", "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@octokit/request-error": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.2.tgz", - "integrity": "sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg==", + "node_modules/@npmcli/map-workspaces": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-5.0.3.tgz", + "integrity": "sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw==", "dev": true, - "requires": { - "@octokit/types": "^8.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@octokit/rest": { - "version": "19.0.5", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.5.tgz", - "integrity": "sha512-+4qdrUFq2lk7Va+Qff3ofREQWGBeoTKNqlJO+FGjFP35ZahP+nBenhZiGdu8USSgmq4Ky3IJ/i4u0xbLqHaeow==", + "node_modules/@npmcli/map-workspaces/node_modules/@npmcli/name-from-folder": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-4.0.0.tgz", + "integrity": "sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg==", "dev": true, - "requires": { - "@octokit/core": "^4.1.0", - "@octokit/plugin-paginate-rest": "^5.0.0", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^6.7.0" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "@octokit/types": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.0.0.tgz", - "integrity": "sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==", + "node_modules/@npmcli/map-workspaces/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "requires": { - "@octokit/openapi-types": "^14.0.0" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, - "@parcel/watcher": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", - "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", + "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, - "requires": { - "node-addon-api": "^3.2.1", - "node-gyp-build": "^4.3.0" + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "@phenomnomnominal/tsquery": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-4.1.1.tgz", - "integrity": "sha512-jjMmK1tnZbm1Jq5a7fBliM4gQwjxMU7TFoRNwIyzwlO+eHPRCFv/Nv+H/Gi1jc3WR7QURG8D5d0Tn12YGrUqBQ==", + "node_modules/@npmcli/map-workspaces/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, - "requires": { - "esquery": "^1.0.1" + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true + "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true + "node_modules/@npmcli/metavuln-calculator": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-9.0.3.tgz", + "integrity": "sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cacache": "^20.0.0", + "json-parse-even-better-errors": "^5.0.0", + "pacote": "^21.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true + "node_modules/@npmcli/metavuln-calculator/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true + "node_modules/@npmcli/metavuln-calculator/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true + "node_modules/@npmcli/name-from-folder": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-3.0.0.tgz", + "integrity": "sha512-61cDL8LUc9y80fXn+lir+iVt8IS0xHqEKwPu/5jCjxQTVoSCmkXvw4vbMrzAMtmghz3/AkiBjhHkDKUH+kf7kA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "@types/parse-json": { + "node_modules/@npmcli/node-gyp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "@types/uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==", - "dev": true + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true + "node_modules/@npmcli/package-json": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.2.tgz", + "integrity": "sha512-0ylN3U5htO1SJTmy2YI78PZZjLkKUGg7EKgukb2CRi0kzyoDr0cfjHAzi7kozVhj2V3SxN1oyKqZ2NSo40z00g==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^11.0.3", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true + "node_modules/@npmcli/package-json/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, - "@yarnpkg/parsers": { - "version": "3.0.0-rc.27", - "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.27.tgz", - "integrity": "sha512-qs2wZulOYVjaOS6tYOs3SsR7m/qeHwjPrB5i4JtBJELsgWrEkyL+rJH21RA+fVwttJobAYQqw5Xj5SYLaDK/bQ==", + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, - "requires": { - "js-yaml": "^3.10.0", - "tslib": "^2.4.0" - }, + "license": "MIT", "dependencies": { - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - } + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "@zkochan/js-yaml": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", - "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, - "requires": { - "argparse": "^2.0.1" - }, + "license": "BlueOak-1.0.0", "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - } + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "add-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", - "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@npmcli/package-json/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, - "requires": { - "debug": "4" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "agentkeepalive": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", - "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "node_modules/@npmcli/package-json/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "requires": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", + "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, + "license": "ISC", "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@npmcli/query": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-4.0.1.tgz", + "integrity": "sha512-4OIPFb4weUUwkDXJf4Hh1inAn8neBGq3xsH4ZsAaN6FK3ldrFkH7jSpCc7N9xesi0Sp+EBXJ9eGMDrEww2Ztqw==", "dev": true, - "requires": { - "color-convert": "^1.9.0" + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/@npmcli/redact": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz", + "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==", "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "node_modules/@npmcli/run-script": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", + "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@npmcli/run-script/node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", + "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true - }, - "array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "node_modules/@npmcli/run-script/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assertion-error-formatter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/assertion-error-formatter/-/assertion-error-formatter-3.0.0.tgz", - "integrity": "sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ==", + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, - "requires": { - "diff": "^4.0.1", - "pad-right": "^0.2.2", - "repeat-string": "^1.6.1" + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "axios": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", - "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "node_modules/@nx/devkit": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-22.7.1.tgz", + "integrity": "sha512-z2ayFHq406MyVpNtksGnsfHOYZVTSInwQgZeg6u+S4sD21Wvb+oldhqkbYX46jiGJSaw5aUjFdzXJu2l4MYP1A==", "dev": true, - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" + "license": "MIT", + "dependencies": { + "@zkochan/js-yaml": "0.0.7", + "ejs": "5.0.1", + "enquirer": "~2.3.6", + "minimatch": "10.2.4", + "semver": "^7.6.3", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + }, + "peerDependencies": { + "nx": ">= 21 <= 23 || ^22.0.0-0" } }, - "babel-plugin-add-module-exports": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz", - "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==", - "dev": true - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "node_modules/@nx/devkit/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "requires": { - "object.assign": "^4.1.0" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, - "babel-plugin-polyfill-corejs2": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", - "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "node_modules/@nx/devkit/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, - "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.2", - "semver": "^6.1.1" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "babel-plugin-polyfill-corejs3": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz", - "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==", + "node_modules/@nx/devkit/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.2", - "core-js-compat": "^3.16.2" + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "babel-plugin-polyfill-regenerator": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", - "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "node_modules/@nx/devkit/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.2" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "bin-links": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-3.0.3.tgz", - "integrity": "sha512-zKdnMPWEdh4F5INR07/eBrodC7QrF5JKvqskjz/ZZRXg5YSAZIbn8zGhbhUrElzHBZ2fvEQdOU59RHcTG3GiwA==", - "dev": true, - "requires": { - "cmd-shim": "^5.0.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0", - "read-cmd-shim": "^3.0.0", - "rimraf": "^3.0.0", - "write-file-atomic": "^4.0.0" - }, - "dependencies": { - "npm-normalize-package-bin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", - "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - } - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/@nx/nx-darwin-arm64": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-22.7.1.tgz", + "integrity": "sha512-m00ZmBn39VUgb0Ahhu5iY6D56ETdXjDbVnOz0XF3DacJrcLtq9sZ+cg1bj6PshqtvRWVg+zJRrZBU6vL7hGuFQ==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@nx/nx-darwin-x64": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-22.7.1.tgz", + "integrity": "sha512-DmD8Qow+Yt7Yrmjlz1AsfiwxW+0kRzg+6MY70+d7qChtD2bTzvA/k0ut8SMy+CxU3kxgUbKhGOtml5JDXoX2ww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@nx/nx-freebsd-x64": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-22.7.1.tgz", + "integrity": "sha512-HboVrUCHcuYTXtuX3dMyRszP7JO90ZVBLWgnmaM7jUM7jnllZjmezUMtpNHfN1GQbVFafJf/NBShDWsu9LuaUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-22.7.1.tgz", + "integrity": "sha512-5Gm8Y7L8WXMLUjHhiy1eqGz5/PiRw1YLanFg5audBNkZvH6Jkwzdpoz0dbeKjwMDHz4NmniUV1s76Th8VLWmiQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-22.7.1.tgz", + "integrity": "sha512-GdgPYMfbijBRFJs1absL/9QdSNLsTAGdyKykDf9CaVxEMZ92VB+pncpX9Vn/ZBCSeeWTLF+bSK3UM5v+loIObQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-22.7.1.tgz", + "integrity": "sha512-HyBgPtY1hyNTk8683nt7F29jh3lVdS/zul9vS0NgKeCSoYL3GRM3nLoTPynoHUxyVP/tWYOE3ymvnk92qYwL4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-22.7.1.tgz", + "integrity": "sha512-bQBgRiEsanNvKcDOjVAUPjvcp0iDLofYYUL2af2iuCDxreLOej+J6MeA5bWTLNly5ly1d4voKGTqa+OsouVyLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-22.7.1.tgz", + "integrity": "sha512-gcco2GjcAztF/fRcAgFxtWxrWDnQdNmPaAN9FTt1+qQ9RUSLvdL8bQxKx4Kd9N9T+gXPlrWhMkBkKbbV09+X1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-22.7.1.tgz", + "integrity": "sha512-IT9oEn0YQ83iPH7666aoPyTRsUzBIBJdBLMXeLX4I60fHPXWhUSGpfiLtIsgU2OfeOVb9hU9idwNh1wc4u9rWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-22.7.1.tgz", + "integrity": "sha512-P2zeSKXVH2Eiwsb8UfP2rMMS7//cHWpiO4M9zt6q0c4lI/hN1vXBciRKVWruGk9ZrWLHuhaMAhG94+MJtzKuRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "engines": { + "node": ">= 18" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/@octokit/core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", + "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", "dev": true, - "requires": { - "fill-range": "^7.0.1" + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "node_modules/@octokit/endpoint": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", + "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "node_modules/@octokit/graphql": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", + "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "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==", - "dev": true + "node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "dev": true, + "license": "MIT" }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", - "dev": true + "node_modules/@octokit/plugin-enterprise-rest": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", + "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", + "dev": true, + "license": "MIT" }, - "byte-size": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-7.0.1.tgz", - "integrity": "sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A==", - "dev": true - }, - "cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "requires": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - } + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", + "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", + "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.8.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" } }, - "caniuse-lite": { - "version": "1.0.30001399", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001399.tgz", - "integrity": "sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA==", - "dev": true - }, - "capital-case": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", - "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "node_modules/@octokit/request": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", + "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3", - "upper-case-first": "^2.0.2" + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "node_modules/@octokit/request-error": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", + "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" } }, - "chai-like": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chai-like/-/chai-like-1.1.1.tgz", - "integrity": "sha512-VKa9z/SnhXhkT1zIjtPACFWSoWsqVoaz1Vg+ecrKo5DCKVlgL30F/pEyEvXPBOVwCgLZcWUleCM/C1okaKdTTA==", - "dev": true + "node_modules/@octokit/rest": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", + "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" + }, + "engines": { + "node": ">= 18" + } }, - "chai-properties": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/chai-properties/-/chai-properties-1.4.0.tgz", - "integrity": "sha512-YcWARvW+X65f0oHdNRsds72l3x/h2w0MUpp+lBnP0/ggXV1tpR/kU5Am0XGp50+6PrxPExdIxu/Wo4B17Vcn3Q==", + "node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", "dev": true, - "requires": { - "lodash": "^4.17.15" + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" } }, - "chai-things": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chai-things/-/chai-things-0.2.0.tgz", - "integrity": "sha1-xVEoN4+bs5nplPAAUhUZhO1uvnA=", - "dev": true + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true, + "license": "MIT" }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true, + "license": "MIT" }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" } }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" }, - "class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==", - "dev": true + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause" }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" } }, - "cli-spinners": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" }, - "cli-table3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", - "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", - "dev": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^4.2.0" - } + "node_modules/@protobufjs/inquire": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.1.tgz", + "integrity": "sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew==", + "license": "BSD-3-Clause" }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true + "node_modules/@protobufjs/utf8": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", + "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", + "license": "BSD-3-Clause" + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.5.tgz", + "integrity": "sha512-Dq1bqBdLaZ1Gb/l2e5/+o3B18+8TI9ANlA1SkejZqDgdU/jK/ThYaMPMJpVMMXy2uRHvGKbkz9vheVGdq3cJfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } + "license": "MIT" }, - "cmd-shim": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-5.0.0.tgz", - "integrity": "sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw==", + "node_modules/@sigstore/bundle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", + "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", "dev": true, - "requires": { - "mkdirp-infer-owner": "^2.0.0" + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@sigstore/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.2.0.tgz", + "integrity": "sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA==", "dev": true, - "requires": { - "color-name": "1.1.3" + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true + "node_modules/@sigstore/protobuf-specs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.1.tgz", + "integrity": "sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "columnify": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", - "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", + "node_modules/@sigstore/sign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.1.tgz", + "integrity": "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==", "dev": true, - "requires": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, + "license": "Apache-2.0", "dependencies": { - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } + "@gar/promise-retry": "^1.0.2", + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.4", + "proc-log": "^6.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/@sigstore/sign/node_modules/@npmcli/redact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", + "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", "dev": true, - "requires": { - "delayed-stream": "~1.0.0" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.5.tgz", + "integrity": "sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg==", "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - }, + "license": "ISC", "dependencies": { - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - } + "@gar/promise-retry": "^1.0.0", + "@npmcli/agent": "^4.0.0", + "@npmcli/redact": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "node_modules/@sigstore/sign/node_modules/minipass-fetch": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.2.tgz", + "integrity": "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "iconv-lite": "^0.7.2" + } }, - "concat-stream": { + "node_modules/@sigstore/sign/node_modules/minipass-sized": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" + "license": "ISC", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">=8" } }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "node_modules/@sigstore/sign/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true + "node_modules/@sigstore/sign/node_modules/ssri": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "node_modules/@sigstore/tuf": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.2.tgz", + "integrity": "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==", "dev": true, - "requires": { - "compare-func": "^2.0.0", - "q": "^1.5.1" + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "conventional-changelog-core": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", - "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "node_modules/@sigstore/verify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", + "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", "dev": true, - "requires": { - "add-stream": "^1.0.0", - "conventional-changelog-writer": "^5.0.0", - "conventional-commits-parser": "^3.2.0", - "dateformat": "^3.0.0", - "get-pkg-repo": "^4.0.0", - "git-raw-commits": "^2.0.8", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^4.1.1", - "lodash": "^4.17.15", - "normalize-package-data": "^3.0.0", - "q": "^1.5.1", - "read-pkg": "^3.0.0", - "read-pkg-up": "^3.0.0", - "through2": "^4.0.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "requires": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "conventional-changelog-preset-loader": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", - "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", - "dev": true + "node_modules/@sinclair/typebox": { + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "dev": true, + "license": "MIT" }, - "conventional-changelog-writer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", - "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, - "requires": { - "conventional-commits-filter": "^2.0.7", - "dateformat": "^3.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "semver": "^6.0.0", - "split": "^1.0.0", - "through2": "^4.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" } }, - "conventional-commits-filter": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", - "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" + "license": "MIT", + "engines": { + "node": ">=4" } }, - "conventional-commits-parser": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", - "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "node_modules/@sinonjs/fake-timers": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", "dev": true, - "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" } }, - "conventional-recommended-bump": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", - "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "node_modules/@sinonjs/samsam": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-10.0.2.tgz", + "integrity": "sha512-8lVwD1Df1BmzoaOLhMcGGcz/Jyr5QY2KSB75/YK1QgKzoabTeLdIVyhXNZK9ojfSKSdirbXqdbsXXqP9/Ve8+A==", "dev": true, - "requires": { - "concat-stream": "^2.0.0", - "conventional-changelog-preset-loader": "^2.3.4", - "conventional-commits-filter": "^2.0.7", - "conventional-commits-parser": "^3.2.0", - "git-raw-commits": "^2.0.8", - "git-semver-tags": "^4.1.1", - "meow": "^8.0.0", - "q": "^1.5.1" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "type-detect": "^4.1.0" } }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "node_modules/@teppeis/multimaps": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-3.0.0.tgz", + "integrity": "sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==", "dev": true, - "requires": { - "safe-buffer": "~5.1.1" + "license": "MIT", + "engines": { + "node": ">=14" } }, - "core-js": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.18.3.tgz", - "integrity": "sha512-tReEhtMReZaPFVw7dajMx0vlsz3oOb8ajgPoHVYGxr8ErnZ6PcYEvvmjGmXlfpnxpkYSdOQttjB+MvVbCGfvLw==", - "dev": true + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "core-js-compat": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.3.tgz", - "integrity": "sha512-4zP6/y0a2RTHN5bRGT7PTq9lVt3WzvffTNjqnTKsXhkAYNDTkdCLOIfAdOLcQ/7TDdyRj3c+NeHe1NmF1eDScw==", + "node_modules/@tufjs/models": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", + "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", "dev": true, - "requires": { - "browserslist": "^4.17.3", - "semver": "7.0.0" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "node_modules/@tufjs/models/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" } }, - "dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true, - "requires": { - "ms": "2.1.2" + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.19.0" } }, - "debuglog": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", - "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==", - "dev": true + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" }, - "decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, + "license": "BSD-2-Clause" + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.7.tgz", + "integrity": "sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==", + "dev": true, + "license": "MIT", "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "deep-eql": { + "node_modules/abbrev": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", "dev": true, - "requires": { - "type-detect": "^4.0.0" + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, - "requires": { - "clone": "^1.0.2" + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "requires": { - "object-keys": "^1.0.12" + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "delayed-stream": { + "node_modules/add-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", + "dev": true, + "license": "MIT" }, - "dezalgo": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" + "license": "MIT", + "engines": { + "node": ">= 14" } }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, - "requires": { - "path-type": "^4.0.0" + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, - "requires": { - "esutils": "^2.0.2" + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, - "requires": { - "is-obj": "^2.0.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "dev": true + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "duration": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", - "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.46" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "durations": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/durations/-/durations-3.4.2.tgz", - "integrity": "sha512-V/lf7y33dGaypZZetVI1eu7BmvkbC4dItq12OElLRpKuaU5JxQstV2zHwLv8P7cNbQ+KL1WD80zMCTx5dNC4dg==", - "dev": true - }, - "ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "requires": { - "jake": "^10.8.5" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "electron-to-chromium": { - "version": "1.3.876", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.876.tgz", - "integrity": "sha512-a6LR4738psrubCtGx5HxM/gNlrIsh4eFTNnokgOqvQo81GWd07lLcOjITkAXn2y4lIp18vgS+DGnehj+/oEAxQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "optional": true, - "requires": { - "iconv-lite": "^0.6.2" + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true, - "requires": { - "once": "^1.4.0" - } + "license": "ISC" }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, - "requires": { - "ansi-colors": "^4.1.1" + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true, + "license": "MIT" }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, - "requires": { - "is-arrayish": "^0.2.1" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "error-stack-parser": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", - "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", - "dev": true, - "requires": { - "stackframe": "^1.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "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==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" } }, - "eslint-config-standard": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz", - "integrity": "sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "node_modules/assertion-error-formatter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/assertion-error-formatter/-/assertion-error-formatter-3.0.0.tgz", + "integrity": "sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ==", "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, + "license": "MIT", "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "diff": "^4.0.1", + "pad-right": "^0.2.2", + "repeat-string": "^1.6.1" } }, - "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "eslint-plugin-chai-friendly": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.5.0.tgz", - "integrity": "sha512-Pxe6z8C9fP0pn2X2nGFU/b3GBOCM/5FVus1hsMwJsXP3R7RiXFl7g0ksJbsc0GxiLyidTW4mEFk77qsNn7Tk7g==", - "dev": true + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "eslint-plugin-flowtype": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-6.1.1.tgz", - "integrity": "sha512-5RodSeZvKh1N0kppB9dSSO0ZqB8rHjdX9BUTVQUBnEzR3QU5aQVKEUlBJE7I7U7rhbJMxe3aHPmt/jD4+5Ya6g==", + "node_modules/axios": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", + "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", "dev": true, - "requires": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" } }, - "eslint-plugin-import": { - "version": "2.25.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz", - "integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==", + "node_modules/babel-plugin-add-module-exports": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz", + "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==", "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.0", - "has": "^1.0.3", - "is-core-module": "^2.7.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "license": "MIT" + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "dev": true, + "license": "MIT", "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "eslint-plugin-promise": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", - "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", - "dev": true + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" }, - "eslint-plugin-standard": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", - "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", - "dev": true + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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" }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/baseline-browser-mapping": { + "version": "2.10.24", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.24.tgz", + "integrity": "sha512-I2NkZOOrj2XuguvWCK6OVh9GavsNjZjK908Rq3mIBK25+GD8vPX5w2WdxVqnQ7xx3SrZJiCiZFu+/Oz50oSYSA==", "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, + "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==", + "license": "BSD-3-Clause", "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "tweetnacl": "^0.14.3" } }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/bin-links": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-5.0.0.tgz", + "integrity": "sha512-sdleLVfCjBtgO5cNjA2HVRvWBJAHs4zwenaCPMNJAJU0yNxpzj80IpjOIimkpkr+mhlA+how5poQtt53PygbHA==", "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, + "license": "ISC", "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "node_modules/bin-links/node_modules/cmd-shim": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-7.0.0.tgz", + "integrity": "sha512-rtpaCbr164TPPh+zFdkWpCyZuKkjpAzODfaZCf/SVJZzJN+4bHQb/LP3Jzq5/+84um3XXY8r548XiWKSborwVw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/bin-links/node_modules/read-cmd-shim": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-5.0.0.tgz", + "integrity": "sha512-SEbJV7tohp3DAAILbEMPXavBjAnMN0tVnh4+9G8ihV4Pq3HYF9h8QNez9zkJ1ILkv9G2BjdzwctznGZXgu/HGw==", "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/bin-links/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "requires": { - "estraverse": "^5.2.0" + "license": "ISC", + "engines": { + "node": ">=14" }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/bin-links/node_modules/write-file-atomic": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz", + "integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==", + "dev": true, + "license": "ISC", "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "requires": { - "type": "^2.5.0" - }, + "license": "MIT", + "optional": true, "dependencies": { - "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", - "dev": true - } + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "extsprintf": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz", - "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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.1.13" + } }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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==", "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } + "license": "MIT" }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "node_modules/buildcheck": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.7.tgz", + "integrity": "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==", + "optional": true, + "engines": { + "node": ">=10.0.0" + } }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "node_modules/builtins": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", "dev": true, - "requires": { - "reusify": "^1.0.4" + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "node_modules/builtins/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/byte-size": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", + "integrity": "sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==", "dev": true, - "requires": { - "flat-cache": "^3.0.4" + "license": "MIT", + "engines": { + "node": ">=12.17" } }, - "filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "node_modules/c8": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-11.0.0.tgz", + "integrity": "sha512-e/uRViGHSVIJv7zsaDKM7VRn2390TgHXqUSvYwPHBQaU6L7E9L0n9JbdkwdYPvshDT0KymBmmlwSpms3yBaMNg==", "dev": true, - "requires": { - "minimatch": "^5.0.1" - }, + "license": "ISC", "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } + "@bcoe/v8-coverage": "^1.0.1", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^8.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": "20 || >=22" + }, + "peerDependencies": { + "monocart-coverage-reports": "^2" + }, + "peerDependenciesMeta": { + "monocart-coverage-reports": { + "optional": true } } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/cacache": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.4.tgz", + "integrity": "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==", "dev": true, - "requires": { - "to-regex-range": "^5.0.1" + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "node_modules/cacache/node_modules/@npmcli/fs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", + "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/cacache/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "requires": { - "locate-path": "^3.0.0" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/cacache/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, + "license": "MIT", "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "flow-bin": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.75.0.tgz", - "integrity": "sha1-uW0e6Z07RGoyJr5mtAEyJM6d8mA=", - "dev": true - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "node_modules/cacache/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/cacache/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/cacache/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "requires": { - "minipass": "^3.0.0" + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/cacache/node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "node_modules/cacache/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "dependencies": { - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } + "engines": { + "node": ">=10" } }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "node_modules/cacache/node_modules/ssri": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "get-pkg-repo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "dev": true, - "requires": { - "@hutson/parse-repository-url": "^3.0.0", - "hosted-git-info": "^4.0.0", - "through2": "^2.0.0", - "yargs": "^16.2.0" - }, + "license": "MIT", "dependencies": { - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-port": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", - "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "requires": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "requires": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">=6" } }, - "git-semver-tags": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", - "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, - "requires": { - "meow": "^8.0.0", - "semver": "^6.0.0" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "git-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", - "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", + "node_modules/caniuse-lite": { + "version": "1.0.30001791", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz", + "integrity": "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==", "dev": true, - "requires": { - "is-ssh": "^1.4.0", - "parse-url": "^8.1.0" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, - "git-url-parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", "dev": true, - "requires": { - "git-up": "^7.0.0" + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" } }, - "gitconfiglocal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, - "requires": { - "ini": "^1.3.2" + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" } }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/chai-like": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chai-like/-/chai-like-1.1.3.tgz", + "integrity": "sha512-JGsxE2PBhXeXxfzkAobp8KcyVdXHa96/I/4oJf6GKtQccTugVaVD68TvPDiCUo+hBC2meR68riSeABHkn+Hyug==", "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "license": "MIT", + "peerDependencies": { + "chai": "2 - 5" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/chai-properties": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/chai-properties/-/chai-properties-1.4.0.tgz", + "integrity": "sha512-YcWARvW+X65f0oHdNRsds72l3x/h2w0MUpp+lBnP0/ggXV1tpR/kU5Am0XGp50+6PrxPExdIxu/Wo4B17Vcn3Q==", "dev": true, - "requires": { - "is-glob": "^4.0.1" + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "npm": ">= 1.2" + }, + "peerDependencies": { + "chai": "^4.1.2" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/chai-things": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chai-things/-/chai-things-0.2.0.tgz", + "integrity": "sha512-6ns0SU21xdRCoEXVKH3HGbwnsgfVMXQ+sU5V8PI9rfxaITos8lss1vUxbF1FAcJKjfqmmmLVlr/z3sLes00w+A==", "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, + "license": "MIT" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "license": "MIT" }, - "has": { + "node_modules/check-error": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, - "requires": { - "function-bind": "^1.1.1" + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" } }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } }, - "has-flag": { + "node_modules/chownr": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, - "requires": { - "has-symbols": "^1.0.2" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hosted-git-info": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", - "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", "dev": true, - "requires": { - "lru-cache": "^6.0.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" } }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true + "node_modules/class-transformer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==", + "dev": true, + "license": "MIT" }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "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==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" } }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dev": true, - "requires": { - "ms": "^2.0.0" + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "license": "ISC", + "engines": { + "node": ">= 12" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "ignore-walk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz", - "integrity": "sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==", - "dev": true, - "requires": { - "minimatch": "^5.0.1" - }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, + "license": "MIT", "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "node_modules/cmd-shim": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz", + "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "license": "ISC", + "bin": { + "color-support": "bin.js" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "init-package-json": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-3.0.2.tgz", - "integrity": "sha512-YhlQPEjNFqlGdzrBfDNRLhvoSgX7iQRgSxgsNknRQ9ITXFT7UMfVMWhBTOh2Y+25lRnGrv5Xz8yZwQ3ACR6T3A==", - "dev": true, - "requires": { - "npm-package-arg": "^9.0.1", - "promzard": "^0.3.0", - "read": "^1.0.7", - "read-package-json": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^4.0.0" - }, + "node_modules/columnify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", + "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", + "dev": true, + "license": "MIT", "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "npm-package-arg": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz", - "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - } + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "inquirer": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", - "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "license": "MIT", + "engines": { + "node": ">= 6" } }, - "ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "dev": true, + "license": "ISC" }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, - "requires": { - "has-bigints": "^1.0.1" + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" } }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } + "license": "MIT" }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" } }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "license": "ISC" }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, - "requires": { - "ci-info": "^2.0.0" + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" } }, - "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "node_modules/conventional-changelog-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz", + "integrity": "sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==", "dev": true, - "requires": { - "has": "^1.0.3" + "license": "MIT", + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-parser": "^4.0.0", + "dateformat": "^3.0.3", + "get-pkg-repo": "^4.2.1", + "git-raw-commits": "^3.0.0", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^5.0.0", + "normalize-package-data": "^3.0.3", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0" + }, + "engines": { + "node": ">=14" } }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/conventional-changelog-preset-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", + "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" + "license": "MIT", + "engines": { + "node": ">=14" } }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true + "node_modules/conventional-changelog-writer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", + "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=14" + } }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "is-fullwidth-code-point": { + "node_modules/conventional-commits-filter": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz", - "integrity": "sha1-wUwhBX7TbjKNuANHlmxpP4hjifM=", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", "dev": true, - "requires": { - "is-extglob": "^2.1.1" + "license": "MIT", + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, + "engines": { + "node": ">=14" } }, - "is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true - }, - "is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "node_modules/conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" + } }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "node_modules/conventional-recommended-bump": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", + "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" + "license": "MIT", + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^3.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "git-raw-commits": "^3.0.0", + "git-semver-tags": "^5.0.0", + "meow": "^8.1.2" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=14" } }, - "is-obj": { + "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/core-js": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", "dev": true, - "requires": { - "isobject": "^3.0.1" + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-ssh": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true, - "requires": { - "protocols": "^2.0.1" + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true + "node_modules/cpu-features": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" + } }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, - "requires": { - "has-symbols": "^1.0.2" + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" } }, - "is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true, - "requires": { - "text-extensions": "^1.0.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } }, - "is-weakref": { + "node_modules/data-view-byte-offset": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, - "requires": { - "call-bind": "^1.0.0" + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true, - "requires": { - "is-docker": "^2.0.0" + "license": "MIT", + "engines": { + "node": "*" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "dev": true, - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "optional": true } } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "json-stringify-nice": { + "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", - "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", - "dev": true - }, - "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==", - "dev": true + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" + "license": "MIT", + "engines": { + "node": ">=0.4.0" } }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" }, - "just-diff": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-5.1.1.tgz", - "integrity": "sha512-u8HXJ3HlNrTzY7zrYYKjNEfBlyjqhdBkoyTVdjtn7p02RJD5NvR8rIClzeGA7t+UYP1/7eAkWNLU0+P3QrEqKQ==", - "dev": true + "node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, - "just-diff-apply": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.4.1.tgz", - "integrity": "sha512-AAV5Jw7tsniWwih8Ly3fXxEZ06y+6p5TwQMsw0dzZ/wPKilzyDgdAnL0Ug4NNIquPUOh1vfFWEHbmXUqM5+o8g==", - "dev": true + "node_modules/docker-modem": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.7.tgz", + "integrity": "sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^1.15.0" + }, + "engines": { + "node": ">= 8.0" + } }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "node_modules/dockerode": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.0.tgz", + "integrity": "sha512-C52mvJ+7lcyhWNfrzVfFsbTrBfy/ezE9FGEYLpu17FUeBcCkxERk9nN7uDl/478ynDiQ4U+5DbQC2vENHkVEtQ==", + "license": "Apache-2.0", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@grpc/grpc-js": "^1.11.1", + "@grpc/proto-loader": "^0.7.13", + "docker-modem": "^5.0.7", + "protobufjs": "^7.3.2", + "tar-fs": "^2.1.4" + }, + "engines": { + "node": ">= 14.17" + } }, - "knuth-shuffle-seeded": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz", - "integrity": "sha1-AfG2VzOqdUDuCNiwF0Fk0iCB5OE=", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "requires": { - "seed-random": "~2.2.0" + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "lerna": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-5.6.2.tgz", - "integrity": "sha512-Y0yMPslvnBnTZi7Nrs/gDyYZYauNf61xWNCehISHIORxZmmpoluNkcWTfcyb47is5uJQCv5QJX5xKKubbs+a6w==", - "dev": true, - "requires": { - "@lerna/add": "5.6.2", - "@lerna/bootstrap": "5.6.2", - "@lerna/changed": "5.6.2", - "@lerna/clean": "5.6.2", - "@lerna/cli": "5.6.2", - "@lerna/command": "5.6.2", - "@lerna/create": "5.6.2", - "@lerna/diff": "5.6.2", - "@lerna/exec": "5.6.2", - "@lerna/import": "5.6.2", - "@lerna/info": "5.6.2", - "@lerna/init": "5.6.2", - "@lerna/link": "5.6.2", - "@lerna/list": "5.6.2", - "@lerna/publish": "5.6.2", - "@lerna/run": "5.6.2", - "@lerna/version": "5.6.2", - "@nrwl/devkit": ">=14.8.1 < 16", - "import-local": "^3.0.2", - "inquirer": "^8.2.4", - "npmlog": "^6.0.2", - "nx": ">=14.8.1 < 16", - "typescript": "^3 || ^4" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "libnpmaccess": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-6.0.4.tgz", - "integrity": "sha512-qZ3wcfIyUoW0+qSFkMBovcTrSGJ3ZeyvpR7d5N9pEYv/kXs8sHP2wiqEIXBKLFrZlmM0kR0RJD7mtfLngtlLag==", + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", "dev": true, - "requires": { - "aproba": "^2.0.0", - "minipass": "^3.1.1", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0" + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" }, - "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "npm-package-arg": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz", - "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - } + "funding": { + "url": "https://dotenvx.com" } }, - "libnpmpublish": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-6.0.5.tgz", - "integrity": "sha512-LUR08JKSviZiqrYTDfywvtnsnxr+tOvBU0BF8H+9frt7HMvc6Qn6F8Ubm72g5hDTHbq8qupKfDvDAln2TVPvFg==", + "node_modules/dotenv-expand": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz", + "integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==", "dev": true, - "requires": { - "normalize-package-data": "^4.0.0", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0", - "semver": "^7.3.7", - "ssri": "^9.0.0" + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "npm-package-arg": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz", - "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - } + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" }, - "load-json-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", - "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "node_modules/ejs": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-5.0.1.tgz", + "integrity": "sha512-COqBPFMxuPTPspXl2DkVYaDS3HtrD1GpzOGkNTJ1IYkifq/r9h8SVEFrjA3D9/VJGOEoMQcrlhpntcSUrM8k6A==", "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "parse-json": "^5.0.0", - "strip-bom": "^4.0.0", - "type-fest": "^0.6.0" + "license": "Apache-2.0", + "bin": { + "ejs": "bin/cli.js" }, - "dependencies": { - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "engines": { + "node": ">=0.12.18" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/electron-to-chromium": { + "version": "1.5.344", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.344.tgz", + "integrity": "sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==", "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } + "license": "ISC" }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "is-arrayish": "^0.2.1" } }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", "dev": true, - "requires": { - "tslib": "^2.0.3" + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" } }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", "dev": true, - "requires": { - "yallist": "^4.0.0" + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "make-dir": { + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "dev": true, - "requires": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - } + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" + "license": "MIT", + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "requires": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-compat-utils/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-config-standard": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" } + ], + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", + "eslint-plugin-promise": "^6.0.0" } }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-chai-friendly": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-1.2.0.tgz", + "integrity": "sha512-um2pBb4ZXNCoTRPRAWiUaXeIaw1dRaPOEZ+G/qcZqfyTdkCXXwOBctnfnbIRbZiQf4AXl3ImV1grt423SlK+mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=3.0.0" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-n": { + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", + "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", + "integrity": "sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-object": "~1.0.1", + "merge-descriptors": "~1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findit2": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", + "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==", + "license": "MIT", + "engines": { + "node": ">=0.8.22" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/flow-bin": { + "version": "0.311.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.311.0.tgz", + "integrity": "sha512-4lXxjhPdmkeizju3F0HDCMYGkoL7hiq0W9bAW4pQpQTi56op+QZrVyMENjbCGZc+KlFBLwWkur+EkyfPTsa6xw==", + "dev": true, + "license": "MIT", + "bin": { + "flow": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/get-pkg-repo/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/get-pkg-repo/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": 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", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/git-raw-commits": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", + "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^7.0.0", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-semver-tags": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", + "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "meow": "^8.1.2", + "semver": "^7.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/git-semver-tags/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", + "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^8.1.0" + } + }, + "node_modules/git-url-parse": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-14.0.0.tgz", + "integrity": "sha512-NnLweV+2A4nCvn4U/m2AoYu0pPKlsmhK9cknG7IMwsjFY1S2jxM+mAhsDxyxfCIGfGaD+dozsyX4b6vkYc83yQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^7.0.0" + } + }, + "node_modules/gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", + "dev": true, + "license": "BSD", + "dependencies": { + "ini": "^1.3.2" + } + }, + "node_modules/gitconfiglocal/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": 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/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-ansi": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-4.0.1.tgz", + "integrity": "sha512-Qr4RtTm30xvEdqUXbSBVWDu+PrTokJOwe/FU+VdfJPk+MXAPoeOzKpRyrDTnZIJwAkQ4oBLTU53nu0HrkF/Z2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "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==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", + "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/ignore-walk/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/init-package-json": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-8.2.2.tgz", + "integrity": "sha512-pXVMn67Jdw2hPKLCuJZj62NC9B2OIDd1R3JwZXTHXuEnfN3Uq5kJbKOSld6YEU+KOGfMD82EzxFTYz5o0SSJoA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^7.0.0", + "npm-package-arg": "^13.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", + "semver": "^7.7.2", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^6.0.2" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/init-package-json/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/inquirer": { + "version": "12.9.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.9.6.tgz", + "integrity": "sha512-603xXOgyfxhuis4nfnWaZrMaotNT0Km9XwwBNWUKbIDqeCY89jGr2F9YPEMiNhU6XjIP4VoWISMBFfcc5NgrTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.0", + "@inquirer/core": "^10.2.2", + "@inquirer/prompts": "^7.8.6", + "@inquirer/type": "^3.0.8", + "mute-stream": "^2.0.0", + "run-async": "^4.0.5", + "rxjs": "^7.8.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip-address": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.1.tgz", + "integrity": "sha512-1FMu8/N15Ck1BL551Jf42NYIoin2unWjLQ2Fze/DXryJRl5twqtwNHlO39qERGbIOcKYWHdgRryhOC+NG4eaLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-diff": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.3.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "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, + "license": "MIT" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-nice": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", + "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "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==", + "dev": 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==", + "dev": 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/just-diff": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz", + "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==", + "dev": true, + "license": "MIT" + }, + "node_modules/just-diff-apply": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz", + "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/knuth-shuffle-seeded": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz", + "integrity": "sha512-9pFH0SplrfyKyojCLxZfMcvkhf5hH0d+UwR9nTVJ/DDQJGuzcXjTwB7TP7sDfehSudlGGaOLblmEWqv04ERVWg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "seed-random": "~2.2.0" + } + }, + "node_modules/lerna": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-9.0.7.tgz", + "integrity": "sha512-PMjbSWYfwL1yZ5c1D2PZuFyzmtYhLdn0f76uG8L25g6eYy34j+2jPb4Q6USx1UJvxVtxkdVEeAAWS/WxgJ8VZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@npmcli/arborist": "9.1.6", + "@npmcli/package-json": "7.0.2", + "@npmcli/run-script": "10.0.3", + "@nx/devkit": ">=21.5.2 < 23.0.0", + "@octokit/plugin-enterprise-rest": "6.0.1", + "@octokit/rest": "20.1.2", + "aproba": "2.0.0", + "byte-size": "8.1.1", + "chalk": "4.1.0", + "ci-info": "4.3.1", + "cmd-shim": "6.0.3", + "color-support": "1.1.3", + "columnify": "1.6.0", + "console-control-strings": "^1.1.0", + "conventional-changelog-angular": "7.0.0", + "conventional-changelog-core": "5.0.1", + "conventional-recommended-bump": "7.0.1", + "cosmiconfig": "9.0.0", + "dedent": "1.5.3", + "envinfo": "7.13.0", + "execa": "5.0.0", + "fs-extra": "^11.2.0", + "get-stream": "6.0.0", + "git-url-parse": "14.0.0", + "glob-parent": "6.0.2", + "has-unicode": "2.0.1", + "import-local": "3.1.0", + "ini": "^1.3.8", + "init-package-json": "8.2.2", + "inquirer": "12.9.6", + "is-ci": "3.0.1", + "jest-diff": ">=30.0.0 < 31", + "js-yaml": "4.1.1", + "libnpmaccess": "10.0.3", + "libnpmpublish": "11.1.2", + "load-json-file": "6.2.0", + "make-fetch-happen": "15.0.2", + "minimatch": "3.1.4", + "npm-package-arg": "13.0.1", + "npm-packlist": "10.0.3", + "npm-registry-fetch": "19.1.0", + "nx": ">=21.5.3 < 23.0.0", + "p-map": "4.0.0", + "p-map-series": "2.1.0", + "p-pipe": "3.1.0", + "p-queue": "6.6.2", + "p-reduce": "2.1.0", + "p-waterfall": "2.1.1", + "pacote": "21.0.1", + "read-cmd-shim": "4.0.0", + "semver": "7.7.2", + "signal-exit": "3.0.7", + "slash": "3.0.0", + "ssri": "12.0.0", + "string-width": "^4.2.3", + "tar": "7.5.11", + "through": "2.3.8", + "tinyglobby": "0.2.12", + "typescript": ">=3 < 6", + "upath": "2.0.1", + "validate-npm-package-license": "3.0.4", + "validate-npm-package-name": "6.0.2", + "wide-align": "1.1.5", + "write-file-atomic": "5.0.1", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "lerna": "dist/cli.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/lerna/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/lerna/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lerna/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/lerna/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/lerna/node_modules/minimatch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/lerna/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==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lerna/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lerna/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libnpmaccess": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-10.0.3.tgz", + "integrity": "sha512-JPHTfWJxIK+NVPdNMNGnkz4XGX56iijPbe0qFWbdt68HL+kIvSzh+euBL8npLZvl2fpaxo+1eZSdoG15f5YdIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/libnpmpublish": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-11.1.2.tgz", + "integrity": "sha512-tNcU3cLH7toloAzhOOrBDhjzgbxpyuYvkf+BPPnnJCdc5EIcdJ8JcT+SglvCQKKyZ6m9dVXtCVlJcA6csxKdEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.7", + "sigstore": "^4.0.0", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/libnpmpublish/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/load-json-file/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/make-fetch-happen": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.2.tgz", + "integrity": "sha512-sI1NY4lWlXBAfjmCtVWIIpBypbBdhHtcjnwnv+gtCnsaOffyFil3aidszGC8hgzJe+fT1qix05sWxmD/Bmf/oQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/meow/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": 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", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz", + "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/mocha": { + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mocha/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/mocha/node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/mocha/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/module-not-found-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", + "integrity": "sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.26.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.26.2.tgz", + "integrity": "sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw==", + "license": "MIT", + "optional": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/navy": { + "resolved": "packages/navy", + "link": true + }, + "node_modules/navy-plugin-nodejs": { + "resolved": "packages/navy-plugin-nodejs", + "link": true + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": 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==", + "dev": true, + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/nock": { + "version": "14.0.13", + "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.13.tgz", + "integrity": "sha512-SCPsQmGVNY8h1rfS3aU0MzOGYY+wKIFukHEsoSIwPRCYocZkya7MFIlWIEYPWQZj+Gaksg6EyUaY255ZDqpQuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mswjs/interceptors": "^0.41.0", + "json-stringify-safe": "^5.0.1", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">=18.20.0 <20 || >=20.12.1" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "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-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.3.0.tgz", + "integrity": "sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-pty": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0.tgz", + "integrity": "sha512-20JqtutY6JPXTUnL0ij1uad7Qe1baT46lyolh2sSENDd4sTzKZ4nmAFkeAARDKwmlLjPx6XKRlwRUxwjOy+lUg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^7.1.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.2.tgz", + "integrity": "sha512-z9HJBCYw9Zr8BqXcllKIs5nI+QggAImbBdHphOzVYrz2CB4iQ6FzWyKmlqDZua+51nAu7FcemlbTc9VgQN5XDQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.1.tgz", + "integrity": "sha512-6zqls5xFvJbgFjB1B2U6yITtyGBjDBORB7suI4zA4T/sZ1OmkMFlaQSNB/4K0LtXNA1t4OprAFxPisadK5O2ag==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-package-arg/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-packlist": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", + "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-packlist/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", + "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/npm-install-checks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", + "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-registry-fetch": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.0.tgz", + "integrity": "sha512-xyZLfs7TxPu/WKjHUs0jZOPinzBAI32kEUel6za0vH+JUTnFZ5zbHI1ZoGZRDm6oMjADtrli6FxtMlk/5ABPNw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx": { + "version": "22.7.1", + "resolved": "https://registry.npmjs.org/nx/-/nx-22.7.1.tgz", + "integrity": "sha512-SadJUQY57MiwRIetm9rhZhdpFeOe1Csib2Vg9C423Pw/h0fZE14qUo6+OBby9vLh5QCkRfRZ0WaHkeO5q6yNtA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@emnapi/core": "1.4.5", + "@emnapi/runtime": "1.4.5", + "@emnapi/wasi-threads": "1.0.4", + "@jest/diff-sequences": "30.0.1", + "@napi-rs/wasm-runtime": "0.2.4", + "@tybys/wasm-util": "0.9.0", + "@yarnpkg/lockfile": "1.1.0", + "@zkochan/js-yaml": "0.0.7", + "ansi-colors": "4.1.3", + "ansi-regex": "5.0.1", + "ansi-styles": "4.3.0", + "argparse": "2.0.1", + "asynckit": "0.4.0", + "axios": "1.15.0", + "balanced-match": "4.0.3", + "base64-js": "1.5.1", + "bl": "4.1.0", + "brace-expansion": "5.0.2", + "buffer": "5.7.1", + "call-bind-apply-helpers": "1.0.2", + "chalk": "4.1.2", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "8.0.1", + "clone": "1.0.4", + "color-convert": "2.0.1", + "color-name": "1.1.4", + "combined-stream": "1.0.8", + "defaults": "1.0.4", + "define-lazy-prop": "2.0.0", + "delayed-stream": "1.0.0", + "dotenv": "16.4.7", + "dotenv-expand": "12.0.3", + "dunder-proto": "1.0.1", + "ejs": "5.0.1", + "emoji-regex": "8.0.0", + "end-of-stream": "1.4.5", + "enquirer": "2.3.6", + "es-define-property": "1.0.1", + "es-errors": "1.3.0", + "es-object-atoms": "1.1.1", + "es-set-tostringtag": "2.1.0", + "escalade": "3.2.0", + "escape-string-regexp": "1.0.5", + "figures": "3.2.0", + "flat": "5.0.2", + "follow-redirects": "1.15.11", + "form-data": "4.0.5", + "fs-constants": "1.0.0", + "function-bind": "1.1.2", + "get-caller-file": "2.0.5", + "get-intrinsic": "1.3.0", + "get-proto": "1.0.1", + "gopd": "1.2.0", + "has-flag": "4.0.0", + "has-symbols": "1.1.0", + "has-tostringtag": "1.0.2", + "hasown": "2.0.2", + "ieee754": "1.2.1", + "ignore": "7.0.5", + "inherits": "2.0.4", + "is-docker": "2.2.1", + "is-fullwidth-code-point": "3.0.0", + "is-interactive": "1.0.0", + "is-unicode-supported": "0.1.0", + "is-wsl": "2.2.0", + "json5": "2.2.3", + "jsonc-parser": "3.2.0", + "lines-and-columns": "2.0.3", + "log-symbols": "4.1.0", + "math-intrinsics": "1.1.0", + "mime-db": "1.52.0", + "mime-types": "2.1.35", + "mimic-fn": "2.1.0", + "minimatch": "10.2.4", + "minimist": "1.2.8", + "npm-run-path": "4.0.1", + "once": "1.4.0", + "onetime": "5.1.2", + "open": "8.4.2", + "ora": "5.3.0", + "path-key": "3.1.1", + "picocolors": "1.1.1", + "proxy-from-env": "2.1.0", + "readable-stream": "3.6.2", + "require-directory": "2.1.1", + "resolve.exports": "2.0.3", + "restore-cursor": "3.1.0", + "safe-buffer": "5.2.1", + "semver": "7.7.4", + "signal-exit": "3.0.7", + "smol-toml": "1.6.1", + "string_decoder": "1.3.0", + "string-width": "4.2.3", + "strip-ansi": "6.0.1", + "strip-bom": "3.0.0", + "supports-color": "7.2.0", + "tar-stream": "2.2.0", + "tmp": "0.2.4", + "tree-kill": "1.2.2", + "tsconfig-paths": "4.2.0", + "tslib": "2.8.1", + "util-deprecate": "1.0.2", + "wcwidth": "1.0.1", + "wrap-ansi": "7.0.0", + "wrappy": "1.0.2", + "y18n": "5.0.8", + "yaml": "2.8.0", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "dist/bin/nx.js", + "nx-cloud": "dist/bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "22.7.1", + "@nx/nx-darwin-x64": "22.7.1", + "@nx/nx-freebsd-x64": "22.7.1", + "@nx/nx-linux-arm-gnueabihf": "22.7.1", + "@nx/nx-linux-arm64-gnu": "22.7.1", + "@nx/nx-linux-arm64-musl": "22.7.1", + "@nx/nx-linux-x64-gnu": "22.7.1", + "@nx/nx-linux-x64-musl": "22.7.1", + "@nx/nx-win32-arm64-msvc": "22.7.1", + "@nx/nx-win32-x64-msvc": "22.7.1" + }, + "peerDependencies": { + "@swc-node/register": "^1.11.1", + "@swc/core": "^1.15.8" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/nx/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nx/node_modules/balanced-match": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.3.tgz", + "integrity": "sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/nx/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nx/node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/nx/node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/nx/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/nx/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nx/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nx/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/nx/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nx/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/object-assign": { + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true, + "license": "MIT" + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz", + "integrity": "sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-pipe": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", + "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-waterfall": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz", + "integrity": "sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.1.tgz", + "integrity": "sha512-LHGIUQUrcDIJUej53KJz1BPvUuHrItrR2yrnN0Kl9657cJ0ZT6QJHk9wWPBnQZhYT5KLyZWrk9jaYc2aKDu4yw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^4.0.0", + "ssri": "^12.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/pacote/node_modules/@npmcli/git": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz", + "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/@npmcli/promise-spawn": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.3.tgz", + "integrity": "sha512-Yb00SWaL4F8w+K8YGhQ55+xE4RUNdMHV43WZGsiTM92gS+lC0mGsn7I4hLug7pbao035S6bj3Y3w0cUNGLfmkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/pacote/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/pacote/node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/npm-pick-manifest/node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pacote/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pad": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pad/-/pad-3.3.0.tgz", + "integrity": "sha512-2/G2Q8J/lbkJ3Zf595U9jattrUkM1rwTr3s4n9smp3+ALe66V+t3I75SG0qjWzuQgmXOgiUS0/qE97S+0hP7Cw==", + "license": "BSD-3-Clause", + "dependencies": { + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">= 4.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-linux-x64-gnu": "4.9.5" + } + }, + "node_modules/pad-right": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", + "integrity": "sha512-4cy8M95ioIGolCoMmm2cMntGR1lPLEbOMzOKu8bzjuJP6JpzEMQcDHmh7hHLYGgob+nKe1YHFMaG4V59HQa89g==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-conflict-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-4.0.0.tgz", + "integrity": "sha512-37CN2VtcuvKgHUs8+0b1uJeEsbGn61GRHz469C94P5xiOoqpDYJYwjg4RY9Vmz39WyZAVkR5++nbJwLMIgOCnQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parse-conflict-json/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "node_modules/parse-json/node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/parse-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, + "license": "MIT", "dependencies": { - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - } + "protocols": "^2.0.0" } }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/parse-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", + "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", "dev": true, - "requires": { - "mime-db": "1.52.0" + "license": "MIT", + "dependencies": { + "parse-path": "^7.0.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "min-indent": { + "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "requires": { - "brace-expansion": "^1.1.7" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" }, - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, + "license": "BlueOak-1.0.0", "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - } + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, - "requires": { - "yallist": "^4.0.0" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, - "requires": { - "minipass": "^3.0.0" + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, - "requires": { - "encoding": "^0.1.13", - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "license": "MIT", + "engines": { + "node": ">=4" } }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "requires": { - "minipass": "^3.0.0" + "license": "MIT", + "engines": { + "node": "*" } }, - "minipass-json-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", - "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "requires": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } + "license": "ISC" }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, - "requires": { - "minipass": "^3.0.0" + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, - "requires": { - "minipass": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "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, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "license": "MIT", + "engines": { + "node": ">= 6" } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mkdirp-infer-owner": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz", - "integrity": "sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==", + "node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, - "requires": { - "chownr": "^2.0.0", - "infer-owner": "^1.0.4", - "mkdirp": "^1.0.3" + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", - "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } + "node_modules/pkg-dir/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multimatch": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", - "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true - }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" } }, - "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - }, + "license": "MIT", "dependencies": { - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node-gyp": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.0.tgz", - "integrity": "sha512-A6rJWfXFz7TQNjpldJ915WFb1LnhO4lIve3ANPbWreuEoLoKlFT3sxIepPBkLhM27crW8YmN+pjlgbasH6cH/Q==", + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", "dev": true, - "requires": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" }, - "node-pty": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-0.9.0.tgz", - "integrity": "sha512-MBnCQl83FTYOu7B4xWw10AW77AAh7ThCE1VXEv+JeWj8mSpGo+0bwgsV+b23ljBFwEM9OmsOv3kM27iUPPm84g==", + "node_modules/proggy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proggy/-/proggy-3.0.0.tgz", + "integrity": "sha512-QE8RApCM3IaRRxVzxrjbgNMpQEX6Wu0p0KBeoSiSEw5/bsGwZHsshF4LCxH2jp/r6BU+bqA3LrMDEYNfJnpD8Q==", "dev": true, - "requires": { - "nan": "^2.14.0" + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", - "dev": true + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } }, - "nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "node_modules/promise-all-reject-late": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", "dev": true, - "requires": { - "abbrev": "^1.0.0" + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "normalize-package-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-4.0.1.tgz", - "integrity": "sha512-EBk5QKKuocMJhB3BILuKhmaPjI8vNRSpIfO9woLC6NyHVkKKdVEdAO1mrT0ZfxNR1lKwCcTkuZfmGIFdizZ8Pg==", + "node_modules/promise-call-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.2.tgz", + "integrity": "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==", "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "license": "MIT", "dependencies": { - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - } + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "node_modules/promzard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/promzard/-/promzard-2.0.0.tgz", + "integrity": "sha512-Ncd0vyS2eXGOjchIRg6PVCYKetJYrW1BSbbIo+bKdig61TB6nH2RQNF2uP+qMpsI73L/jURLWojcw8JNIKZ3gg==", + "dev": true, + "license": "ISC", + "dependencies": { + "read": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "npm-bundled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", - "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", "dev": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" + "license": "MIT", + "engines": { + "node": ">= 8" } }, - "npm-install-checks": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-5.0.0.tgz", - "integrity": "sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA==", + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", "dev": true, - "requires": { - "semver": "^7.1.1" - }, + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.6.tgz", + "integrity": "sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.1", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" } }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true - }, - "npm-package-arg": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.1.tgz", - "integrity": "sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg==", + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", "dev": true, - "requires": { - "hosted-git-info": "^3.0.6", - "semver": "^7.0.0", - "validate-npm-package-name": "^3.0.0" - }, - "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } + "license": "MIT" }, - "npm-packlist": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.3.tgz", - "integrity": "sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==", + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "dev": true, - "requires": { - "glob": "^8.0.1", - "ignore-walk": "^5.0.1", - "npm-bundled": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "npm-bundled": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz", - "integrity": "sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==", - "dev": true, - "requires": { - "npm-normalize-package-bin": "^2.0.0" - } - }, - "npm-normalize-package-bin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", - "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">=10" } }, - "npm-pick-manifest": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-7.0.2.tgz", - "integrity": "sha512-gk37SyRmlIjvTfcYl6RzDbSmS9Y4TOBXfsPnoYqTHARNgWbyDiCSMLUpmALDj4jjcTZpURiEfsSHJj9k7EV4Rw==", + "node_modules/proxyquire": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", + "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", "dev": true, - "requires": { - "npm-install-checks": "^5.0.0", - "npm-normalize-package-bin": "^2.0.0", - "npm-package-arg": "^9.0.0", - "semver": "^7.3.5" - }, + "license": "MIT", "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "npm-normalize-package-bin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", - "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", - "dev": true - }, - "npm-package-arg": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz", - "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - } + "fill-keys": "^1.0.2", + "module-not-found-error": "^1.0.1", + "resolve": "^1.11.1" } }, - "npm-registry-fetch": { - "version": "13.3.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz", - "integrity": "sha512-eukJPi++DKRTjSBRcDZSDDsGqRK3ehbxfFUcgaRd0Yp6kRwOwh2WVn0r+8rMB4nnuzvAk6rQVzl6K5CkYOmnvw==", - "dev": true, - "requires": { - "make-fetch-happen": "^10.0.6", - "minipass": "^3.1.6", - "minipass-fetch": "^2.0.3", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.1", - "proc-log": "^2.0.0" - }, - "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "npm-package-arg": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz", - "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - } + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "requires": { - "path-key": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - } - }, - "nx": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/nx/-/nx-15.0.13.tgz", - "integrity": "sha512-5mJGWz91B9/sxzLjXdD+pmZTel54NeNNxFDis8OhtGDn6eRZ25qWsZNDgzqIDtwKn3c9gThAMHU4XH2OTgWUnA==", - "dev": true, - "requires": { - "@nrwl/cli": "15.0.13", - "@nrwl/tao": "15.0.13", - "@parcel/watcher": "2.0.4", - "@yarnpkg/lockfile": "^1.1.0", - "@yarnpkg/parsers": "^3.0.0-rc.18", - "@zkochan/js-yaml": "0.0.6", - "axios": "^1.0.0", - "chalk": "4.1.0", - "chokidar": "^3.5.1", - "cli-cursor": "3.1.0", - "cli-spinners": "2.6.1", - "cliui": "^7.0.2", - "dotenv": "~10.0.0", - "enquirer": "~2.3.6", - "fast-glob": "3.2.7", - "figures": "3.2.0", - "flat": "^5.0.2", - "fs-extra": "^10.1.0", - "glob": "7.1.4", - "ignore": "^5.0.4", - "js-yaml": "4.1.0", - "jsonc-parser": "3.2.0", - "minimatch": "3.0.5", - "npm-run-path": "^4.0.1", - "open": "^8.4.0", - "semver": "7.3.4", - "string-width": "^4.2.3", - "strong-log-transformer": "^2.1.0", - "tar-stream": "~2.2.0", - "tmp": "~0.2.1", - "tsconfig-paths": "^3.9.0", - "tslib": "^2.3.0", - "v8-compile-cache": "2.3.0", - "yargs": "^17.6.2", - "yargs-parser": "21.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "dependencies": { - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - } - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" } - } + ], + "license": "MIT" }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true + "node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "node_modules/read": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/read/-/read-4.1.0.tgz", + "integrity": "sha512-uRfX6K+f+R8OOrYScaM3ixPY4erg69f8DN6pgTvMcA9iRc8iDhwrA4m3Yu8YYKsXJgVvum+m8PkRboZwwuLzYA==", "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" + "license": "ISC", + "dependencies": { + "mute-stream": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "node_modules/read-cmd-shim": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/read-package-up": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-12.0.0.tgz", + "integrity": "sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==", "dev": true, - "requires": { - "wrappy": "1" + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.1", + "read-pkg": "^10.0.0", + "type-fest": "^5.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/read-package-up/node_modules/normalize-package-data": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", "dev": true, - "requires": { - "mimic-fn": "^2.1.0" + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^9.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "node_modules/read-package-up/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", "dev": true, - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/read-package-up/node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "node_modules/read-package-up/node_modules/read-pkg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", + "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", "dev": true, - "requires": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "@types/normalize-package-data": "^2.4.4", + "normalize-package-data": "^8.0.0", + "parse-json": "^8.3.0", + "type-fest": "^5.4.4", + "unicorn-magic": "^0.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true + "node_modules/read-package-up/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/read-package-up/node_modules/type-fest": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", "dev": true, - "requires": { - "p-try": "^2.0.0" + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/read-pkg": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, - "requires": { - "p-limit": "^2.0.0" + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", "dev": true, - "requires": { - "aggregate-error": "^3.0.0" + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-map-series": { + "node_modules/read-pkg-up/node_modules/find-up": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz", - "integrity": "sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==", - "dev": true - }, - "p-pipe": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", - "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==", - "dev": true - }, - "p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, - "requires": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-reduce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", - "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", - "dev": true - }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, - "requires": { - "p-finally": "^1.0.0" + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } }, - "p-waterfall": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz", - "integrity": "sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==", + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, - "requires": { - "p-reduce": "^2.0.0" + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "pacote": { - "version": "13.6.2", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.6.2.tgz", - "integrity": "sha512-Gu8fU3GsvOPkak2CkbojR7vjs3k3P9cA6uazKTHdsdV0gpCEQq2opelnEv30KRQWgVzP5Vd/5umjcedma3MKtg==", - "dev": true, - "requires": { - "@npmcli/git": "^3.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/run-script": "^4.1.0", - "cacache": "^16.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "infer-owner": "^1.0.4", - "minipass": "^3.1.6", - "mkdirp": "^1.0.4", - "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.1.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^5.0.0", - "read-package-json-fast": "^2.0.3", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11" - }, - "dependencies": { - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "hosted-git-info": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", - "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "lru-cache": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", - "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", - "dev": true - }, - "npm-package-arg": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz", - "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - } + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, - "pad-right": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", - "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, - "requires": { - "repeat-string": "^1.5.2" + "license": "MIT", + "engines": { + "node": ">=4" } }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true, - "requires": { - "callsites": "^3.0.0" + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "parse-conflict-json": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-2.0.2.tgz", - "integrity": "sha512-jDbRGb00TAPFsKWCpZZOT93SxVP9nONOSgES3AevqRq/CHvavEBvKAjxX9p5Y5F0RZLxH9Ufd9+RwtCsa+lFDA==", + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.1", - "just-diff": "^5.0.1", - "just-diff-apply": "^5.2.0" + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/read-pkg/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", + "license": "MIT", + "dependencies": { "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" } }, - "parse-path": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", - "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", + "node_modules/read-pkg/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, - "requires": { - "protocols": "^2.0.0" + "license": "MIT", + "engines": { + "node": ">=4" } }, - "parse-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", - "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "requires": { - "parse-path": "^7.0.0" + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "path-exists": { + "node_modules/read-pkg/node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" + "license": "MIT", + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "pkg-dir": { + "node_modules/redent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, - "requires": { - "find-up": "^3.0.0" + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" }, - "proc-log": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", - "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", - "dev": true + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } }, - "promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "dev": true + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" }, - "promise-call-limit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-1.0.1.tgz", - "integrity": "sha512-3+hgaa19jzCGLuSCbieeRsu5C2joKfYn8pY6JAuXFRVfF4IO+L7UPpFWNTeWT9pM7uhskvbPPd/oEOktCn317Q==", - "dev": true + "node_modules/regexp-match-indices": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", + "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "regexp-tree": "^0.1.11" + } }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } }, - "promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "promzard": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", - "integrity": "sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw==", + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", "dev": true, - "requires": { - "read": "1" + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" } }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" }, - "protocols": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", - "dev": true + "node_modules/regjsparser": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } }, - "punycode": { + "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "requires": { - "safe-buffer": "^5.1.0" + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "requires": { - "mute-stream": "~0.0.4" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "read-cmd-shim": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-3.0.1.tgz", - "integrity": "sha512-kEmDUoYf/CDy8yZbLTmhB1X9kkjf9Q80PCNsDMb7ufrGd6zZSQA1+UyjrO+pZm5K/S4OXCWJeiIt1JA8kAsa6g==", - "dev": true - }, - "read-package-json": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.2.tgz", - "integrity": "sha512-BSzugrt4kQ/Z0krro8zhTwV1Kd79ue25IhNN/VtHFy1mG/6Tluyi+msc0UpwaoQzxSHa28mntAjIZY6kEgfR9Q==", - "dev": true, - "requires": { - "glob": "^8.0.1", - "json-parse-even-better-errors": "^2.3.1", - "normalize-package-data": "^4.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", - "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", - "dev": true - } + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, - "read-package-json-fast": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz", - "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==", + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.0", - "npm-normalize-package-bin": "^1.0.1" + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">=10" } }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - } + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "license": "MIT", + "engines": { + "node": ">= 4" } }, - "readdir-scoped-modules": { + "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", - "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "dev": true, - "requires": { - "picomatch": "^2.2.1" + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "node_modules/rimraf/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", - "dev": true - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "node_modules/rimraf/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, - "requires": { - "regenerate": "^1.4.2" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "node_modules/rimraf/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "regexp-match-indices": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", - "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, - "requires": { - "regexp-tree": "^0.1.11" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "regexp-tree": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", - "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", - "dev": true + "node_modules/rimraf/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true + "node_modules/rimraf/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "node_modules/rimraf/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true + "node_modules/rimraf/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" }, - "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, + "license": "ISC", "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "node_modules/rimraf/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "node_modules/rimraf/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "requires": { - "resolve-from": "^5.0.0" + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz", - "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==", + "node_modules/rimraf/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, - "requires": { - "resolve-from": "^5.0.0" + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "node_modules/rimraf/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "node_modules/run-async": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-4.0.6.tgz", + "integrity": "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==", "dev": true, - "requires": { - "glob": "^7.1.3" + "license": "MIT", + "engines": { + "node": ">=0.12.0" } }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-parallel": { + "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "requires": { + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { "queue-microtask": "^1.2.2" } }, - "rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", - "dev": true, - "requires": { + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { "tslib": "^2.1.0" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "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/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "safer-buffer": { + "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 + "license": "MIT" }, - "seed-random": { + "node_modules/seed-random": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", - "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=", - "dev": true + "integrity": "sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ==", + "dev": true, + "license": "MIT" }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/serialize-javascript": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", "dev": true, - "requires": { - "randombytes": "^2.1.0" + "license": "BSD-3-Clause", + "engines": { + "node": ">=20.0.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } }, - "shallow-clone": { + "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" } }, - "shebang-command": { + "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "node_modules/side-channel": { + "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, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "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, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "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, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "license": "ISC" + }, + "node_modules/sigstore": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", + "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.0", + "@sigstore/tuf": "^4.0.1", + "@sigstore/verify": "^3.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/sinon": { + "version": "21.1.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.1.2.tgz", + "integrity": "sha512-FS6mN+/bx7e2ajpXkEmOcWB6xBzWiuNoAQT18/+a20SS4U7FSYl8Ms7N6VTUxN/1JAjkx7aXp+THMC8xdpp0gA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^15.3.2", + "@sinonjs/samsam": "^10.0.2", + "diff": "^8.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, - "slash": { + "node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">=6" } }, - "smart-buffer": { + "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true - }, - "socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "node_modules/smol-toml": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", + "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==", "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/socks": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.8.tgz", + "integrity": "sha512-NlGELfPrgX2f1TAAcz0WawlLn+0r3FyhhCRpFFK2CemXenPYvzMWWZINv3eDNo9ucdwme7oCHRY0Jnbs4aIkog==", + "dev": true, + "license": "MIT", "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "node_modules/source-map-support": { + "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, - "requires": { + "license": "MIT", + "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" }, - "spdx-expression-parse": { + "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" }, - "split": { + "node_modules/split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "through": "2" + }, + "engines": { + "node": "*" } }, - "split2": { + "node_modules/split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==", + "license": "ISC" + }, + "node_modules/split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "readable-stream": "^3.0.0" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "requires": { - "minipass": "^3.1.1" + "node_modules/ssh2": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", + "integrity": "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==", + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.10", + "nan": "^2.23.0" } }, - "stack-chain": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz", - "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==", - "dev": true - }, - "stack-generator": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.5.tgz", - "integrity": "sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q==", + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", "dev": true, - "requires": { - "stackframe": "^1.1.1" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "stackframe": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", - "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", - "dev": true + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "dev": true, + "license": "MIT" }, - "stacktrace-gps": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz", - "integrity": "sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg==", + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", "dev": true, - "requires": { - "source-map": "0.5.6", - "stackframe": "^1.1.1" - }, + "license": "MIT", "dependencies": { - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - } + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" } }, - "stacktrace-js": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", - "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", "dev": true, - "requires": { - "error-stack-parser": "^2.0.6", - "stack-generator": "^2.0.5", - "stacktrace-gps": "^3.0.4" + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "string-argv": { + "node_modules/string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } }, - "string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", - "dev": true + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, - "string-width": { + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">=8" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "strip-indent": { + "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "strong-log-transformer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", - "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", "dev": true, - "requires": { - "duplexer": "^0.1.1", - "minimist": "^1.2.0", - "through": "^2.3.4" + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "requires": { - "has-flag": "^3.0.0" + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "license": "MIT", + "engines": { + "node": ">=20" }, - "dependencies": { - "ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "tar": { - "version": "6.1.12", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.12.tgz", - "integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==", + "node_modules/tar": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", + "integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==", "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" } }, - "tar-stream": { + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" } }, - "temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", - "dev": true + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-8.0.0.tgz", + "integrity": "sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^13.0.6", + "minimatch": "^10.2.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/test-exclude/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "text-extensions": { + "node_modules/text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" }, - "thenify": { + "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "any-promise": "^1.0.0" } }, - "thenify-all": { + "node_modules/thenify-all": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" } }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "license": "MIT" }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, - "requires": { - "readable-stream": "3" + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "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==", "dev": true, - "requires": { - "rimraf": "^3.0.0" - }, + "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==", + "dev": 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/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "dev": true, + "license": "MIT", "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true } } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "to-regex-range": { + "node_modules/tmp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz", + "integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "license": "MIT", + "optional": true, + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "treeverse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-2.0.0.tgz", - "integrity": "sha512-N5gJCkLu1aXccpOTtqV6ddSEi6ZmGkh3hjmbu1IjcavJK4qyOVQmi0myQKM7z5jVGmD68SJoliaVrMmVObhj6A==", - "dev": true + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/treeverse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz", + "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "trim-newlines": { + "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } }, - "tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", + "json5": "^1.0.2", + "minimist": "^1.2.6", "strip-bom": "^3.0.0" - }, + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" } }, - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", + "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "type-check": { + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, + "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "typedarray": { + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "dev": true, + "license": "MIT" }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, - "requires": { - "is-typedarray": "^1.0.0" + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true + "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" + } }, - "uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, - "optional": true + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "node_modules/undici": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" + "license": "MIT", + "engines": { + "node": ">=18.17" } }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true + "node_modules/undici-types": { + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "unicode-match-property-ecmascript": { + "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", - "dev": true + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "dev": true, - "requires": { - "unique-slug": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=4" } }, - "unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "dev": true, - "requires": { - "imurmurhash": "^0.1.4" + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "license": "ISC" }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } }, - "upath": { + "node_modules/upath": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } }, - "upper-case-first": { + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/upper-case-first": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "tslib": "^2.0.3" } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { + "license": "BSD-2-Clause", + "dependencies": { "punycode": "^2.1.0" } }, - "util-arity": { + "node_modules/util-arity": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/util-arity/-/util-arity-1.1.0.tgz", - "integrity": "sha1-WdAa8f2z/t4KxOYysKtfbOl8kzA=", - "dev": true + "integrity": "sha512-kkyIsXKwemfSy8ZEoaIz06ApApnWsk5hQO0vLjZS6UkBiGiW++Jsyb8vSBoc0WKlffGoGs5yYy/j5pp8zckrFA==", + "dev": true, + "license": "MIT" }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true + "license": "MIT" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "node_modules/validate-npm-package-name": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", + "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==", "dev": true, - "requires": { - "builtins": "^1.0.3" + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "node_modules/walk-up-path": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", + "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "license": "ISC", + "engines": { + "node": "20 || >=22" } }, - "walk-up-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-1.0.0.tgz", - "integrity": "sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==", - "dev": true - }, - "wcwidth": { + "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "defaults": "^1.0.3" } }, - "which": { + "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==", + "license": "BSD-2-Clause" + }, + "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==", + "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", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "which-boxed-primitive": { + "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "wide-align": { + "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "wordwrap": { + "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "dev": true, + "license": "MIT" }, - "workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true + "node_modules/workerpool": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } }, - "wrap-ansi": { + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, - "requires": { - "graceful-fs": "^4.1.11", + "license": "ISC", + "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "write-json-file": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz", - "integrity": "sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==", + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "requires": { - "detect-indent": "^6.0.0", - "graceful-fs": "^4.1.15", - "is-plain-obj": "^2.0.0", - "make-dir": "^3.0.0", - "sort-keys": "^4.0.0", - "write-file-atomic": "^3.0.0" + "license": "ISC", + "engines": { + "node": ">=14" }, - "dependencies": { - "detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "sort-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", - "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", - "dev": true, - "requires": { - "is-plain-obj": "^2.0.0" - } - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "write-pkg": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz", - "integrity": "sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==", + "node_modules/www-authenticate": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/www-authenticate/-/www-authenticate-0.6.3.tgz", + "integrity": "sha512-8VkdLBJiBh5aXlJvcVaPykwSI//OA+Sxw7g84vIyCqoqlXtLupGNhyXxbgVuZ7g5ZS+lCJ4bTtcw/gJciqEuAg==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "dev": true, - "requires": { - "sort-keys": "^2.0.0", - "type-fest": "^0.4.1", - "write-json-file": "^3.2.0" - }, - "dependencies": { - "type-fest": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", - "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==", - "dev": true - }, - "write-json-file": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", - "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", - "dev": true, - "requires": { - "detect-indent": "^5.0.0", - "graceful-fs": "^4.1.15", - "make-dir": "^2.1.0", - "pify": "^4.0.1", - "sort-keys": "^2.0.0", - "write-file-atomic": "^2.4.2" - } - } + "license": "MIT", + "engines": { + "node": ">=8.0" } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, - "requires": { - "cliui": "^7.0.2", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } }, - "yargs-unparser": { + "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - } + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/navy": { + "version": "7.0.0-alpha.4", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7", + "bluebird": "^3.7.2", + "chalk": "^4.1.2", + "cli-spinners": "^2.6.1", + "commander": "^12.1.0", + "debug": "^4.4.0", + "dockerode": "^5.0.0", + "eventemitter2": "^6.4.5", + "inquirer": "^8.2.6", + "invariant": "^2.2.4", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "node-fetch": "^2.6.5", + "node-forge": "^1.3.0", + "open": "^8.4.2", + "pad": "^3.2.0", + "promise-retry": "^2.0.1", + "ramda": "^0.30.1", + "resolve": "^1.20.0", + "strip-ansi": "^6.0.1", + "www-authenticate": "^0.6.3" + }, + "bin": { + "navy": "bin/navy.js" + }, + "engines": { + "node": ">=22" + } + }, + "packages/navy-plugin-nodejs": { + "version": "7.0.0-alpha.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7", + "findit2": "^2.2.3", + "lodash.mapvalues": "^4.4.0" + }, + "engines": { + "node": ">=22" + } + }, + "packages/navy/node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "packages/navy/node_modules/commander": { + "version": "12.1.0", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "packages/navy/node_modules/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "packages/navy/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" + }, + "packages/navy/node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/navy/node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } } } } diff --git a/package.json b/package.json index b8b2e95..e41e80f 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,11 @@ "mocha": "--require @babel/register packages/*/src/{,**}/__tests__/*.js" }, "engines": { - "node": ">=10" + "node": ">=22" }, + "workspaces": [ + "packages/*" + ], "scripts": { "build": "./scripts/build.sh", "watch": "./scripts/watch.sh", @@ -16,13 +19,13 @@ "flow": "flow", "unit": "mocha $npm_package_config_mocha", "unit-watch": "mocha -w $npm_package_config_mocha", + "coverage": "c8 mocha $npm_package_config_mocha", + "coverage-no-check": "c8 --no-check-coverage mocha $npm_package_config_mocha", "test": "./scripts/test.sh", - "preinstall": "which npx >/dev/null 2>&1 && npx npm-force-resolutions || npm exec -- npm-force-resolutions", "prepare": "npm run build", "publish": "lerna publish", "publish-rc": "NPM_DIST_TAG=next npm run publish", "publish-website": "cd website && SITE_URL=https://moneyhub.github.io/navy npm run build && gh-pages -d build", - "bootstrap": "lerna bootstrap", "updated": "lerna updated" }, "repository": { @@ -42,31 +45,44 @@ "@babel/preset-typescript": "^7", "@babel/register": "^7", "@babel/runtime": "^7", - "@cucumber/cucumber": "^7", + "@cucumber/cucumber": "^12.8.2", "babel-plugin-add-module-exports": "^1.0.4", + "c8": "^11.0.0", "chai": "^4.3.4", "chai-like": "^1.1.1", "chai-properties": "^1.4.0", "chai-things": "^0.2.0", "core-js": "^3", - "eslint": "^7", - "eslint-config-standard": "^11.0.0", - "eslint-plugin-chai-friendly": "^0.5.0", - "eslint-plugin-flowtype": "^6", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-node": "^11", - "eslint-plugin-promise": "^5", - "eslint-plugin-standard": "^5", - "flow-bin": "^0.75.0", - "lerna": "^5.5.1", + "eslint": "^8.57.1", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-chai-friendly": "^1.2.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-promise": "^6.6.0", + "flow-bin": "^0.311.0", + "lerna": "^9.0.7", "lodash": "^4.17.21", - "mocha": "^10.0.0", + "mocha": "^11.0.0", + "nock": "^14.0.13", "node-fetch": "^2.6.5", - "node-pty": "^0.9.0", - "regenerator-runtime": "0.13.9", - "rimraf": "^2.7.1", - "strip-ansi": "^3.0.1" + "node-pty": "^1.0.0", + "proxyquire": "^2.1.3", + "regenerator-runtime": "^0.14.1", + "rimraf": "^5.0.10", + "sinon": "^21.1.2", + "strip-ansi": "^6.0.1" }, - "resolutions": {}, - "dependencies": {} + "overrides": { + "mocha": { + "diff": "^8.0.3", + "serialize-javascript": "^7.0.5" + }, + "lerna": { + "nx": { + "brace-expansion": "^5.0.5", + "follow-redirects": "^1.16.0", + "yaml": "^2.8.3" + } + } + } } diff --git a/packages/navy-plugin-nodejs/package-lock.json b/packages/navy-plugin-nodejs/package-lock.json deleted file mode 100644 index 8e68f1c..0000000 --- a/packages/navy-plugin-nodejs/package-lock.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "navy-plugin-nodejs", - "version": "5.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", - "requires": { - "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - } - } - }, - "findit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", - "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=" - }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=" - } - } -} diff --git a/packages/navy-plugin-nodejs/package.json b/packages/navy-plugin-nodejs/package.json index 590d0c8..2a47386 100644 --- a/packages/navy-plugin-nodejs/package.json +++ b/packages/navy-plugin-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "navy-plugin-nodejs", - "version": "5.0.1", + "version": "7.0.0-alpha.1", "description": "A set of helpers to help improve the experience of developing NodeJS applications with Navy", "main": "lib/index.js", "scripts": { @@ -23,9 +23,12 @@ "url": "https://github.com/moneyhub/navy/issues" }, "homepage": "https://github.com/moneyhub/navy#readme", + "engines": { + "node": ">=22" + }, "dependencies": { "@babel/runtime": "^7", - "findit": "^2.0.0", + "findit2": "^2.2.3", "lodash.mapvalues": "^4.4.0" } } diff --git a/packages/navy-plugin-nodejs/src/__tests__/index.js b/packages/navy-plugin-nodejs/src/__tests__/index.js new file mode 100644 index 0000000..a2fd328 --- /dev/null +++ b/packages/navy-plugin-nodejs/src/__tests__/index.js @@ -0,0 +1,59 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('navy-plugin-nodejs/index', function () { + + let sandbox + let mountUserHomeMiddleware + let rewriteLinkedNodeModules + let plugin + + beforeEach(function () { + sandbox = sinon.createSandbox() + + mountUserHomeMiddleware = function () {} + rewriteLinkedNodeModules = function () {} + + plugin = proxyquire.noCallThru()('../index', { + './middleware/mount-user-home': mountUserHomeMiddleware, + './hooks/rewrite-linked-node-modules': rewriteLinkedNodeModules, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should register the mount-user-home middleware on the navy', function () { + const navy = { + registerMiddleware: sandbox.stub(), + on: sandbox.stub(), + } + + plugin(navy) + + expect(navy.registerMiddleware.calledOnce).to.equal(true) + expect(navy.registerMiddleware.firstCall.args[0]).to.equal(mountUserHomeMiddleware) + }) + + it('should register the rewrite-linked-node-modules hook for cli.develop.beforeLaunch', function () { + const navy = { + registerMiddleware: sandbox.stub(), + on: sandbox.stub(), + } + + plugin(navy) + + expect(navy.on.calledOnce).to.equal(true) + expect(navy.on.firstCall.args[0]).to.equal('cli.develop.beforeLaunch') + expect(navy.on.firstCall.args[1]).to.equal(rewriteLinkedNodeModules) + }) + + }) + +}) diff --git a/packages/navy-plugin-nodejs/src/hooks/__tests__/rewrite-linked-node-modules.js b/packages/navy-plugin-nodejs/src/hooks/__tests__/rewrite-linked-node-modules.js new file mode 100644 index 0000000..0d5178a --- /dev/null +++ b/packages/navy-plugin-nodejs/src/hooks/__tests__/rewrite-linked-node-modules.js @@ -0,0 +1,115 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { EventEmitter } from 'events' + +describe('navy-plugin-nodejs/hooks/rewrite-linked-node-modules', function () { + + let sandbox + let finditStub + let finder + let fsStub + let pathStub + let osStub + let consoleLogStub + let consoleErrorStub + let originalCwd + let rewriteLinkedNodeModules + + beforeEach(function () { + sandbox = sinon.createSandbox() + + finder = new EventEmitter() + finditStub = sandbox.stub().returns(finder) + + fsStub = { + realpathSync: sandbox.stub().callsFake(link => `${link}.real`), + unlinkSync: sandbox.stub(), + symlinkSync: sandbox.stub(), + } + + pathStub = { + join: sandbox.stub().callsFake((...args) => args.join('/')), + } + + osStub = { EOL: '\n' } + + consoleLogStub = sandbox.stub(console, 'log') + consoleErrorStub = sandbox.stub(console, 'error') + + originalCwd = process.cwd + sandbox.stub(process, 'cwd').returns('/project') + + rewriteLinkedNodeModules = proxyquire.noCallThru()('../rewrite-linked-node-modules', { + findit2: finditStub, + path: pathStub, + fs: fsStub, + os: osStub, + '../../package.json': { name: 'navy-plugin-nodejs' }, + }) + }) + + afterEach(function () { + process.cwd = originalCwd + sandbox.restore() + }) + + describe('default export', function () { + + it('should walk node_modules under the current working directory', function () { + rewriteLinkedNodeModules() + + expect(finditStub.calledOnce).to.equal(true) + expect(finditStub.firstCall.args[0]).to.equal('/project/node_modules') + }) + + it('should log an error when finder emits an error', function () { + rewriteLinkedNodeModules() + + finder.emit('error', new Error('walk failed')) + + expect(consoleErrorStub.calledOnce).to.equal(true) + const printed = consoleErrorStub.firstCall.args.join(' ') + expect(printed).to.contain('navy-plugin-nodejs') + expect(printed).to.contain('walk failed') + }) + + it('should rewrite a symlink to its absolute path', function () { + rewriteLinkedNodeModules() + + finder.emit('link', '/project/node_modules/foo') + + expect(fsStub.realpathSync.calledWith('/project/node_modules/foo')).to.equal(true) + expect(fsStub.unlinkSync.calledWith('/project/node_modules/foo')).to.equal(true) + expect(fsStub.symlinkSync.calledWith( + '/project/node_modules/foo.real', + '/project/node_modules/foo', + )).to.equal(true) + }) + + it('should log the rewritten link', function () { + rewriteLinkedNodeModules() + + finder.emit('link', '/project/node_modules/foo') + + const printed = consoleLogStub.firstCall.args.join(' ') + expect(printed).to.contain('Linked') + expect(printed).to.contain('/project/node_modules/foo') + expect(printed).to.contain('/project/node_modules/foo.real') + }) + + it('should ignore links inside .bin directories', function () { + rewriteLinkedNodeModules() + + finder.emit('link', '/project/node_modules/.bin/something') + + expect(fsStub.realpathSync.called).to.equal(false) + expect(fsStub.unlinkSync.called).to.equal(false) + expect(fsStub.symlinkSync.called).to.equal(false) + }) + + }) + +}) diff --git a/packages/navy-plugin-nodejs/src/hooks/rewrite-linked-node-modules.js b/packages/navy-plugin-nodejs/src/hooks/rewrite-linked-node-modules.js index fba9a37..ced5298 100644 --- a/packages/navy-plugin-nodejs/src/hooks/rewrite-linked-node-modules.js +++ b/packages/navy-plugin-nodejs/src/hooks/rewrite-linked-node-modules.js @@ -1,9 +1,9 @@ -import findit from 'findit' +import findit from 'findit2' import path from 'path' import fs from 'fs' import os from 'os' -import {name as pluginName} from '../../package.json' +import { name as pluginName } from '../../package.json' export default () => { const finder = findit(path.join(process.cwd(), 'node_modules')) diff --git a/packages/navy-plugin-nodejs/src/middleware/__tests__/mount-user-home.js b/packages/navy-plugin-nodejs/src/middleware/__tests__/mount-user-home.js new file mode 100644 index 0000000..808d8fa --- /dev/null +++ b/packages/navy-plugin-nodejs/src/middleware/__tests__/mount-user-home.js @@ -0,0 +1,113 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' + +import mountUserHome from '../mount-user-home' + +describe('navy-plugin-nodejs/middleware/mount-user-home', function () { + + let originalHome + + beforeEach(function () { + originalHome = process.env.HOME + process.env.HOME = '/home/test-user' + }) + + afterEach(function () { + if (originalHome === undefined) { + delete process.env.HOME + } else { + process.env.HOME = originalHome + } + }) + + describe('default export', function () { + + it('should pass through the original config when no services have _develop state', function () { + const config = { + services: { + web: { image: 'nginx' }, + api: { image: 'node' }, + }, + } + const state = { services: {} } + + const result = mountUserHome(config, state) + + expect(result.services.web).to.eql({ image: 'nginx' }) + expect(result.services.api).to.eql({ image: 'node' }) + }) + + it('should add a HOME volume mount for services in _develop state', function () { + const config = { + services: { + web: { image: 'node' }, + }, + } + const state = { + services: { + web: { _develop: { mounts: {} } }, + }, + } + + const result = mountUserHome(config, state) + + expect(result.services.web.volumes).to.eql([ + '/home/test-user:/home/test-user', + ]) + }) + + it('should append the HOME volume to existing volumes when in develop mode', function () { + const config = { + services: { + web: { image: 'node', volumes: ['/data:/data'] }, + }, + } + const state = { + services: { + web: { _develop: { mounts: {} } }, + }, + } + + const result = mountUserHome(config, state) + + expect(result.services.web.volumes).to.eql([ + '/data:/data', + '/home/test-user:/home/test-user', + ]) + }) + + it('should leave services without _develop state untouched', function () { + const config = { + services: { + web: { image: 'node', volumes: ['/data:/data'] }, + }, + } + const state = { + services: { + web: {}, + }, + } + + const result = mountUserHome(config, state) + + expect(result.services.web).to.eql({ image: 'node', volumes: ['/data:/data'] }) + }) + + it('should preserve the rest of the config object', function () { + const config = { + version: '3', + services: { web: {} }, + networks: { default: {} }, + } + const state = { services: {} } + + const result = mountUserHome(config, state) + + expect(result.version).to.equal('3') + expect(result.networks).to.eql({ default: {} }) + }) + + }) + +}) diff --git a/packages/navy/package-lock.json b/packages/navy/package-lock.json deleted file mode 100644 index 4921e17..0000000 --- a/packages/navy/package-lock.json +++ /dev/null @@ -1,842 +0,0 @@ -{ - "name": "navy", - "version": "5.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", - "requires": { - "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - } - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - } - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==" - }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "cpu-features": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.2.tgz", - "integrity": "sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==", - "optional": true, - "requires": { - "nan": "^2.14.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "requires": { - "clone": "^1.0.2" - } - }, - "docker-modem": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.3.tgz", - "integrity": "sha512-Tgkn2a+yiNP9FoZgMa/D9Wk+D2Db///0KOyKSYZRJa8w4+DzKyzQMkczKSdR/adQ0x46BOpeNkoyEOKjPhCzjw==", - "requires": { - "debug": "^4.1.1", - "readable-stream": "^3.5.0", - "split-ca": "^1.0.1", - "ssh2": "^1.4.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "dockerode": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.1.tgz", - "integrity": "sha512-AS2mr8Lp122aa5n6d99HkuTNdRV1wkkhHwBdcnY6V0+28D3DSYwhxAk85/mM9XwD3RMliTxyr63iuvn5ZblFYQ==", - "requires": { - "docker-modem": "^3.0.0", - "tar-fs": "~2.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "eventemitter2": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", - "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "requires": { - "has": "^1.0.3" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true - }, - "node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz", - "integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "pad": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/pad/-/pad-3.2.0.tgz", - "integrity": "sha512-2u0TrjcGbOjBTJpyewEl4hBO3OeX5wWue7eIFPzQTg6wFSvoaHcBTTUY5m+n0hd04gmTCPuY0kCpVIVuw5etwg==", - "requires": { - "wcwidth": "^1.0.1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "promise-retry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", - "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "ramda": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.28.0.tgz", - "integrity": "sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" - }, - "split-ca": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", - "integrity": "sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY=" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "ssh2": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.5.0.tgz", - "integrity": "sha512-iUmRkhH9KGeszQwDW7YyyqjsMTf4z+0o48Cp4xOwlY5LjtbIAvyd3fwnsoUZW/hXmTCRA3yt7S/Jb9uVjErVlA==", - "requires": { - "asn1": "^0.2.4", - "bcrypt-pbkdf": "^1.0.2", - "cpu-features": "0.0.2", - "nan": "^2.15.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "tar-fs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", - "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "requires": { - "defaults": "^1.0.3" - } - }, - "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==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "www-authenticate": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/www-authenticate/-/www-authenticate-0.6.3.tgz", - "integrity": "sha512-8VkdLBJiBh5aXlJvcVaPykwSI//OA+Sxw7g84vIyCqoqlXtLupGNhyXxbgVuZ7g5ZS+lCJ4bTtcw/gJciqEuAg==" - } - } -} diff --git a/packages/navy/package.json b/packages/navy/package.json index 6288709..5aecff5 100644 --- a/packages/navy/package.json +++ b/packages/navy/package.json @@ -1,6 +1,6 @@ { "name": "navy", - "version": "5.0.1", + "version": "7.0.0-alpha.4", "description": "Quick and powerful development environments using Docker and Docker Compose", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -24,29 +24,30 @@ "url": "https://github.com/moneyhub/navy/issues" }, "homepage": "https://github.com/moneyhub/navy#readme", + "engines": { + "node": ">=22" + }, "dependencies": { "@babel/runtime": "^7", "bluebird": "^3.7.2", - "chalk": "^1.1.3", + "chalk": "^4.1.2", "cli-spinners": "^2.6.1", - "commander": "^2.20.3", - "debug": "^2.2.0", - "dockerode": "^3.3.1", + "commander": "^12.1.0", + "debug": "^4.4.0", + "dockerode": "^5.0.0", "eventemitter2": "^6.4.5", - "inquirer": "^7.3.3", + "inquirer": "^8.2.6", "invariant": "^2.2.4", - "js-yaml": "^3.14.1", + "js-yaml": "^4.1.0", "lodash": "^4.17.21", - "mkdirp": "^0.5.5", "node-fetch": "^2.6.5", "node-forge": "^1.3.0", - "opn": "^5.5.0", + "open": "^8.4.2", "pad": "^3.2.0", - "promise-retry": "^1.1.1", - "ramda": "^0.28.0", + "promise-retry": "^2.0.1", + "ramda": "^0.30.1", "resolve": "^1.20.0", - "rimraf": "^2.7.1", - "strip-ansi": "^3.0.1", + "strip-ansi": "^6.0.1", "www-authenticate": "^0.6.3" } } diff --git a/packages/navy/src/__tests__/config-provider.js b/packages/navy/src/__tests__/config-provider.js new file mode 100644 index 0000000..bd4d64b --- /dev/null +++ b/packages/navy/src/__tests__/config-provider.js @@ -0,0 +1,95 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import FileSystem from '../config-providers/filesystem' +import NPM from '../config-providers/npm' +import { + resolveConfigProviderFromName, + getImportCommandLineOptions, + getImportOptionsForCLI, +} from '../config-provider' + +describe('config-provider', function () { + + let sandbox + + beforeEach(function () { + sandbox = sinon.createSandbox() + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('resolveConfigProviderFromName', function () { + + it('should return the FileSystem provider for "filesystem"', function () { + expect(resolveConfigProviderFromName('filesystem')).to.equal(FileSystem) + }) + + it('should return the NPM provider for "npm"', function () { + expect(resolveConfigProviderFromName('npm')).to.equal(NPM) + }) + + it('should return null for unknown provider names', function () { + expect(resolveConfigProviderFromName('git')).to.equal(null) + }) + + }) + + describe('getImportCommandLineOptions', function () { + + it('should return the concatenation of every provider\'s importCliOptions', function () { + const options = getImportCommandLineOptions() + + expect(options).to.be.an('array') + expect(options).to.eql([...NPM.importCliOptions, ...FileSystem.importCliOptions]) + }) + + }) + + describe('getImportOptionsForCLI', function () { + + it('should return options from the first provider that returns a non-null value', async function () { + const npmStub = sandbox.stub(NPM, 'getImportOptionsForCLI').resolves(null) + const fsResult = { configProvider: 'filesystem' } + const fsStub = sandbox.stub(FileSystem, 'getImportOptionsForCLI').resolves(fsResult) + + const result = await getImportOptionsForCLI({ path: '/tmp' }) + + expect(result).to.equal(fsResult) + expect(npmStub.calledOnce).to.equal(true) + expect(fsStub.calledOnce).to.equal(true) + }) + + it('should not call subsequent providers once one returns options', async function () { + const npmResult = { configProvider: 'npm' } + const npmStub = sandbox.stub(NPM, 'getImportOptionsForCLI').resolves(npmResult) + const fsStub = sandbox.stub(FileSystem, 'getImportOptionsForCLI').resolves(null) + + const result = await getImportOptionsForCLI({}) + + expect(result).to.equal(npmResult) + expect(npmStub.calledOnce).to.equal(true) + expect(fsStub.called).to.equal(false) + }) + + it('should throw an invariant violation when no provider matches', async function () { + sandbox.stub(NPM, 'getImportOptionsForCLI').resolves(null) + sandbox.stub(FileSystem, 'getImportOptionsForCLI').resolves(null) + + let caught + try { + await getImportOptionsForCLI({}) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.match(/CLI_IMPORT_RESOLVE_OPTIONS_ERR/) + }) + + }) + +}) diff --git a/packages/navy/src/__tests__/config.js b/packages/navy/src/__tests__/config.js new file mode 100644 index 0000000..6babe18 --- /dev/null +++ b/packages/navy/src/__tests__/config.js @@ -0,0 +1,145 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import path from 'path' +import fs from 'fs' +import { promises as fsPromises } from 'fs' +import { getConfig, getConfigDir, getConfigPath, setConfig, DEFAULT_TLS_ROOT_CA_DIR } from '../config' + +async function clearConfigCache(sandbox) { + const mkdirRestore = sandbox.stub(fsPromises, 'mkdir').resolves() + const writeRestore = sandbox.stub(fsPromises, 'writeFile').resolves() + await setConfig(null) + mkdirRestore.restore() + writeRestore.restore() +} + +describe('config', function () { + + let sandbox + let originalHome + + beforeEach(async function () { + sandbox = sinon.createSandbox() + originalHome = process.env.HOME + process.env.HOME = '/home/test-user' + await clearConfigCache(sandbox) + }) + + afterEach(function () { + sandbox.restore() + if (originalHome === undefined) { + delete process.env.HOME + } else { + process.env.HOME = originalHome + } + }) + + describe('getConfigDir', function () { + + it('should join $HOME with .navy', function () { + expect(getConfigDir()).to.equal(path.join('/home/test-user', '.navy')) + }) + + it('should throw when HOME is not set', function () { + delete process.env.HOME + expect(() => getConfigDir()).to.throw(/NO_HOME_DIRECTORY/) + }) + + }) + + describe('getConfigPath', function () { + + it('should return /config.json', function () { + expect(getConfigPath()).to.equal(path.join('/home/test-user', '.navy', 'config.json')) + }) + + }) + + describe('DEFAULT_TLS_ROOT_CA_DIR', function () { + + it('should be exported as a string referencing tls-root-ca', function () { + expect(DEFAULT_TLS_ROOT_CA_DIR).to.be.a('string') + expect(DEFAULT_TLS_ROOT_CA_DIR).to.contain('tls-root-ca') + }) + + }) + + describe('getConfig', function () { + + it('should read the config file from disk and parse it as JSON', function () { + const onDisk = { defaultNavy: 'mine', externalIP: '10.0.0.1', tlsRootCaDir: '/tmp/ca' } + sandbox.stub(fs, 'readFileSync').returns(JSON.stringify(onDisk)) + + expect(getConfig()).to.eql(onDisk) + }) + + it('should return the cached config on subsequent calls', function () { + const onDisk = { defaultNavy: 'mine' } + const readStub = sandbox.stub(fs, 'readFileSync').returns(JSON.stringify(onDisk)) + + getConfig() + getConfig() + getConfig() + + expect(readStub.callCount).to.equal(1) + }) + + it('should fall back to default config when reading the file fails', function () { + sandbox.stub(fs, 'readFileSync').throws(new Error('ENOENT')) + + const cfg = getConfig() + expect(cfg).to.have.property('defaultNavy', 'dev') + expect(cfg).to.have.property('externalIP', null) + expect(cfg).to.have.property('tlsRootCaDir').that.is.a('string') + }) + + }) + + describe('setConfig', function () { + + it('should write the provided config to the config file', async function () { + const mkdirStub = sandbox.stub(fsPromises, 'mkdir').resolves() + const writeStub = sandbox.stub(fsPromises, 'writeFile').resolves() + + await setConfig({ defaultNavy: 'env-1' }) + + expect(mkdirStub.calledOnce).to.equal(true) + expect(mkdirStub.firstCall.args[0]).to.equal(path.join('/home/test-user', '.navy')) + expect(mkdirStub.firstCall.args[1]).to.eql({ recursive: true }) + + expect(writeStub.calledOnce).to.equal(true) + expect(writeStub.firstCall.args[0]).to.equal(path.join('/home/test-user', '.navy', 'config.json')) + expect(JSON.parse(writeStub.firstCall.args[1])).to.eql({ defaultNavy: 'env-1' }) + }) + + it('should write the default config when called with null', async function () { + sandbox.stub(fsPromises, 'mkdir').resolves() + const writeStub = sandbox.stub(fsPromises, 'writeFile').resolves() + + await setConfig(null) + + const written = JSON.parse(writeStub.firstCall.args[1]) + expect(written).to.have.property('defaultNavy', 'dev') + }) + + it('should invalidate the cached config so the next getConfig re-reads', async function () { + const readStub = sandbox.stub(fs, 'readFileSync').returns(JSON.stringify({ defaultNavy: 'one' })) + + getConfig() + expect(readStub.callCount).to.equal(1) + + sandbox.stub(fsPromises, 'mkdir').resolves() + sandbox.stub(fsPromises, 'writeFile').resolves() + await setConfig({ defaultNavy: 'two' }) + + readStub.returns(JSON.stringify({ defaultNavy: 'two' })) + const cfg = getConfig() + expect(readStub.callCount).to.equal(2) + expect(cfg).to.eql({ defaultNavy: 'two' }) + }) + + }) + +}) diff --git a/packages/navy/src/__tests__/driver-logging.js b/packages/navy/src/__tests__/driver-logging.js new file mode 100644 index 0000000..d230b82 --- /dev/null +++ b/packages/navy/src/__tests__/driver-logging.js @@ -0,0 +1,191 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import { dots } from 'cli-spinners' +import { + startDriverLogging, + stopDriverLogging, + isDriverLogging, + log, +} from '../driver-logging' + +describe('driver-logging', function () { + + let sandbox + let clock + let stdoutWrite + let cursorTo + let moveCursor + let consoleLog + let originalIsTTY + let originalCursorTo + let originalMoveCursor + + beforeEach(function () { + sandbox = sinon.createSandbox() + clock = sandbox.useFakeTimers() + + stdoutWrite = sandbox.stub(process.stdout, 'write').returns(true) + + originalCursorTo = process.stdout.cursorTo + originalMoveCursor = process.stdout.moveCursor + process.stdout.cursorTo = function () {} + process.stdout.moveCursor = function () {} + + cursorTo = sandbox.stub(process.stdout, 'cursorTo') + moveCursor = sandbox.stub(process.stdout, 'moveCursor') + consoleLog = sandbox.stub(console, 'log') + + originalIsTTY = process.stdout.isTTY + process.stdout.isTTY = true + }) + + afterEach(function () { + if (isDriverLogging()) { + stopDriverLogging({ success: true }) + } + process.stdout.isTTY = originalIsTTY + sandbox.restore() + if (originalCursorTo === undefined) { + delete process.stdout.cursorTo + } else { + process.stdout.cursorTo = originalCursorTo + } + if (originalMoveCursor === undefined) { + delete process.stdout.moveCursor + } else { + process.stdout.moveCursor = originalMoveCursor + } + }) + + describe('startDriverLogging / isDriverLogging', function () { + + it('should mark logging as active and write the initial spinner frame', function () { + expect(isDriverLogging()).to.equal(false) + + startDriverLogging('Doing thing') + + expect(isDriverLogging()).to.equal(true) + expect(stdoutWrite.called).to.equal(true) + const written = stdoutWrite.getCalls().map(c => c.args[0]).join('') + expect(written).to.contain('Doing thing') + }) + + it('should advance the spinner frame on each interval tick', function () { + startDriverLogging('Working') + + const writesBefore = stdoutWrite.callCount + clock.tick(dots.interval) + expect(stdoutWrite.callCount).to.be.greaterThan(writesBefore) + }) + + it('should wrap the spinner frame index back to 0 after exhausting all frames', function () { + startDriverLogging('Wrap test') + + clock.tick(dots.interval * (dots.frames.length + 1)) + + expect(isDriverLogging()).to.equal(true) + }) + + }) + + describe('stopDriverLogging', function () { + + it('should clear the logging state and emit a final success line', function () { + startDriverLogging('Working') + + stopDriverLogging({ success: true }) + + expect(isDriverLogging()).to.equal(false) + }) + + it('should default success to true when not provided', function () { + startDriverLogging('Working') + + stopDriverLogging() + + expect(isDriverLogging()).to.equal(false) + }) + + it('should mark a failure when success is false', function () { + startDriverLogging('Working') + + stopDriverLogging({ success: false }) + + expect(isDriverLogging()).to.equal(false) + }) + + it('should be a no-op if logging was never started', function () { + expect(isDriverLogging()).to.equal(false) + + stopDriverLogging({ success: true }) + + expect(stdoutWrite.called).to.equal(false) + expect(cursorTo.called).to.equal(false) + expect(moveCursor.called).to.equal(false) + }) + + }) + + describe('non-TTY behaviour', function () { + + beforeEach(function () { + process.stdout.isTTY = false + }) + + it('should print a SUCCESS line via console.log when stopping with success', function () { + startDriverLogging('Working') + + stopDriverLogging({ success: true }) + + const messages = consoleLog.getCalls().map(c => c.args.join(' ')) + const success = messages.find(m => m.includes('SUCCESS')) + expect(success).to.be.a('string') + }) + + it('should print a FAILURE line via console.log when stopping with success=false', function () { + startDriverLogging('Working') + + stopDriverLogging({ success: false }) + + const messages = consoleLog.getCalls().map(c => c.args.join(' ')) + const failure = messages.find(m => m.includes('FAILURE')) + expect(failure).to.be.a('string') + }) + + it('should not print anything during ongoing spinner ticks while non-TTY', function () { + startDriverLogging('Working') + const callsAtStart = consoleLog.callCount + + clock.tick(dots.interval * 3) + + expect(consoleLog.callCount).to.equal(callsAtStart) + }) + + }) + + describe('log', function () { + + it('should write the dimmed message to stdout while logging is active', function () { + startDriverLogging('Active') + + stdoutWrite.resetHistory() + log('hello') + + expect(stdoutWrite.calledOnce).to.equal(true) + expect(stdoutWrite.firstCall.args[0]).to.contain('hello') + }) + + it('should be a no-op when logging is not active', function () { + expect(isDriverLogging()).to.equal(false) + + stdoutWrite.resetHistory() + log('ignored') + + expect(stdoutWrite.called).to.equal(false) + }) + + }) + +}) diff --git a/packages/navy/src/__tests__/driver.js b/packages/navy/src/__tests__/driver.js new file mode 100644 index 0000000..ff7e604 --- /dev/null +++ b/packages/navy/src/__tests__/driver.js @@ -0,0 +1,22 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { resolveDriverFromName } from '../driver' +import DockerCompose from '../drivers/docker-compose' + +describe('driver', function () { + + describe('resolveDriverFromName', function () { + + it('should return the docker-compose driver factory when given "docker-compose"', function () { + expect(resolveDriverFromName('docker-compose')).to.equal(DockerCompose) + }) + + it('should return null for an unknown driver name', function () { + expect(resolveDriverFromName('podman')).to.equal(null) + expect(resolveDriverFromName('')).to.equal(null) + }) + + }) + +}) diff --git a/packages/navy/src/__tests__/errors.js b/packages/navy/src/__tests__/errors.js new file mode 100644 index 0000000..7ea8271 --- /dev/null +++ b/packages/navy/src/__tests__/errors.js @@ -0,0 +1,60 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import { NavyError, NavyNotInitialisedError } from '../errors' + +describe('errors', function () { + + describe('NavyError', function () { + + it('should expose the message passed to the constructor', function () { + const err = new NavyError('something went wrong') + + expect(err.message).to.equal('something went wrong') + }) + + it('should print a red ERROR banner followed by the message and blank lines via prettyPrint', function () { + const log = sinon.stub(console, 'log') + try { + new NavyError('boom').prettyPrint() + } finally { + log.restore() + } + + expect(log.callCount).to.equal(5) + expect(log.firstCall.args).to.eql([]) + expect(log.secondCall.args[0]).to.contain('ERROR') + expect(log.thirdCall.args).to.eql([]) + expect(log.getCall(3).args[0]).to.equal(' boom') + expect(log.getCall(4).args).to.eql([]) + }) + + }) + + describe('NavyNotInitialisedError', function () { + + it('should be a NavyError that includes the navy name in the message', function () { + const err = new NavyNotInitialisedError('myenv') + + expect(err).to.be.instanceof(NavyError) + expect(err.message).to.equal('Navy "myenv" not imported') + }) + + it('should call the parent prettyPrint and add a hint about navy import', function () { + const log = sinon.stub(console, 'log') + try { + new NavyNotInitialisedError('foo').prettyPrint() + } finally { + log.restore() + } + + const messages = log.getCalls().map(call => call.args[0] || '') + const hint = messages.find(m => typeof m === 'string' && m.includes('navy import')) + expect(hint).to.be.a('string') + expect(hint).to.contain('imported the navy') + }) + + }) + +}) diff --git a/packages/navy/src/__tests__/http-proxy.js b/packages/navy/src/__tests__/http-proxy.js new file mode 100644 index 0000000..4e0bca1 --- /dev/null +++ b/packages/navy/src/__tests__/http-proxy.js @@ -0,0 +1,431 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import os from 'os' +import path from 'path' +import yaml from 'js-yaml' +import fs from 'fs' +import dockerClient from '../util/docker-client' +import * as httpsModule from '../util/https' +import * as execAsyncModule from '../util/exec-async' +import * as driverLogging from '../driver-logging' +import * as navyModule from '../navy' +import { + resolveProxyImage, + resolveProxyEnvFromNavyFile, + resolveProxyEnvAllowlist, + resolveProxyEnv, + resolveDockerSocketPath, + reconfigureHTTPProxy, +} from '../http-proxy' + +describe('resolveProxyImage', function () { + + afterEach(function () { + delete process.env.NAVY_HTTP_PROXY_IMAGE + }) + + it('should return the default image when no env var or navyFile config is provided', function () { + expect(resolveProxyImage()).to.equal('navycloud/navy-proxy') + expect(resolveProxyImage(null)).to.equal('navycloud/navy-proxy') + expect(resolveProxyImage(undefined)).to.equal('navycloud/navy-proxy') + }) + + it('should return the default image when navyFile has no httpProxyImage', function () { + expect(resolveProxyImage({})).to.equal('navycloud/navy-proxy') + expect(resolveProxyImage({ plugins: [] })).to.equal('navycloud/navy-proxy') + }) + + it('should use httpProxyImage from navyFile when set', function () { + const navyFile = { httpProxyImage: 'myregistry/custom-proxy:latest' } + expect(resolveProxyImage(navyFile)).to.equal('myregistry/custom-proxy:latest') + }) + + it('should use NAVY_HTTP_PROXY_IMAGE env var when set', function () { + process.env.NAVY_HTTP_PROXY_IMAGE = 'envregistry/env-proxy:v2' + expect(resolveProxyImage()).to.equal('envregistry/env-proxy:v2') + }) + + it('should give NAVY_HTTP_PROXY_IMAGE env var precedence over navyFile httpProxyImage', function () { + process.env.NAVY_HTTP_PROXY_IMAGE = 'envregistry/env-proxy:v2' + const navyFile = { httpProxyImage: 'myregistry/custom-proxy:latest' } + expect(resolveProxyImage(navyFile)).to.equal('envregistry/env-proxy:v2') + }) + + it('should give NAVY_HTTP_PROXY_IMAGE env var precedence over default', function () { + process.env.NAVY_HTTP_PROXY_IMAGE = 'override/image:tag' + expect(resolveProxyImage(null)).to.equal('override/image:tag') + }) + + it('should fall back to default when httpProxyImage is an empty string', function () { + expect(resolveProxyImage({ httpProxyImage: '' })).to.equal('navycloud/navy-proxy') + }) + + it('should fall back to default when NAVY_HTTP_PROXY_IMAGE is an empty string', function () { + process.env.NAVY_HTTP_PROXY_IMAGE = '' + expect(resolveProxyImage()).to.equal('navycloud/navy-proxy') + }) + +}) + +describe('resolveProxyEnvFromNavyFile', function () { + + it('should return an empty object when no navyFile is provided', function () { + expect(resolveProxyEnvFromNavyFile()).to.eql({}) + expect(resolveProxyEnvFromNavyFile(null)).to.eql({}) + expect(resolveProxyEnvFromNavyFile(undefined)).to.eql({}) + }) + + it('should return an empty object when navyFile has no httpProxyEnv', function () { + expect(resolveProxyEnvFromNavyFile({})).to.eql({}) + expect(resolveProxyEnvFromNavyFile({ plugins: [] })).to.eql({}) + }) + + it('should return the httpProxyEnv map from navyFile', function () { + const navyFile = { httpProxyEnv: { FOO: 'bar', BAZ: 'qux' } } + expect(resolveProxyEnvFromNavyFile(navyFile)).to.eql({ FOO: 'bar', BAZ: 'qux' }) + }) + + it('should drop entries with empty string, null, or undefined values', function () { + const navyFile = { + httpProxyEnv: { + EMPTY: '', + NULL: null, + UNDEF: undefined, + KEEP: 'value', + }, + } + expect(resolveProxyEnvFromNavyFile(navyFile)).to.eql({ KEEP: 'value' }) + }) + + it('should coerce numeric values to strings', function () { + const navyFile = { httpProxyEnv: { PORT: 8080, ZERO: 0 } } + expect(resolveProxyEnvFromNavyFile(navyFile)).to.eql({ PORT: '8080', ZERO: '0' }) + }) + + it('should return an empty object when httpProxyEnv is a string', function () { + expect(resolveProxyEnvFromNavyFile({ httpProxyEnv: 'FOO=bar' })).to.eql({}) + }) + + it('should return an empty object when httpProxyEnv is an array', function () { + expect(resolveProxyEnvFromNavyFile({ httpProxyEnv: ['FOO=bar'] })).to.eql({}) + }) + +}) + +describe('resolveProxyEnvAllowlist', function () { + + const namesSetDuringTest = [] + + function setEnv(name, value) { + namesSetDuringTest.push(name) + process.env[name] = value + } + + afterEach(function () { + delete process.env.NAVY_HTTP_PROXY_ENV + while (namesSetDuringTest.length > 0) { + delete process.env[namesSetDuringTest.pop()] + } + }) + + it('should return an empty object when NAVY_HTTP_PROXY_ENV is unset', function () { + expect(resolveProxyEnvAllowlist()).to.eql({}) + }) + + it('should return an empty object when NAVY_HTTP_PROXY_ENV is empty', function () { + process.env.NAVY_HTTP_PROXY_ENV = '' + expect(resolveProxyEnvAllowlist()).to.eql({}) + }) + + it('should forward a single name whose value is present in process.env', function () { + process.env.NAVY_HTTP_PROXY_ENV = 'FORWARD_ME' + setEnv('FORWARD_ME', 'hello') + expect(resolveProxyEnvAllowlist()).to.eql({ FORWARD_ME: 'hello' }) + }) + + it('should trim whitespace from comma-separated names', function () { + process.env.NAVY_HTTP_PROXY_ENV = ' FOO , BAR ' + setEnv('FOO', 'one') + setEnv('BAR', 'two') + expect(resolveProxyEnvAllowlist()).to.eql({ FOO: 'one', BAR: 'two' }) + }) + + it('should deduplicate repeated names', function () { + process.env.NAVY_HTTP_PROXY_ENV = 'FOO,FOO,BAR,FOO' + setEnv('FOO', 'one') + setEnv('BAR', 'two') + expect(resolveProxyEnvAllowlist()).to.eql({ FOO: 'one', BAR: 'two' }) + }) + + it('should drop names whose value is empty or unset', function () { + process.env.NAVY_HTTP_PROXY_ENV = 'PRESENT,EMPTY,MISSING' + setEnv('PRESENT', 'value') + setEnv('EMPTY', '') + expect(resolveProxyEnvAllowlist()).to.eql({ PRESENT: 'value' }) + }) + + it('should ignore empty entries produced by trailing or repeated commas', function () { + process.env.NAVY_HTTP_PROXY_ENV = ',FOO,,' + setEnv('FOO', 'value') + expect(resolveProxyEnvAllowlist()).to.eql({ FOO: 'value' }) + }) + +}) + +describe('resolveProxyEnv', function () { + + const namesSetDuringTest = [] + + function setEnv(name, value) { + namesSetDuringTest.push(name) + process.env[name] = value + } + + afterEach(function () { + delete process.env.NAVY_HTTP_PROXY_ENV + while (namesSetDuringTest.length > 0) { + delete process.env[namesSetDuringTest.pop()] + } + }) + + it('should return null when both sources are empty', function () { + expect(resolveProxyEnv()).to.equal(null) + expect(resolveProxyEnv({})).to.equal(null) + }) + + it('should return only the navyFile entries when no allowlist is set', function () { + const navyFile = { httpProxyEnv: { FOO: 'bar' } } + expect(resolveProxyEnv(navyFile)).to.eql({ FOO: 'bar' }) + }) + + it('should return only the allowlisted entries when navyFile has none', function () { + process.env.NAVY_HTTP_PROXY_ENV = 'FORWARD_ME' + setEnv('FORWARD_ME', 'hello') + expect(resolveProxyEnv()).to.eql({ FORWARD_ME: 'hello' }) + }) + + it('should merge entries from both sources', function () { + process.env.NAVY_HTTP_PROXY_ENV = 'FROM_ENV' + setEnv('FROM_ENV', 'env-value') + const navyFile = { httpProxyEnv: { FROM_FILE: 'file-value' } } + expect(resolveProxyEnv(navyFile)).to.eql({ + FROM_FILE: 'file-value', + FROM_ENV: 'env-value', + }) + }) + + it('should give the allowlist precedence on key collisions', function () { + process.env.NAVY_HTTP_PROXY_ENV = 'SHARED' + setEnv('SHARED', 'env-value') + const navyFile = { httpProxyEnv: { SHARED: 'file-value' } } + expect(resolveProxyEnv(navyFile)).to.eql({ SHARED: 'env-value' }) + }) + +}) + +describe('resolveDockerSocketPath', function () { + + let originalDockerHost + + beforeEach(function () { + originalDockerHost = process.env.DOCKER_HOST + delete process.env.DOCKER_HOST + }) + + afterEach(function () { + if (originalDockerHost === undefined) { + delete process.env.DOCKER_HOST + } else { + process.env.DOCKER_HOST = originalDockerHost + } + }) + + it('should default to /var/run/docker.sock when DOCKER_HOST is not set', function () { + expect(resolveDockerSocketPath()).to.equal('/var/run/docker.sock') + }) + + it('should default to /var/run/docker.sock when DOCKER_HOST is empty', function () { + process.env.DOCKER_HOST = '' + expect(resolveDockerSocketPath()).to.equal('/var/run/docker.sock') + }) + + it('should extract the socket path when DOCKER_HOST uses the unix:// scheme', function () { + process.env.DOCKER_HOST = 'unix:///home/runner/setup-docker-action-abc/docker.sock' + expect(resolveDockerSocketPath()).to.equal('/home/runner/setup-docker-action-abc/docker.sock') + }) + + it('should fall back to default when DOCKER_HOST is unix:// with no path', function () { + process.env.DOCKER_HOST = 'unix://' + expect(resolveDockerSocketPath()).to.equal('/var/run/docker.sock') + }) + + it('should fall back to default when DOCKER_HOST uses tcp:// scheme', function () { + process.env.DOCKER_HOST = 'tcp://localhost:2375' + expect(resolveDockerSocketPath()).to.equal('/var/run/docker.sock') + }) + +}) + +describe('reconfigureHTTPProxy', function () { + + let sandbox + let writeFileSyncStub + let existsSyncStub + let listNetworksStub + let execStub + let originalDockerHost + + const composeFile = path.join(os.tmpdir(), 'navyinternaldockercompose.yml') + + beforeEach(function () { + originalDockerHost = process.env.DOCKER_HOST + delete process.env.DOCKER_HOST + + sandbox = sinon.createSandbox() + + listNetworksStub = sandbox.stub(dockerClient, 'listNetworks') + sandbox.stub(httpsModule, 'getCertsPath').resolves('') + sandbox.stub(driverLogging, 'log') + sandbox.stub(navyModule, 'getLaunchedNavyNames').resolves([]) + + execStub = sandbox.stub(execAsyncModule, 'execAsync').resolves('') + writeFileSyncStub = sandbox.stub(fs, 'writeFileSync') + existsSyncStub = sandbox.stub(fs, 'existsSync').returns(false) + }) + + afterEach(function () { + sandbox.restore() + if (originalDockerHost === undefined) { + delete process.env.DOCKER_HOST + } else { + process.env.DOCKER_HOST = originalDockerHost + } + }) + + it('should default opts.navies via getLaunchedNavyNames when not supplied', async function () { + listNetworksStub.resolves([]) + navyModule.getLaunchedNavyNames.resolves(['navyA']) + + await reconfigureHTTPProxy() + + expect(navyModule.getLaunchedNavyNames.calledOnce).to.equal(true) + }) + + it('should write a docker-compose config containing only matching docker-compose networks', async function () { + listNetworksStub.resolves([ + { Name: 'navyA_default' }, + { Name: 'navyB_default' }, + { Name: 'host' }, + { Name: 'navyB_other' }, + { Name: 'name-without-underscore' }, + ]) + + await reconfigureHTTPProxy({ navies: ['navyA'] }) + + expect(writeFileSyncStub.calledOnce).to.equal(true) + expect(writeFileSyncStub.firstCall.args[0]).to.equal(composeFile) + const written = yaml.load(writeFileSyncStub.firstCall.args[1]) + expect(written.networks).to.have.property('navyA_default').that.eql({ external: true }) + expect(written.networks).to.not.have.property('navyB_default') + expect(written.networks).to.not.have.property('host') + expect(written.services['nginx-proxy'].image).to.equal('navycloud/navy-proxy') + expect(written.services['nginx-proxy'].ports).to.eql(['80:80']) + expect(written.services['nginx-proxy'].volumes[0]) + .to.equal('/var/run/docker.sock:/tmp/docker.sock:ro') + }) + + it('should mount certs and expose port 443 when a certs path is available', async function () { + httpsModule.getCertsPath.resolves('/certs') + listNetworksStub.resolves([]) + + await reconfigureHTTPProxy({ navies: [] }) + + const written = yaml.load(writeFileSyncStub.firstCall.args[1]) + expect(written.services['nginx-proxy'].ports).to.eql(['80:80', '443:443']) + expect(written.services['nginx-proxy'].volumes).to.include('/certs:/etc/nginx/certs') + expect(written.services['nginx-proxy'].volumes).to.include('/certs:/etc/nginx/dhparam') + }) + + it('should pass the configured proxy image from navyFile through to the compose config', async function () { + listNetworksStub.resolves([]) + + await reconfigureHTTPProxy({ navies: [], navyFile: { httpProxyImage: 'custom/proxy:1' } }) + + const written = yaml.load(writeFileSyncStub.firstCall.args[1]) + expect(written.services['nginx-proxy'].image).to.equal('custom/proxy:1') + }) + + it('should run docker compose up after writing the config', async function () { + listNetworksStub.resolves([]) + + await reconfigureHTTPProxy({ navies: [] }) + + const upCall = execStub.getCalls() + .find(c => Array.isArray(c.args[1]) && c.args[1].includes('up')) + // eslint-disable-next-line no-unused-expressions + expect(upCall).to.exist + expect(upCall.args[0]).to.equal('docker compose') + expect(upCall.args[1]).to.eql(['-f', composeFile, '-p', 'navyinternal', 'up', '-d']) + }) + + it('should rm the existing nginx-proxy container before reconfiguring when restart=true and the file exists', async function () { + listNetworksStub.resolves([]) + existsSyncStub.withArgs(composeFile).returns(true) + + await reconfigureHTTPProxy({ navies: [], restart: true }) + + const rmCall = execStub.getCalls() + .find(c => Array.isArray(c.args[1]) && c.args[1].includes('rm')) + // eslint-disable-next-line no-unused-expressions + expect(rmCall).to.exist + expect(rmCall.args[1]).to.eql([ + '-f', composeFile, + '-p', 'navyinternal', 'rm', '-s', '-f', 'nginx-proxy', + ]) + }) + + it('should skip the rm step when restart=true but no compose file exists yet', async function () { + listNetworksStub.resolves([]) + existsSyncStub.withArgs(composeFile).returns(false) + + await reconfigureHTTPProxy({ navies: [], restart: true }) + + const rmCall = execStub.getCalls() + .find(c => Array.isArray(c.args[1]) && c.args[1].includes('rm')) + expect(rmCall).to.equal(undefined) + }) + + it('should omit the environment block from the proxy compose service when no env config is provided', async function () { + listNetworksStub.resolves([]) + + await reconfigureHTTPProxy({ navies: [] }) + + const written = yaml.load(writeFileSyncStub.firstCall.args[1]) + expect(written.services['nginx-proxy']).to.not.have.property('environment') + }) + + it('should include the merged environment block on the proxy compose service when httpProxyEnv or NAVY_HTTP_PROXY_ENV is set', async function () { + listNetworksStub.resolves([]) + process.env.NAVY_HTTP_PROXY_ENV = 'FROM_ENV' + process.env.FROM_ENV = 'env-value' + + try { + await reconfigureHTTPProxy({ + navies: [], + navyFile: { httpProxyEnv: { FROM_FILE: 'file-value' } }, + }) + + const written = yaml.load(writeFileSyncStub.firstCall.args[1]) + expect(written.services['nginx-proxy'].environment).to.eql({ + FROM_FILE: 'file-value', + FROM_ENV: 'env-value', + }) + } finally { + delete process.env.NAVY_HTTP_PROXY_ENV + delete process.env.FROM_ENV + } + }) + +}) diff --git a/packages/navy/src/__tests__/index.js b/packages/navy/src/__tests__/index.js new file mode 100644 index 0000000..aef5dc4 --- /dev/null +++ b/packages/navy/src/__tests__/index.js @@ -0,0 +1,28 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import * as navyModule from '../index' + +describe('navy package entry point', function () { + + it('should re-export the Navy class and navy lookup helpers', function () { + expect(navyModule).to.have.property('Navy').that.is.a('function') + expect(navyModule).to.have.property('getNavy').that.is.a('function') + expect(navyModule).to.have.property('getLaunchedNavies').that.is.a('function') + expect(navyModule).to.have.property('getLaunchedNavyNames').that.is.a('function') + }) + + it('should expose the Service module under Service', function () { + expect(navyModule).to.have.property('Service').that.is.an('object') + expect(navyModule.Service).to.have.property('Status').that.is.an('object') + }) + + it('should re-export NavyError', function () { + expect(navyModule).to.have.property('NavyError').that.is.a('function') + }) + + it('should re-export middlewareHelpers', function () { + expect(navyModule).to.have.property('middlewareHelpers').that.is.an('object') + }) + +}) diff --git a/packages/navy/src/__tests__/service.js b/packages/navy/src/__tests__/service.js new file mode 100644 index 0000000..7b3e56a --- /dev/null +++ b/packages/navy/src/__tests__/service.js @@ -0,0 +1,19 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { Status } from '../service' + +describe('service', function () { + + describe('Status', function () { + + it('should expose RUNNING and EXITED string constants', function () { + expect(Status).to.eql({ + RUNNING: 'running', + EXITED: 'exited', + }) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/develop.js b/packages/navy/src/cli/__tests__/develop.js new file mode 100644 index 0000000..eac6c7e --- /dev/null +++ b/packages/navy/src/cli/__tests__/develop.js @@ -0,0 +1,225 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../errors' + +describe('cli/develop', function () { + + let sandbox + let getNavyStub + let navyStub + let getNavyRcStub + let dockerStub + let containerObj + let consoleLogStub + let originalCwd + let developCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + name: 'env-1', + getState: sandbox.stub().resolves({}), + saveState: sandbox.stub().resolves(), + emitAsync: sandbox.stub().resolves(), + kill: sandbox.stub().resolves(), + launch: sandbox.stub().resolves(), + ps: sandbox.stub().resolves([{ name: 'web', id: 'abc123' }]), + } + getNavyStub = sandbox.stub().returns(navyStub) + getNavyRcStub = sandbox.stub().resolves({ + services: ['web'], + develop: { mounts: { './src': '/app/src' }, command: 'npm start' }, + }) + + containerObj = { + attach: sandbox.stub().resolves('stream'), + modem: { demuxStream: sandbox.stub() }, + } + dockerStub = { getContainer: sandbox.stub().returns(containerObj) } + + consoleLogStub = sandbox.stub(console, 'log') + + originalCwd = process.cwd + sandbox.stub(process, 'cwd').returns('/work') + + developCli = proxyquire.noCallThru()('../develop', { + '../': { getNavy: getNavyStub }, + '../errors': { NavyError }, + '../util/docker-client': dockerStub, + '../util/navyrc': getNavyRcStub, + }) + }) + + afterEach(function () { + process.cwd = originalCwd + sandbox.restore() + }) + + describe('default export', function () { + + it('should throw a NavyError when navyrc is null', async function () { + getNavyRcStub.resolves(null) + + let caught + try { + await developCli('web', { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('No valid .navyrc') + }) + + it('should throw a NavyError when navyrc has no services', async function () { + getNavyRcStub.resolves({ services: undefined }) + + let caught + try { + await developCli('web', { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + }) + + it('should throw a NavyError when develop key is missing', async function () { + getNavyRcStub.resolves({ services: ['web'] }) + + let caught + try { + await developCli('web', { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('No develop mounts') + }) + + it('should throw when multiple services are listed and none specified', async function () { + getNavyRcStub.resolves({ + services: ['web', 'api'], + develop: { mounts: {}, command: 'x' }, + }) + + let caught + try { + await developCli(undefined, { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('Multiple service mappings') + }) + + it('should infer the only service when one is listed', async function () { + await developCli(undefined, { navy: 'env-1' }) + + expect(navyStub.kill.calledWith(['web'])).to.equal(true) + }) + + it('should throw when the service is not in the navyrc list', async function () { + let caught + try { + await developCli('unknown', { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('not a valid development target') + }) + + it('should resolve mount keys to absolute paths and persist them in state', async function () { + await developCli('web', { navy: 'env-1' }) + + expect(navyStub.saveState.calledOnce).to.equal(true) + const newState = navyStub.saveState.firstCall.args[0] + const mountKeys = Object.keys(newState.services.web._develop.mounts) + expect(mountKeys[0].endsWith('src')).to.equal(true) + expect(newState.services.web._develop.command).to.equal('npm start') + }) + + it('should preserve existing state.services entries on save', async function () { + navyStub.getState.resolves({ + services: { + api: { _tag: 'v1' }, + }, + }) + + await developCli('web', { navy: 'env-1' }) + + const newState = navyStub.saveState.firstCall.args[0] + expect(newState.services.api).to.eql({ _tag: 'v1' }) + }) + + it('should default to {} when navy.getState returns null', async function () { + navyStub.getState.resolves(null) + + await developCli('web', { navy: 'env-1' }) + + const newState = navyStub.saveState.firstCall.args[0] + // eslint-disable-next-line no-unused-expressions + expect(newState.services.web._develop).to.exist + }) + + it('should kill, then launch the service in develop mode', async function () { + await developCli('web', { navy: 'env-1' }) + + expect(navyStub.emitAsync.calledWith('cli.develop.beforeLaunch')).to.equal(true) + expect(navyStub.kill.calledOnce).to.equal(true) + expect(navyStub.launch.calledOnce).to.equal(true) + expect(navyStub.launch.firstCall.args[0]).to.eql(['web']) + expect(navyStub.launch.firstCall.args[1]).to.eql({ noDeps: true }) + }) + + it('should attach to the container and demux the stream', async function () { + await developCli('web', { navy: 'env-1' }) + + expect(dockerStub.getContainer.calledWith('abc123')).to.equal(true) + expect(containerObj.attach.calledOnce).to.equal(true) + + // Wait for the .then callback to fire on the attach promise + await new Promise(resolve => setImmediate(resolve)) + + expect(containerObj.modem.demuxStream.calledOnce).to.equal(true) + expect(containerObj.modem.demuxStream.firstCall.args[0]).to.equal('stream') + }) + + it('should log a graceful exit message when attach rejects', async function () { + containerObj.attach.rejects(new Error('attach failed')) + + await developCli('web', { navy: 'env-1' }) + + // Wait microtask flush + await new Promise(resolve => setImmediate(resolve)) + await new Promise(resolve => setImmediate(resolve)) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('exited') + }) + + it('should throw an invariant violation when no container is found for the service', async function () { + navyStub.ps.resolves([{ name: 'other', id: 'xyz' }]) + + let caught + try { + await developCli('web', { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.contain('DEVELOP_NO_CONTAINER_ID') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/external-ip.js b/packages/navy/src/cli/__tests__/external-ip.js new file mode 100644 index 0000000..9557ece --- /dev/null +++ b/packages/navy/src/cli/__tests__/external-ip.js @@ -0,0 +1,76 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/external-ip', function () { + + let sandbox + let getConfigStub + let getExternalIPStub + let consoleLogStub + let externalIpCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getConfigStub = sandbox.stub() + getExternalIPStub = sandbox.stub() + consoleLogStub = sandbox.stub(console, 'log') + + externalIpCli = proxyquire.noCallThru()('../external-ip', { + '../config': { getConfig: getConfigStub }, + '../util/external-ip': { getExternalIP: getExternalIPStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should pass the externalIP value from config to getExternalIP', async function () { + getConfigStub.returns({ externalIP: 'configured.host' }) + getExternalIPStub.resolves('1.2.3.4') + + await externalIpCli() + + expect(getConfigStub.calledOnce).to.equal(true) + expect(getExternalIPStub.calledOnce).to.equal(true) + expect(getExternalIPStub.firstCall.args[0]).to.equal('configured.host') + }) + + it('should log the resolved external IP', async function () { + getConfigStub.returns({ externalIP: null }) + getExternalIPStub.resolves('5.6.7.8') + + await externalIpCli() + + expect(consoleLogStub.calledOnce).to.equal(true) + expect(consoleLogStub.firstCall.args[0]).to.equal('5.6.7.8') + }) + + it('should pass undefined when config has no externalIP key', async function () { + getConfigStub.returns({}) + getExternalIPStub.resolves('127.0.0.1') + + await externalIpCli() + + expect(getExternalIPStub.firstCall.args[0]).to.equal(undefined) + }) + + it('should support an asynchronous getConfig implementation', async function () { + getConfigStub.resolves({ externalIP: 'async.host' }) + getExternalIPStub.resolves('9.9.9.9') + + await externalIpCli() + + expect(getExternalIPStub.firstCall.args[0]).to.equal('async.host') + expect(consoleLogStub.firstCall.args[0]).to.equal('9.9.9.9') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/health.js b/packages/navy/src/cli/__tests__/health.js new file mode 100644 index 0000000..ff0a21e --- /dev/null +++ b/packages/navy/src/cli/__tests__/health.js @@ -0,0 +1,230 @@ +/* eslint-env mocha */ + +// NOTE (potential source bugs in health.js, not locked in by these tests): +// 1. `getStatus` and `getHistory` both compute `service.raw && service.raw.State.Health`. +// If `service.raw` is truthy but `service.raw.State` is undefined, this throws a +// TypeError reading 'Health' of undefined. The guard chain is incomplete; it +// should be `service.raw && service.raw.State && service.raw.State.Health`. +// 2. Both helpers accept a `state` parameter that is never used (dead parameter). + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import stripAnsi from 'strip-ansi' + +describe('cli/health', function () { + + let sandbox + let getNavyStub + let navyStub + let consoleLogStub + let healthCli + + function makeService(overrides = {}) { + return { + id: 'svc-1', + name: 'api', + raw: undefined, + ...overrides, + } + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + ps: sandbox.stub().resolves([]), + getState: sandbox.stub().resolves(null), + } + getNavyStub = sandbox.stub().returns(navyStub) + consoleLogStub = sandbox.stub(console, 'log') + + healthCli = proxyquire.noCallThru()('../health', { + '../': { getNavy: getNavyStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + function lastLoggedString() { + const last = consoleLogStub.lastCall + return last ? String(last.args[0]) : '' + } + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await healthCli({ navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should print the table headers even when there are no services', async function () { + navyStub.ps.resolves([]) + + await healthCli({ navy: 'env-1' }) + + expect(consoleLogStub.calledOnce).to.equal(true) + const text = stripAnsi(consoleLogStub.firstCall.args[0]) + expect(text).to.contain('NAME') + expect(text).to.contain('STATUS') + expect(text).to.contain('HISTORY') + }) + + it('should call ps and getState exactly once each', async function () { + navyStub.ps.resolves([makeService()]) + + await healthCli({ navy: 'env-1' }) + + expect(navyStub.ps.calledOnce).to.equal(true) + expect(navyStub.getState.calledOnce).to.equal(true) + }) + + }) + + describe('getStatus (via default export)', function () { + + it('should render - when the service has no raw container info', async function () { + navyStub.ps.resolves([makeService({ name: 'api', raw: undefined })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('api') + expect(text).to.contain('-') + }) + + it('should render - when the service has raw but no Health record', async function () { + navyStub.ps.resolves([makeService({ + name: 'api', + raw: { State: { Health: null } }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('api') + expect(text).to.contain('-') + }) + + it('should render Healthy when health status is "healthy"', async function () { + navyStub.ps.resolves([makeService({ + raw: { State: { Health: { Status: 'healthy', Log: [] } } }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('Healthy') + }) + + it('should render Unhealthy when health status is anything other than healthy', async function () { + navyStub.ps.resolves([makeService({ + raw: { State: { Health: { Status: 'starting', Log: [] } } }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('Unhealthy') + }) + + }) + + describe('getHistory (via default export)', function () { + + it('should render - when the service has no raw container info', async function () { + navyStub.ps.resolves([makeService({ name: 'api', raw: undefined })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('-') + }) + + it('should render - when the service has raw but no Health record', async function () { + navyStub.ps.resolves([makeService({ + raw: { State: { Health: null } }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('-') + }) + + it('should render only success markers when every entry has ExitCode 0', async function () { + navyStub.ps.resolves([makeService({ + raw: { + State: { + Health: { + Status: 'healthy', + Log: [{ ExitCode: 0 }, { ExitCode: 0 }], + }, + }, + }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('█ █') + expect(text).not.to.contain('x') + }) + + it('should render only failure markers when every entry has a non-zero ExitCode', async function () { + navyStub.ps.resolves([makeService({ + raw: { + State: { + Health: { + Status: 'unhealthy', + Log: [{ ExitCode: 1 }, { ExitCode: 2 }], + }, + }, + }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('x x') + expect(text).not.to.contain('█') + }) + + it('should render mixed success and failure markers based on each entry ExitCode', async function () { + navyStub.ps.resolves([makeService({ + raw: { + State: { + Health: { + Status: 'healthy', + Log: [{ ExitCode: 0 }, { ExitCode: 1 }, { ExitCode: 0 }], + }, + }, + }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('█ x █') + }) + + it('should render an empty history string when Log is an empty array', async function () { + navyStub.ps.resolves([makeService({ + raw: { State: { Health: { Status: 'healthy', Log: [] } } }, + })]) + + await healthCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('Healthy') + expect(text).not.to.contain('█') + expect(text).not.to.contain('x') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/https.js b/packages/navy/src/cli/__tests__/https.js new file mode 100644 index 0000000..6fefcb0 --- /dev/null +++ b/packages/navy/src/cli/__tests__/https.js @@ -0,0 +1,217 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../errors' + +describe('cli/https', function () { + + let sandbox + let getNavyStub + let navyStub + let getConfigStub + let getConfigDirStub + let DEFAULT_TLS_ROOT_CA_DIR + let reconfigureHTTPProxyStub + let createCertStub + let generateRootCaStub + let removeCertStub + let fsStub + let consoleLogStub + let httpsCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + isInitialised: sandbox.stub().resolves(true), + getNavyFile: sandbox.stub().resolves({ ports: 'whatever' }), + ensurePluginsLoaded: sandbox.stub().resolves(), + getAvailableServiceNames: sandbox.stub().resolves(['web', 'api']), + url: sandbox.stub().resolves('https://web.local'), + } + getNavyStub = sandbox.stub().resolves(navyStub) + + getConfigStub = sandbox.stub().returns({}) + getConfigDirStub = sandbox.stub().returns('/cfg') + DEFAULT_TLS_ROOT_CA_DIR = '/default-ca-dir' + + reconfigureHTTPProxyStub = sandbox.stub().resolves() + createCertStub = sandbox.stub().resolves() + generateRootCaStub = sandbox.stub().resolves() + removeCertStub = sandbox.stub().resolves() + + fsStub = { + existsSync: sandbox.stub().returns(true), + readdirSync: sandbox.stub().returns(['web.local.crt', 'api.local.crt', 'something.txt']), + } + + consoleLogStub = sandbox.stub(console, 'log') + + httpsCli = proxyquire.noCallThru()('../https', { + '../errors': { NavyError }, + '../navy': { getNavy: getNavyStub }, + '../config': { + getConfig: getConfigStub, + getConfigDir: getConfigDirStub, + DEFAULT_TLS_ROOT_CA_DIR, + }, + '../http-proxy': { reconfigureHTTPProxy: reconfigureHTTPProxyStub }, + '../util/https': { + createCert: createCertStub, + generateRootCa: generateRootCaStub, + removeCert: removeCertStub, + }, + fs: fsStub, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + describe('disable mode', function () { + + it('should remove the cert and reconfigure the proxy', async function () { + await httpsCli([], { navy: 'env-1', disable: 'web' }) + + expect(removeCertStub.calledOnce).to.equal(true) + expect(reconfigureHTTPProxyStub.calledOnce).to.equal(true) + expect(reconfigureHTTPProxyStub.firstCall.args[0].restart).to.equal(true) + }) + + it('should pass navyFile to reconfigureHTTPProxy when the navy is initialised', async function () { + navyStub.isInitialised.resolves(true) + navyStub.getNavyFile.resolves({ foo: 'bar' }) + + await httpsCli([], { navy: 'env-1', disable: 'web' }) + + expect(reconfigureHTTPProxyStub.firstCall.args[0].navyFile).to.eql({ foo: 'bar' }) + }) + + it('should pass undefined navyFile when the navy is not initialised', async function () { + navyStub.isInitialised.resolves(false) + + await httpsCli([], { navy: 'env-1', disable: 'web' }) + + expect(reconfigureHTTPProxyStub.firstCall.args[0].navyFile).to.equal(undefined) + expect(navyStub.getNavyFile.called).to.equal(false) + }) + + it('should print a confirmation message naming the disabled service', async function () { + await httpsCli([], { navy: 'env-1', disable: 'web' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('web') + expect(printed).to.contain('disabled') + }) + + }) + + describe('list mode (no services and no disable)', function () { + + it('should return early when the certs path does not exist', async function () { + fsStub.existsSync.returns(false) + + await httpsCli([], { navy: 'env-1' }) + + expect(fsStub.readdirSync.called).to.equal(false) + expect(generateRootCaStub.called).to.equal(false) + }) + + it('should print only .crt urls when listing', async function () { + fsStub.existsSync.callsFake(p => p === '/cfg/tls-certs') + + await httpsCli([], { navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('https://web.local') + expect(printed).to.contain('https://api.local') + expect(printed).to.not.contain('something.txt') + }) + + it('should also handle a null services arg as list mode', async function () { + fsStub.existsSync.returns(false) + + await httpsCli(null, { navy: 'env-1' }) + + expect(generateRootCaStub.called).to.equal(false) + }) + + }) + + describe('enable mode', function () { + + it('should generate the root CA when the CA cert/key are missing', async function () { + fsStub.existsSync.callsFake(p => !p.endsWith('ca.crt')) + + await httpsCli(['web'], { navy: 'env-1' }) + + expect(generateRootCaStub.calledOnce).to.equal(true) + }) + + it('should skip generating the root CA when ca.crt and ca.key both exist', async function () { + fsStub.existsSync.returns(true) + + await httpsCli(['web'], { navy: 'env-1' }) + + expect(generateRootCaStub.called).to.equal(false) + }) + + it('should create a cert for each available service', async function () { + await httpsCli(['web', 'api'], { navy: 'env-1' }) + + expect(createCertStub.callCount).to.equal(2) + }) + + it('should skip services that are not in the available service list', async function () { + await httpsCli(['web', 'unknown'], { navy: 'env-1' }) + + expect(createCertStub.callCount).to.equal(1) + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('unknown') + expect(printed).to.contain('not found') + }) + + it('should rethrow as NavyError when createCert fails', async function () { + createCertStub.rejects(new Error('cert error')) + + let caught + try { + await httpsCli(['web'], { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('Could not generate TLS cert') + }) + + it('should reconfigure HTTPS proxy after enabling and print services list', async function () { + await httpsCli(['web', 'api'], { navy: 'env-1' }) + + expect(reconfigureHTTPProxyStub.calledOnce).to.equal(true) + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('web') + expect(printed).to.contain('api') + expect(printed).to.contain('HTTPS') + }) + + it('should use a custom tlsRootCaDir when set in config', async function () { + getConfigStub.returns({ tlsRootCaDir: '/custom-ca' }) + fsStub.existsSync.callsFake(p => p === '/custom-ca/ca.crt' || p === '/custom-ca/ca.key') + + await httpsCli(['web'], { navy: 'env-1' }) + + const checkedPaths = fsStub.existsSync.getCalls().map(c => c.args[0]) + expect(checkedPaths.some(p => p === '/custom-ca/ca.crt')).to.equal(true) + }) + + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/import.js b/packages/navy/src/cli/__tests__/import.js new file mode 100644 index 0000000..6172134 --- /dev/null +++ b/packages/navy/src/cli/__tests__/import.js @@ -0,0 +1,103 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/import', function () { + + let sandbox + let getNavyStub + let navyStub + let getImportOptionsForCLIStub + let importNavyStub + let fsStub + let consoleLogStub + let originalIsTTY + let importCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { name: 'env-1' } + getNavyStub = sandbox.stub().returns(navyStub) + getImportOptionsForCLIStub = sandbox.stub().resolves({ configProvider: 'filesystem', path: '/some/path' }) + importNavyStub = sandbox.stub().resolves() + fsStub = { readFileSync: sandbox.stub().returns(' ___ \n /___\\ \n') } + consoleLogStub = sandbox.stub(console, 'log') + + originalIsTTY = process.stdout.isTTY + process.stdout.isTTY = false + + importCli = proxyquire.noCallThru()('../import', { + '../util/fs': fsStub, + '../': { getNavy: getNavyStub }, + '../config-provider': { getImportOptionsForCLI: getImportOptionsForCLIStub }, + './util': { importNavy: importNavyStub }, + }) + }) + + afterEach(function () { + process.stdout.isTTY = originalIsTTY + sandbox.restore() + }) + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await importCli({ navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should read the sailing-boat ASCII art file', async function () { + await importCli({ navy: 'env-1' }) + + expect(fsStub.readFileSync.calledOnce).to.equal(true) + expect(fsStub.readFileSync.firstCall.args[0]).to.contain('sailing-boat.txt') + }) + + it('should derive initialise opts via getImportOptionsForCLI and pass them to importNavy', async function () { + const opts = { navy: 'env-1', someOpt: 'value' } + const initialiseOpts = { configProvider: 'filesystem', path: '/cwd' } + getImportOptionsForCLIStub.resolves(initialiseOpts) + + await importCli(opts) + + expect(getImportOptionsForCLIStub.calledOnce).to.equal(true) + expect(getImportOptionsForCLIStub.firstCall.args[0]).to.equal(opts) + expect(importNavyStub.calledOnce).to.equal(true) + expect(importNavyStub.firstCall.args[0]).to.equal(navyStub) + expect(importNavyStub.firstCall.args[1]).to.equal(initialiseOpts) + }) + + it('should log the post-import help line', async function () { + await importCli({ navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join(' ') + expect(printed).to.contain('navy') + expect(printed).to.contain('any directory') + }) + + it('should not print the boat ASCII art when stdout is not a TTY', async function () { + process.stdout.isTTY = false + + await importCli({ navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.not.contain('___') + }) + + it('should print the boat ASCII art when stdout is a TTY', async function () { + process.stdout.isTTY = true + + await importCli({ navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('___') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/index.js b/packages/navy/src/cli/__tests__/index.js new file mode 100644 index 0000000..0c06dd3 --- /dev/null +++ b/packages/navy/src/cli/__tests__/index.js @@ -0,0 +1,130 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../errors' + +describe('cli/index', function () { + + let sandbox + let programStub + let helpCmdStub + let parseCalls + let actionHandlerForHelp + let originalArgv + + function loadModule({ args = ['placeholder'], parseImpl } = {}) { + actionHandlerForHelp = null + parseCalls = [] + + helpCmdStub = { + alias: sandbox.stub().returnsThis(), + action: sandbox.stub().callsFake(handler => { + actionHandlerForHelp = handler + return helpCmdStub + }), + } + + programStub = { + args, + version: sandbox.stub().returnsThis(), + command: sandbox.stub().returns(helpCmdStub), + help: sandbox.stub(), + parse: sandbox.stub().callsFake(argv => { + parseCalls.push(argv) + if (parseImpl) parseImpl() + }), + } + + return proxyquire.noCallThru()('../index', { + '../../package.json': { version: '1.2.3' }, + './program': programStub, + '../errors': { NavyError }, + }) + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + sandbox.stub(console, 'log') + sandbox.stub(console, 'error') + originalArgv = process.argv + }) + + afterEach(function () { + process.argv = originalArgv + sandbox.restore() + }) + + describe('module side effects', function () { + + it('should set the program version from package.json', function () { + loadModule() + + expect(programStub.version.calledOnce).to.equal(true) + expect(programStub.version.firstCall.args[0]).to.equal('1.2.3') + }) + + it('should register a help command with * alias', function () { + loadModule() + + expect(programStub.command.calledWith('help')).to.equal(true) + expect(helpCmdStub.alias.calledWith('*')).to.equal(true) + }) + + it('should call program.help() when invoking the help action', function () { + loadModule() + + actionHandlerForHelp() + + expect(programStub.help.called).to.equal(true) + }) + + it('should call program.parse with process.argv', function () { + loadModule() + + expect(parseCalls).to.have.length(1) + expect(parseCalls[0]).to.equal(process.argv) + }) + + it('should call program.help when no args are present', function () { + loadModule({ args: [] }) + + expect(programStub.help.calledOnce).to.equal(true) + }) + + it('should not call program.help when args are present', function () { + loadModule({ args: ['some-cmd'] }) + + expect(programStub.help.called).to.equal(false) + }) + + it('should pretty-print a NavyError when parse throws one', function () { + const navyError = new NavyError('boom') + const prettyPrintStub = sandbox.stub(navyError, 'prettyPrint') + + loadModule({ + parseImpl: () => { throw navyError }, + }) + + expect(prettyPrintStub.calledOnce).to.equal(true) + }) + + it('should rethrow non-NavyError exceptions from parse', function () { + const otherError = new Error('boom') + + let caught + try { + loadModule({ + parseImpl: () => { throw otherError }, + }) + } catch (err) { + caught = err + } + + expect(caught).to.equal(otherError) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/lan-ip.js b/packages/navy/src/cli/__tests__/lan-ip.js new file mode 100644 index 0000000..21fba68 --- /dev/null +++ b/packages/navy/src/cli/__tests__/lan-ip.js @@ -0,0 +1,98 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/lan-ip', function () { + + let sandbox + let getLANIPStub + let setConfigStub + let getConfigStub + let reconfigureAllNaviesStub + let consoleLogStub + let lanIpCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getLANIPStub = sandbox.stub() + setConfigStub = sandbox.stub().resolves() + getConfigStub = sandbox.stub() + reconfigureAllNaviesStub = sandbox.stub().resolves() + consoleLogStub = sandbox.stub(console, 'log') + + lanIpCli = proxyquire.noCallThru()('../lan-ip', { + '../util/get-lan-ip': { getLANIP: getLANIPStub }, + '../config': { setConfig: setConfigStub, getConfig: getConfigStub }, + './util/reconfigure': { reconfigureAllNavies: reconfigureAllNaviesStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should look up the LAN IP via getLANIP', async function () { + getLANIPStub.resolves('10.0.0.5') + getConfigStub.returns({ defaultNavy: 'dev' }) + + await lanIpCli() + + expect(getLANIPStub.calledOnce).to.equal(true) + }) + + it('should write a config that merges existing config with the new externalIP', async function () { + getLANIPStub.resolves('10.0.0.5') + getConfigStub.returns({ defaultNavy: 'dev', tlsRootCaDir: '/ca' }) + + await lanIpCli() + + expect(setConfigStub.calledOnce).to.equal(true) + expect(setConfigStub.firstCall.args[0]).to.eql({ + defaultNavy: 'dev', + tlsRootCaDir: '/ca', + externalIP: '10.0.0.5', + }) + }) + + it('should override an existing externalIP in config with the LAN IP', async function () { + getLANIPStub.resolves('10.0.0.5') + getConfigStub.returns({ externalIP: 'old.host', defaultNavy: 'dev' }) + + await lanIpCli() + + expect(setConfigStub.firstCall.args[0].externalIP).to.equal('10.0.0.5') + }) + + it('should reconfigure all navies after writing the new config', async function () { + getLANIPStub.resolves('10.0.0.5') + getConfigStub.returns({}) + + await lanIpCli() + + expect(reconfigureAllNaviesStub.calledOnce).to.equal(true) + expect( + setConfigStub.calledBefore(reconfigureAllNaviesStub), + ).to.equal(true) + }) + + it('should log a confirmation including the LAN IP', async function () { + getLANIPStub.resolves('10.0.0.5') + getConfigStub.returns({}) + + await lanIpCli() + + const messages = consoleLogStub.getCalls().map(c => c.args[0] || '') + const hasLanIp = messages.some(m => typeof m === 'string' && m.includes('10.0.0.5')) + expect(hasLanIp).to.equal(true) + const hasLabel = messages.some(m => typeof m === 'string' && m.includes('LAN IP')) + expect(hasLabel).to.equal(true) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/launch.js b/packages/navy/src/cli/__tests__/launch.js new file mode 100644 index 0000000..8fa909e --- /dev/null +++ b/packages/navy/src/cli/__tests__/launch.js @@ -0,0 +1,170 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/launch', function () { + + let sandbox + let inquirerStub + let getOrInitialiseNavyStub + let navyStub + let startDriverLoggingStub + let stopDriverLoggingStub + let launchCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + name: 'env-1', + ensurePluginsLoaded: sandbox.stub().resolves(), + getNavyFile: sandbox.stub().resolves(null), + getAvailableServiceNames: sandbox.stub().resolves(['web', 'api', 'db']), + getLaunchedServiceNames: sandbox.stub().resolves([]), + emitAsync: sandbox.stub().resolves(), + launch: sandbox.stub().resolves(), + } + + getOrInitialiseNavyStub = sandbox.stub().resolves(navyStub) + inquirerStub = { prompt: sandbox.stub().resolves({ services: [] }) } + startDriverLoggingStub = sandbox.stub() + stopDriverLoggingStub = sandbox.stub() + + launchCli = proxyquire.noCallThru()('../launch', { + inquirer: inquirerStub, + './util': { getOrInitialiseNavy: getOrInitialiseNavyStub }, + '../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should resolve the navy via getOrInitialiseNavy(opts.navy)', async function () { + await launchCli(['web'], { navy: 'env-1' }) + + expect(getOrInitialiseNavyStub.calledWith('env-1')).to.equal(true) + }) + + it('should launch services without prompting when services are provided', async function () { + await launchCli(['web', 'api'], { navy: 'env-1' }) + + expect(inquirerStub.prompt.called).to.equal(false) + expect(navyStub.launch.calledOnce).to.equal(true) + expect(navyStub.launch.firstCall.args[0]).to.eql(['web', 'api']) + }) + + it('should bracket launch with start/stopDriverLogging', async function () { + await launchCli(['web'], { navy: 'env-1' }) + + expect(startDriverLoggingStub.calledOnce).to.equal(true) + expect(stopDriverLoggingStub.calledOnce).to.equal(true) + expect(startDriverLoggingStub.calledBefore(navyStub.launch)).to.equal(true) + expect(navyStub.launch.calledBefore(stopDriverLoggingStub)).to.equal(true) + }) + + it('should emit cli.before.launch before launching', async function () { + await launchCli(['web'], { navy: 'env-1' }) + + expect(navyStub.emitAsync.calledOnce).to.equal(true) + expect(navyStub.emitAsync.firstCall.args[0]).to.equal('cli.before.launch') + expect(navyStub.emitAsync.calledBefore(navyStub.launch)).to.equal(true) + }) + + it('should prompt with inquirer when no services are provided', async function () { + inquirerStub.prompt.resolves({ services: ['web'] }) + + await launchCli([], { navy: 'env-1' }) + + expect(inquirerStub.prompt.calledOnce).to.equal(true) + const promptArgs = inquirerStub.prompt.firstCall.args[0] + expect(promptArgs[0].type).to.equal('checkbox') + expect(promptArgs[0].name).to.equal('services') + expect(promptArgs[0].choices.map(c => c.name)).to.have.members(['web', 'api', 'db']) + }) + + it('should pre-check services from launchedServiceNames when present', async function () { + navyStub.getLaunchedServiceNames.resolves(['api']) + inquirerStub.prompt.resolves({ services: [] }) + + await launchCli([], { navy: 'env-1' }) + + const choices = inquirerStub.prompt.firstCall.args[0][0].choices + const apiChoice = choices.find(c => c.name === 'api') + const webChoice = choices.find(c => c.name === 'web') + expect(apiChoice.checked).to.equal(true) + expect(webChoice.checked).to.equal(false) + }) + + it('should pre-check services from navyFile.launchDefaults when nothing is launched', async function () { + navyStub.getNavyFile.resolves({ launchDefaults: ['web'] }) + inquirerStub.prompt.resolves({ services: [] }) + + await launchCli([], { navy: 'env-1' }) + + const choices = inquirerStub.prompt.firstCall.args[0][0].choices + const webChoice = choices.find(c => c.name === 'web') + expect(webChoice.checked).to.equal(true) + }) + + it('should fall back to no defaults when navyFile is null and nothing is launched', async function () { + navyStub.getNavyFile.resolves(null) + inquirerStub.prompt.resolves({ services: [] }) + + await launchCli([], { navy: 'env-1' }) + + const choices = inquirerStub.prompt.firstCall.args[0][0].choices + choices.forEach(c => expect(c.checked).to.equal(false)) + }) + + it('should fall back to empty defaults when navyFile lacks launchDefaults', async function () { + navyStub.getNavyFile.resolves({}) + inquirerStub.prompt.resolves({ services: [] }) + + await launchCli([], { navy: 'env-1' }) + + const choices = inquirerStub.prompt.firstCall.args[0][0].choices + choices.forEach(c => expect(c.checked).to.equal(false)) + }) + + it('should return early without launching when the user selects no services', async function () { + inquirerStub.prompt.resolves({ services: [] }) + + await launchCli([], { navy: 'env-1' }) + + expect(navyStub.launch.called).to.equal(false) + expect(navyStub.emitAsync.called).to.equal(false) + expect(startDriverLoggingStub.called).to.equal(false) + expect(stopDriverLoggingStub.called).to.equal(false) + }) + + it('should launch with the services chosen via the interactive prompt', async function () { + inquirerStub.prompt.resolves({ services: ['db', 'web'] }) + + await launchCli([], { navy: 'env-1' }) + + expect(navyStub.launch.calledOnce).to.equal(true) + expect(navyStub.launch.firstCall.args[0]).to.eql(['db', 'web']) + }) + + it('should treat a null services arg as no selection and prompt', async function () { + inquirerStub.prompt.resolves({ services: ['web'] }) + + await launchCli(null, { navy: 'env-1' }) + + expect(inquirerStub.prompt.calledOnce).to.equal(true) + expect(navyStub.launch.calledOnce).to.equal(true) + expect(navyStub.launch.firstCall.args[0]).to.eql(['web']) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/live.js b/packages/navy/src/cli/__tests__/live.js new file mode 100644 index 0000000..cc762e8 --- /dev/null +++ b/packages/navy/src/cli/__tests__/live.js @@ -0,0 +1,143 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../errors' + +describe('cli/live', function () { + + let sandbox + let getNavyStub + let navyStub + let getNavyRcStub + let consoleLogStub + let originalCwd + let liveCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + name: 'env-1', + getState: sandbox.stub().resolves({ + services: { + web: { _develop: { mounts: {}, command: 'x' } }, + }, + }), + saveState: sandbox.stub().resolves(), + kill: sandbox.stub().resolves(), + relaunch: sandbox.stub().resolves(), + } + getNavyStub = sandbox.stub().returns(navyStub) + getNavyRcStub = sandbox.stub().resolves(null) + + consoleLogStub = sandbox.stub(console, 'log') + + originalCwd = process.cwd + sandbox.stub(process, 'cwd').returns('/work') + + liveCli = proxyquire.noCallThru()('../live', { + '../': { getNavy: getNavyStub }, + '../errors': { NavyError }, + '../util/navyrc': getNavyRcStub, + }) + }) + + afterEach(function () { + process.cwd = originalCwd + sandbox.restore() + }) + + describe('default export', function () { + + it('should throw NavyError when navyrc exists but services is missing', async function () { + getNavyRcStub.resolves({ services: undefined }) + + let caught + try { + await liveCli('web', { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('No valid .navyrc') + }) + + it('should throw when navyrc lists multiple services and none specified', async function () { + getNavyRcStub.resolves({ services: ['web', 'api'] }) + + let caught + try { + await liveCli(undefined, { navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('Multiple service mappings') + }) + + it('should infer the only service from a single-service navyrc', async function () { + getNavyRcStub.resolves({ services: ['only-svc'] }) + navyStub.getState.resolves({ + services: { 'only-svc': { _develop: { mounts: {} } } }, + }) + + await liveCli(undefined, { navy: 'env-1' }) + + expect(navyStub.kill.calledWith(['only-svc'])).to.equal(true) + }) + + it('should log a "nothing to do" message when service is not in develop mode', async function () { + navyStub.getState.resolves({ services: { web: {} } }) + + await liveCli('web', { navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Nothing to do') + expect(navyStub.kill.called).to.equal(false) + expect(navyStub.relaunch.called).to.equal(false) + }) + + it('should log "nothing to do" when state has no services key', async function () { + navyStub.getState.resolves({}) + + await liveCli('web', { navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Nothing to do') + }) + + it('should log "nothing to do" when state is null', async function () { + navyStub.getState.resolves(null) + + await liveCli('web', { navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Nothing to do') + }) + + it('should clear _develop, kill, and relaunch when service is in develop mode', async function () { + await liveCli('web', { navy: 'env-1' }) + + expect(navyStub.saveState.calledOnce).to.equal(true) + const newState = navyStub.saveState.firstCall.args[0] + expect(newState.services.web._develop).to.equal(undefined) + + expect(navyStub.kill.calledWith(['web'])).to.equal(true) + expect(navyStub.relaunch.calledOnce).to.equal(true) + expect(navyStub.relaunch.firstCall.args[0]).to.eql({ noDeps: true }) + }) + + it('should log a confirmation message after switching out of dev mode', async function () { + await liveCli('web', { navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('no longer in development') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/local-ip.js b/packages/navy/src/cli/__tests__/local-ip.js new file mode 100644 index 0000000..9dd4df3 --- /dev/null +++ b/packages/navy/src/cli/__tests__/local-ip.js @@ -0,0 +1,82 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/local-ip', function () { + + let sandbox + let setConfigStub + let getConfigStub + let reconfigureAllNaviesStub + let consoleLogStub + let localIpCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + setConfigStub = sandbox.stub().resolves() + getConfigStub = sandbox.stub() + reconfigureAllNaviesStub = sandbox.stub().resolves() + consoleLogStub = sandbox.stub(console, 'log') + + localIpCli = proxyquire.noCallThru()('../local-ip', { + '../config': { setConfig: setConfigStub, getConfig: getConfigStub }, + './util/reconfigure': { reconfigureAllNavies: reconfigureAllNaviesStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should write a config that merges existing config with externalIP=127.0.0.1', async function () { + getConfigStub.returns({ defaultNavy: 'dev', tlsRootCaDir: '/ca' }) + + await localIpCli() + + expect(setConfigStub.calledOnce).to.equal(true) + expect(setConfigStub.firstCall.args[0]).to.eql({ + defaultNavy: 'dev', + tlsRootCaDir: '/ca', + externalIP: '127.0.0.1', + }) + }) + + it('should override an existing externalIP in config with 127.0.0.1', async function () { + getConfigStub.returns({ externalIP: 'remote.host' }) + + await localIpCli() + + expect(setConfigStub.firstCall.args[0].externalIP).to.equal('127.0.0.1') + }) + + it('should reconfigure all navies after writing the new config', async function () { + getConfigStub.returns({}) + + await localIpCli() + + expect(reconfigureAllNaviesStub.calledOnce).to.equal(true) + expect( + setConfigStub.calledBefore(reconfigureAllNaviesStub), + ).to.equal(true) + }) + + it('should log a confirmation including the local IP', async function () { + getConfigStub.returns({}) + + await localIpCli() + + const messages = consoleLogStub.getCalls().map(c => c.args[0] || '') + const hasIp = messages.some(m => typeof m === 'string' && m.includes('127.0.0.1')) + expect(hasIp).to.equal(true) + const hasLabel = messages.some(m => typeof m === 'string' && m.includes('local IP')) + expect(hasLabel).to.equal(true) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/logs.js b/packages/navy/src/cli/__tests__/logs.js new file mode 100644 index 0000000..0f77826 --- /dev/null +++ b/packages/navy/src/cli/__tests__/logs.js @@ -0,0 +1,57 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/logs', function () { + + let sandbox + let getNavyStub + let navyStub + let logs + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + spawnLogStream: sandbox.stub().resolves(), + } + getNavyStub = sandbox.stub().returns(navyStub) + + logs = proxyquire.noCallThru()('../logs', { + '../': { getNavy: getNavyStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await logs(['api'], { navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should call spawnLogStream with the supplied services array', async function () { + const services = ['api', 'web'] + + await logs(services, { navy: 'env-1' }) + + expect(navyStub.spawnLogStream.calledOnce).to.equal(true) + expect(navyStub.spawnLogStream.firstCall.args[0]).to.equal(services) + }) + + it('should propagate empty service lists through to spawnLogStream', async function () { + await logs([], { navy: 'env-1' }) + + expect(navyStub.spawnLogStream.firstCall.args[0]).to.eql([]) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/open.js b/packages/navy/src/cli/__tests__/open.js new file mode 100644 index 0000000..3d009db --- /dev/null +++ b/packages/navy/src/cli/__tests__/open.js @@ -0,0 +1,70 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/open', function () { + + let sandbox + let getNavyStub + let navyStub + let openStub + let consoleLogStub + let openCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + url: sandbox.stub().resolves('http://service.local'), + } + getNavyStub = sandbox.stub().returns(navyStub) + openStub = sandbox.stub() + consoleLogStub = sandbox.stub(console, 'log') + + openCli = proxyquire.noCallThru()('../open', { + open: openStub, + '../': { getNavy: getNavyStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await openCli('api', { navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should resolve the URL for the requested service via navy.url', async function () { + await openCli('api', { navy: 'env-1' }) + + expect(navyStub.url.calledOnce).to.equal(true) + expect(navyStub.url.firstCall.args[0]).to.equal('api') + }) + + it('should pass the resolved URL to the open package', async function () { + navyStub.url.resolves('http://my-service.test') + + await openCli('api', { navy: 'env-1' }) + + expect(openStub.calledOnce).to.equal(true) + expect(openStub.firstCall.args[0]).to.equal('http://my-service.test') + }) + + it('should log a message indicating which service is being opened', async function () { + await openCli('api', { navy: 'env-1' }) + + expect(consoleLogStub.calledOnce).to.equal(true) + expect(consoleLogStub.firstCall.args[0]).to.contain('Opening api...') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/program-unknown-options.js b/packages/navy/src/cli/__tests__/program-unknown-options.js new file mode 100644 index 0000000..dfae9c3 --- /dev/null +++ b/packages/navy/src/cli/__tests__/program-unknown-options.js @@ -0,0 +1,97 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { Command } from 'commander' + +/** + * These tests check that the commander configuration the navy CLI relies on + * (positional options + per-subcommand option declarations) rejects options + * that a subcommand does not declare, using the exact error format commander + * emits by default. + * + * We build a minimal program with the same shape as packages/navy/src/cli/program.js + * rather than loading that module, because importing program.js has side effects + * (config reading, action wiring) that are not relevant to argument parsing. + */ +describe('cli/program unknown option handling', function () { + + function buildProgram() { + const program = new Command() + program.exitOverride() + program.configureOutput({ writeErr: () => {}, writeOut: () => {} }) + + program.enablePositionalOptions() + program.option('-e, --navy [env]', 'set the navy name to be used', 'dev') + + program + .command('status') + .option('--json', 'output JSON instead of a table') + .action(() => {}) + + program + .command('start [services...]') + .option('-e, --navy [env]', 'set the navy name to be used', 'dev') + .action(() => {}) + + return program + } + + describe('a subcommand that does not declare the option', function () { + + it('should throw a commander error for an unknown short option', function () { + const program = buildProgram() + + expect(() => program.parse(['node', 'navy', 'status', '-e', 'foo'])) + .to.throw(/unknown option '-e'/) + }) + + it('should produce a non-zero exit code on the thrown error', function () { + const program = buildProgram() + + try { + program.parse(['node', 'navy', 'status', '-e', 'foo']) + expect.fail('expected parse to throw') + } catch (ex) { + expect(ex.exitCode).to.be.greaterThan(0) + } + }) + + it('should emit the canonical commander unknown-option message', function () { + const program = buildProgram() + + try { + program.parse(['node', 'navy', 'status', '-e', 'foo']) + expect.fail('expected parse to throw') + } catch (ex) { + expect(ex.message).to.equal("error: unknown option '-e'") + } + }) + + it('should still accept declared options on the same subcommand', function () { + const program = buildProgram() + + expect(() => program.parse(['node', 'navy', 'status', '--json'])) + .to.not.throw() + }) + + }) + + describe('a subcommand that declares the option', function () { + + it('should accept the option after the subcommand name', function () { + const program = buildProgram() + + expect(() => program.parse(['node', 'navy', 'start', '-e', 'foo'])) + .to.not.throw() + }) + + it('should accept the option before the subcommand name (parent inherits)', function () { + const program = buildProgram() + + expect(() => program.parse(['node', 'navy', '-e', 'foo', 'start'])) + .to.not.throw() + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/program.js b/packages/navy/src/cli/__tests__/program.js new file mode 100644 index 0000000..aced0a2 --- /dev/null +++ b/packages/navy/src/cli/__tests__/program.js @@ -0,0 +1,602 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../errors' + +describe('cli/program', function () { + + let sandbox + let fakeProgram + let actionsByCommand + let getConfigStub + let startDriverLoggingStub + let stopDriverLoggingStub + let getImportCommandLineOptionsStub + let getNavyStub + let navyStub + let consoleLogStub + let consoleErrorStub + let processExitStub + let processOnStub + let originalEnvName + + let helpHandlersByCommand + + function loadModule() { + actionsByCommand = {} + helpHandlersByCommand = {} + + fakeProgram = { + option: sandbox.stub().returnsThis(), + enablePositionalOptions: sandbox.stub().returnsThis(), + command(spec) { + const name = spec.split(' ')[0] + const cmd = { + option: sandbox.stub().returnsThis(), + description: sandbox.stub().returnsThis(), + action(handler) { + actionsByCommand[name] = handler + return cmd + }, + on(event, handler) { + if (event === '--help') { + helpHandlersByCommand[name] = handler + } + return cmd + }, + } + return cmd + }, + } + + return proxyquire.noCallThru()('../program', { + commander: { program: fakeProgram }, + '../errors': { NavyError }, + '../config': { getConfig: getConfigStub }, + '../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + '../config-provider': { getImportCommandLineOptions: getImportCommandLineOptionsStub }, + '../navy': { getNavy: getNavyStub }, + './import': () => Promise.resolve('imported'), + './launch': () => Promise.resolve('launched'), + './ps': () => Promise.resolve(undefined), + './updates': () => Promise.resolve(undefined), + './logs': () => Promise.resolve(undefined), + './health': () => Promise.resolve(undefined), + './wait-for-healthy': () => Promise.resolve(undefined), + './https': () => Promise.resolve(undefined), + './open': () => Promise.resolve(undefined), + './develop': () => Promise.resolve(undefined), + './live': () => Promise.resolve(undefined), + './run': () => Promise.resolve(undefined), + './refresh-config': () => Promise.resolve(undefined), + './status': () => Promise.resolve(undefined), + './doctor': () => Promise.resolve(undefined), + './config/wrapper': () => Promise.resolve(undefined), + './external-ip': () => Promise.resolve(undefined), + './lan-ip': () => Promise.resolve(undefined), + './local-ip': () => Promise.resolve(undefined), + }) + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getConfigStub = sandbox.stub().returns({ defaultNavy: 'dev' }) + startDriverLoggingStub = sandbox.stub() + stopDriverLoggingStub = sandbox.stub() + getImportCommandLineOptionsStub = sandbox.stub().returns([ + ['-c, --config-provider [provider]', 'Config provider to use'], + ]) + + navyStub = { + ensurePluginsLoaded: sandbox.stub().resolves(), + emitAsync: sandbox.stub().resolves(), + destroy: sandbox.stub().resolves(), + kill: sandbox.stub().resolves(), + start: sandbox.stub().resolves(), + stop: sandbox.stub().resolves(), + url: sandbox.stub().resolves('http://web'), + getAvailableServiceNames: sandbox.stub().resolves(['web', 'api']), + } + getNavyStub = sandbox.stub().returns(navyStub) + + consoleLogStub = sandbox.stub(console, 'log') + consoleErrorStub = sandbox.stub(console, 'error') + processExitStub = sandbox.stub(process, 'exit') + processOnStub = sandbox.stub(process, 'on') + + originalEnvName = process.env.NAVY_NAME + }) + + afterEach(function () { + if (originalEnvName === undefined) { + delete process.env.NAVY_NAME + } else { + process.env.NAVY_NAME = originalEnvName + } + sandbox.restore() + }) + + describe('module side effects', function () { + + it('should register all known commands on the program', function () { + loadModule() + + expect(actionsByCommand).to.have.keys( + 'import', 'launch', 'destroy', 'delete', 'ps', 'start', 'stop', + 'restart', 'kill', 'rm', 'update', 'updates', 'logs', 'health', + 'wait-for-healthy', 'use-tag', 'reset-tag', 'https', 'use-port', + 'reset-port', 'url', 'open', 'port', 'available-services', 'develop', + 'live', 'run', 'refresh-config', 'status', 'doctor', 'config', + 'external-ip', 'use-lan-ip', 'use-local-ip', + ) + }) + + it('should derive the default navy from NAVY_NAME env when set', function () { + process.env.NAVY_NAME = 'foo-env' + loadModule() + + expect(actionsByCommand.import).to.be.a('function') + }) + + it('should fall back to getConfig().defaultNavy when env is not set', function () { + delete process.env.NAVY_NAME + loadModule() + + expect(getConfigStub.called).to.equal(true) + }) + + it('should add import command-line options from getImportCommandLineOptions', function () { + loadModule() + + expect(getImportCommandLineOptionsStub.calledOnce).to.equal(true) + }) + + it('should export the program as default', function () { + const mod = loadModule() + expect(mod).to.equal(fakeProgram) + }) + + it('should print examples when each command --help handler is invoked', function () { + loadModule() + + Object.keys(helpHandlersByCommand).forEach(name => { + helpHandlersByCommand[name]() + }) + + expect(consoleLogStub.called).to.equal(true) + }) + + it('should register a global -e, --navy option on the root program', function () { + loadModule() + + expect(fakeProgram.option.calledWith( + '-e, --navy [env]', + sinon.match.string, + 'dev', + )).to.equal(true) + }) + + it('should enable positional options so unknown subcommand options are rejected', function () { + loadModule() + + expect(fakeProgram.enablePositionalOptions.calledOnce).to.equal(true) + }) + + }) + + describe('lazyRequire wrapped action', function () { + + it('should pass through arguments to the underlying module', async function () { + loadModule() + + const result = actionsByCommand.import({ navy: 'env-1' }) + return expect(result).to.exist + }) + + it('should call stopDriverLogging and prettyPrint when the action throws a NavyError', async function () { + const err = new NavyError('boom') + const prettyPrintStub = sandbox.stub(err, 'prettyPrint') + + proxyquire.noCallThru()('../program', { + commander: { program: createCapturingProgram() }, + '../errors': { NavyError }, + '../config': { getConfig: getConfigStub }, + '../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + '../config-provider': { getImportCommandLineOptions: getImportCommandLineOptionsStub }, + '../navy': { getNavy: getNavyStub }, + './import': () => Promise.reject(err), + './launch': () => Promise.resolve(), + './ps': () => Promise.resolve(), + './updates': () => Promise.resolve(), + './logs': () => Promise.resolve(), + './health': () => Promise.resolve(), + './wait-for-healthy': () => Promise.resolve(), + './https': () => Promise.resolve(), + './open': () => Promise.resolve(), + './develop': () => Promise.resolve(), + './live': () => Promise.resolve(), + './run': () => Promise.resolve(), + './refresh-config': () => Promise.resolve(), + './status': () => Promise.resolve(), + './doctor': () => Promise.resolve(), + './config/wrapper': () => Promise.resolve(), + './external-ip': () => Promise.resolve(), + './lan-ip': () => Promise.resolve(), + './local-ip': () => Promise.resolve(), + }) + + capturedActions.import({ navy: 'env-1' }) + await new Promise(resolve => setImmediate(resolve)) + + expect(prettyPrintStub.calledOnce).to.equal(true) + expect(processExitStub.calledWith(1)).to.equal(true) + expect(stopDriverLoggingStub.calledWith({ success: false })).to.equal(true) + }) + + it('should pretty-print invariant violations with troubleshooting hint', async function () { + const err = new Error('CODE: something went wrong') + err.name = 'Invariant Violation' + + proxyquire.noCallThru()('../program', { + commander: { program: createCapturingProgram() }, + '../errors': { NavyError }, + '../config': { getConfig: getConfigStub }, + '../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + '../config-provider': { getImportCommandLineOptions: getImportCommandLineOptionsStub }, + '../navy': { getNavy: getNavyStub }, + './import': () => Promise.reject(err), + './launch': () => Promise.resolve(), + './ps': () => Promise.resolve(), + './updates': () => Promise.resolve(), + './logs': () => Promise.resolve(), + './health': () => Promise.resolve(), + './wait-for-healthy': () => Promise.resolve(), + './https': () => Promise.resolve(), + './open': () => Promise.resolve(), + './develop': () => Promise.resolve(), + './live': () => Promise.resolve(), + './run': () => Promise.resolve(), + './refresh-config': () => Promise.resolve(), + './status': () => Promise.resolve(), + './doctor': () => Promise.resolve(), + './config/wrapper': () => Promise.resolve(), + './external-ip': () => Promise.resolve(), + './lan-ip': () => Promise.resolve(), + './local-ip': () => Promise.resolve(), + }) + + capturedActions.import({ navy: 'env-1' }) + await new Promise(resolve => setImmediate(resolve)) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Invariant Violation') + expect(printed).to.contain('navy doctor') + expect(processExitStub.calledWith(1)).to.equal(true) + }) + + it('should print stack for non-NavyError, non-Invariant errors', async function () { + const err = new Error('something broke') + + proxyquire.noCallThru()('../program', { + commander: { program: createCapturingProgram() }, + '../errors': { NavyError }, + '../config': { getConfig: getConfigStub }, + '../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + '../config-provider': { getImportCommandLineOptions: getImportCommandLineOptionsStub }, + '../navy': { getNavy: getNavyStub }, + './import': () => Promise.reject(err), + './launch': () => Promise.resolve(), + './ps': () => Promise.resolve(), + './updates': () => Promise.resolve(), + './logs': () => Promise.resolve(), + './health': () => Promise.resolve(), + './wait-for-healthy': () => Promise.resolve(), + './https': () => Promise.resolve(), + './open': () => Promise.resolve(), + './develop': () => Promise.resolve(), + './live': () => Promise.resolve(), + './run': () => Promise.resolve(), + './refresh-config': () => Promise.resolve(), + './status': () => Promise.resolve(), + './doctor': () => Promise.resolve(), + './config/wrapper': () => Promise.resolve(), + './external-ip': () => Promise.resolve(), + './lan-ip': () => Promise.resolve(), + './local-ip': () => Promise.resolve(), + }) + + capturedActions.import({ navy: 'env-1' }) + await new Promise(resolve => setImmediate(resolve)) + + expect(consoleErrorStub.calledWith(err.stack)).to.equal(true) + }) + + // NOTE: The internal wrapper in program.js does `if (res.catch)` without + // null-checking, so passing a non-promise return value would throw. All + // production action handlers return promises, so this code path is not + // exercised in practice. We do not test it because asserting that + // behaviour would lock in a latent bug. + + }) + + describe('normaliseLazyRequireArgs (via lazyRequire wrapped action)', function () { + + let importSpy + + function loadWithImportSpy() { + importSpy = sandbox.stub().resolves('imported') + return proxyquire.noCallThru()('../program', { + commander: { program: createCapturingProgram() }, + '../errors': { NavyError }, + '../config': { getConfig: getConfigStub }, + '../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + '../config-provider': { getImportCommandLineOptions: getImportCommandLineOptionsStub }, + '../navy': { getNavy: getNavyStub }, + './import': importSpy, + './launch': () => Promise.resolve(), + './ps': () => Promise.resolve(), + './updates': () => Promise.resolve(), + './logs': () => Promise.resolve(), + './health': () => Promise.resolve(), + './wait-for-healthy': () => Promise.resolve(), + './https': () => Promise.resolve(), + './open': () => Promise.resolve(), + './develop': () => Promise.resolve(), + './live': () => Promise.resolve(), + './run': () => Promise.resolve(), + './refresh-config': () => Promise.resolve(), + './status': () => Promise.resolve(), + './doctor': () => Promise.resolve(), + './config/wrapper': () => Promise.resolve(), + './external-ip': () => Promise.resolve(), + './lan-ip': () => Promise.resolve(), + './local-ip': () => Promise.resolve(), + }) + } + + it('should pass through unchanged when invoked with no arguments at all', async function () { + loadWithImportSpy() + + capturedActions.import() + await new Promise(resolve => setImmediate(resolve)) + + expect(importSpy.calledOnce).to.equal(true) + expect(importSpy.firstCall.args).to.eql([]) + }) + + it('should strip the trailing Command instance when no other args were supplied', async function () { + loadWithImportSpy() + const fakeCommand = { optsWithGlobals: () => ({ navy: 'global' }) } + + capturedActions.import(fakeCommand) + await new Promise(resolve => setImmediate(resolve)) + + expect(importSpy.calledOnce).to.equal(true) + expect(importSpy.firstCall.args).to.eql([]) + }) + + it('should merge inherited globals into the trailing options object before forwarding', async function () { + loadWithImportSpy() + const fakeCommand = { + optsWithGlobals: () => ({ navy: 'from-global', extra: 1 }), + getOptionValueSource: () => 'default', + } + + capturedActions.import({ navy: 'subcommand-default' }, fakeCommand) + await new Promise(resolve => setImmediate(resolve)) + + expect(importSpy.calledOnce).to.equal(true) + expect(importSpy.firstCall.args).to.have.lengthOf(1) + expect(importSpy.firstCall.args[0]).to.eql({ navy: 'from-global', extra: 1 }) + }) + + it('should leave non-object trailing arguments untouched when stripping the command', async function () { + loadWithImportSpy() + const fakeCommand = { optsWithGlobals: () => ({ navy: 'global' }) } + + capturedActions.import(['web', 'api'], fakeCommand) + await new Promise(resolve => setImmediate(resolve)) + + expect(importSpy.calledOnce).to.equal(true) + expect(importSpy.firstCall.args).to.eql([['web', 'api']]) + }) + + }) + + describe('basicCliWrapper action', function () { + + beforeEach(function () { + loadModule() + }) + + it('should call the named navy method with the supplied service list', async function () { + navyStub.start = sandbox.stub().resolves() + + await actionsByCommand.start(['web', 'api'], { navy: 'env-1' }, {}) + + expect(navyStub.start.calledOnce).to.equal(true) + expect(navyStub.start.firstCall.args[0]).to.eql(['web', 'api']) + expect(navyStub.ensurePluginsLoaded.calledOnce).to.equal(true) + }) + + it('should merge optsWithGlobals so global navy is used when Commander passes the command', async function () { + navyStub.start = sandbox.stub().resolves() + const fakeCommand = { optsWithGlobals: () => ({ navy: 'from-global' }) } + + await actionsByCommand.start(['web'], { navy: 'subcommand-default' }, fakeCommand) + + expect(getNavyStub.firstCall.args[0]).to.equal('from-global') + }) + + it('should fall back to maybeServices as opts when only an opts object and command are passed', async function () { + navyStub.getAvailableServiceNames = sandbox.stub().resolves([]) + const fakeCommand = { optsWithGlobals: () => ({ navy: 'from-global' }) } + + await actionsByCommand['available-services']({ navy: 'subcommand-default' }, fakeCommand) + + expect(getNavyStub.firstCall.args[0]).to.equal('from-global') + }) + + it('should pass undefined when called with an empty service list', async function () { + navyStub.start = sandbox.stub().resolves() + + await actionsByCommand.start([], { navy: 'env-1' }, {}) + + expect(navyStub.start.firstCall.args[0]).to.equal(undefined) + }) + + it('should drive logging by default', async function () { + navyStub.start = sandbox.stub().resolves() + + await actionsByCommand.start(['web'], { navy: 'env-1' }, {}) + + expect(startDriverLoggingStub.calledWith('Starting services...')).to.equal(true) + expect(stopDriverLoggingStub.calledOnce).to.equal(true) + }) + + it('should skip driver logging for the url command (driverLogging: false)', async function () { + navyStub.url = sandbox.stub().resolves('http://web') + + await actionsByCommand.url('web', { navy: 'env-1' }, {}) + + expect(startDriverLoggingStub.called).to.equal(false) + expect(stopDriverLoggingStub.called).to.equal(false) + }) + + it('should print arrays joined by newlines', async function () { + navyStub.getAvailableServiceNames = sandbox.stub().resolves(['web', 'api']) + + await actionsByCommand['available-services']({ navy: 'env-1' }, {}) + + expect(consoleLogStub.calledWith('web\napi')).to.equal(true) + }) + + it('should print non-null scalar return values', async function () { + navyStub.url = sandbox.stub().resolves('http://web') + + await actionsByCommand.url('web', { navy: 'env-1' }, {}) + + expect(consoleLogStub.calledWith('http://web')).to.equal(true) + }) + + it('should not print when the navy method returns null', async function () { + navyStub.start = sandbox.stub().resolves(null) + + await actionsByCommand.start(['web'], { navy: 'env-1' }, {}) + + expect(consoleLogStub.called).to.equal(false) + }) + + it('should redirect destroy with services to kill via serviceBasedAlias', async function () { + navyStub.kill = sandbox.stub().resolves() + + await actionsByCommand.destroy('web api', { navy: 'env-1' }, {}) + + expect(navyStub.kill.calledOnce).to.equal(true) + expect(navyStub.kill.firstCall.args[0]).to.eql(['web', 'api']) + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('should not be called with a list') + }) + + it('should emit cli.before. and cli.after.', async function () { + navyStub.start = sandbox.stub().resolves() + + await actionsByCommand.start(['web'], { navy: 'env-1' }, {}) + + const events = navyStub.emitAsync.getCalls().map(c => c.args[0]) + expect(events).to.include('cli.before.start') + expect(events).to.include('cli.after.start') + }) + + it('should register an unhandledRejection handler', async function () { + navyStub.start = sandbox.stub().resolves() + + await actionsByCommand.start(['web'], { navy: 'env-1' }, {}) + + expect(processOnStub.calledWith('unhandledRejection')).to.equal(true) + }) + + describe('unhandledRejection handler', function () { + + it('should pretty-print NavyError and exit', async function () { + navyStub.start = sandbox.stub().resolves() + await actionsByCommand.start(['web'], { navy: 'env-1' }, {}) + + const handlers = processOnStub.getCalls() + .filter(c => c.args[0] === 'unhandledRejection') + .map(c => c.args[1]) + const handler = handlers[handlers.length - 1] + + const err = new NavyError('boom') + const prettyPrintStub = sandbox.stub(err, 'prettyPrint') + + handler(err) + + expect(prettyPrintStub.calledOnce).to.equal(true) + expect(processExitStub.called).to.equal(true) + }) + + it('should print stack for non-NavyError and exit', async function () { + navyStub.start = sandbox.stub().resolves() + await actionsByCommand.start(['web'], { navy: 'env-1' }, {}) + + const handlers = processOnStub.getCalls() + .filter(c => c.args[0] === 'unhandledRejection') + .map(c => c.args[1]) + const handler = handlers[handlers.length - 1] + + const err = new Error('boom') + + handler(err) + + expect(consoleErrorStub.calledWith(err.stack)).to.equal(true) + expect(processExitStub.called).to.equal(true) + }) + + }) + + }) + + // Helper to capture program actions for the failure-path tests + let capturedActions + + function createCapturingProgram() { + capturedActions = {} + return { + option: sandbox.stub().returnsThis(), + enablePositionalOptions: sandbox.stub().returnsThis(), + command(spec) { + const name = spec.split(' ')[0] + const cmd = { + option: sandbox.stub().returnsThis(), + description: sandbox.stub().returnsThis(), + action(handler) { + capturedActions[name] = handler + return cmd + }, + on: sandbox.stub().returnsThis(), + } + return cmd + }, + } + } + +}) diff --git a/packages/navy/src/cli/__tests__/ps.js b/packages/navy/src/cli/__tests__/ps.js new file mode 100644 index 0000000..56e48af --- /dev/null +++ b/packages/navy/src/cli/__tests__/ps.js @@ -0,0 +1,312 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import stripAnsi from 'strip-ansi' + +describe('cli/ps', function () { + + let sandbox + let getNavyStub + let getUrlFromServiceStub + let navyStub + let consoleLogStub + let originalIsTTY + let originalGetWindowSize + let psCli + + function makeService(overrides = {}) { + return { + id: 'abcdefghijklmnop', + name: 'api', + image: 'navy/api:latest', + status: 'running', + raw: undefined, + ...overrides, + } + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + ps: sandbox.stub().resolves([]), + getState: sandbox.stub().resolves(null), + } + + getNavyStub = sandbox.stub().returns(navyStub) + getUrlFromServiceStub = sandbox.stub().returns(null) + consoleLogStub = sandbox.stub(console, 'log') + + originalIsTTY = process.stdout.isTTY + originalGetWindowSize = process.stdout.getWindowSize + process.stdout.isTTY = false + process.stdout.getWindowSize = () => [200, 50] + + psCli = proxyquire.noCallThru()('../ps', { + '../': { getNavy: getNavyStub }, + '../util/service-host': { getUrlFromService: getUrlFromServiceStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + process.stdout.isTTY = originalIsTTY + if (originalGetWindowSize === undefined) { + delete process.stdout.getWindowSize + } else { + process.stdout.getWindowSize = originalGetWindowSize + } + }) + + function lastLoggedString() { + const last = consoleLogStub.lastCall + return last ? String(last.args[0]) : '' + } + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await psCli({ navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should print JSON when opts.json is true', async function () { + const services = [makeService({ id: 'svc-id', name: 'api' })] + navyStub.ps.resolves(services) + + await psCli({ navy: 'env-1', json: true }) + + expect(consoleLogStub.calledOnce).to.equal(true) + expect(consoleLogStub.firstCall.args[0]).to.equal(JSON.stringify(services, null, 2)) + }) + + it('should render the wide 6-column table by default in non-TTY', async function () { + navyStub.ps.resolves([makeService()]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('IMAGE') + expect(text).to.contain('navy/api:latest') + }) + + it('should render the small 5-column table when TTY width is below threshold', async function () { + process.stdout.isTTY = true + process.stdout.getWindowSize = () => [80, 50] + navyStub.ps.resolves([makeService()]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('NAME') + expect(text).to.contain('STATUS') + expect(text).to.not.contain('IMAGE') + }) + + it('should render the wide 6-column table when TTY width is at or above threshold', async function () { + process.stdout.isTTY = true + process.stdout.getWindowSize = () => [200, 50] + navyStub.ps.resolves([makeService()]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('IMAGE') + }) + + it('should truncate the service id to 12 characters', async function () { + navyStub.ps.resolves([makeService({ id: '0123456789abcdef9999' })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('0123456789ab') + expect(text).not.to.contain('0123456789abcdef') + }) + + }) + + describe('getStatus (via default export)', function () { + + it('should print the status as-is when not exited and no state present', async function () { + navyStub.ps.resolves([makeService({ status: 'running' })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('running') + expect(text).not.to.contain('(development)') + expect(text).not.to.contain('@') + }) + + it('should render the exited status (taking the chalk.red branch)', async function () { + navyStub.ps.resolves([makeService({ status: 'exited' })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('exited') + }) + + it('should append (development) when the service has _develop set in state', async function () { + navyStub.ps.resolves([makeService({ name: 'api' })]) + navyStub.getState.resolves({ services: { api: { _develop: true } } }) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('(development)') + }) + + it('should append the @ tag when the service has _tag set in state', async function () { + navyStub.ps.resolves([makeService({ name: 'api' })]) + navyStub.getState.resolves({ services: { api: { _tag: 'v1.2.3' } } }) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('@ v1.2.3') + }) + + it('should append both (development) and the @ tag when both are set', async function () { + navyStub.ps.resolves([makeService({ name: 'api' })]) + navyStub.getState.resolves({ services: { api: { _develop: true, _tag: 'v9' } } }) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('(development)') + expect(text).to.contain('@ v9') + }) + + it('should not annotate the status when state has no entry for the service name', async function () { + navyStub.ps.resolves([makeService({ name: 'api' })]) + navyStub.getState.resolves({ services: { web: { _develop: true } } }) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).not.to.contain('(development)') + }) + + it('should handle a state object with no services map', async function () { + navyStub.ps.resolves([makeService({ name: 'api' })]) + navyStub.getState.resolves({}) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('running') + expect(text).not.to.contain('(development)') + }) + + }) + + describe('getPorts (via default export)', function () { + + it('should render - when raw is missing', async function () { + navyStub.ps.resolves([makeService({ raw: undefined })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.match(/-/) + }) + + it('should render - when raw.NetworkSettings is missing', async function () { + navyStub.ps.resolves([makeService({ raw: {} })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.match(/-/) + }) + + it('should render - when raw.NetworkSettings.Ports is missing', async function () { + navyStub.ps.resolves([makeService({ raw: { NetworkSettings: {} } })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.match(/-/) + }) + + it('should render only the port key when there are no host bindings', async function () { + navyStub.ps.resolves([makeService({ + raw: { NetworkSettings: { Ports: { '8080/tcp': null } } }, + })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('8080/tcp') + expect(text).not.to.contain('->') + }) + + it('should render HostPort->portKey when bindings exist', async function () { + navyStub.ps.resolves([makeService({ + raw: { + NetworkSettings: { + Ports: { + '8080/tcp': [{ HostPort: '32001' }, { HostPort: '32002' }], + }, + }, + }, + })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('32001, 32002->8080/tcp') + }) + + it('should join multiple port keys with commas', async function () { + navyStub.ps.resolves([makeService({ + raw: { + NetworkSettings: { + Ports: { + '8080/tcp': [{ HostPort: '32001' }], + '9090/tcp': null, + }, + }, + }, + })]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('32001->8080/tcp') + expect(text).to.contain('9090/tcp') + }) + + }) + + describe('getDisplayUrl (via default export)', function () { + + it('should render - when getUrlFromService returns null', async function () { + getUrlFromServiceStub.returns(null) + navyStub.ps.resolves([makeService()]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.match(/\s-\s|\s-$/) + }) + + it('should render the URL string when getUrlFromService returns a string', async function () { + getUrlFromServiceStub.returns('https://api.example.local') + navyStub.ps.resolves([makeService()]) + + await psCli({ navy: 'env-1' }) + + const text = stripAnsi(lastLoggedString()) + expect(text).to.contain('https://api.example.local') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/refresh-config.js b/packages/navy/src/cli/__tests__/refresh-config.js new file mode 100644 index 0000000..7e1c420 --- /dev/null +++ b/packages/navy/src/cli/__tests__/refresh-config.js @@ -0,0 +1,104 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/refresh-config', function () { + + let sandbox + let getNavyStub + let navyStub + let configProvider + let startDriverLoggingStub + let stopDriverLoggingStub + let consoleLogStub + let refreshConfigCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + + configProvider = { + refreshConfig: sandbox.stub().resolves(), + } + navyStub = { + name: 'env-1', + getConfigProvider: sandbox.stub().resolves(configProvider), + reconfigure: sandbox.stub().resolves(), + } + getNavyStub = sandbox.stub().returns(navyStub) + startDriverLoggingStub = sandbox.stub() + stopDriverLoggingStub = sandbox.stub() + consoleLogStub = sandbox.stub(console, 'log') + + refreshConfigCli = proxyquire.noCallThru()('../refresh-config', { + '../': { getNavy: getNavyStub }, + '../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await refreshConfigCli({ navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should call refreshConfig on the resolved config provider', async function () { + await refreshConfigCli({ navy: 'env-1' }) + + expect(navyStub.getConfigProvider.calledOnce).to.equal(true) + expect(configProvider.refreshConfig.calledOnce).to.equal(true) + }) + + it('should bracket reconfigure with start/stopDriverLogging', async function () { + await refreshConfigCli({ navy: 'env-1' }) + + expect(startDriverLoggingStub.calledOnce).to.equal(true) + expect(navyStub.reconfigure.calledOnce).to.equal(true) + expect(stopDriverLoggingStub.calledOnce).to.equal(true) + expect( + startDriverLoggingStub.calledBefore(navyStub.reconfigure), + ).to.equal(true) + expect( + navyStub.reconfigure.calledBefore(stopDriverLoggingStub), + ).to.equal(true) + }) + + it('should log a success message naming the navy', async function () { + await refreshConfigCli({ navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join(' ') + expect(printed).to.contain('Config refreshed') + expect(printed).to.contain('env-1') + }) + + it('should throw an invariant violation when the navy has no config provider', async function () { + navyStub.getConfigProvider.resolves(null) + + let caught + try { + await refreshConfigCli({ navy: 'env-1' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.match(/NO_CONFIG_PROVIDER/) + expect(configProvider.refreshConfig.called).to.equal(false) + expect(navyStub.reconfigure.called).to.equal(false) + expect(startDriverLoggingStub.called).to.equal(false) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/run.js b/packages/navy/src/cli/__tests__/run.js new file mode 100644 index 0000000..6328ed6 --- /dev/null +++ b/packages/navy/src/cli/__tests__/run.js @@ -0,0 +1,60 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/run', function () { + + let sandbox + let getNavyStub + let navyStub + let run + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + ensurePluginsLoaded: sandbox.stub().resolves(), + invokeCommand: sandbox.stub().resolves(), + } + getNavyStub = sandbox.stub().returns(navyStub) + + run = proxyquire.noCallThru()('../run', { + '../': { getNavy: getNavyStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await run('cmd', [], { navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should call ensurePluginsLoaded before invokeCommand', async function () { + await run('cmd', ['a'], { navy: 'env-1' }) + + expect(navyStub.ensurePluginsLoaded.calledOnce).to.equal(true) + expect(navyStub.invokeCommand.calledOnce).to.equal(true) + expect( + navyStub.ensurePluginsLoaded.calledBefore(navyStub.invokeCommand), + ).to.equal(true) + }) + + it('should pass through name and args to invokeCommand', async function () { + await run('migrate', ['--up', 'db'], { navy: 'env-1' }) + + expect(navyStub.invokeCommand.firstCall.args[0]).to.equal('migrate') + expect(navyStub.invokeCommand.firstCall.args[1]).to.eql(['--up', 'db']) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/status.js b/packages/navy/src/cli/__tests__/status.js new file mode 100644 index 0000000..002edf8 --- /dev/null +++ b/packages/navy/src/cli/__tests__/status.js @@ -0,0 +1,201 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import stripAnsi from 'strip-ansi' + +describe('cli/status', function () { + + let sandbox + let getLaunchedNaviesStub + let getConfigStub + let consoleLogStub + let statusCli + + function makeNavy(overrides = {}) { + return { + name: 'env-1', + ps: sandbox.stub().resolves([]), + getState: sandbox.stub().resolves({ configProvider: 'filesystem' }), + getConfigProvider: sandbox.stub().resolves({ + getLocationDisplayName: sandbox.stub().resolves('/path/to/cfg'), + }), + url: sandbox.stub().callsFake(async (svc) => `http://${svc}.local`), + ...overrides, + } + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getLaunchedNaviesStub = sandbox.stub().resolves([]) + getConfigStub = sandbox.stub().resolves({ defaultNavy: 'env-1' }) + consoleLogStub = sandbox.stub(console, 'log') + + statusCli = proxyquire.noCallThru()('../status', { + '../': { getLaunchedNavies: getLaunchedNaviesStub }, + '../config': { getConfig: getConfigStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + function combinedLog() { + return consoleLogStub.getCalls().map(c => String(c.args[0] || '')).join('\n') + } + + describe('default export', function () { + + it('should render an empty table when there are no navies', async function () { + getLaunchedNaviesStub.resolves([]) + + await statusCli({}) + + expect(consoleLogStub.calledOnce).to.equal(true) + const text = stripAnsi(consoleLogStub.firstCall.args[0]) + expect(text).to.contain('NAME') + expect(text).to.contain('ACTIVE') + expect(text).to.contain('SERVICES') + expect(text).to.contain('CONFIG PROVIDER') + expect(text).to.contain('CONFIG LOCATION') + expect(text).to.contain('URL') + }) + + it('should mark a navy with at least one running service as active', async function () { + const navy = makeNavy() + navy.ps.resolves([ + { name: 'api', status: 'running' }, + { name: 'db', status: 'exited' }, + ]) + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({}) + + const text = stripAnsi(combinedLog()) + expect(text).to.contain('yes') + expect(text).to.contain('2') + }) + + it('should mark a navy with no running services as inactive', async function () { + const navy = makeNavy() + navy.ps.resolves([{ name: 'api', status: 'exited' }]) + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({}) + + const text = stripAnsi(combinedLog()) + expect(text).to.contain('no') + expect(text).to.contain('1') + }) + + it('should highlight the default navy with (default)', async function () { + const navy = makeNavy({ name: 'env-1' }) + getLaunchedNaviesStub.resolves([navy]) + getConfigStub.resolves({ defaultNavy: 'env-1' }) + + await statusCli({}) + + const text = stripAnsi(combinedLog()) + expect(text).to.contain('env-1') + expect(text).to.contain('(default)') + }) + + it('should not highlight non-default navies as default', async function () { + const navy = makeNavy({ name: 'env-2' }) + getLaunchedNaviesStub.resolves([navy]) + getConfigStub.resolves({ defaultNavy: 'env-1' }) + + await statusCli({}) + + const text = stripAnsi(combinedLog()) + expect(text).to.contain('env-2') + expect(text).not.to.contain('(default)') + }) + + it('should include the config provider name and the config location', async function () { + const navy = makeNavy() + navy.getState.resolves({ configProvider: 'filesystem' }) + navy.getConfigProvider.resolves({ + getLocationDisplayName: sandbox.stub().resolves('/etc/navy'), + }) + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({}) + + const text = stripAnsi(combinedLog()) + expect(text).to.contain('filesystem') + expect(text).to.contain('/etc/navy') + }) + + it('should call navy.url with the dimmed "service" placeholder for the table column', async function () { + const navy = makeNavy() + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({}) + + expect(navy.url.calledOnce).to.equal(true) + expect(stripAnsi(navy.url.firstCall.args[0])).to.equal('service') + }) + + it('should print JSON when opts.json is true', async function () { + const navy = makeNavy({ name: 'env-1' }) + navy.ps.resolves([{ name: 'api', status: 'running' }]) + navy.getState.resolves({ configProvider: 'filesystem' }) + navy.getConfigProvider.resolves({ + getLocationDisplayName: sandbox.stub().resolves('/cfg/location'), + }) + navy.url.resolves('http://[service].local') + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({ json: true }) + + expect(consoleLogStub.calledOnce).to.equal(true) + const parsed = JSON.parse(consoleLogStub.firstCall.args[0]) + expect(parsed).to.be.an('array').with.lengthOf(1) + expect(parsed[0]).to.deep.include({ + name: 'env-1', + isActive: true, + configProvider: 'filesystem', + configLocation: '/cfg/location', + url: 'http://[service].local', + }) + expect(parsed[0].services).to.be.an('array').with.lengthOf(1) + expect(parsed[0].state).to.deep.equal({ configProvider: 'filesystem' }) + }) + + it('should mark JSON output as inactive when no services are running', async function () { + const navy = makeNavy() + navy.ps.resolves([{ name: 'api', status: 'exited' }]) + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({ json: true }) + + const parsed = JSON.parse(consoleLogStub.firstCall.args[0]) + expect(parsed[0].isActive).to.equal(false) + }) + + it('should not call getConfig when running in json mode', async function () { + const navy = makeNavy() + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({ json: true }) + + expect(getConfigStub.called).to.equal(false) + }) + + it('should pass [service] (not chalk-dim "service") to navy.url when in json mode', async function () { + const navy = makeNavy() + getLaunchedNaviesStub.resolves([navy]) + + await statusCli({ json: true }) + + expect(navy.url.calledOnce).to.equal(true) + expect(navy.url.firstCall.args[0]).to.equal('[service]') + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/updates.js b/packages/navy/src/cli/__tests__/updates.js new file mode 100644 index 0000000..c056fc5 --- /dev/null +++ b/packages/navy/src/cli/__tests__/updates.js @@ -0,0 +1,268 @@ +/* eslint-env mocha */ + +// NOTE (potential source bug in updates.js, not locked in by these tests): +// The Promise.all body checks `if (!service || !service.raw || !service.raw.Image)` +// then immediately runs `updateStatus[service.id] = 'NO_IMAGE'`. If `service` were +// falsy the guard would let us through, but the very next assignment dereferences +// `service.id` and would throw. The `!service` part of the guard is therefore +// either dead defensive code or a latent bug. + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import readline from 'readline' +import { dots } from 'cli-spinners' +import stripAnsi from 'strip-ansi' + +describe('cli/updates', function () { + + let sandbox + let clock + let getNavyStub + let navyStub + let hasUpdateStub + let consoleLogStub + let clearLineStub + let cursorToStub + let moveCursorStub + let updatesCli + + function makeService(overrides = {}) { + return { + id: 'svc-1', + name: 'api', + image: 'navy/api:latest', + raw: { Image: 'sha256:abcdef' }, + ...overrides, + } + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + clock = sandbox.useFakeTimers() + + navyStub = { + getNavyFile: sandbox.stub().resolves({}), + ps: sandbox.stub().resolves([]), + } + getNavyStub = sandbox.stub().returns(navyStub) + hasUpdateStub = sandbox.stub().resolves(false) + consoleLogStub = sandbox.stub(console, 'log') + clearLineStub = sandbox.stub(readline, 'clearLine') + cursorToStub = sandbox.stub(readline, 'cursorTo') + moveCursorStub = sandbox.stub(readline, 'moveCursor') + + updatesCli = proxyquire.noCallThru()('../updates', { + '../': { getNavy: getNavyStub }, + '../util/has-update': hasUpdateStub, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + function combinedLog() { + return consoleLogStub.getCalls().map(c => stripAnsi(String(c.args[0] || ''))).join('\n') + } + + describe('default export', function () { + + it('should resolve the navy instance using opts.navy', async function () { + await updatesCli({ navy: 'env-1' }) + + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + }) + + it('should fetch the navy file and the running services list', async function () { + await updatesCli({ navy: 'env-1' }) + + expect(navyStub.getNavyFile.calledOnce).to.equal(true) + expect(navyStub.ps.calledOnce).to.equal(true) + }) + + it('should print the table headers in the initial draw', async function () { + navyStub.ps.resolves([]) + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('NAME') + expect(text).to.contain('IMAGE') + expect(text).to.contain('UPDATES') + }) + + it('should clear the spinner interval before resolving', async function () { + navyStub.ps.resolves([makeService()]) + + await updatesCli({ navy: 'env-1' }) + + expect(clock.countTimers()).to.equal(0) + }) + + it('should call readline cursor/clear helpers when redrawing', async function () { + navyStub.ps.resolves([makeService()]) + + await updatesCli({ navy: 'env-1' }) + + expect(clearLineStub.called).to.equal(true) + expect(cursorToStub.called).to.equal(true) + expect(moveCursorStub.called).to.equal(true) + }) + + }) + + describe('renderStatus (via default export, final draw)', function () { + + it('should mark a service as NO_IMAGE when raw is missing', async function () { + navyStub.ps.resolves([makeService({ raw: undefined })]) + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('No image for service') + expect(hasUpdateStub.called).to.equal(false) + }) + + it('should mark a service as NO_IMAGE when raw.Image is missing', async function () { + navyStub.ps.resolves([makeService({ raw: {} })]) + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('No image for service') + expect(hasUpdateStub.called).to.equal(false) + }) + + it('should mark a service as Update available when hasUpdate returns true', async function () { + navyStub.ps.resolves([makeService()]) + hasUpdateStub.resolves(true) + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('Update available') + }) + + it('should mark a service as Up to date when hasUpdate returns false', async function () { + navyStub.ps.resolves([makeService()]) + hasUpdateStub.resolves(false) + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('Up to date') + }) + + it('should mark a service as Not found when hasUpdate returns UNKNOWN_REMOTE', async function () { + navyStub.ps.resolves([makeService()]) + hasUpdateStub.resolves('UNKNOWN_REMOTE') + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('Not found') + }) + + it('should mark a service as Up to date when hasUpdate returns an unrecognised string', async function () { + navyStub.ps.resolves([makeService()]) + hasUpdateStub.resolves('SOME_OTHER_VALUE') + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('Up to date') + }) + + it('should mark a service as Internal error when hasUpdate throws', async function () { + navyStub.ps.resolves([makeService()]) + hasUpdateStub.rejects(new Error('boom')) + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('Internal error') + }) + + it('should mark a service as Internal error when hasUpdate throws an error with no stack', async function () { + navyStub.ps.resolves([makeService()]) + const errNoStack = { message: 'no stack' } + hasUpdateStub.callsFake(() => Promise.reject(errNoStack)) + + await updatesCli({ navy: 'env-1' }) + + const text = combinedLog() + expect(text).to.contain('Internal error') + }) + + it('should pass image, raw image id, and navy file through to hasUpdate', async function () { + const navyFile = { ignoreUnauthorizedRequestsForRegistries: ['r'] } + navyStub.getNavyFile.resolves(navyFile) + navyStub.ps.resolves([makeService({ + image: 'navy/api:latest', + raw: { Image: 'sha256:abc' }, + })]) + + await updatesCli({ navy: 'env-1' }) + + expect(hasUpdateStub.calledOnce).to.equal(true) + expect(hasUpdateStub.firstCall.args).to.eql([ + 'navy/api:latest', + 'sha256:abc', + navyFile, + ]) + }) + + }) + + describe('renderStatus null branch (initial Checking... state)', function () { + + it('should print Checking... in the very first draw before any update results', async function () { + let resolveHasUpdate + hasUpdateStub.callsFake(() => new Promise(resolve => { + resolveHasUpdate = resolve + })) + navyStub.ps.resolves([makeService()]) + + const cliPromise = updatesCli({ navy: 'env-1' }) + + await clock.tickAsync(0) + + const before = combinedLog() + expect(before).to.contain('Checking...') + + resolveHasUpdate(false) + await cliPromise + }) + + }) + + describe('spinner interval', function () { + + it('should advance the spinner frame on each interval tick and wrap back to 0 after frames.length ticks', async function () { + let resolveHasUpdate + hasUpdateStub.callsFake(() => new Promise(resolve => { + resolveHasUpdate = resolve + })) + navyStub.ps.resolves([makeService()]) + + const cliPromise = updatesCli({ navy: 'env-1' }) + + await clock.tickAsync(0) + + const drawsBefore = consoleLogStub.callCount + + await clock.tickAsync(dots.interval * (dots.frames.length + 1)) + + expect(consoleLogStub.callCount).to.be.greaterThan(drawsBefore) + + resolveHasUpdate(false) + await cliPromise + + expect(clock.countTimers()).to.equal(0) + }) + + }) + +}) diff --git a/packages/navy/src/cli/__tests__/wait-for-healthy.js b/packages/navy/src/cli/__tests__/wait-for-healthy.js new file mode 100644 index 0000000..79093a2 --- /dev/null +++ b/packages/navy/src/cli/__tests__/wait-for-healthy.js @@ -0,0 +1,151 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/wait-for-healthy', function () { + + let sandbox + let getNavyStub + let navyStub + let readlineStub + let consoleLogStub + let originalIsTTY + let waitForHealthyCli + let clock + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + name: 'env-1', + waitForHealthy: sandbox.stub().resolves(), + } + getNavyStub = sandbox.stub().returns(navyStub) + + readlineStub = { + clearLine: sandbox.stub(), + cursorTo: sandbox.stub(), + moveCursor: sandbox.stub(), + } + + consoleLogStub = sandbox.stub(console, 'log') + + originalIsTTY = process.stdout.isTTY + + waitForHealthyCli = proxyquire.noCallThru()('../wait-for-healthy', { + '../': { getNavy: getNavyStub }, + readline: readlineStub, + }) + }) + + afterEach(function () { + process.stdout.isTTY = originalIsTTY + if (clock) { + clock.restore() + clock = null + } + sandbox.restore() + }) + + describe('default export', function () { + + describe('non-TTY mode', function () { + + beforeEach(function () { + process.stdout.isTTY = false + }) + + it('should call waitForHealthy with undefined when services are empty', async function () { + await waitForHealthyCli([], { navy: 'env-1' }) + + expect(navyStub.waitForHealthy.calledOnce).to.equal(true) + expect(navyStub.waitForHealthy.firstCall.args[0]).to.equal(undefined) + }) + + it('should call waitForHealthy with the supplied services', async function () { + await waitForHealthyCli(['web', 'api'], { navy: 'env-1' }) + + expect(navyStub.waitForHealthy.firstCall.args[0]).to.eql(['web', 'api']) + }) + + it('should log "Now available" after the wait completes', async function () { + await waitForHealthyCli([], { navy: 'env-1' }) + + expect(consoleLogStub.calledWith('Now available')).to.equal(true) + }) + + }) + + describe('TTY mode', function () { + + beforeEach(function () { + process.stdout.isTTY = true + clock = sinon.useFakeTimers() + }) + + it('should call waitForHealthy with a callback for service health updates', async function () { + const promise = waitForHealthyCli([], { navy: 'env-1' }) + + await promise + + expect(navyStub.waitForHealthy.calledOnce).to.equal(true) + expect(navyStub.waitForHealthy.firstCall.args[1]).to.be.a('function') + }) + + it('should print "Waiting" while no health status is reported', async function () { + await waitForHealthyCli([], { navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Waiting') + }) + + it('should render a checkmark for healthy services and spinner for unhealthy', async function () { + navyStub.waitForHealthy.callsFake(async (services, cb) => { + cb([ + { service: 'web', health: 'healthy' }, + { service: 'api', health: 'starting' }, + ]) + }) + + await waitForHealthyCli([], { navy: 'env-1' }) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('web') + expect(printed).to.contain('api') + }) + + it('should advance the spinner frame and redraw on the timer interval', async function () { + navyStub.waitForHealthy.callsFake(() => new Promise(() => {})) + + const promise = waitForHealthyCli([], { navy: 'env-1' }) + + clock.tick(1000) + + expect(readlineStub.clearLine.called).to.equal(true) + + promise.catch(() => {}) + }) + + it('should wrap spinner index back to zero when reaching the end of frames', async function () { + navyStub.waitForHealthy.callsFake(() => new Promise(() => {})) + + waitForHealthyCli([], { navy: 'env-1' }).catch(() => {}) + + clock.tick(10000) + + expect(readlineStub.clearLine.called).to.equal(true) + }) + + it('should pass services through to waitForHealthy', async function () { + await waitForHealthyCli(['web'], { navy: 'env-1' }) + + expect(navyStub.waitForHealthy.firstCall.args[0]).to.eql(['web']) + }) + + }) + + }) + +}) diff --git a/packages/navy/src/cli/config/__tests__/index.js b/packages/navy/src/cli/config/__tests__/index.js new file mode 100644 index 0000000..c71923c --- /dev/null +++ b/packages/navy/src/cli/config/__tests__/index.js @@ -0,0 +1,305 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../../errors' + +describe('cli/config/index', function () { + + let sandbox + let getConfigStub + let setConfigStub + let reconfigureAllNaviesStub + let consoleLogStub + let consoleErrorStub + let processOnStub + let actions + let program + let mod + + function loadModule() { + actions = {} + + function commandFactory() { + const builder = { + description() { return builder }, + action(handler) { + builder._lastAction = handler + return builder + }, + } + return builder + } + + program = { + _commands: {}, + command(spec) { + const name = spec.split(' ')[0] + const builder = commandFactory() + const origAction = builder.action.bind(builder) + builder.action = handler => { + actions[name] = handler + return origAction(handler) + } + return builder + }, + parse: sandbox.stub(), + help: sandbox.stub(), + args: ['placeholder'], + } + + mod = proxyquire.noCallThru()('../index', { + commander: { program }, + '../../config': { getConfig: getConfigStub, setConfig: setConfigStub }, + '../../errors': { NavyError }, + '../util/reconfigure': { reconfigureAllNavies: reconfigureAllNaviesStub }, + }) + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getConfigStub = sandbox.stub().resolves({}) + setConfigStub = sandbox.stub().resolves() + reconfigureAllNaviesStub = sandbox.stub().resolves() + consoleLogStub = sandbox.stub(console, 'log') + consoleErrorStub = sandbox.stub(console, 'error') + processOnStub = sandbox.stub(process, 'on') + + loadModule() + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('reconfigureIfNecessary', function () { + + it('should call reconfigureAllNavies for externalIP', async function () { + await mod.reconfigureIfNecessary('externalIP') + + expect(reconfigureAllNaviesStub.calledOnce).to.equal(true) + }) + + it('should not call reconfigureAllNavies for unrelated config props', async function () { + await mod.reconfigureIfNecessary('defaultNavy') + + expect(reconfigureAllNaviesStub.called).to.equal(false) + }) + + }) + + describe('module side effects', function () { + + it('should register a process unhandledRejection handler', function () { + expect(processOnStub.calledWith('unhandledRejection')).to.equal(true) + }) + + it('should call program.parse with process.argv', function () { + expect(program.parse.calledOnce).to.equal(true) + expect(program.parse.firstCall.args[0]).to.equal(process.argv) + }) + + it('should not call help when args are present', function () { + expect(program.help.called).to.equal(false) + }) + + it('should call help when args are empty', function () { + sandbox.restore() + sandbox = sinon.createSandbox() + getConfigStub = sandbox.stub().resolves({}) + setConfigStub = sandbox.stub().resolves() + reconfigureAllNaviesStub = sandbox.stub().resolves() + sandbox.stub(console, 'log') + sandbox.stub(console, 'error') + sandbox.stub(process, 'on') + + actions = {} + program = { + command(spec) { + const name = spec.split(' ')[0] + const builder = { + description() { return builder }, + action(handler) { + actions[name] = handler + return builder + }, + } + return builder + }, + parse: sandbox.stub(), + help: sandbox.stub(), + args: [], + } + + proxyquire.noCallThru()('../index', { + commander: { program }, + '../../config': { getConfig: getConfigStub, setConfig: setConfigStub }, + '../../errors': { NavyError }, + '../util/reconfigure': { reconfigureAllNavies: reconfigureAllNaviesStub }, + }) + + expect(program.help.calledOnce).to.equal(true) + }) + + describe('unhandledRejection handler', function () { + + it('should call prettyPrint on a NavyError', function () { + const handler = processOnStub.firstCall.args[1] + const err = new NavyError('boom') + const prettyPrintStub = sandbox.stub(err, 'prettyPrint') + + handler(err) + + expect(prettyPrintStub.calledOnce).to.equal(true) + }) + + it('should log the stack of a generic error', function () { + const handler = processOnStub.firstCall.args[1] + const err = new Error('boom') + + handler(err) + + expect(consoleErrorStub.calledWith(err.stack)).to.equal(true) + }) + + }) + + }) + + describe('set command', function () { + + it('should throw a NavyError for an unknown key', async function () { + let caught + try { + await actions.set('not-a-key', 'value') + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('Invalid config key') + expect(setConfigStub.called).to.equal(false) + }) + + it('should map default-navy and call setConfig with merged config', async function () { + getConfigStub.resolves({ existing: 'value' }) + + await actions.set('default-navy', 'dev') + + expect(setConfigStub.calledOnce).to.equal(true) + expect(setConfigStub.firstCall.args[0]).to.eql({ existing: 'value', defaultNavy: 'dev' }) + }) + + it('should reconfigure all navies when externalIP changes', async function () { + await actions.set('external-ip', '10.0.0.1') + + expect(reconfigureAllNaviesStub.calledOnce).to.equal(true) + }) + + it('should not reconfigure when default-navy changes', async function () { + await actions.set('default-navy', 'dev') + + expect(reconfigureAllNaviesStub.called).to.equal(false) + }) + + }) + + describe('get command', function () { + + it('should throw a NavyError for an unknown key', async function () { + let caught + try { + await actions.get('not-a-key') + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + }) + + it('should print the mapped config value', async function () { + getConfigStub.resolves({ defaultNavy: 'dev' }) + + await actions.get('default-navy') + + expect(consoleLogStub.calledWith('dev')).to.equal(true) + }) + + }) + + describe('rm command', function () { + + it('should throw a NavyError for an unknown key', async function () { + let caught + try { + await actions.rm('not-a-key') + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(setConfigStub.called).to.equal(false) + }) + + it('should set the mapped property to null', async function () { + getConfigStub.resolves({ defaultNavy: 'dev' }) + + await actions.rm('default-navy') + + expect(setConfigStub.firstCall.args[0]).to.eql({ defaultNavy: null }) + }) + + it('should reconfigure all navies when externalIP is removed', async function () { + await actions.rm('external-ip') + + expect(reconfigureAllNaviesStub.calledOnce).to.equal(true) + }) + + it('should not reconfigure when default-navy is removed', async function () { + await actions.rm('default-navy') + + expect(reconfigureAllNaviesStub.called).to.equal(false) + }) + + }) + + describe('ls command', function () { + + it('should print one line per known key with values', async function () { + getConfigStub.resolves({ defaultNavy: 'dev', externalIP: '10.0.0.1', tlsRootCaDir: null }) + + await actions.ls() + + const printed = consoleLogStub.firstCall.args[0] + expect(printed).to.contain('default-navy=dev') + expect(printed).to.contain('external-ip=10.0.0.1') + expect(printed).to.contain('tlsCa-dir=null') + }) + + it('should print null for missing keys', async function () { + getConfigStub.resolves({}) + + await actions.ls() + + const printed = consoleLogStub.firstCall.args[0] + expect(printed).to.contain('default-navy=null') + }) + + }) + + describe('json command', function () { + + it('should print the full config as pretty JSON', async function () { + getConfigStub.resolves({ a: 1, b: 'two' }) + + await actions.json() + + expect(consoleLogStub.calledOnce).to.equal(true) + expect(consoleLogStub.firstCall.args[0]).to.equal(JSON.stringify({ a: 1, b: 'two' }, null, 2)) + }) + + }) + +}) diff --git a/packages/navy/src/cli/config/__tests__/wrapper.js b/packages/navy/src/cli/config/__tests__/wrapper.js new file mode 100644 index 0000000..38ff965 --- /dev/null +++ b/packages/navy/src/cli/config/__tests__/wrapper.js @@ -0,0 +1,64 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/config/wrapper', function () { + + let sandbox + let execSyncStub + let originalArgv + let wrapperCli + + beforeEach(function () { + sandbox = sinon.createSandbox() + execSyncStub = sandbox.stub() + + originalArgv = process.argv + + wrapperCli = proxyquire.noCallThru()('../wrapper', { + child_process: { execSync: execSyncStub }, + }) + }) + + afterEach(function () { + process.argv = originalArgv + sandbox.restore() + }) + + describe('default export', function () { + + it('should invoke navy-config.js via execSync with stdio inherit', async function () { + process.argv = ['node', 'navy', 'config'] + + await wrapperCli('env-1') + + expect(execSyncStub.calledOnce).to.equal(true) + const command = execSyncStub.firstCall.args[0] + expect(command).to.contain('navy-config.js') + const opts = execSyncStub.firstCall.args[1] + expect(opts).to.eql({ stdio: 'inherit' }) + }) + + it('should pass through any extra command-line args from process.argv', async function () { + process.argv = ['node', 'navy', 'config', 'set', 'default-navy', 'dev'] + + await wrapperCli('env-1') + + const command = execSyncStub.firstCall.args[0] + expect(command).to.contain('set default-navy dev') + }) + + it('should invoke with no extra args when only the wrapper command is supplied', async function () { + process.argv = ['node', 'navy', 'config'] + + await wrapperCli('env-1') + + const command = execSyncStub.firstCall.args[0] + expect(command.endsWith('navy-config.js ')).to.equal(true) + }) + + }) + +}) diff --git a/packages/navy/src/cli/config/index.js b/packages/navy/src/cli/config/index.js index 8f66fc6..3cdb28d 100644 --- a/packages/navy/src/cli/config/index.js +++ b/packages/navy/src/cli/config/index.js @@ -1,11 +1,11 @@ /* @flow */ -import program from 'commander' -import {getConfig, setConfig} from '../../config' -import {NavyError} from '../../errors' -import {reconfigureAllNavies} from '../util/reconfigure' +import { program } from 'commander' +import { getConfig, setConfig } from '../../config' +import { NavyError } from '../../errors' +import { reconfigureAllNavies } from '../util/reconfigure' -const NAME_MAP = { +const NAME_MAP: {[string]: string} = { 'default-navy': 'defaultNavy', 'external-ip': 'externalIP', 'tlsCa-dir': 'tlsRootCaDir', @@ -33,10 +33,9 @@ program throw new NavyError('Invalid config key: ' + key) } - await setConfig({ - ...(await getConfig()), - [configProp]: value, - }) + const updated = { ...(await getConfig()) } + updated[configProp] = value + await setConfig(updated) await reconfigureIfNecessary(configProp) }) @@ -64,10 +63,9 @@ program throw new NavyError('Invalid config key: ' + key) } - await setConfig({ - ...(await getConfig()), - [configProp]: null, - }) + const updated = { ...(await getConfig()) } + updated[configProp] = null + await setConfig(updated) await reconfigureIfNecessary(configProp) }) diff --git a/packages/navy/src/cli/config/wrapper.js b/packages/navy/src/cli/config/wrapper.js index d988a31..8abd5ef 100644 --- a/packages/navy/src/cli/config/wrapper.js +++ b/packages/navy/src/cli/config/wrapper.js @@ -1,9 +1,8 @@ /* @flow */ -import {execSync} from 'child_process' +import { execSync } from 'child_process' import path from 'path' export default async function (navy: string): Promise { - // $FlowIgnore flow bug with execSync execSync(path.join(__dirname, '../../../bin/navy-config.js') + ' ' + process.argv.slice(3).join(' '), { stdio: 'inherit' }) } diff --git a/packages/navy/src/cli/develop.js b/packages/navy/src/cli/develop.js index 556fd6a..b741571 100644 --- a/packages/navy/src/cli/develop.js +++ b/packages/navy/src/cli/develop.js @@ -4,8 +4,8 @@ import path from 'path' import chalk from 'chalk' import invariant from 'invariant' -import {getNavy} from '../' -import {NavyError} from '../errors' +import { getNavy } from '../' +import { NavyError } from '../errors' import docker from '../util/docker-client' import getNavyRc from '../util/navyrc' @@ -38,13 +38,14 @@ export default async function (service: string, opts: Object): Promise { ) const state = (await navy.getState()) || {} + const stateServices: {[string]: Object} = state.services || {} await navy.saveState({ ...state, services: { - ...state.services, + ...stateServices, [service]: { - ...(state.services || {})[service], + ...stateServices[service], _develop: { mounts, command: navyRc.develop.command, @@ -69,7 +70,7 @@ export default async function (service: string, opts: Object): Promise { const containerId = container.id const containerObj = docker.getContainer(containerId) - containerObj.attach({stream: true, stdout: true, stderr: true}) + containerObj.attach({ stream: true, stdout: true, stderr: true }) .then(stream => containerObj.modem.demuxStream(stream, process.stdout, process.stderr) ) diff --git a/packages/navy/src/cli/doctor/__tests__/clean-compose-files.js b/packages/navy/src/cli/doctor/__tests__/clean-compose-files.js new file mode 100644 index 0000000..e87a9cb --- /dev/null +++ b/packages/navy/src/cli/doctor/__tests__/clean-compose-files.js @@ -0,0 +1,81 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/doctor/clean-compose-files', function () { + + let sandbox + let getLaunchedNavyNamesStub + let startStub + let pathToNavyStub + let normaliseNavyNameStub + let rmStub + let cleanComposeFiles + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getLaunchedNavyNamesStub = sandbox.stub().resolves([]) + startStub = sandbox.stub() + pathToNavyStub = sandbox.stub().callsFake(name => `/state/${name}`) + normaliseNavyNameStub = sandbox.stub().callsFake(name => name.toLowerCase()) + rmStub = sandbox.stub().resolves() + + cleanComposeFiles = proxyquire.noCallThru()('../clean-compose-files', { + '../../': { getLaunchedNavyNames: getLaunchedNavyNamesStub }, + './util': { start: startStub }, + '../../navy/state': { pathToNavy: pathToNavyStub }, + '../../navy/util': { normaliseNavyName: normaliseNavyNameStub }, + fs: { promises: { rm: rmStub } }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should print a starting message', async function () { + await cleanComposeFiles() + + expect(startStub.calledOnce).to.equal(true) + expect(startStub.firstCall.args[0]).to.contain('Cleaning') + }) + + it('should not call rm when there are no launched navies', async function () { + getLaunchedNavyNamesStub.resolves([]) + + await cleanComposeFiles() + + expect(rmStub.called).to.equal(false) + }) + + it('should remove docker-compose.tmp.yml from each launched navy path', async function () { + getLaunchedNavyNamesStub.resolves(['env-1', 'Dev']) + + await cleanComposeFiles() + + expect(rmStub.callCount).to.equal(2) + const paths = rmStub.getCalls().map(c => c.args[0]) + expect(paths).to.include('/state/env-1/docker-compose.tmp.yml') + expect(paths).to.include('/state/dev/docker-compose.tmp.yml') + + rmStub.getCalls().forEach(call => { + expect(call.args[1]).to.eql({ recursive: true, force: true }) + }) + }) + + it('should normalise navy names when resolving paths', async function () { + getLaunchedNavyNamesStub.resolves(['MyEnv']) + + await cleanComposeFiles() + + expect(normaliseNavyNameStub.calledWith('MyEnv')).to.equal(true) + }) + + }) + +}) diff --git a/packages/navy/src/cli/doctor/__tests__/index.js b/packages/navy/src/cli/doctor/__tests__/index.js new file mode 100644 index 0000000..e98db6a --- /dev/null +++ b/packages/navy/src/cli/doctor/__tests__/index.js @@ -0,0 +1,83 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/doctor/index', function () { + + let sandbox + let cleanComposeStub + let invalidStateStub + let invalidComposeConfigStub + let consoleLogStub + let doctorCli + + function loadModule() { + doctorCli = proxyquire.noCallThru()('../index', { + './clean-compose-files': cleanComposeStub, + './invalid-state': invalidStateStub, + './invalid-compose-config': invalidComposeConfigStub, + }) + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + cleanComposeStub = sandbox.stub().resolves() + invalidStateStub = sandbox.stub().resolves() + invalidComposeConfigStub = sandbox.stub().resolves() + consoleLogStub = sandbox.stub(console, 'log') + + loadModule() + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should run all checks in order', async function () { + await doctorCli() + + expect(cleanComposeStub.calledOnce).to.equal(true) + expect(invalidStateStub.calledOnce).to.equal(true) + expect(invalidComposeConfigStub.calledOnce).to.equal(true) + expect(cleanComposeStub.calledBefore(invalidStateStub)).to.equal(true) + expect(invalidStateStub.calledBefore(invalidComposeConfigStub)).to.equal(true) + }) + + it('should print a success message when all checks pass', async function () { + await doctorCli() + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Finished tests') + }) + + it('should print error stacks and a warning when checks fail', async function () { + const error1 = new Error('boom1') + const error2 = new Error('boom2') + cleanComposeStub.rejects(error1) + invalidStateStub.rejects(error2) + + await doctorCli() + + const printedArgs = consoleLogStub.getCalls().map(c => c.args[0] || '') + const all = printedArgs.join('\n') + expect(all).to.contain('There were some issues') + expect(printedArgs.some(arg => typeof arg === 'string' && arg.includes(error1.stack))).to.equal(true) + expect(printedArgs.some(arg => typeof arg === 'string' && arg.includes(error2.stack))).to.equal(true) + }) + + it('should run all checks even when an early one throws', async function () { + cleanComposeStub.rejects(new Error('boom')) + + await doctorCli() + + expect(invalidStateStub.calledOnce).to.equal(true) + expect(invalidComposeConfigStub.calledOnce).to.equal(true) + }) + + }) + +}) diff --git a/packages/navy/src/cli/doctor/__tests__/invalid-compose-config.js b/packages/navy/src/cli/doctor/__tests__/invalid-compose-config.js new file mode 100644 index 0000000..0fb97ab --- /dev/null +++ b/packages/navy/src/cli/doctor/__tests__/invalid-compose-config.js @@ -0,0 +1,111 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/doctor/invalid-compose-config', function () { + + let sandbox + let getLaunchedNaviesStub + let startStub + let fixStub + let catchInvariantStub + let invalidComposeConfig + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getLaunchedNaviesStub = sandbox.stub().resolves([]) + startStub = sandbox.stub() + fixStub = sandbox.stub().callsFake(async (msg, name, callback) => callback()) + catchInvariantStub = sandbox.stub().callsFake(async (code, fn, catchCallback) => { + try { + await fn() + } catch (err) { + if (err.name === 'Invariant Violation' && err.message.indexOf(code) === 0) { + await catchCallback() + } + } + }) + + invalidComposeConfig = proxyquire.noCallThru()('../invalid-compose-config', { + '../../': { getLaunchedNavies: getLaunchedNaviesStub }, + './util': { start: startStub, fix: fixStub, catchInvariant: catchInvariantStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should log a starting message', async function () { + await invalidComposeConfig() + + expect(startStub.calledOnce).to.equal(true) + expect(startStub.firstCall.args[0]).to.contain('compose') + }) + + it('should do nothing further when there are no launched navies', async function () { + getLaunchedNaviesStub.resolves([]) + + await invalidComposeConfig() + + expect(catchInvariantStub.called).to.equal(false) + expect(fixStub.called).to.equal(false) + }) + + it('should call safeGetDriver().getConfig() for each navy', async function () { + const driver = { getConfig: sandbox.stub().resolves({}) } + const navy = { + name: 'env-1', + safeGetDriver: sandbox.stub().resolves(driver), + delete: sandbox.stub().resolves(), + } + getLaunchedNaviesStub.resolves([navy]) + + await invalidComposeConfig() + + expect(navy.safeGetDriver.calledOnce).to.equal(true) + expect(driver.getConfig.calledOnce).to.equal(true) + }) + + it('should remove a navy whose driver throws NO_DOCKER_COMPOSE_FILE invariant', async function () { + const err = new Error('NO_DOCKER_COMPOSE_FILE: not found') + err.name = 'Invariant Violation' + const driver = { getConfig: sandbox.stub().rejects(err) } + const navy = { + name: 'env-1', + safeGetDriver: sandbox.stub().resolves(driver), + delete: sandbox.stub().resolves(), + } + getLaunchedNaviesStub.resolves([navy]) + + await invalidComposeConfig() + + expect(fixStub.calledOnce).to.equal(true) + expect(navy.delete.calledOnce).to.equal(true) + }) + + it('should not call delete when the driver throws a different invariant', async function () { + const err = new Error('SOMETHING_ELSE: nope') + err.name = 'Invariant Violation' + const driver = { getConfig: sandbox.stub().rejects(err) } + const navy = { + name: 'env-1', + safeGetDriver: sandbox.stub().resolves(driver), + delete: sandbox.stub().resolves(), + } + getLaunchedNaviesStub.resolves([navy]) + + await invalidComposeConfig() + + expect(fixStub.called).to.equal(false) + expect(navy.delete.called).to.equal(false) + }) + + }) + +}) diff --git a/packages/navy/src/cli/doctor/__tests__/invalid-state.js b/packages/navy/src/cli/doctor/__tests__/invalid-state.js new file mode 100644 index 0000000..b55512e --- /dev/null +++ b/packages/navy/src/cli/doctor/__tests__/invalid-state.js @@ -0,0 +1,91 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/doctor/invalid-state', function () { + + let sandbox + let getLaunchedNaviesStub + let startStub + let fixStub + let invalidState + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getLaunchedNaviesStub = sandbox.stub().resolves([]) + startStub = sandbox.stub() + fixStub = sandbox.stub().callsFake(async (msg, name, callback) => callback()) + + invalidState = proxyquire.noCallThru()('../invalid-state', { + '../../': { getLaunchedNavies: getLaunchedNaviesStub }, + './util': { start: startStub, fix: fixStub }, + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('default export', function () { + + it('should log a starting message', async function () { + await invalidState() + + expect(startStub.calledOnce).to.equal(true) + expect(startStub.firstCall.args[0]).to.contain('dangling') + }) + + it('should remove a navy that has no config provider', async function () { + const navy = { + name: 'env-1', + getConfigProvider: sandbox.stub().resolves(null), + delete: sandbox.stub().resolves(), + } + getLaunchedNaviesStub.resolves([navy]) + + await invalidState() + + expect(fixStub.calledOnce).to.equal(true) + expect(fixStub.firstCall.args[0]).to.contain('without config provider') + expect(navy.delete.calledOnce).to.equal(true) + }) + + it('should destroy a dangling navy whose config is invalid', async function () { + const configProvider = { isDangling: sandbox.stub().resolves(true) } + const navy = { + name: 'env-1', + getConfigProvider: sandbox.stub().resolves(configProvider), + destroy: sandbox.stub().resolves(), + } + getLaunchedNaviesStub.resolves([navy]) + + await invalidState() + + expect(fixStub.calledOnce).to.equal(true) + expect(fixStub.firstCall.args[0]).to.contain('dangling Navy') + expect(navy.destroy.calledOnce).to.equal(true) + }) + + it('should leave alone a navy whose config provider exists and is not dangling', async function () { + const configProvider = { isDangling: sandbox.stub().resolves(false) } + const navy = { + name: 'env-1', + getConfigProvider: sandbox.stub().resolves(configProvider), + destroy: sandbox.stub().resolves(), + delete: sandbox.stub().resolves(), + } + getLaunchedNaviesStub.resolves([navy]) + + await invalidState() + + expect(fixStub.called).to.equal(false) + expect(navy.destroy.called).to.equal(false) + expect(navy.delete.called).to.equal(false) + }) + + }) + +}) diff --git a/packages/navy/src/cli/doctor/__tests__/util.js b/packages/navy/src/cli/doctor/__tests__/util.js new file mode 100644 index 0000000..88135db --- /dev/null +++ b/packages/navy/src/cli/doctor/__tests__/util.js @@ -0,0 +1,116 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' + +import { fix, start, catchInvariant } from '../util' + +describe('cli/doctor/util', function () { + + let sandbox + let consoleLogStub + + beforeEach(function () { + sandbox = sinon.createSandbox() + consoleLogStub = sandbox.stub(console, 'log') + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('fix', function () { + + it('should throw an invariant violation when no callback is provided', async function () { + let caught + try { + await fix('a message') + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.contain('DOCTOR_FIX_NO_PARAMS') + }) + + it('should print the formatted message and call the callback', async function () { + const callback = sandbox.stub().resolves() + + await fix('Found %s, removing', 'env-1', callback) + + expect(consoleLogStub.calledOnce).to.equal(true) + const printed = consoleLogStub.firstCall.args[0] + expect(printed).to.contain('Found env-1, removing') + expect(callback.calledOnce).to.equal(true) + }) + + it('should await the callback before resolving', async function () { + let resolved = false + const callback = sandbox.stub().callsFake(() => new Promise(resolve => { + setImmediate(() => { + resolved = true + resolve() + }) + })) + + await fix('msg', callback) + + expect(resolved).to.equal(true) + }) + + }) + + describe('start', function () { + + it('should log a dimmed message with arrow prefix', function () { + start('Doing thing') + + expect(consoleLogStub.calledOnce).to.equal(true) + const printed = consoleLogStub.getCalls().map(c => c.args.join(' ')).join(' ') + expect(printed).to.contain('----->') + expect(printed).to.contain('Doing thing') + }) + + }) + + describe('catchInvariant', function () { + + it('should call the catch callback when fn throws an Invariant Violation matching the code', async function () { + const catchCallback = sandbox.stub().resolves() + const err = new Error('MY_CODE: failure happened') + err.name = 'Invariant Violation' + + await catchInvariant('MY_CODE', async () => { throw err }, catchCallback) + + expect(catchCallback.calledOnce).to.equal(true) + }) + + it('should not call the catch callback when fn throws a non-invariant error', async function () { + const catchCallback = sandbox.stub().resolves() + + await catchInvariant('MY_CODE', async () => { throw new Error('some other error') }, catchCallback) + + expect(catchCallback.called).to.equal(false) + }) + + it('should not call the catch callback when invariant code does not match', async function () { + const catchCallback = sandbox.stub().resolves() + const err = new Error('OTHER_CODE: failure') + err.name = 'Invariant Violation' + + await catchInvariant('MY_CODE', async () => { throw err }, catchCallback) + + expect(catchCallback.called).to.equal(false) + }) + + it('should not call the catch callback when fn resolves without throwing', async function () { + const catchCallback = sandbox.stub().resolves() + + await catchInvariant('MY_CODE', async () => undefined, catchCallback) + + expect(catchCallback.called).to.equal(false) + }) + + }) + +}) diff --git a/packages/navy/src/cli/doctor/clean-compose-files.js b/packages/navy/src/cli/doctor/clean-compose-files.js index bb9f803..b07028d 100644 --- a/packages/navy/src/cli/doctor/clean-compose-files.js +++ b/packages/navy/src/cli/doctor/clean-compose-files.js @@ -1,22 +1,20 @@ /* @flow */ -import bluebird from 'bluebird' import path from 'path' +import { promises as fsp } from 'fs' -import {getLaunchedNavyNames} from '../../' -import {start} from './util' -import {pathToNavy} from '../../navy/state' -import {normaliseNavyName} from '../../navy/util' +import { getLaunchedNavyNames } from '../../' +import { start } from './util' +import { pathToNavy } from '../../navy/state' +import { normaliseNavyName } from '../../navy/util' export default async function () { - const rimraf = bluebird.promisify(require('rimraf')) - start('Cleaning temporary Docker Compose files') const navyNames = await getLaunchedNavyNames() await Promise.all(navyNames.map(async navyName => { const navyPath = pathToNavy(normaliseNavyName(navyName)) - await rimraf(path.join(navyPath, 'docker-compose.tmp.yml')) + await fsp.rm(path.join(navyPath, 'docker-compose.tmp.yml'), { recursive: true, force: true }) })) } diff --git a/packages/navy/src/cli/doctor/index.js b/packages/navy/src/cli/doctor/index.js index 780c3e8..d421131 100644 --- a/packages/navy/src/cli/doctor/index.js +++ b/packages/navy/src/cli/doctor/index.js @@ -5,7 +5,7 @@ import cleanTemporaryComposeFiles from './clean-compose-files' import checkForInvalidState from './invalid-state' import checkForInvalidComposeConfig from './invalid-compose-config' -async function run(fns) { +async function run(fns: Array<() => mixed>) { const errors = [] for (const fn of fns) { diff --git a/packages/navy/src/cli/doctor/invalid-compose-config.js b/packages/navy/src/cli/doctor/invalid-compose-config.js index 19aaa9e..b0d95e5 100644 --- a/packages/navy/src/cli/doctor/invalid-compose-config.js +++ b/packages/navy/src/cli/doctor/invalid-compose-config.js @@ -1,7 +1,7 @@ /* @flow */ -import {getLaunchedNavies} from '../../' -import {start, fix, catchInvariant} from './util' +import { getLaunchedNavies } from '../../' +import { start, fix, catchInvariant } from './util' export default async function () { start('Checking for Navies with invalid/no compose config') diff --git a/packages/navy/src/cli/doctor/invalid-state.js b/packages/navy/src/cli/doctor/invalid-state.js index 4c4faf8..943fa25 100644 --- a/packages/navy/src/cli/doctor/invalid-state.js +++ b/packages/navy/src/cli/doctor/invalid-state.js @@ -1,7 +1,7 @@ /* @flow */ -import {getLaunchedNavies} from '../../' -import {start, fix} from './util' +import { getLaunchedNavies } from '../../' +import { start, fix } from './util' export default async function () { start('Checking for dangling Navies') diff --git a/packages/navy/src/cli/external-ip.js b/packages/navy/src/cli/external-ip.js index e833e60..a2dddb6 100644 --- a/packages/navy/src/cli/external-ip.js +++ b/packages/navy/src/cli/external-ip.js @@ -1,5 +1,5 @@ -import {getConfig} from '../config' -import {getExternalIP} from '../util/external-ip' +import { getConfig } from '../config' +import { getExternalIP } from '../util/external-ip' export default async () => { const config = await getConfig() diff --git a/packages/navy/src/cli/health.js b/packages/navy/src/cli/health.js index 4c5d276..bca91f4 100644 --- a/packages/navy/src/cli/health.js +++ b/packages/navy/src/cli/health.js @@ -2,10 +2,10 @@ import chalk from 'chalk' -import {getNavy} from '../' +import { getNavy } from '../' import table from '../util/table' -function getStatus(service, state) { +function getStatus(service: Object, state: ?Object) { const health = service.raw && service.raw.State.Health if (!health) { @@ -19,7 +19,7 @@ function getStatus(service, state) { return statusString } -function getHistory(service, state) { +function getHistory(service: Object, state: ?Object) { const health = service.raw && service.raw.State.Health if (!health) { diff --git a/packages/navy/src/cli/https.js b/packages/navy/src/cli/https.js index c423071..b12ddb1 100644 --- a/packages/navy/src/cli/https.js +++ b/packages/navy/src/cli/https.js @@ -1,21 +1,26 @@ /* @flow */ import chalk from 'chalk' -import {NavyError} from '../errors' -import {getNavy} from '../navy' -import {getConfig, getConfigDir, DEFAULT_TLS_ROOT_CA_DIR} from '../config' -import {reconfigureHTTPProxy} from '../http-proxy' -import {createCert, generateRootCa, removeCert} from '../util/https' +import { NavyError } from '../errors' +import { getNavy } from '../navy' +import { getConfig, getConfigDir, DEFAULT_TLS_ROOT_CA_DIR } from '../config' +import { reconfigureHTTPProxy } from '../http-proxy' +import { createCert, generateRootCa, removeCert } from '../util/https' import fs from 'fs' -export default async function (services: string, opts: Object): Promise { +export default async function (services: Array, opts: Object): Promise { const tlsRootCaDir = getConfig().tlsRootCaDir || DEFAULT_TLS_ROOT_CA_DIR const configDir = getConfigDir() if (opts.disable) { await removeCert(opts) - await reconfigureHTTPProxy({restart: true}) + + // Guard isInitialised so `--disable` still works when the navy has + // never been launched (otherwise getNavyFile throws). + const navy = await getNavy(opts.navy) + const navyFile = (await navy.isInitialised()) ? await navy.getNavyFile() : undefined + await reconfigureHTTPProxy({ restart: true, navyFile }) console.log() console.log(chalk.green(`✅ HTTPS for service ${opts.disable} is now disabled`)) @@ -51,7 +56,7 @@ export default async function (services: string, opts: Object): Promise { } const serviceUrl = await navy.url(service) try { - await createCert({serviceUrl}) + await createCert({ serviceUrl }) httpsReadyServices.push(service) } catch (error) { console.log(error) @@ -59,7 +64,7 @@ export default async function (services: string, opts: Object): Promise { } } - await reconfigureHTTPProxy({restart: true}) + await reconfigureHTTPProxy({ restart: true, navyFile: await navy.getNavyFile() }) console.log() console.log(chalk.green(`✅ Service(s) ${httpsReadyServices.join(', ')} now accessible via HTTPS🔒`)) diff --git a/packages/navy/src/cli/import.js b/packages/navy/src/cli/import.js index 3d6bb6c..d9e2fe0 100644 --- a/packages/navy/src/cli/import.js +++ b/packages/navy/src/cli/import.js @@ -4,9 +4,9 @@ import path from 'path' import chalk from 'chalk' import fs from '../util/fs' -import {getNavy} from '../' -import {getImportOptionsForCLI} from '../config-provider' -import {importNavy} from './util' +import { getNavy } from '../' +import { getImportOptionsForCLI } from '../config-provider' +import { importNavy } from './util' export default async function (opts: Object): Promise { const navy = getNavy(opts.navy) diff --git a/packages/navy/src/cli/index.js b/packages/navy/src/cli/index.js index 23862bb..7d6a73f 100644 --- a/packages/navy/src/cli/index.js +++ b/packages/navy/src/cli/index.js @@ -2,7 +2,7 @@ import pkg from '../../package.json' import program from './program' -import {NavyError} from '../errors' +import { NavyError } from '../errors' const debug = require('debug')('navy:cli') diff --git a/packages/navy/src/cli/lan-ip.js b/packages/navy/src/cli/lan-ip.js index f1f449a..54dfccf 100644 --- a/packages/navy/src/cli/lan-ip.js +++ b/packages/navy/src/cli/lan-ip.js @@ -1,9 +1,9 @@ /* @flow */ import chalk from 'chalk' -import {getLANIP} from '../util/get-lan-ip' -import {setConfig, getConfig} from '../config' -import {reconfigureAllNavies} from './util/reconfigure' +import { getLANIP } from '../util/get-lan-ip' +import { setConfig, getConfig } from '../config' +import { reconfigureAllNavies } from './util/reconfigure' export default async function (navy: string): Promise { const lanIP = await getLANIP() diff --git a/packages/navy/src/cli/launch.js b/packages/navy/src/cli/launch.js index 4e28f14..3cd9f42 100644 --- a/packages/navy/src/cli/launch.js +++ b/packages/navy/src/cli/launch.js @@ -1,8 +1,8 @@ /* @flow */ import inquirer from 'inquirer' -import {getOrInitialiseNavy} from './util' -import {startDriverLogging, stopDriverLogging} from '../driver-logging' +import { getOrInitialiseNavy } from './util' +import { startDriverLogging, stopDriverLogging } from '../driver-logging' const SELECTED_WEIGHT = 100 // make sure selected services appear at the top diff --git a/packages/navy/src/cli/live.js b/packages/navy/src/cli/live.js index f9d7532..81e9aa9 100644 --- a/packages/navy/src/cli/live.js +++ b/packages/navy/src/cli/live.js @@ -2,8 +2,8 @@ import chalk from 'chalk' -import {getNavy} from '../' -import {NavyError} from '../errors' +import { getNavy } from '../' +import { NavyError } from '../errors' import getNavyRc from '../util/navyrc' export default async function (service: string, opts: Object): Promise { @@ -34,7 +34,7 @@ export default async function (service: string, opts: Object): Promise { services: { ...state.services, [service]: { - ...(state.services || {})[service], + ...state.services[service], _develop: undefined, }, }, diff --git a/packages/navy/src/cli/local-ip.js b/packages/navy/src/cli/local-ip.js index f233525..25a8368 100644 --- a/packages/navy/src/cli/local-ip.js +++ b/packages/navy/src/cli/local-ip.js @@ -1,8 +1,8 @@ /* @flow */ import chalk from 'chalk' -import {setConfig, getConfig} from '../config' -import {reconfigureAllNavies} from './util/reconfigure' +import { setConfig, getConfig } from '../config' +import { reconfigureAllNavies } from './util/reconfigure' export default async function (navy: string): Promise { await setConfig({ diff --git a/packages/navy/src/cli/logs.js b/packages/navy/src/cli/logs.js index 5f84a3b..6997cd0 100644 --- a/packages/navy/src/cli/logs.js +++ b/packages/navy/src/cli/logs.js @@ -1,6 +1,6 @@ /* @flow */ -import {getNavy} from '../' +import { getNavy } from '../' export default async function (services: Array, opts: Object): Promise { const env = getNavy(opts.navy) diff --git a/packages/navy/src/cli/open.js b/packages/navy/src/cli/open.js index 693bd55..d2f31a2 100644 --- a/packages/navy/src/cli/open.js +++ b/packages/navy/src/cli/open.js @@ -1,7 +1,7 @@ /* @flow */ -import open from 'opn' -import {getNavy} from '../' +import open from 'open' +import { getNavy } from '../' export default async function (service: string, opts: Object): Promise { const navy = getNavy(opts.navy) diff --git a/packages/navy/src/cli/program.js b/packages/navy/src/cli/program.js index 6ee5e23..604aaeb 100644 --- a/packages/navy/src/cli/program.js +++ b/packages/navy/src/cli/program.js @@ -1,9 +1,10 @@ -import program from 'commander' +import { program } from 'commander' import chalk from 'chalk' -import {NavyError} from '../errors' -import {getConfig} from '../config' -import {startDriverLogging, stopDriverLogging} from '../driver-logging' -import {getImportCommandLineOptions} from '../config-provider' +import { NavyError } from '../errors' +import { getConfig } from '../config' +import { startDriverLogging, stopDriverLogging } from '../driver-logging' +import { getImportCommandLineOptions } from '../config-provider' +import { mergeActionOptions } from './util/merge-action-options' const loadingLabelMap = { destroy: 'Destroying services...', @@ -24,6 +25,24 @@ function removeFirstLineFromStackTrace(stack) { return stack?.split('\n')?.slice(1)?.join('\n') } +function normaliseLazyRequireArgs(args) { + if (args.length === 0) return args + const last = args[args.length - 1] + if (!last || typeof last.optsWithGlobals !== 'function') { + return args + } + const command = last + const rest = args.slice(0, -1) + if (rest.length === 0) { + return rest + } + const lastOpt = rest[rest.length - 1] + if (lastOpt && typeof lastOpt === 'object' && !Array.isArray(lastOpt)) { + return [...rest.slice(0, -1), mergeActionOptions(lastOpt, command)] + } + return rest +} + function wrapper(res) { if (res.catch) { res.catch(ex => { @@ -58,8 +77,23 @@ function basicCliWrapper(fnName, wrapperOpts = {}) { return async function (maybeServices, ...args) { const { getNavy } = require('../navy') - const opts = args.length === 0 ? maybeServices : args[args.length - 1] + // commander v12 invokes action handlers with a trailing Command instance + // appended after the parsed options. Strip it and merge global options + // (e.g. `navy -e dev start`) into the opts object. + let command = null + if (args.length > 0) { + const last = args[args.length - 1] + if (last && typeof last.optsWithGlobals === 'function') { + command = last + args = args.slice(0, -1) + } + } + + let opts = args.length === 0 ? maybeServices : args[args.length - 1] const otherArgs = args.slice(0, args.length - 1) + if (command && opts && typeof opts === 'object' && !Array.isArray(opts)) { + opts = mergeActionOptions(opts, command) + } const envName = opts.navy if (wrapperOpts.serviceBasedAlias && maybeServices.length) { @@ -110,12 +144,21 @@ function basicCliWrapper(fnName, wrapperOpts = {}) { function lazyRequire(path) { return function (...args) { const mod = require(path) - return wrapper((mod.default || mod)(...args)) + const normalised = normaliseLazyRequireArgs(args) + return wrapper((mod.default || mod)(...normalised)) } } const defaultNavy = process.env.NAVY_NAME || getConfig().defaultNavy +// Strictly separate parent and subcommand options so an option that isn't +// declared on a subcommand (e.g. `navy status -e foo`) is reported as +// unknown rather than silently absorbed by the parent program. +program.enablePositionalOptions() + +program + .option('-e, --navy [env]', `set the navy name to be used [${defaultNavy}]`, defaultNavy) + const importCommand = program .command('import') .option('-e, --navy [env]', `set the navy name to be used [${defaultNavy}]`, defaultNavy) @@ -138,7 +181,7 @@ program .command('destroy') .option('-e, --navy [env]', `set the navy name to be used [${defaultNavy}]`, defaultNavy) .description('Destroys a navy and all related data and services') - .action(basicCliWrapper('destroy', {serviceBasedAlias: 'kill'})) + .action(basicCliWrapper('destroy', { serviceBasedAlias: 'kill' })) .on('--help', () => console.log(` This will destroy an entire navy and all of its data and services. diff --git a/packages/navy/src/cli/ps.js b/packages/navy/src/cli/ps.js index be26d25..8e6493b 100644 --- a/packages/navy/src/cli/ps.js +++ b/packages/navy/src/cli/ps.js @@ -2,13 +2,13 @@ import chalk from 'chalk' -import {getNavy} from '../' -import {getUrlFromService} from '../util/service-host' +import { getNavy } from '../' +import { getUrlFromService } from '../util/service-host' import table from '../util/table' const SMALL_WINDOW_COLUMNS = 185 -function getStatus(service, state) { +function getStatus(service: Object, state: ?Object) { let statusString = service.status === 'exited' ? chalk.red(service.status) : service.status @@ -28,7 +28,7 @@ function getStatus(service, state) { return statusString } -function getPorts(service) { +function getPorts(service: Object) { if (!service || !service.raw || !service.raw.NetworkSettings || !service.raw.NetworkSettings.Ports) { return '-' } @@ -43,14 +43,13 @@ function getPorts(service) { }).join(', ') } -const getDisplayUrl = (serviceUrl) => serviceUrl != null ? serviceUrl : '-' +const getDisplayUrl = (serviceUrl: ?string) => serviceUrl != null ? serviceUrl : '-' export default async function (opts: Object): Promise { const navy = getNavy(opts.navy) const ps = await navy.ps() const state = await navy.getState() - // $FlowIgnore getWindowSize not on type const isSmallConsole = process.stdout.isTTY && process.stdout.getWindowSize()[0] < SMALL_WINDOW_COLUMNS if (opts.json) { diff --git a/packages/navy/src/cli/refresh-config.js b/packages/navy/src/cli/refresh-config.js index ca96f6f..3cf0757 100644 --- a/packages/navy/src/cli/refresh-config.js +++ b/packages/navy/src/cli/refresh-config.js @@ -2,8 +2,8 @@ import chalk from 'chalk' import invariant from 'invariant' -import {getNavy} from '../' -import {startDriverLogging, stopDriverLogging} from '../driver-logging' +import { getNavy } from '../' +import { startDriverLogging, stopDriverLogging } from '../driver-logging' export default async function (opts: Object): Promise { const navy = getNavy(opts.navy) diff --git a/packages/navy/src/cli/run.js b/packages/navy/src/cli/run.js index a35dd93..44f3dff 100644 --- a/packages/navy/src/cli/run.js +++ b/packages/navy/src/cli/run.js @@ -1,6 +1,6 @@ /* @flow */ -import {getNavy} from '../' +import { getNavy } from '../' export default async function (name: string, args: Array, opts: Object): Promise { const navy = getNavy(opts.navy) diff --git a/packages/navy/src/cli/status.js b/packages/navy/src/cli/status.js index 274ae39..2354ab4 100644 --- a/packages/navy/src/cli/status.js +++ b/packages/navy/src/cli/status.js @@ -1,7 +1,7 @@ import chalk from 'chalk' -import {getLaunchedNavies} from '../' +import { getLaunchedNavies } from '../' import table from '../util/table' -import {getConfig} from '../config' +import { getConfig } from '../config' function formatNavyName(navy, defaultNavy) { if (navy.name === defaultNavy) { diff --git a/packages/navy/src/cli/updates.js b/packages/navy/src/cli/updates.js index 2fe4168..e38ac69 100644 --- a/packages/navy/src/cli/updates.js +++ b/packages/navy/src/cli/updates.js @@ -2,8 +2,8 @@ import chalk from 'chalk' import readline from 'readline' -import {dots} from 'cli-spinners' -import {getNavy} from '../' +import { dots } from 'cli-spinners' +import { getNavy } from '../' import table from '../util/table' import hasUpdate from '../util/has-update' @@ -12,7 +12,7 @@ const debug = require('debug')('navy:updates') let spinnerIndex = 0 let spinnerFrame = dots.frames[0] -function renderStatus(status) { +function renderStatus(status: ?(boolean | string)) { if (status == null) { return chalk.yellow(spinnerFrame) + ' ' + chalk.dim('Checking...') } else if (status === true) { @@ -34,7 +34,7 @@ export default async function (opts: Object): Promise { const navyFile = await navy.getNavyFile() const ps = await navy.ps() - const updateStatus = {} + const updateStatus: {[string]: ?(boolean | string)} = {} let drawnLines = 0 diff --git a/packages/navy/src/cli/util/__tests__/get-or-initialise-navy.js b/packages/navy/src/cli/util/__tests__/get-or-initialise-navy.js new file mode 100644 index 0000000..3e5a3ba --- /dev/null +++ b/packages/navy/src/cli/util/__tests__/get-or-initialise-navy.js @@ -0,0 +1,72 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/util/get-or-initialise-navy', function () { + + let sandbox + let getNavyStub + let importNavyStub + let getImportOptionsForCLIStub + let navyStub + let getOrInitialiseNavy + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + isInitialised: sandbox.stub(), + } + getNavyStub = sandbox.stub().returns(navyStub) + importNavyStub = sandbox.stub().resolves() + getImportOptionsForCLIStub = sandbox.stub() + .resolves({ configProvider: 'filesystem', path: '/cwd' }) + + getOrInitialiseNavy = proxyquire.noCallThru()('../get-or-initialise-navy', { + '../../': { getNavy: getNavyStub }, + './import': { importNavy: importNavyStub }, + '../../config-providers/filesystem': { + getImportOptionsForCLI: getImportOptionsForCLIStub, + }, + }).getOrInitialiseNavy + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('getOrInitialiseNavy', function () { + + it('should return the navy without importing when already initialised', async function () { + navyStub.isInitialised.resolves(true) + + const result = await getOrInitialiseNavy('env-1') + + expect(result).to.equal(navyStub) + expect(getNavyStub.calledOnce).to.equal(true) + expect(getNavyStub.firstCall.args[0]).to.equal('env-1') + expect(importNavyStub.called).to.equal(false) + expect(getImportOptionsForCLIStub.called).to.equal(false) + }) + + it('should import the navy using filesystem provider opts when not initialised', async function () { + navyStub.isInitialised.resolves(false) + + const result = await getOrInitialiseNavy('env-2') + + expect(result).to.equal(navyStub) + expect(getImportOptionsForCLIStub.calledOnce).to.equal(true) + expect(getImportOptionsForCLIStub.firstCall.args[0]).to.eql({}) + expect(importNavyStub.calledOnce).to.equal(true) + expect(importNavyStub.firstCall.args[0]).to.equal(navyStub) + expect(importNavyStub.firstCall.args[1]).to.eql({ + configProvider: 'filesystem', + path: '/cwd', + }) + }) + + }) + +}) diff --git a/packages/navy/src/cli/util/__tests__/import.js b/packages/navy/src/cli/util/__tests__/import.js new file mode 100644 index 0000000..cd8680a --- /dev/null +++ b/packages/navy/src/cli/util/__tests__/import.js @@ -0,0 +1,152 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../../errors' + +describe('cli/util/import', function () { + + let sandbox + let startDriverLoggingStub + let stopDriverLoggingStub + let consoleLogStub + let navyStub + let importNavy + + beforeEach(function () { + sandbox = sinon.createSandbox() + + navyStub = { + name: 'env-1', + isInitialised: sandbox.stub().resolves(false), + initialise: sandbox.stub().resolves(), + ensurePluginsLoaded: sandbox.stub().resolves(), + emitAsync: sandbox.stub().resolves(), + relaunch: sandbox.stub().resolves(), + } + + startDriverLoggingStub = sandbox.stub() + stopDriverLoggingStub = sandbox.stub() + consoleLogStub = sandbox.stub(console, 'log') + + importNavy = proxyquire.noCallThru()('../import', { + '../../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + '../../errors': { NavyError }, + }).importNavy + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('importNavy', function () { + + it('should throw a NavyError when the navy has already been initialised', async function () { + navyStub.isInitialised.resolves(true) + + let caught + try { + await importNavy(navyStub, {}) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('env-1') + expect(caught.message).to.contain('already been imported') + expect(navyStub.initialise.called).to.equal(false) + }) + + it('should initialise the navy with the provided opts', async function () { + const opts = { configProvider: 'filesystem', path: '/cwd' } + + await importNavy(navyStub, opts) + + expect(navyStub.initialise.calledOnce).to.equal(true) + expect(navyStub.initialise.firstCall.args[0]).to.equal(opts) + }) + + it('should ensure plugins are loaded and emit cli.import in order before relaunch', async function () { + await importNavy(navyStub, {}) + + expect(navyStub.ensurePluginsLoaded.calledOnce).to.equal(true) + expect(navyStub.emitAsync.calledOnce).to.equal(true) + expect(navyStub.emitAsync.firstCall.args[0]).to.equal('cli.import') + expect(navyStub.relaunch.calledOnce).to.equal(true) + expect( + navyStub.initialise.calledBefore(navyStub.ensurePluginsLoaded), + ).to.equal(true) + expect( + navyStub.ensurePluginsLoaded.calledBefore(navyStub.emitAsync), + ).to.equal(true) + expect( + navyStub.emitAsync.calledBefore(navyStub.relaunch), + ).to.equal(true) + }) + + it('should bracket relaunch with start/stopDriverLogging', async function () { + await importNavy(navyStub, {}) + + expect(startDriverLoggingStub.calledOnce).to.equal(true) + expect(stopDriverLoggingStub.calledOnce).to.equal(true) + expect( + startDriverLoggingStub.calledBefore(navyStub.relaunch), + ).to.equal(true) + expect( + navyStub.relaunch.calledBefore(stopDriverLoggingStub), + ).to.equal(true) + }) + + it('should log a success message containing the navy name', async function () { + await importNavy(navyStub, {}) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join(' ') + expect(printed).to.contain('env-1') + expect(printed).to.contain('imported and initialised') + }) + + it('should print a labelled line for each known option key', async function () { + const opts = { + configProvider: 'filesystem', + path: '/cwd', + npmPackage: 'some-pkg', + } + + await importNavy(navyStub, opts) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Provider') + expect(printed).to.contain('filesystem') + expect(printed).to.contain('Directory') + expect(printed).to.contain('/cwd') + expect(printed).to.contain('NPM Package') + expect(printed).to.contain('some-pkg') + }) + + it('should ignore unknown option keys when printing labels', async function () { + const opts = { configProvider: 'filesystem', unrecognised: 'value' } + + await importNavy(navyStub, opts) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.contain('Provider') + expect(printed).to.not.contain('unrecognised') + expect(printed).to.not.contain('value') + }) + + it('should not print any option label lines when no known options are supplied', async function () { + await importNavy(navyStub, {}) + + const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join('\n') + expect(printed).to.not.contain('Provider') + expect(printed).to.not.contain('Directory') + expect(printed).to.not.contain('NPM Package') + }) + + }) + +}) diff --git a/packages/navy/src/cli/util/__tests__/index.js b/packages/navy/src/cli/util/__tests__/index.js new file mode 100644 index 0000000..2f92c14 --- /dev/null +++ b/packages/navy/src/cli/util/__tests__/index.js @@ -0,0 +1,20 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import * as cliUtil from '../index' + +describe('cli/util/index', function () { + + describe('module exports', function () { + + it('should re-export getOrInitialiseNavy as a function', function () { + expect(cliUtil).to.have.property('getOrInitialiseNavy').that.is.a('function') + }) + + it('should re-export importNavy as a function', function () { + expect(cliUtil).to.have.property('importNavy').that.is.a('function') + }) + + }) + +}) diff --git a/packages/navy/src/cli/util/__tests__/merge-action-options.js b/packages/navy/src/cli/util/__tests__/merge-action-options.js new file mode 100644 index 0000000..25f8227 --- /dev/null +++ b/packages/navy/src/cli/util/__tests__/merge-action-options.js @@ -0,0 +1,56 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import { mergeActionOptions } from '../merge-action-options' + +describe('cli/util/merge-action-options', function () { + + it('should return parsed opts when command is missing', function () { + const opts = { navy: 'dev' } + expect(mergeActionOptions(opts, null)).to.equal(opts) + }) + + it('should return parsed opts when optsWithGlobals is missing', function () { + const opts = { navy: 'dev' } + expect(mergeActionOptions(opts, {})).to.equal(opts) + }) + + it('should merge optsWithGlobals so global navy wins over subcommand defaults', function () { + const command = { + optsWithGlobals: () => ({ navy: 'dev', json: true }), + } + const merged = mergeActionOptions({ navy: 'default', json: false }, command) + + expect(merged.navy).to.equal('dev') + expect(merged.json).to.equal(true) + }) + + it('should call optsWithGlobals on the command', function () { + const spy = sinon.stub().returns({ navy: 'x' }) + mergeActionOptions({ navy: 'y' }, { optsWithGlobals: spy }) + + expect(spy.calledOnce).to.equal(true) + }) + + it('should let an explicit subcommand option beat the inherited parent default', function () { + const command = { + optsWithGlobals: () => ({ navy: 'parent-default' }), + getOptionValueSource: key => (key === 'navy' ? 'cli' : 'default'), + } + const merged = mergeActionOptions({ navy: 'from-subcommand' }, command) + + expect(merged.navy).to.equal('from-subcommand') + }) + + it('should keep the parent value when the subcommand value came from its default', function () { + const command = { + optsWithGlobals: () => ({ navy: 'from-parent' }), + getOptionValueSource: () => 'default', + } + const merged = mergeActionOptions({ navy: 'subcommand-default' }, command) + + expect(merged.navy).to.equal('from-parent') + }) + +}) diff --git a/packages/navy/src/cli/util/__tests__/reconfigure.js b/packages/navy/src/cli/util/__tests__/reconfigure.js new file mode 100644 index 0000000..ee82036 --- /dev/null +++ b/packages/navy/src/cli/util/__tests__/reconfigure.js @@ -0,0 +1,86 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +describe('cli/util/reconfigure', function () { + + let sandbox + let getLaunchedNaviesStub + let startDriverLoggingStub + let stopDriverLoggingStub + let reconfigureAllNavies + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getLaunchedNaviesStub = sandbox.stub() + startDriverLoggingStub = sandbox.stub() + stopDriverLoggingStub = sandbox.stub() + + reconfigureAllNavies = proxyquire.noCallThru()('../reconfigure', { + '../../': { getLaunchedNavies: getLaunchedNaviesStub }, + '../../driver-logging': { + startDriverLogging: startDriverLoggingStub, + stopDriverLogging: stopDriverLoggingStub, + }, + }).reconfigureAllNavies + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('reconfigureAllNavies', function () { + + it('should be a no-op when there are no launched navies', async function () { + getLaunchedNaviesStub.resolves([]) + + await reconfigureAllNavies() + + expect(getLaunchedNaviesStub.calledOnce).to.equal(true) + expect(startDriverLoggingStub.called).to.equal(false) + expect(stopDriverLoggingStub.called).to.equal(false) + }) + + it('should reconfigure each launched navy in turn with bracketed driver logging', async function () { + const navyA = { name: 'envA', reconfigure: sandbox.stub().resolves() } + const navyB = { name: 'envB', reconfigure: sandbox.stub().resolves() } + getLaunchedNaviesStub.resolves([navyA, navyB]) + + await reconfigureAllNavies() + + expect(navyA.reconfigure.calledOnce).to.equal(true) + expect(navyB.reconfigure.calledOnce).to.equal(true) + expect(startDriverLoggingStub.callCount).to.equal(2) + expect(stopDriverLoggingStub.callCount).to.equal(2) + }) + + it('should pass a message that includes the navy name to startDriverLogging', async function () { + const navy = { name: 'envA', reconfigure: sandbox.stub().resolves() } + getLaunchedNaviesStub.resolves([navy]) + + await reconfigureAllNavies() + + expect(startDriverLoggingStub.firstCall.args[0]).to.contain('envA') + expect(startDriverLoggingStub.firstCall.args[0]).to.contain('Reconfiguring') + }) + + it('should call startDriverLogging before each reconfigure and stopDriverLogging after', async function () { + const navy = { name: 'envA', reconfigure: sandbox.stub().resolves() } + getLaunchedNaviesStub.resolves([navy]) + + await reconfigureAllNavies() + + expect( + startDriverLoggingStub.calledBefore(navy.reconfigure), + ).to.equal(true) + expect( + navy.reconfigure.calledBefore(stopDriverLoggingStub), + ).to.equal(true) + }) + + }) + +}) diff --git a/packages/navy/src/cli/util/get-or-initialise-navy.js b/packages/navy/src/cli/util/get-or-initialise-navy.js index 69031b2..4ca593b 100644 --- a/packages/navy/src/cli/util/get-or-initialise-navy.js +++ b/packages/navy/src/cli/util/get-or-initialise-navy.js @@ -1,10 +1,12 @@ /* @flow */ -import {getNavy} from '../../' -import {importNavy} from './import' +import { getNavy } from '../../' +import { importNavy } from './import' import fileSystemConfigProvider from '../../config-providers/filesystem' -export async function getOrInitialiseNavy(navyName: string) { +import type { Navy } from '../../navy' + +export async function getOrInitialiseNavy(navyName: string): Promise { const navy = getNavy(navyName) if (!await navy.isInitialised()) { diff --git a/packages/navy/src/cli/util/import.js b/packages/navy/src/cli/util/import.js index dbfb2d8..963cbae 100644 --- a/packages/navy/src/cli/util/import.js +++ b/packages/navy/src/cli/util/import.js @@ -1,12 +1,12 @@ /* @flow */ import chalk from 'chalk' -import {startDriverLogging, stopDriverLogging} from '../../driver-logging' -import {NavyError} from '../../errors' +import { startDriverLogging, stopDriverLogging } from '../../driver-logging' +import { NavyError } from '../../errors' -import type {Navy} from '../../' +import type { Navy } from '../../' -const OPTION_LABEL_MAP = { +const OPTION_LABEL_MAP: {[string]: string} = { configProvider: 'Provider', path: 'Directory', npmPackage: 'NPM Package', diff --git a/packages/navy/src/cli/util/index.js b/packages/navy/src/cli/util/index.js index 0ccde0a..ec61904 100644 --- a/packages/navy/src/cli/util/index.js +++ b/packages/navy/src/cli/util/index.js @@ -1,4 +1,4 @@ /* @flow */ -export {getOrInitialiseNavy} from './get-or-initialise-navy' -export {importNavy} from './import' +export { getOrInitialiseNavy } from './get-or-initialise-navy' +export { importNavy } from './import' diff --git a/packages/navy/src/cli/util/merge-action-options.js b/packages/navy/src/cli/util/merge-action-options.js new file mode 100644 index 0000000..2f6a649 --- /dev/null +++ b/packages/navy/src/cli/util/merge-action-options.js @@ -0,0 +1,26 @@ +/** + * Merge Commander's per-command opts with inherited globals (e.g. `navy -e dev ps`). + * `optsWithGlobals()` has "globals overwrite locals" semantics, which makes parent + * defaults win over child defaults. With positional options enabled, however, a + * value supplied after the subcommand name (e.g. `navy ps -e dev`) is parsed onto + * the subcommand, not the parent, so we re-apply any option whose source on the + * subcommand is non-default to keep the explicit value. + */ +export function mergeActionOptions(parsedOpts, command) { + if (!command || typeof command.optsWithGlobals !== 'function') { + return parsedOpts + } + + const merged = { ...command.optsWithGlobals() } + + if (typeof command.getOptionValueSource === 'function') { + for (const key of Object.keys(parsedOpts)) { + const source = command.getOptionValueSource(key) + if (source && source !== 'default') { + merged[key] = parsedOpts[key] + } + } + } + + return merged +} diff --git a/packages/navy/src/cli/util/reconfigure.js b/packages/navy/src/cli/util/reconfigure.js index 80ade47..a372ab9 100644 --- a/packages/navy/src/cli/util/reconfigure.js +++ b/packages/navy/src/cli/util/reconfigure.js @@ -1,7 +1,7 @@ /* @flow */ -import {getLaunchedNavies} from '../../' -import {startDriverLogging, stopDriverLogging} from '../../driver-logging' +import { getLaunchedNavies } from '../../' +import { startDriverLogging, stopDriverLogging } from '../../driver-logging' export async function reconfigureAllNavies() { const navies = await getLaunchedNavies() diff --git a/packages/navy/src/cli/wait-for-healthy.js b/packages/navy/src/cli/wait-for-healthy.js index 1289714..3f380a3 100644 --- a/packages/navy/src/cli/wait-for-healthy.js +++ b/packages/navy/src/cli/wait-for-healthy.js @@ -2,8 +2,8 @@ import chalk from 'chalk' import readline from 'readline' -import {dots} from 'cli-spinners' -import {getNavy} from '../' +import { dots } from 'cli-spinners' +import { getNavy } from '../' let spinnerIndex = 0 let spinnerFrame = dots.frames[0] @@ -18,7 +18,7 @@ export default async function (services: Array, opts: Object): Promise = [] let drawnLines = 0 diff --git a/packages/navy/src/client/registry/__tests__/get-credentials.js b/packages/navy/src/client/registry/__tests__/get-credentials.js new file mode 100644 index 0000000..19661d8 --- /dev/null +++ b/packages/navy/src/client/registry/__tests__/get-credentials.js @@ -0,0 +1,57 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import * as execAsyncModule from '../../../util/exec-async' +import { DEFAULT_REGISTRY, DEFAULT_REGISTRY_AUTH } from '../../../domain/container-image' +import getAuthenticationForRegistry from '../get-credentials' + +describe('get-credentials', function () { + + let sandbox + + beforeEach(function () { + sandbox = sinon.createSandbox() + }) + + afterEach(function () { + sandbox.restore() + }) + + it('should call docker-credential-desktop with the default auth URL when registry is the default registry', async function () { + const execStub = sandbox.stub(execAsyncModule, 'execAsync') + .resolves(JSON.stringify({ Username: 'u', Secret: 's' })) + + const result = await getAuthenticationForRegistry(DEFAULT_REGISTRY) + + expect(result).to.eql({ username: 'u', password: 's' }) + const args = execStub.firstCall.args + expect(args[0]).to.equal('echo') + expect(args[1]).to.include(DEFAULT_REGISTRY_AUTH) + expect(args[1]).to.include('docker-credential-desktop') + expect(args[1]).to.include('get') + }) + + it('should pass the registry hostname directly when not the default registry', async function () { + const execStub = sandbox.stub(execAsyncModule, 'execAsync') + .resolves(JSON.stringify({ Username: 'alice', Secret: 'pw' })) + + const result = await getAuthenticationForRegistry('myregistry.local:5000') + + expect(result).to.eql({ username: 'alice', password: 'pw' }) + expect(execStub.firstCall.args[1]).to.include('myregistry.local:5000') + }) + + it('should return empty credentials when execAsync rejects', async function () { + sandbox.stub(execAsyncModule, 'execAsync').rejects(new Error('not installed')) + + expect(await getAuthenticationForRegistry('any')).to.eql({ username: '', password: '' }) + }) + + it('should return empty credentials when stdout is not valid JSON', async function () { + sandbox.stub(execAsyncModule, 'execAsync').resolves('not-json') + + expect(await getAuthenticationForRegistry('any')).to.eql({ username: '', password: '' }) + }) + +}) diff --git a/packages/navy/src/client/registry/__tests__/get-endpoint.js b/packages/navy/src/client/registry/__tests__/get-endpoint.js new file mode 100644 index 0000000..584d115 --- /dev/null +++ b/packages/navy/src/client/registry/__tests__/get-endpoint.js @@ -0,0 +1,125 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import nock from 'nock' +import proxyquire from 'proxyquire' + +function loadModule({ getCredentials, getToken } = {}) { + return proxyquire.noCallThru()('../get-endpoint', { + './get-credentials': getCredentials || sinon.stub().resolves({ username: 'u', password: 'p' }), + './get-token': getToken || sinon.stub().resolves('the-token'), + }) +} + +describe('get-endpoint', function () { + + afterEach(function () { + nock.cleanAll() + }) + + it('should return the response when the registry replies 200', async function () { + const body = { schemaVersion: 2 } + nock('https://reg.example.com') + .get('/v2/library/node/manifests/latest') + .reply(200, body) + + const getEndpoint = loadModule() + const response = await getEndpoint({ + registry: 'reg.example.com', + endpoint: 'library/node/manifests/latest', + }) + + expect(response.status).to.equal(200) + expect(await response.json()).to.eql(body) + }) + + it('should throw "Operation not found" when the registry returns 404', async function () { + nock('https://reg.example.com') + .get('/v2/missing') + .reply(404, { errors: [] }) + + const getEndpoint = loadModule() + let caught + try { + await getEndpoint({ registry: 'reg.example.com', endpoint: 'missing' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.equal('Operation not found') + }) + + it('should retry with a Bearer token when the response is 401 with a Bearer challenge', async function () { + nock('https://reg.example.com') + .get('/v2/secret') + .reply(401, '', { + 'WWW-Authenticate': 'Bearer realm="https://auth.example.com/token",service="reg.example.com",scope="repository:secret:pull"', + }) + .get('/v2/secret') + .matchHeader('authorization', 'Bearer the-token') + .reply(200, { ok: true }) + + const getToken = sinon.stub().resolves('the-token') + const getEndpoint = loadModule({ getToken }) + const response = await getEndpoint({ registry: 'reg.example.com', endpoint: 'secret' }) + + expect(response.status).to.equal(200) + expect(await response.json()).to.eql({ ok: true }) + expect(getToken.calledOnce).to.equal(true) + }) + + it('should throw "Access denied" when the bearer-token retry still returns 401', async function () { + nock('https://reg.example.com') + .get('/v2/secret') + .reply(401, '', { + 'WWW-Authenticate': 'Bearer realm="https://auth.example.com/token",service="reg.example.com",scope="repository:secret:pull"', + }) + .get('/v2/secret') + .reply(401, '') + + const getEndpoint = loadModule() + let caught + try { + await getEndpoint({ registry: 'reg.example.com', endpoint: 'secret' }) + } catch (err) { + caught = err + } + + expect(caught.message).to.equal('Access denied') + }) + + it('should throw "Invalid authentication" for a Basic challenge', async function () { + nock('https://reg.example.com') + .get('/v2/needs-basic') + .reply(401, '', { 'WWW-Authenticate': 'Basic realm="reg"' }) + + const getEndpoint = loadModule() + let caught + try { + await getEndpoint({ registry: 'reg.example.com', endpoint: 'needs-basic' }) + } catch (err) { + caught = err + } + + expect(caught.message).to.equal('Invalid authentication') + }) + + it('should throw "Invalid authentication" for an unknown auth scheme', async function () { + nock('https://reg.example.com') + .get('/v2/weird') + .reply(401, '', { 'WWW-Authenticate': 'Digest realm="reg"' }) + + const getEndpoint = loadModule() + let caught + try { + await getEndpoint({ registry: 'reg.example.com', endpoint: 'weird' }) + } catch (err) { + caught = err + } + + expect(caught.message).to.equal('Invalid authentication') + }) + +}) diff --git a/packages/navy/src/client/registry/__tests__/get-fat-manifest.js b/packages/navy/src/client/registry/__tests__/get-fat-manifest.js new file mode 100644 index 0000000..5fc4bca --- /dev/null +++ b/packages/navy/src/client/registry/__tests__/get-fat-manifest.js @@ -0,0 +1,56 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { MEDIA_TYPES } from '../../../domain/oci-api-specification' + +function fakeResponse({ digest, body }) { + return { + headers: { get: name => name === 'docker-content-digest' ? digest : null }, + json: async () => body, + } +} + +function loadModule(getEndpointStub) { + return proxyquire.noCallThru()('../get-fat-manifest', { + './get-endpoint': getEndpointStub, + }) +} + +describe('get-fat-manifest', function () { + + it('should call getEndpoint with the manifest path and the FAT_MANIFEST accept header', async function () { + const getEndpoint = sinon.stub().resolves(fakeResponse({ digest: 'sha256:abc', body: { manifests: [] } })) + const getFatManifest = loadModule(getEndpoint) + + const result = await getFatManifest({ + repository: 'library/node', + registry: 'registry-1.docker.io', + tag: 'lts', + }) + + expect(result).to.eql({ tag: 'sha256:abc', data: { manifests: [] } }) + expect(getEndpoint.calledOnce).to.equal(true) + const args = getEndpoint.firstCall.args[0] + expect(args.endpoint).to.equal('library/node/manifests/lts') + expect(args.options.headers.Accept).to.equal(MEDIA_TYPES.FAT_MANIFEST) + expect(args.allowUnauthorizedRequest).to.equal(false) + expect(args.registry).to.equal('registry-1.docker.io') + }) + + it('should propagate allowUnauthorizedRequest=true', async function () { + const getEndpoint = sinon.stub().resolves(fakeResponse({ digest: 'd', body: {} })) + const getFatManifest = loadModule(getEndpoint) + + await getFatManifest({ + allowUnauthorizedRequest: true, + repository: 'org/img', + registry: 'r', + tag: 't', + }) + + expect(getEndpoint.firstCall.args[0].allowUnauthorizedRequest).to.equal(true) + }) + +}) diff --git a/packages/navy/src/client/registry/__tests__/get-token.js b/packages/navy/src/client/registry/__tests__/get-token.js new file mode 100644 index 0000000..3cd1788 --- /dev/null +++ b/packages/navy/src/client/registry/__tests__/get-token.js @@ -0,0 +1,75 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import nock from 'nock' +import getToken from '../get-token' + +describe('get-token', function () { + + afterEach(function () { + nock.cleanAll() + }) + + it('should call the realm with service+scope and return the token from the JSON body', async function () { + const scope = nock('https://auth.docker.io') + .get('/token') + .query({ service: 'registry.docker.io', scope: 'repository:library/node:pull' }) + .matchHeader('authorization', 'Basic dXNlcjpwYXNz') + .reply(200, { token: 'abc123' }) + + const token = await getToken({ + realm: 'https://auth.docker.io/token', + service: 'registry.docker.io', + scope: 'repository:library/node:pull', + }, { + headers: { Authorization: 'Basic dXNlcjpwYXNz' }, + }) + + expect(token).to.equal('abc123') + scope.done() + }) + + it('should throw "Invalid authentication" when the realm responds 401', async function () { + nock('https://auth.docker.io') + .get('/token') + .query(true) + .reply(401, {}) + + let caught + try { + await getToken({ + realm: 'https://auth.docker.io/token', + service: 'reg', + scope: 'sc', + }, { headers: {} }) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.equal('Invalid authentication') + }) + + it('should pick only the Authorization header from the supplied headers (no other headers leak)', async function () { + nock('https://auth.example.com') + .get('/token') + .query(true) + .matchHeader('authorization', 'Basic xyz') + .reply(200, { token: 't' }) + + const token = await getToken({ + realm: 'https://auth.example.com/token', + service: 'svc', + scope: 'sc', + }, { + headers: { + Authorization: 'Basic xyz', + Cookie: 'should-not-be-sent', + 'X-Custom': 'should-not-be-sent', + }, + }) + + expect(token).to.equal('t') + }) + +}) diff --git a/packages/navy/src/client/registry/__tests__/helpers.js b/packages/navy/src/client/registry/__tests__/helpers.js new file mode 100644 index 0000000..1ebfa7b --- /dev/null +++ b/packages/navy/src/client/registry/__tests__/helpers.js @@ -0,0 +1,27 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { basicAuthentication } from '../helpers' + +describe('registry helpers', function () { + + describe('basicAuthentication', function () { + + it('should return null for empty credentials', function () { + expect(basicAuthentication({})).to.equal(null) + }) + + it('should base64-encode user:password into a Basic header', function () { + const result = basicAuthentication({ username: 'alice', password: 's3cret' }) + + expect(result).to.equal('Basic ' + Buffer.from('alice:s3cret').toString('base64')) + }) + + it('should still return a Basic header for non-empty objects with empty values', function () { + expect(basicAuthentication({ username: '', password: '' })) + .to.equal('Basic ' + Buffer.from(':').toString('base64')) + }) + + }) + +}) diff --git a/packages/navy/src/client/registry/get-credentials.js b/packages/navy/src/client/registry/get-credentials.js index e1eaf66..b15ea98 100644 --- a/packages/navy/src/client/registry/get-credentials.js +++ b/packages/navy/src/client/registry/get-credentials.js @@ -1,6 +1,6 @@ -import {always as noop} from 'ramda' -import {execAsync} from '../../util/exec-async' -import {DEFAULT_REGISTRY, DEFAULT_REGISTRY_AUTH} from '../../domain/container-image' +import { always as noop } from 'ramda' +import { execAsync } from '../../util/exec-async' +import { DEFAULT_REGISTRY, DEFAULT_REGISTRY_AUTH } from '../../domain/container-image' const getAuthenticationForRegistry = async (registry) => { try { @@ -16,8 +16,8 @@ const getAuthenticationForRegistry = async (registry) => { const credentials = JSON.parse(stdout) return { - username: credentials['Username'], - password: credentials['Secret'], + username: credentials.Username, + password: credentials.Secret, } } catch (exception) { return { diff --git a/packages/navy/src/client/registry/get-endpoint.js b/packages/navy/src/client/registry/get-endpoint.js index 745d24c..e83d18f 100644 --- a/packages/navy/src/client/registry/get-endpoint.js +++ b/packages/navy/src/client/registry/get-endpoint.js @@ -2,18 +2,18 @@ import * as R from 'ramda' import https from 'https' import fetch from 'node-fetch' import getToken from './get-token' -import {restSpecification} from '../../domain/oci-api-specification' +import { restSpecification } from '../../domain/oci-api-specification' import getAuthenticationForRegistry from './get-credentials' -import {basicAuthentication} from './helpers' +import { basicAuthentication } from './helpers' import parsers from 'www-authenticate/lib/parsers' const handleUnauthorizedResponse = async ({ - response, + response: initialResponse, context, url, }) => { - const challenges = response.headers.get('WWW-Authenticate') - const {scheme, parms} = new parsers.WWW_Authenticate(challenges) + const challenges = initialResponse.headers.get('WWW-Authenticate') + const { scheme, parms } = new parsers.WWW_Authenticate(challenges) if (scheme === 'Basic') { throw new Error('Invalid authentication') @@ -23,25 +23,21 @@ const handleUnauthorizedResponse = async ({ throw new Error('Invalid authentication') } - try { - const token = await getToken(parms, context) + const token = await getToken(parms, context) - const options = R.mergeDeepRight(context, { - headers: { - 'Authorization': `Bearer ${token}` - }, - }) - - const response = await fetch(url, options) + const options = R.mergeDeepRight(context, { + headers: { + Authorization: `Bearer ${token}` + }, + }) - if (response.status === 401) { - throw new Error('Access denied') - } + const response = await fetch(url, options) - return response - } catch (exception) { - throw exception + if (response.status === 401) { + throw new Error('Access denied') } + + return response } const get = async ({ @@ -55,7 +51,7 @@ const get = async ({ const context = R.mergeDeepLeft(options, { headers: R.reject(R.isNil, { - 'Authorization': basicAuthentication(credentials), + Authorization: basicAuthentication(credentials), }), agent: new https.Agent({ @@ -63,28 +59,24 @@ const get = async ({ }) }) - try { - const response = await fetch(url, context) - - switch (response.status) { - case 401: - return handleUnauthorizedResponse({ - response, - context, - url, - }) - - case 404: - throw new Error('Operation not found', { - status: 404, - body: await response.json() - }) - - default: - return response - } - } catch (exception) { - throw exception + const response = await fetch(url, context) + + switch (response.status) { + case 401: + return handleUnauthorizedResponse({ + response, + context, + url, + }) + + case 404: + throw new Error('Operation not found', { + status: 404, + body: await response.json() + }) + + default: + return response } } diff --git a/packages/navy/src/client/registry/get-fat-manifest.js b/packages/navy/src/client/registry/get-fat-manifest.js index 0de1223..892fa03 100644 --- a/packages/navy/src/client/registry/get-fat-manifest.js +++ b/packages/navy/src/client/registry/get-fat-manifest.js @@ -1,5 +1,5 @@ import getEndpoint from './get-endpoint' -import {restSpecification, MEDIA_TYPES} from '../../domain/oci-api-specification' +import { restSpecification, MEDIA_TYPES } from '../../domain/oci-api-specification' const getFatManifest = async ({ allowUnauthorizedRequest = false, @@ -10,7 +10,7 @@ const getFatManifest = async ({ const endpoint = restSpecification.getManifest(repository, tag) const options = { headers: { - 'Accept': MEDIA_TYPES.FAT_MANIFEST, + Accept: MEDIA_TYPES.FAT_MANIFEST, } } diff --git a/packages/navy/src/client/registry/get-token.js b/packages/navy/src/client/registry/get-token.js index e97ee4a..8a359df 100644 --- a/packages/navy/src/client/registry/get-token.js +++ b/packages/navy/src/client/registry/get-token.js @@ -21,7 +21,7 @@ const getToken = async ({ throw new Error('Invalid authentication') } - const {token} = await response.json() + const { token } = await response.json() return token } diff --git a/packages/navy/src/client/registry/helpers.js b/packages/navy/src/client/registry/helpers.js index 7e770e6..88159ff 100644 --- a/packages/navy/src/client/registry/helpers.js +++ b/packages/navy/src/client/registry/helpers.js @@ -1,4 +1,4 @@ -import {isEmpty} from 'ramda' +import { isEmpty } from 'ramda' export const basicAuthentication = (credentials) => { if (isEmpty(credentials)) { diff --git a/packages/navy/src/config-provider.js b/packages/navy/src/config-provider.js index be9423f..36fd9fc 100644 --- a/packages/navy/src/config-provider.js +++ b/packages/navy/src/config-provider.js @@ -4,8 +4,8 @@ import invariant from 'invariant' import FileSystem from './config-providers/filesystem' import NPM from './config-providers/npm' -import type {State} from './navy/state' -import type {Navy} from './navy' +import type { State } from './navy/state' +import type { Navy } from './navy' const PROVIDERS = [ NPM, @@ -15,7 +15,7 @@ const PROVIDERS = [ export type ConfigProvider = { getNavyPath(): Promise; getNavyFilePath(): Promise; - refreshConfig(): Promise; + refreshConfig(): Promise; getLocationDisplayName(): Promise; isDangling(): Promise; } @@ -37,7 +37,7 @@ export function getImportCommandLineOptions(): Array> { return PROVIDERS.reduce((arr, provider) => [...arr, ...provider.importCliOptions], []) } -export async function getImportOptionsForCLI(opts: Object): State { +export async function getImportOptionsForCLI(opts: Object): Promise { for (const provider of PROVIDERS) { const optionsFromProvider: ?State = await provider.getImportOptionsForCLI(opts) diff --git a/packages/navy/src/config-providers/filesystem/__tests__/index.js b/packages/navy/src/config-providers/filesystem/__tests__/index.js new file mode 100644 index 0000000..95c27a0 --- /dev/null +++ b/packages/navy/src/config-providers/filesystem/__tests__/index.js @@ -0,0 +1,162 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import path from 'path' +import fs from '../../../util/fs' +import * as execAsyncModule from '../../../util/exec-async' +import createFileSystemConfigProvider from '../index' + +function makeNavy({ name = 'env', state = null } = {}) { + return { + name, + getState: sinon.stub().resolves(state), + } +} + +describe('filesystem config provider', function () { + + let sandbox + + beforeEach(function () { + sandbox = sinon.createSandbox() + sandbox.stub(process, 'cwd').returns('/work/dir') + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('getNavyPath', function () { + + it('should return the path from state when the path exists on disk', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: { path: '/some/path' } })) + sandbox.stub(fs, 'statAsync').resolves({}) + + expect(await provider.getNavyPath()).to.equal('/some/path') + }) + + it('should throw STATE_NONEXISTANT when state is missing', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: null })) + + let caught + try { await provider.getNavyPath() } catch (e) { caught = e } + expect(caught.message).to.match(/STATE_NONEXISTANT/) + }) + + it('should throw FILESYSTEM_PROVIDER_REQUIRES_PATH when state has no path', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: {} })) + + let caught + try { await provider.getNavyPath() } catch (e) { caught = e } + expect(caught.message).to.match(/FILESYSTEM_PROVIDER_REQUIRES_PATH/) + }) + + it('should throw FILESYSTEM_PROVIDER_INVALID_PATH when stat of the path fails', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: { path: '/missing' } })) + sandbox.stub(fs, 'statAsync').rejects(new Error('ENOENT')) + + let caught + try { await provider.getNavyPath() } catch (e) { caught = e } + expect(caught.message).to.match(/FILESYSTEM_PROVIDER_INVALID_PATH/) + }) + + }) + + describe('getNavyFilePath', function () { + + it('should return /Navyfile.js', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: { path: '/some/path' } })) + sandbox.stub(fs, 'statAsync').resolves({}) + + expect(await provider.getNavyFilePath()).to.equal(path.join('/some/path', 'Navyfile.js')) + }) + + }) + + describe('refreshConfig', function () { + + it('should be a no-op that returns false', async function () { + const provider = createFileSystemConfigProvider(makeNavy()) + expect(await provider.refreshConfig()).to.equal(false) + }) + + }) + + describe('getLocationDisplayName', function () { + + it('should return the path from state', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: { path: '/x' } })) + expect(await provider.getLocationDisplayName()).to.equal('/x') + }) + + it('should throw STATE_NONEXISTANT when state is missing', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: null })) + + let caught + try { await provider.getLocationDisplayName() } catch (e) { caught = e } + expect(caught.message).to.match(/STATE_NONEXISTANT/) + }) + + }) + + describe('isDangling', function () { + + it('should return true when state is null', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: null })) + expect(await provider.isDangling()).to.equal(true) + }) + + it('should return true when state has no path', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: {} })) + expect(await provider.isDangling()).to.equal(true) + }) + + it('should return true when stat of the path fails', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: { path: '/x' } })) + sandbox.stub(fs, 'statAsync').rejects(new Error('ENOENT')) + expect(await provider.isDangling()).to.equal(true) + }) + + it('should return false when state has a valid path', async function () { + const provider = createFileSystemConfigProvider(makeNavy({ state: { path: '/x' } })) + sandbox.stub(fs, 'statAsync').resolves({}) + expect(await provider.isDangling()).to.equal(false) + }) + + }) + + describe('importCliOptions', function () { + + it('should expose an empty CLI options array', function () { + expect(createFileSystemConfigProvider.importCliOptions).to.eql([]) + }) + + }) + + describe('getImportOptionsForCLI', function () { + + it('should return { configProvider: "filesystem", path: cwd } when docker-compose config is valid', async function () { + sandbox.stub(execAsyncModule, 'execAsync').resolves('') + + expect(await createFileSystemConfigProvider.getImportOptionsForCLI({})).to.eql({ + configProvider: 'filesystem', + path: '/work/dir', + }) + }) + + it('should throw NO_DOCKER_COMPOSE_FILE when docker-compose config fails', async function () { + sandbox.stub(execAsyncModule, 'execAsync').rejects(new Error('boom')) + + let caught + try { + await createFileSystemConfigProvider.getImportOptionsForCLI({}) + } catch (e) { + caught = e + } + expect(caught.message).to.match(/NO_DOCKER_COMPOSE_FILE/) + }) + + }) + +}) diff --git a/packages/navy/src/config-providers/filesystem/index.js b/packages/navy/src/config-providers/filesystem/index.js index 0aae54f..12b7b9b 100644 --- a/packages/navy/src/config-providers/filesystem/index.js +++ b/packages/navy/src/config-providers/filesystem/index.js @@ -3,11 +3,11 @@ import path from 'path' import invariant from 'invariant' import fs from '../../util/fs' -import {execAsync} from '../../util/exec-async' +import { execAsync } from '../../util/exec-async' -import type {ConfigProvider} from '../../config-provider' -import type {State} from '../../navy' -import type {Navy} from '../../navy' +import type { ConfigProvider } from '../../config-provider' +import type { State } from '../../navy' +import type { Navy } from '../../navy' async function cwdHasValidDockerComposeConfig() { try { @@ -20,7 +20,7 @@ async function cwdHasValidDockerComposeConfig() { } export default function createFileSystemConfigProvider(navy: Navy): ConfigProvider { - return { + const provider: ConfigProvider = { async getNavyPath(): Promise { const envState: ?State = await navy.getState() @@ -37,10 +37,12 @@ export default function createFileSystemConfigProvider(navy: Navy): ConfigProvid }, async getNavyFilePath(): Promise { - return path.join(await this.getNavyPath(), 'Navyfile.js') + const navyPath = await provider.getNavyPath() + invariant(navyPath, 'STATE_NONEXISTANT', navy.name) + return path.join(navyPath, 'Navyfile.js') }, - async refreshConfig(): Promise { + async refreshConfig(): Promise { // no-op return false }, @@ -69,11 +71,13 @@ export default function createFileSystemConfigProvider(navy: Navy): ConfigProvid return false }, } + + return provider } -createFileSystemConfigProvider.importCliOptions = [] +createFileSystemConfigProvider.importCliOptions = ([]: Array>) -createFileSystemConfigProvider.getImportOptionsForCLI = async (opts) => { +createFileSystemConfigProvider.getImportOptionsForCLI = async (opts: Object): Promise => { const hasValidComposeConfig = await cwdHasValidDockerComposeConfig() invariant(hasValidComposeConfig, 'NO_DOCKER_COMPOSE_FILE') diff --git a/packages/navy/src/config-providers/npm/__tests__/index.js b/packages/navy/src/config-providers/npm/__tests__/index.js new file mode 100644 index 0000000..81b386a --- /dev/null +++ b/packages/navy/src/config-providers/npm/__tests__/index.js @@ -0,0 +1,195 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import { promises as fsp } from 'fs' +import childProcess from 'child_process' +import fs from '../../../util/fs' +import createNpmConfigProvider from '../index' + +function makeNavy({ name = 'env', state = null } = {}) { + return { + name, + getState: sinon.stub().resolves(state), + } +} + +describe('npm config provider', function () { + + let sandbox + let originalHome + + beforeEach(function () { + sandbox = sinon.createSandbox() + originalHome = process.env.HOME + process.env.HOME = '/home/test' + }) + + afterEach(function () { + sandbox.restore() + if (originalHome === undefined) { + delete process.env.HOME + } else { + process.env.HOME = originalHome + } + }) + + describe('getNavyPath', function () { + + it('should return the resolved module path when the package is installed', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: { npmPackage: 'my-config' } })) + sandbox.stub(fs, 'accessSync') + + const result = await provider.getNavyPath() + + expect(result).to.contain('node_modules') + expect(result).to.contain('my-config') + }) + + it('should throw STATE_NONEXISTANT when state is missing', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: null })) + + let caught + try { await provider.getNavyPath() } catch (e) { caught = e } + expect(caught.message).to.match(/STATE_NONEXISTANT/) + }) + + it('should throw NPM_PROVIDER_REQUIRES_PACKAGE when state has no npmPackage', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: {} })) + + let caught + try { await provider.getNavyPath() } catch (e) { caught = e } + expect(caught.message).to.match(/NPM_PROVIDER_REQUIRES_PACKAGE/) + }) + + it('should throw when accessSync fails', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: { npmPackage: 'missing' } })) + sandbox.stub(fs, 'accessSync').throws(new Error('ENOENT')) + + let caught + try { await provider.getNavyPath() } catch (e) { caught = e } + expect(caught).to.be.an('error') + }) + + }) + + describe('getNavyFilePath', function () { + + it('should return /Navyfile.js', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: { npmPackage: 'my-config' } })) + sandbox.stub(fs, 'accessSync') + + const filePath = await provider.getNavyFilePath() + expect(filePath).to.match(/my-config\/Navyfile\.js$/) + }) + + }) + + describe('refreshConfig', function () { + + it('should reinstall the package via npm and return true', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: { npmPackage: 'pkg' } })) + sandbox.stub(fsp, 'mkdir').resolves() + const execSync = sandbox.stub(childProcess, 'execSync').returns('') + + expect(await provider.refreshConfig()).to.equal(true) + const calls = execSync.getCalls().map(c => c.args[0]) + expect(calls[0]).to.match(/npm info pkg name/) + expect(calls[1]).to.match(/npm i pkg/) + }) + + it('should throw STATE_NONEXISTANT when state is missing', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: null })) + + let caught + try { await provider.refreshConfig() } catch (e) { caught = e } + expect(caught.message).to.match(/STATE_NONEXISTANT/) + }) + + it('should throw NPM_PROVIDER_REQUIRES_PACKAGE when no npmPackage in state', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: {} })) + + let caught + try { await provider.refreshConfig() } catch (e) { caught = e } + expect(caught.message).to.match(/NPM_PROVIDER_REQUIRES_PACKAGE/) + }) + + it('should throw a friendly error when npm info fails', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: { npmPackage: 'unknown-pkg' } })) + sandbox.stub(fsp, 'mkdir').resolves() + sandbox.stub(childProcess, 'execSync').callsFake(cmd => { + if (cmd.startsWith('npm info')) throw new Error('not found') + return '' + }) + + let caught + try { await provider.refreshConfig() } catch (e) { caught = e } + expect(caught.message).to.contain('Package "unknown-pkg" not found or unreachable') + }) + + }) + + describe('getLocationDisplayName', function () { + + it('should return the npmPackage from state', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: { npmPackage: 'pkg' } })) + expect(await provider.getLocationDisplayName()).to.equal('pkg') + }) + + it('should throw STATE_NONEXISTANT when state is missing', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: null })) + + let caught + try { await provider.getLocationDisplayName() } catch (e) { caught = e } + expect(caught.message).to.match(/STATE_NONEXISTANT/) + }) + + }) + + describe('isDangling', function () { + + it('should return true when state is null', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: null })) + expect(await provider.isDangling()).to.equal(true) + }) + + it('should return true when state has no npmPackage', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: {} })) + expect(await provider.isDangling()).to.equal(true) + }) + + it('should return false when state has an npmPackage', async function () { + const provider = createNpmConfigProvider(makeNavy({ state: { npmPackage: 'pkg' } })) + expect(await provider.isDangling()).to.equal(false) + }) + + }) + + describe('importCliOptions', function () { + + it('should advertise the --npm-package CLI option', function () { + expect(createNpmConfigProvider.importCliOptions).to.have.lengthOf(1) + expect(createNpmConfigProvider.importCliOptions[0][0]).to.match(/--npm-package/) + }) + + }) + + describe('getImportOptionsForCLI', function () { + + it('should install the package and return npm provider config when --npm-package is provided', async function () { + sandbox.stub(fsp, 'mkdir').resolves() + sandbox.stub(childProcess, 'execSync').returns('') + + const result = await createNpmConfigProvider.getImportOptionsForCLI({ npmPackage: 'my-pkg' }) + + expect(result).to.eql({ configProvider: 'npm', npmPackage: 'my-pkg' }) + }) + + it('should return undefined when --npm-package is not provided', async function () { + const result = await createNpmConfigProvider.getImportOptionsForCLI({}) + expect(result).to.equal(undefined) + }) + + }) + +}) diff --git a/packages/navy/src/config-providers/npm/__tests__/util.js b/packages/navy/src/config-providers/npm/__tests__/util.js index c33dbb3..16e807a 100644 --- a/packages/navy/src/config-providers/npm/__tests__/util.js +++ b/packages/navy/src/config-providers/npm/__tests__/util.js @@ -1,7 +1,7 @@ /* eslint-env mocha */ -import {expect} from 'chai' -import {pathToModule} from '../util' +import { expect } from 'chai' +import { pathToModule } from '../util' describe('npm config provider', function () { diff --git a/packages/navy/src/config-providers/npm/index.js b/packages/navy/src/config-providers/npm/index.js index b99ac00..6316560 100644 --- a/packages/navy/src/config-providers/npm/index.js +++ b/packages/navy/src/config-providers/npm/index.js @@ -1,38 +1,34 @@ /* @flow */ import path from 'path' -import {execSync} from 'child_process' +import { execSync } from 'child_process' import invariant from 'invariant' -import bluebird from 'bluebird' +import { promises as fsp } from 'fs' import fs from '../../util/fs' -import {pathToNavyRoot} from '../../navy/state' -import {pathToModule} from './util' +import { pathToNavyRoot } from '../../navy/state' +import { pathToModule } from './util' -import type {ConfigProvider} from '../../config-provider' -import type {State} from '../../navy' -import type {Navy} from '../../navy' - -const mkdirp = bluebird.promisify(require('mkdirp')) +import type { ConfigProvider } from '../../config-provider' +import type { State } from '../../navy' +import type { Navy } from '../../navy' const npmContext = path.join(pathToNavyRoot(), 'npm') const nodeModulesPath = path.join(npmContext, 'node_modules') async function tryAndInstall(pkgName: string) { - await mkdirp(nodeModulesPath) + await fsp.mkdir(nodeModulesPath, { recursive: true }) try { - // $FlowIgnore some weird bug with execSync execSync(`npm info ${pkgName} name`, { stdio: 'ignore' }) } catch (ex) { throw new Error(`Package "${pkgName}" not found or unreachable`) } - // $FlowIgnore some weird bug with execSync execSync(`npm i ${pkgName}`, { stdio: 'inherit', cwd: npmContext }) } export default function createNpmConfigProvider(navy: Navy): ConfigProvider { - return { + const provider: ConfigProvider = { async getNavyPath(): Promise { const envState: ?State = await navy.getState() @@ -47,10 +43,12 @@ export default function createNpmConfigProvider(navy: Navy): ConfigProvider { }, async getNavyFilePath(): Promise { - return path.join(await this.getNavyPath(), 'Navyfile.js') + const navyPath = await provider.getNavyPath() + invariant(navyPath, 'STATE_NONEXISTANT', navy.name) + return path.join(navyPath, 'Navyfile.js') }, - async refreshConfig(): Promise { + async refreshConfig(): Promise { const envState: ?State = await navy.getState() invariant(!!envState, 'STATE_NONEXISTANT', navy.name) @@ -75,13 +73,15 @@ export default function createNpmConfigProvider(navy: Navy): ConfigProvider { return !envState || !envState.npmPackage }, } + + return provider } createNpmConfigProvider.importCliOptions = [ ['--npm-package [package]', 'set the NPM package to use for docker compose config'], ] -createNpmConfigProvider.getImportOptionsForCLI = async (opts) => { +createNpmConfigProvider.getImportOptionsForCLI = async (opts: Object): Promise => { if (opts.npmPackage) { await tryAndInstall(opts.npmPackage) diff --git a/packages/navy/src/config.js b/packages/navy/src/config.js index ce1d9b6..ae8e0be 100644 --- a/packages/navy/src/config.js +++ b/packages/navy/src/config.js @@ -3,22 +3,22 @@ import path from 'path' import invariant from 'invariant' import fs from 'fs' -// $FlowIgnore import { promises as fsPromises } from 'fs' const DEFAULT_ENVIRONMENT_NAME = 'dev' export const DEFAULT_TLS_ROOT_CA_DIR = `${getConfigDir()}/tls-root-ca` -const DEFAULT_CONFIG = { - defaultNavy: DEFAULT_ENVIRONMENT_NAME, - externalIP: null, - tlsRootCaDir: DEFAULT_TLS_ROOT_CA_DIR, -} - export type Config = { defaultNavy: ?string, externalIP: ?string, tlsRootCaDir: ?string, + [string]: ?string, +} + +const DEFAULT_CONFIG: Config = { + defaultNavy: DEFAULT_ENVIRONMENT_NAME, + externalIP: null, + tlsRootCaDir: DEFAULT_TLS_ROOT_CA_DIR, } let _config: ?Config = null @@ -55,7 +55,7 @@ export function getConfig(): Config { export async function setConfig(config: ?Config): Promise { if (config == null) config = DEFAULT_CONFIG - await fsPromises.mkdir(path.dirname(getConfigPath()), {recursive: true}) + await fsPromises.mkdir(path.dirname(getConfigPath()), { recursive: true }) await fsPromises.writeFile(getConfigPath(), JSON.stringify(config, null, 2)) // trash cached config diff --git a/packages/navy/src/domain/__tests__/container-image.js b/packages/navy/src/domain/__tests__/container-image.js new file mode 100644 index 0000000..2a04587 --- /dev/null +++ b/packages/navy/src/domain/__tests__/container-image.js @@ -0,0 +1,123 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { + DEFAULT_REGISTRY, + DEFAULT_REGISTRY_AUTH, + getImageFromImageWithTag, + getTagFromImageWithTag, + getRegistryFromImage, + getRepositoryFromImage, +} from '../container-image' + +describe('container-image', function () { + + describe('constants', function () { + + it('should expose the default registry hostname', function () { + expect(DEFAULT_REGISTRY).to.equal('registry-1.docker.io') + }) + + it('should expose the docker config.json auth URL', function () { + expect(DEFAULT_REGISTRY_AUTH).to.equal('https://index.docker.io/v1/') + }) + + }) + + describe('getImageFromImageWithTag', function () { + + it('should strip the tag from a registry/org/image:tag string', function () { + expect(getImageFromImageWithTag('someregistry.com/some/image:latest')) + .to.equal('someregistry.com/some/image') + }) + + it('should return the image unchanged when it has slashes but no tag', function () { + expect(getImageFromImageWithTag('someregistry.com/some/image')) + .to.equal('someregistry.com/some/image') + }) + + it('should strip the tag from a single-segment image:tag string', function () { + expect(getImageFromImageWithTag('node:18')).to.equal('node') + }) + + it('should return a single-segment image unchanged when it has no tag', function () { + expect(getImageFromImageWithTag('node')).to.equal('node') + }) + + it('should not be confused by a colon in the registry port (no tag)', function () { + expect(getImageFromImageWithTag('myregistry.local:5000/foo/bar')) + .to.equal('myregistry.local:5000/foo/bar') + }) + + it('should strip the tag while preserving the registry port', function () { + expect(getImageFromImageWithTag('myregistry.local:5000/foo/bar:1.0')) + .to.equal('myregistry.local:5000/foo/bar') + }) + + }) + + describe('getTagFromImageWithTag', function () { + + it('should extract the tag from a registry/org/image:tag string', function () { + expect(getTagFromImageWithTag('someregistry.com/some/image:1.2.3')).to.equal('1.2.3') + }) + + it('should default to "latest" when slashes exist but no tag', function () { + expect(getTagFromImageWithTag('someregistry.com/some/image')).to.equal('latest') + }) + + it('should extract the tag from a single-segment image:tag', function () { + expect(getTagFromImageWithTag('node:18-alpine')).to.equal('18-alpine') + }) + + it('should default to "latest" for a single-segment image with no tag', function () { + expect(getTagFromImageWithTag('node')).to.equal('latest') + }) + + it('should not treat the registry port colon as a tag', function () { + expect(getTagFromImageWithTag('myregistry.local:5000/foo/bar')).to.equal('latest') + }) + + it('should extract the tag with a registry port present', function () { + expect(getTagFromImageWithTag('myregistry.local:5000/foo/bar:1.0')).to.equal('1.0') + }) + + }) + + describe('getRegistryFromImage', function () { + + it('should return the registry from a registry/org/image string', function () { + expect(getRegistryFromImage('someregistry.com/some/image')).to.equal('someregistry.com') + }) + + it('should fall back to the default registry when no registry is present', function () { + expect(getRegistryFromImage('library/node')).to.equal(DEFAULT_REGISTRY) + }) + + it('should fall back to default for an unprefixed image', function () { + expect(getRegistryFromImage('node')).to.equal(DEFAULT_REGISTRY) + }) + + }) + + describe('getRepositoryFromImage', function () { + + it('should prefix a single-segment image with library/', function () { + expect(getRepositoryFromImage('node')).to.equal('library/node') + }) + + it('should strip the registry from a 3-segment image', function () { + expect(getRepositoryFromImage('someregistry.com/some/image')).to.equal('some/image') + }) + + it('should return a 2-segment image unchanged', function () { + expect(getRepositoryFromImage('library/node')).to.equal('library/node') + }) + + it('should return a 4+-segment image unchanged', function () { + expect(getRepositoryFromImage('host/a/b/c')).to.equal('host/a/b/c') + }) + + }) + +}) diff --git a/packages/navy/src/domain/__tests__/oci-api-specification.js b/packages/navy/src/domain/__tests__/oci-api-specification.js new file mode 100644 index 0000000..bb95513 --- /dev/null +++ b/packages/navy/src/domain/__tests__/oci-api-specification.js @@ -0,0 +1,35 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { restSpecification, MEDIA_TYPES } from '../oci-api-specification' + +describe('oci-api-specification', function () { + + describe('restSpecification.operation', function () { + + it('should build a v2 endpoint URL for the given registry and endpoint', function () { + expect(restSpecification.operation('registry-1.docker.io', 'library/node/manifests/latest')) + .to.equal('https://registry-1.docker.io/v2/library/node/manifests/latest') + }) + + }) + + describe('restSpecification.getManifest', function () { + + it('should produce /manifests/', function () { + expect(restSpecification.getManifest('library/node', 'lts')) + .to.equal('library/node/manifests/lts') + }) + + }) + + describe('MEDIA_TYPES', function () { + + it('should expose the docker fat manifest list media type', function () { + expect(MEDIA_TYPES.FAT_MANIFEST) + .to.equal('application/vnd.docker.distribution.manifest.list.v2+json') + }) + + }) + +}) diff --git a/packages/navy/src/driver-logging.js b/packages/navy/src/driver-logging.js index 9adf9a3..17f3a9d 100644 --- a/packages/navy/src/driver-logging.js +++ b/packages/navy/src/driver-logging.js @@ -1,4 +1,4 @@ -import {dots} from 'cli-spinners' +import { dots } from 'cli-spinners' import chalk from 'chalk' let _isDriverLogging = false diff --git a/packages/navy/src/driver.js b/packages/navy/src/driver.js index 5baa22e..98f3c9d 100644 --- a/packages/navy/src/driver.js +++ b/packages/navy/src/driver.js @@ -2,8 +2,8 @@ import DockerCompose from './drivers/docker-compose' -import type {ServiceList} from './service' -import type {Navy} from './navy' +import type { ServiceList } from './service' +import type { Navy } from './navy' export type Driver = { launch(services: Array, opts: ?Object): Promise; diff --git a/packages/navy/src/drivers/docker-compose/__tests__/client.js b/packages/navy/src/drivers/docker-compose/__tests__/client.js new file mode 100644 index 0000000..70370dc --- /dev/null +++ b/packages/navy/src/drivers/docker-compose/__tests__/client.js @@ -0,0 +1,291 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import path from 'path' +import { EventEmitter } from 'events' +import fs from '../../../util/fs' +import * as execAsyncModule from '../../../util/exec-async' +import * as driverLogging from '../../../driver-logging' +import { createComposeClient } from '../client' + +function makeNavy({ name = 'env', normalisedName = 'env', configProvider = null } = {}) { + return { + name, + normalisedName, + getConfigProvider: sinon.stub().resolves(configProvider), + } +} + +describe('docker-compose client', function () { + + let sandbox + let originalHome + let execStub + + beforeEach(function () { + sandbox = sinon.createSandbox() + originalHome = process.env.HOME + process.env.HOME = '/home/test' + + execStub = sandbox.stub(execAsyncModule, 'execAsync').resolves('') + sandbox.stub(driverLogging, 'log') + }) + + afterEach(function () { + sandbox.restore() + if (originalHome === undefined) { + delete process.env.HOME + } else { + process.env.HOME = originalHome + } + }) + + describe('createComposeClient', function () { + + it('should expose exec, getCompiledDockerComposePath, getDockerComposeFilePath, getOriginalDockerComposeDirectory', function () { + const client = createComposeClient(makeNavy()) + + expect(client).to.have.property('exec').that.is.a('function') + expect(client).to.have.property('getCompiledDockerComposePath').that.is.a('function') + expect(client).to.have.property('getDockerComposeFilePath').that.is.a('function') + expect(client).to.have.property('getOriginalDockerComposeDirectory').that.is.a('function') + }) + + }) + + describe('getCompiledDockerComposePath', function () { + + it('should return $HOME/.navy/navies//docker-compose.tmp.yml', function () { + const client = createComposeClient(makeNavy({ normalisedName: 'envname' })) + + expect(client.getCompiledDockerComposePath()).to.equal( + path.join('/home/test', '.navy', 'navies', 'envname', 'docker-compose.tmp.yml') + ) + }) + + }) + + describe('getDockerComposeFilePath', function () { + + it('should return the compiled path when the file exists', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + + const result = await client.getDockerComposeFilePath() + expect(result).to.contain('docker-compose.tmp.yml') + }) + + it('should return null when the compiled file does not exist', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').rejects(new Error('ENOENT')) + + expect(await client.getDockerComposeFilePath()).to.equal(null) + }) + + }) + + describe('getOriginalDockerComposeDirectory', function () { + + it('should return the navy path from the config provider', async function () { + const client = createComposeClient(makeNavy({ + configProvider: { getNavyPath: async () => '/some/path' }, + })) + + expect(await client.getOriginalDockerComposeDirectory()).to.equal('/some/path') + }) + + it('should throw an invariant violation when there is no config provider', async function () { + const client = createComposeClient(makeNavy({ configProvider: null })) + + let caught + try { + await client.getOriginalDockerComposeDirectory() + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.match(/NO_CONFIG_PROVIDER/) + }) + + }) + + describe('exec', function () { + + it('should call docker compose with -p -f when compiled file exists', async function () { + const client = createComposeClient(makeNavy({ normalisedName: 'env' })) + sandbox.stub(fs, 'statAsync').resolves({}) + + await client.exec('up', ['-d']) + + expect(execStub.calledOnce).to.equal(true) + const [cmd, args, , opts] = execStub.firstCall.args + expect(cmd).to.equal('docker compose') + expect(args[0]).to.equal('-p') + expect(args[1]).to.equal('env') + expect(args[2]).to.equal('-f') + expect(args[3]).to.contain('docker-compose.tmp.yml') + expect(args.slice(4)).to.eql(['up', '-d']) + expect(opts.maxBuffer).to.equal(Infinity) + }) + + it('should set cwd to the original docker-compose directory when the compiled file is missing', async function () { + const client = createComposeClient(makeNavy({ + configProvider: { getNavyPath: async () => '/orig/path' }, + })) + sandbox.stub(fs, 'statAsync').rejects(new Error('ENOENT')) + + await client.exec('config') + + const [, args, , opts] = execStub.firstCall.args + expect(args).to.not.include('-f') + expect(opts.cwd).to.equal('/orig/path') + }) + + it('should pass useOriginalDockerComposeFiles to bypass the compiled file', async function () { + const client = createComposeClient(makeNavy({ + configProvider: { getNavyPath: async () => '/orig/path' }, + })) + sandbox.stub(fs, 'statAsync').resolves({}) + + await client.exec('config', [], { useOriginalDockerComposeFiles: true }) + + const [, args, , opts] = execStub.firstCall.args + expect(args).to.not.include('-f') + expect(opts.cwd).to.equal('/orig/path') + }) + + it('should respect a custom maxBuffer', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + + await client.exec('up', [], { maxBuffer: 1024 }) + + const [, , , opts] = execStub.firstCall.args + expect(opts.maxBuffer).to.equal(1024) + }) + + it('should default args to an empty array', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + + await client.exec('config') + + expect(execStub.calledOnce).to.equal(true) + }) + + it('should pipe child stdout/stderr through the spinner log when noLog and pipeLog are not set', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + + const child = new EventEmitter() + child.stdout = new EventEmitter() + child.stderr = new EventEmitter() + execStub.callsFake(async (cmd, args, callback) => { + callback(child) + child.stdout.emit('data', 'out-line') + child.stderr.emit('data', 'err-line') + return '' + }) + + await client.exec('up') + + expect(driverLogging.log.callCount).to.equal(2) + expect(driverLogging.log.firstCall.args[0]).to.equal('out-line') + expect(driverLogging.log.secondCall.args[0]).to.equal('err-line') + }) + + it('should pipe child stdout/stderr to process.stdout/stderr when pipeLog is true', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + + const child = new EventEmitter() + child.stdout = new EventEmitter() + child.stderr = new EventEmitter() + const stdoutWrite = sandbox.stub(process.stdout, 'write').returns(true) + const stderrWrite = sandbox.stub(process.stderr, 'write').returns(true) + + execStub.callsFake(async (cmd, args, callback) => { + callback(child) + child.stdout.emit('data', 'out') + child.stderr.emit('data', 'err') + return '' + }) + + await client.exec('logs', [], { pipeLog: true }) + + expect(stdoutWrite.calledWith('out')).to.equal(true) + expect(stderrWrite.calledWith('err')).to.equal(true) + }) + + it('should NOT attach stdout/stderr listeners when noLog is true', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + + const child = new EventEmitter() + child.stdout = new EventEmitter() + child.stderr = new EventEmitter() + + execStub.callsFake(async (cmd, args, callback) => { + callback(child) + return '' + }) + + await client.exec('config', [], { noLog: true }) + + expect(child.stdout.listenerCount('data')).to.equal(0) + expect(child.stderr.listenerCount('data')).to.equal(0) + }) + + it('should map "Can\'t find a suitable configuration file" errors to NO_DOCKER_COMPOSE_FILE invariant', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + execStub.rejects(new Error("Can't find a suitable configuration file")) + + let caught + try { + await client.exec('config') + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.match(/NO_DOCKER_COMPOSE_FILE/) + }) + + it('should rethrow other exec errors as-is', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + const err = new Error('some other failure') + execStub.rejects(err) + + let caught + try { + await client.exec('up') + } catch (e) { + caught = e + } + + expect(caught).to.equal(err) + }) + + it('should rethrow errors that have no message', async function () { + const client = createComposeClient(makeNavy()) + sandbox.stub(fs, 'statAsync').resolves({}) + const err = {} + execStub.rejects(err) + + let caught + try { + await client.exec('up') + } catch (e) { + caught = e + } + + expect(caught).to.equal(err) + }) + + }) + +}) diff --git a/packages/navy/src/drivers/docker-compose/__tests__/index.js b/packages/navy/src/drivers/docker-compose/__tests__/index.js new file mode 100644 index 0000000..b37dae0 --- /dev/null +++ b/packages/navy/src/drivers/docker-compose/__tests__/index.js @@ -0,0 +1,421 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import yaml from 'js-yaml' +import dockerClient from '../../../util/docker-client' +import fs from '../../../util/fs' +import * as execAsyncModule from '../../../util/exec-async' +import * as driverLogging from '../../../driver-logging' +import { Status } from '../../../service' +import createDockerComposeDriver from '../index' + +function makeNavy({ normalisedName = 'env', configProvider = null } = {}) { + return { + name: normalisedName, + normalisedName, + getConfigProvider: sinon.stub().resolves(configProvider), + } +} + +describe('docker-compose driver', function () { + + let sandbox + let originalHome + let execStub + + beforeEach(function () { + sandbox = sinon.createSandbox() + originalHome = process.env.HOME + process.env.HOME = '/home/test' + + execStub = sandbox.stub(execAsyncModule, 'execAsync').resolves('') + sandbox.stub(driverLogging, 'log') + sandbox.stub(fs, 'statAsync').resolves({}) + }) + + afterEach(function () { + sandbox.restore() + if (originalHome === undefined) { + delete process.env.HOME + } else { + process.env.HOME = originalHome + } + }) + + describe('launch', function () { + + it('should run "docker compose up -d" with the given services and no extra args by default', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.launch(['api']) + + const [, args] = execStub.firstCall.args + expect(args).to.include('up') + expect(args).to.include('-d') + expect(args).to.include('api') + }) + + it('should map opts.noDeps to --no-deps and opts.forceRecreate to --force-recreate', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.launch(['api'], { noDeps: true, forceRecreate: true }) + + const [, args] = execStub.firstCall.args + expect(args).to.include('--no-deps') + expect(args).to.include('--force-recreate') + }) + + it('should ignore unknown opts keys', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.launch(['api'], { unknownOption: true }) + + const [, args] = execStub.firstCall.args + expect(args.includes('unknownOption')).to.equal(false) + }) + + it('should default services to an empty array if not given', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.launch(undefined, {}) + + const [, args] = execStub.firstCall.args + expect(args.slice(-2)).to.eql(['up', '-d']) + }) + + it('should default opts to an empty object', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.launch(['api']) + + expect(execStub.calledOnce).to.equal(true) + }) + + it('should still call exec when opts is null (treated falsy by checks)', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.launch(['api'], null) + + expect(execStub.calledOnce).to.equal(true) + }) + + }) + + describe('destroy', function () { + + it('should run kill followed by down -v', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.destroy() + + expect(execStub.callCount).to.equal(2) + expect(execStub.firstCall.args[1]).to.include('kill') + expect(execStub.secondCall.args[1]).to.include('down') + expect(execStub.secondCall.args[1]).to.include('-v') + }) + + }) + + describe('start/stop/restart/kill', function () { + + [ + { method: 'start', cmd: 'start' }, + { method: 'stop', cmd: 'stop' }, + { method: 'restart', cmd: 'restart' }, + { method: 'kill', cmd: 'kill' }, + ].forEach(({ method, cmd }) => { + it(`should call docker compose ${cmd} with the given services`, async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver[method](['api']) + + const [, args] = execStub.firstCall.args + expect(args).to.include(cmd) + expect(args).to.include('api') + }) + }) + + }) + + describe('rm', function () { + + it('should call docker compose rm -f -v with services', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.rm(['api']) + + const [, args] = execStub.firstCall.args + expect(args).to.include('rm') + expect(args).to.include('-f') + expect(args).to.include('-v') + expect(args).to.include('api') + }) + + it('should default services to [] when not provided', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.rm() + + const [, args] = execStub.firstCall.args + expect(args).to.include('rm') + expect(args).to.include('-f') + expect(args).to.include('-v') + }) + + }) + + describe('update', function () { + + it('should pull all services then relaunch only the running ones', async function () { + const navy = makeNavy() + const driver = createDockerComposeDriver(navy) + sandbox.stub(dockerClient, 'listContainers').resolves([ + { Labels: { 'com.docker.compose.service': 'api' } }, + { Labels: { 'com.docker.compose.service': 'redis' } }, + ]) + + await driver.update(['api', 'web', 'redis']) + + const pullCall = execStub.getCalls().find(c => c.args[1].includes('pull')) + const relaunchCall = execStub.getCalls() + .find(c => c.args[1].includes('up') && c.args[1].includes('--no-deps')) + + expect(pullCall.args[1]).to.include('api') + expect(pullCall.args[1]).to.include('web') + expect(pullCall.args[1]).to.include('redis') + + expect(relaunchCall.args[1]).to.include('api') + expect(relaunchCall.args[1]).to.include('redis') + expect(relaunchCall.args[1].includes('web')).to.equal(false) + }) + + it('should not call up when no services need relaunching', async function () { + const driver = createDockerComposeDriver(makeNavy()) + sandbox.stub(dockerClient, 'listContainers').resolves([]) + + await driver.update(['api']) + + const upCall = execStub.getCalls().find(c => c.args[1].includes('--no-deps')) + expect(upCall).to.equal(undefined) + }) + + it('should default services to an empty array when not provided', async function () { + const driver = createDockerComposeDriver(makeNavy()) + sandbox.stub(dockerClient, 'listContainers').resolves([]) + + await driver.update() + + expect(execStub.firstCall.args[1]).to.include('pull') + }) + + }) + + describe('spawnLogStream', function () { + + it('should call docker compose logs -f --tail=250 services with pipeLog', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.spawnLogStream(['api']) + + const [, args, , opts] = execStub.firstCall.args + expect(args).to.include('logs') + expect(args).to.include('-f') + expect(args).to.include('--tail=250') + expect(args).to.include('api') + expect(opts.maxBuffer).to.equal(Infinity) + }) + + it('should default services to [] when not provided', async function () { + const driver = createDockerComposeDriver(makeNavy()) + + await driver.spawnLogStream() + + const [, args] = execStub.firstCall.args + expect(args).to.include('logs') + }) + + }) + + describe('ps', function () { + + let listContainersStub + let getContainerStub + + beforeEach(function () { + listContainersStub = sandbox.stub(dockerClient, 'listContainers') + getContainerStub = sandbox.stub(dockerClient, 'getContainer') + }) + + it('should map docker inspect output to a ServiceList of running services', async function () { + const driver = createDockerComposeDriver(makeNavy({ normalisedName: 'env' })) + listContainersStub.resolves([{ Id: 'c1' }]) + getContainerStub.returns({ + inspect: async () => ({ + Id: 'c1-full', + Config: { Image: 'api:1', Labels: { 'com.docker.compose.service': 'api' } }, + State: { Running: true }, + }) + }) + + const services = await driver.ps() + + expect(services).to.have.lengthOf(1) + expect(services[0]).to.include({ + id: 'c1-full', + name: 'api', + image: 'api:1', + status: Status.RUNNING, + }) + expect(services[0].raw).to.have.property('Id', 'c1-full') + }) + + it('should mark non-running services as EXITED', async function () { + const driver = createDockerComposeDriver(makeNavy()) + listContainersStub.resolves([{ Id: 'c1' }]) + getContainerStub.returns({ + inspect: async () => ({ + Id: 'c1', Config: { Image: 'a', Labels: { 'com.docker.compose.service': 'a' } }, State: { Running: false }, + }) + }) + + const services = await driver.ps() + + expect(services[0].status).to.equal(Status.EXITED) + }) + + it('should add a service-specific label filter when service is provided', async function () { + const driver = createDockerComposeDriver(makeNavy({ normalisedName: 'env' })) + listContainersStub.resolves([]) + + await driver.ps('api') + + const filter = listContainersStub.firstCall.args[0] + expect(filter.filters.label).to.include('com.docker.compose.project=env') + expect(filter.filters.label).to.include('com.docker.compose.service=api') + }) + + }) + + describe('port', function () { + + it('should return the host port from container.NetworkSettings.Ports[/tcp]', async function () { + const driver = createDockerComposeDriver(makeNavy()) + sandbox.stub(dockerClient, 'listContainers').resolves([{ Id: 'c1' }]) + sandbox.stub(dockerClient, 'getContainer').returns({ + inspect: async () => ({ + Id: 'c1', + Config: { Image: 'a', Labels: { 'com.docker.compose.service': 'api' } }, + State: { Running: true }, + NetworkSettings: { Ports: { '80/tcp': [{ HostPort: '8080' }] } }, + }) + }) + + expect(await driver.port('api', 80)).to.equal(8080) + }) + + it('should return null when no container is found for the service', async function () { + const driver = createDockerComposeDriver(makeNavy()) + sandbox.stub(dockerClient, 'listContainers').resolves([]) + + expect(await driver.port('api', 80)).to.equal(null) + }) + + it('should return null when port mapping is missing or empty', async function () { + const driver = createDockerComposeDriver(makeNavy()) + sandbox.stub(dockerClient, 'listContainers').resolves([{ Id: 'c1' }]) + sandbox.stub(dockerClient, 'getContainer').returns({ + inspect: async () => ({ + Id: 'c1', + Config: { Image: 'a', Labels: { 'com.docker.compose.service': 'api' } }, + State: { Running: true }, + NetworkSettings: { Ports: {} }, + }) + }) + + expect(await driver.port('api', 80)).to.equal(null) + }) + + it('should default the index argument to 1 when not provided', async function () { + const driver = createDockerComposeDriver(makeNavy()) + sandbox.stub(dockerClient, 'listContainers').resolves([{ Id: 'c1' }]) + sandbox.stub(dockerClient, 'getContainer').returns({ + inspect: async () => ({ + Id: 'c1', + Config: { Image: 'a', Labels: { 'com.docker.compose.service': 'api' } }, + State: { Running: true }, + NetworkSettings: { Ports: { '80/tcp': [{ HostPort: '8080' }] } }, + }) + }) + + expect(await driver.port('api', 80)).to.equal(8080) + }) + + }) + + describe('writeConfig', function () { + + it('should write the YAML serialised config to the compiled compose path', async function () { + const driver = createDockerComposeDriver(makeNavy({ normalisedName: 'env' })) + const writeStub = sandbox.stub(fs, 'writeFileAsync').resolves() + + const config = { version: '3', services: { api: { image: 'api' } } } + await driver.writeConfig(config) + + expect(writeStub.calledOnce).to.equal(true) + expect(writeStub.firstCall.args[0]).to.contain('docker-compose.tmp.yml') + const written = yaml.load(writeStub.firstCall.args[1]) + expect(written).to.eql(config) + }) + + }) + + describe('getConfig', function () { + + it('should run docker compose config and parse the YAML output', async function () { + const driver = createDockerComposeDriver(makeNavy({ + configProvider: { getNavyPath: async () => '/orig' }, + })) + execStub.resolves('version: "3"\nservices:\n api:\n image: api:1\n') + + const config = await driver.getConfig() + + expect(config).to.eql({ version: '3', services: { api: { image: 'api:1' } } }) + }) + + }) + + describe('getLaunchedServiceNames', function () { + + it('should return the compose service names of all running containers', async function () { + const driver = createDockerComposeDriver(makeNavy({ normalisedName: 'env' })) + const listStub = sandbox.stub(dockerClient, 'listContainers').resolves([ + { Labels: { 'com.docker.compose.service': 'api' } }, + { Labels: { 'com.docker.compose.service': 'web' } }, + ]) + + const names = await driver.getLaunchedServiceNames() + + expect(names).to.eql(['api', 'web']) + const filter = listStub.firstCall.args[0] + expect(filter.filters.label).to.include('com.docker.compose.project=env') + }) + + }) + + describe('getAvailableServiceNames', function () { + + it('should return the keys of services from the parsed config', async function () { + const driver = createDockerComposeDriver(makeNavy({ + configProvider: { getNavyPath: async () => '/orig' }, + })) + execStub.resolves('services:\n api:\n image: a\n web:\n image: w\n') + + const names = await driver.getAvailableServiceNames() + + expect(names).to.eql(['api', 'web']) + }) + + }) + +}) diff --git a/packages/navy/src/drivers/docker-compose/client.js b/packages/navy/src/drivers/docker-compose/client.js index 3a3dc4a..a0482e7 100644 --- a/packages/navy/src/drivers/docker-compose/client.js +++ b/packages/navy/src/drivers/docker-compose/client.js @@ -4,17 +4,18 @@ import path from 'path' import invariant from 'invariant' import fs from '../../util/fs' -import {execAsync} from '../../util/exec-async' -import {log} from '../../driver-logging' -import {pathToNavy} from '../../navy/state' +import { execAsync } from '../../util/exec-async' +import { log } from '../../driver-logging' +import { pathToNavy } from '../../navy/state' -import type {ConfigProvider} from '../../config-provider' -import type {Navy} from '../../navy' +import type { ConfigProvider } from '../../config-provider' +import type { Navy } from '../../navy' export type ComposeClient = { exec(command: string, args: any, opts?: Object): Promise, getCompiledDockerComposePath(): string, getDockerComposeFilePath(): Promise, + getOriginalDockerComposeDirectory(): Promise, } export type ExecOpts = { diff --git a/packages/navy/src/drivers/docker-compose/index.js b/packages/navy/src/drivers/docker-compose/index.js index 5d6dd4b..81ee4c3 100644 --- a/packages/navy/src/drivers/docker-compose/index.js +++ b/packages/navy/src/drivers/docker-compose/index.js @@ -4,12 +4,12 @@ import yaml from 'js-yaml' import fs from '../../util/fs' import docker from '../../util/docker-client' -import {createComposeClient} from './client' -import {Status as ServiceStatus} from '../../service' +import { createComposeClient } from './client' +import { Status as ServiceStatus } from '../../service' -import type {Driver} from '../../driver' -import type {ServiceList} from '../../service' -import type {Navy} from '../../navy' +import type { Driver } from '../../driver' +import type { ServiceList } from '../../service' +import type { Navy } from '../../navy' const debug = require('debug')('navy:docker-compose') @@ -32,7 +32,7 @@ export default function createDockerComposeDriver(navy: Navy): Driver { const driver = { async launch(services: Array, opts: ?Object = {}): Promise { - const additionalArgs = [] + const additionalArgs: Array = [] debug('Got launch', services, opts) @@ -117,7 +117,7 @@ export default function createDockerComposeDriver(navy: Navy): Driver { await exec('pull', services) // only relaunch services which are already running - const launchedServiceNames = toLookupTable(await this.getLaunchedServiceNames()) + const launchedServiceNames = toLookupTable(await driver.getLaunchedServiceNames()) const servicesToRelaunch = services.filter((name) => launchedServiceNames[name]) if (servicesToRelaunch.length) { @@ -136,8 +136,8 @@ export default function createDockerComposeDriver(navy: Navy): Driver { async port(service: string, privatePort: number, index: ?number): Promise { if (index == null) index = 1 - const container = (await this.ps(service)).pop() - if (!container) { + const container = (await driver.ps(service)).pop() + if (!container || !container.raw) { return null } @@ -151,7 +151,7 @@ export default function createDockerComposeDriver(navy: Navy): Driver { }, async writeConfig(config: Object): Promise { - const yamlOut = yaml.safeDump(config, {skipInvalid: true}) + const yamlOut = yaml.dump(config, { skipInvalid: true }) await fs.writeFileAsync(getCompiledDockerComposePath(), yamlOut) debug('Wrote docker-compose.tmp.yml', yamlOut) @@ -159,7 +159,7 @@ export default function createDockerComposeDriver(navy: Navy): Driver { async getConfig(): Promise { const output = await exec('config', [], { useOriginalDockerComposeFiles: true, noLog: true }) - const config = yaml.safeLoad(output) + const config = yaml.load(output) return config }, @@ -191,8 +191,8 @@ export default function createDockerComposeDriver(navy: Navy): Driver { return driver } -function toLookupTable(keys: Array): Object { - const lookupTable = {} +function toLookupTable(keys: Array): {[string]: boolean} { + const lookupTable: {[string]: boolean} = {} keys.forEach((key) => lookupTable[key] = true) return lookupTable } diff --git a/packages/navy/src/errors.js b/packages/navy/src/errors.js index 7116eb9..e3b99bf 100644 --- a/packages/navy/src/errors.js +++ b/packages/navy/src/errors.js @@ -3,7 +3,7 @@ import chalk from 'chalk' export class NavyError { - message: string; + message: string constructor(message: string) { this.message = message diff --git a/packages/navy/src/http-proxy.js b/packages/navy/src/http-proxy.js index 76b855a..0c4dc33 100644 --- a/packages/navy/src/http-proxy.js +++ b/packages/navy/src/http-proxy.js @@ -5,13 +5,79 @@ import path from 'path' import yaml from 'js-yaml' import docker from './util/docker-client' import fs from 'fs' -import {getCertsPath} from './util/https' -import {execAsync} from './util/exec-async' -import {log} from './driver-logging' -import {getLaunchedNavyNames} from './navy' +import { getCertsPath } from './util/https' +import { execAsync } from './util/exec-async' +import { log } from './driver-logging' +import { getLaunchedNavyNames } from './navy' -async function updateComposeConfig(navies: Array) { - const networks = await docker.listNetworks() +const DEFAULT_PROXY_IMAGE = 'navycloud/navy-proxy' +const DEFAULT_DOCKER_SOCKET = '/var/run/docker.sock' + +export function resolveProxyImage(navyFile: ?Object): string { + return process.env.NAVY_HTTP_PROXY_IMAGE || + (navyFile && navyFile.httpProxyImage) || + DEFAULT_PROXY_IMAGE +} + +export function resolveProxyEnvFromNavyFile(navyFile: ?Object): {[key: string]: string} { + if (!navyFile) return {} + const raw: any = navyFile.httpProxyEnv + if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {} + + const result: {[key: string]: string} = {} + for (const key of Object.keys(raw)) { + const value: any = raw[key] + if (value === null || value === undefined) continue + const coerced = String(value) + if (coerced === '') continue + result[key] = coerced + } + return result +} + +export function resolveProxyEnvAllowlist(): {[key: string]: string} { + const allowlist = process.env.NAVY_HTTP_PROXY_ENV + if (!allowlist) return {} + + const seen: Set = new Set() + const result: {[key: string]: string} = {} + for (const rawName of allowlist.split(',')) { + const name = rawName.trim() + if (!name || seen.has(name)) continue + seen.add(name) + const value = process.env[name] + if (typeof value !== 'string' || value === '') continue + result[name] = value + } + return result +} + +export function resolveProxyEnv(navyFile: ?Object): ?{[key: string]: string} { + const merged = { + ...resolveProxyEnvFromNavyFile(navyFile), + ...resolveProxyEnvAllowlist(), + } + if (Object.keys(merged).length === 0) return null + return merged +} + +// Resolve the host path to the Docker socket. The proxy container needs to +// read events from the same daemon as the rest of navy, so we honour +// DOCKER_HOST when it points at a unix socket (e.g. on CI where +// `docker/setup-docker-action` puts the daemon on a custom path) and fall +// back to the conventional `/var/run/docker.sock` otherwise. +export function resolveDockerSocketPath(): string { + const dockerHost = process.env.DOCKER_HOST + if (dockerHost && dockerHost.indexOf('unix://') === 0) { + const socketPath = dockerHost.slice('unix://'.length) + if (socketPath) return socketPath + } + return DEFAULT_DOCKER_SOCKET +} + +async function updateComposeConfig(navies: Array, navyFile: ?Object) { + const allNetworks = await docker.listNetworks() + const networks = allNetworks .filter(net => net.Name.indexOf('_') !== -1) // is docker-compose network? .filter(net => { for (const navy of navies) { @@ -30,7 +96,7 @@ async function updateComposeConfig(navies: Array) { }) const ports = ['80:80'] const volumes = [ - '/var/run/docker.sock:/tmp/docker.sock:ro', + `${resolveDockerSocketPath()}:/tmp/docker.sock:ro`, ] // Enable HTTPS for services that @@ -42,15 +108,18 @@ async function updateComposeConfig(navies: Array) { volumes.push(`${certsPath}:/etc/nginx/dhparam`) // to persist DH params } + const proxyEnv = resolveProxyEnv(navyFile) + const config = { version: '2', services: { 'nginx-proxy': { - image: 'navycloud/navy-proxy', + image: resolveProxyImage(navyFile), ports, networks: networks.map(net => net.Name), volumes, + ...(proxyEnv ? { environment: proxyEnv } : {}), restart: 'always', }, }, @@ -76,7 +145,7 @@ export async function reconfigureHTTPProxy(opts: Object = {}) { } if (!opts.navies) opts.navies = await getLaunchedNavyNames() - await updateComposeConfig(opts.navies) + await updateComposeConfig(opts.navies, opts.navyFile) log('Configuring HTTP proxy...') await execAsync('docker compose', [ diff --git a/packages/navy/src/index.js b/packages/navy/src/index.js index 2d4c95a..bb361fc 100644 --- a/packages/navy/src/index.js +++ b/packages/navy/src/index.js @@ -1,6 +1,6 @@ /* @flow */ -export {Navy, getNavy, getLaunchedNavies, getLaunchedNavyNames} from './navy' +export { Navy, getNavy, getLaunchedNavies, getLaunchedNavyNames } from './navy' export * as Service from './service' -export {NavyError} from './errors' -export {middlewareHelpers} from './middleware/helpers' +export { NavyError } from './errors' +export { middlewareHelpers } from './middleware/helpers' diff --git a/packages/navy/src/middleware/__tests__/add-service-proxy-config.js b/packages/navy/src/middleware/__tests__/add-service-proxy-config.js new file mode 100644 index 0000000..03eb6f1 --- /dev/null +++ b/packages/navy/src/middleware/__tests__/add-service-proxy-config.js @@ -0,0 +1,226 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import * as serviceHostModule from '../../util/service-host' +import * as httpsModule from '../../util/https' +import addServiceProxyConfig from '../add-service-proxy-config' + +function makeNavy({ navyFile = null, externalIP = '10.0.0.1' } = {}) { + return { + name: 'env', + normalisedName: 'env', + getNavyFile: sinon.stub().resolves(navyFile), + externalIP: sinon.stub().resolves(externalIP), + } +} + +describe('add-service-proxy-config middleware', function () { + + let sandbox + let createCertStub + let createHostStub + + beforeEach(function () { + sandbox = sinon.createSandbox() + createCertStub = sandbox.stub(httpsModule, 'createCert').resolves() + createHostStub = sandbox.stub(serviceHostModule, 'createHostForService') + .callsFake(async (svc, navyName) => `${svc}.${navyName}.test.local`) + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('factory', function () { + + it('should return an async middleware function when invoked with a navy', function () { + const fn = addServiceProxyConfig(makeNavy()) + expect(fn).to.be.a('function') + }) + + }) + + describe('auto-proxy of port 80', function () { + + it('should add VIRTUAL_HOST/VIRTUAL_PORT for services exposing port 80 by default', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + const config = { + services: { + web: { ports: ['80:80'] }, + }, + } + + const result = await middleware(config, {}) + + expect(result.services.web.environment.VIRTUAL_HOST).to.equal('web.env.test.local') + expect(result.services.web.environment.VIRTUAL_PORT).to.equal(80) + }) + + it('should not auto-proxy services that do not expose port 80', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + const config = { + services: { + worker: { ports: ['8080:8080'] }, + }, + } + + const result = await middleware(config, {}) + + expect(result.services.worker).to.eql({ ports: ['8080:8080'] }) + }) + + it('should not auto-proxy services that have no ports declared', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + const config = { + services: { + worker: {}, + }, + } + + const result = await middleware(config, {}) + + expect(result.services.worker).to.eql({}) + }) + + }) + + describe('explicit httpProxy config in navyFile', function () { + + it('should use the explicit httpProxy config to set VIRTUAL_HOST and VIRTUAL_PORT', async function () { + const navy = makeNavy({ + navyFile: { httpProxy: { api: { port: 3000 } } }, + }) + const middleware = addServiceProxyConfig(navy) + + const result = await middleware({ + services: { + api: { ports: ['3000:3000'] }, + }, + }, {}) + + expect(result.services.api.environment.VIRTUAL_PORT).to.equal(3000) + expect(result.services.api.environment.VIRTUAL_HOST).to.equal('api.env.test.local') + }) + + it('should issue a TLS cert when proxyConfig.enableHttps is set', async function () { + const navy = makeNavy({ + navyFile: { httpProxy: { api: { port: 3000, enableHttps: true } } }, + }) + const middleware = addServiceProxyConfig(navy) + + await middleware({ services: { api: {} } }, {}) + + expect(createCertStub.calledOnce).to.equal(true) + expect(createCertStub.firstCall.args[0]).to.eql({ hostName: 'api.env.test.local' }) + }) + + it('should not issue a TLS cert when proxyConfig is implicit (no enableHttps)', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + + await middleware({ services: { web: { ports: ['80:80'] } } }, {}) + + expect(createCertStub.called).to.equal(false) + }) + + }) + + describe('httpProxyAutoPorts navyFile config', function () { + + it('should auto-proxy a different port when configured via httpProxyAutoPorts', async function () { + const navy = makeNavy({ navyFile: { httpProxyAutoPorts: ['3000'] } }) + const middleware = addServiceProxyConfig(navy) + + const result = await middleware({ + services: { + api: { ports: ['3000:3000'] }, + }, + }, {}) + + expect(result.services.api.environment.VIRTUAL_PORT).to.equal(3000) + }) + + it('should fall back to ["80"] when httpProxyAutoPorts is not an array', async function () { + const navy = makeNavy({ navyFile: { httpProxyAutoPorts: 'not-an-array' } }) + const middleware = addServiceProxyConfig(navy) + + const result = await middleware({ + services: { + web: { ports: ['80:80'] }, + }, + }, {}) + + expect(result.services.web.environment.VIRTUAL_PORT).to.equal(80) + }) + + }) + + describe('port matching forms', function () { + + it('should match a numeric port equal to the auto port', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + const result = await middleware({ services: { web: { ports: [80] } } }, {}) + // eslint-disable-next-line no-unused-expressions + expect(result.services.web.environment).to.exist + }) + + it('should match a "80/tcp" protocol-suffixed port', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + const result = await middleware({ services: { web: { ports: ['80/tcp'] } } }, {}) + // eslint-disable-next-line no-unused-expressions + expect(result.services.web.environment).to.exist + }) + + it('should match a port object with a target field equal to the auto port', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + const result = await middleware({ services: { web: { ports: [{ target: 80, published: 8080 }] } } }, {}) + // eslint-disable-next-line no-unused-expressions + expect(result.services.web.environment).to.exist + }) + + }) + + describe('environment merge', function () { + + it('should not overwrite existing env vars with VIRTUAL_HOST/VIRTUAL_PORT', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + + const result = await middleware({ + services: { + web: { + ports: ['80:80'], + environment: { VIRTUAL_HOST: 'preset.host', OTHER: 'x' }, + }, + }, + }, {}) + + expect(result.services.web.environment.VIRTUAL_HOST).to.equal('preset.host') + expect(result.services.web.environment.OTHER).to.equal('x') + }) + + }) + + it('should preserve other top-level config keys', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + + const result = await middleware({ + version: '3.7', + services: { web: { ports: ['80:80'] } }, + networks: { default: {} }, + }, {}) + + expect(result.version).to.equal('3.7') + expect(result.networks).to.eql({ default: {} }) + }) + + it('should not call externalIP/createHostForService for services without proxy config', async function () { + const middleware = addServiceProxyConfig(makeNavy()) + + await middleware({ + services: { worker: { ports: ['9000:9000'] } }, + }, {}) + + expect(createHostStub.called).to.equal(false) + }) + +}) diff --git a/packages/navy/src/middleware/__tests__/develop.js b/packages/navy/src/middleware/__tests__/develop.js new file mode 100644 index 0000000..e8f2204 --- /dev/null +++ b/packages/navy/src/middleware/__tests__/develop.js @@ -0,0 +1,78 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import develop from '../develop' + +describe('develop middleware', function () { + + it('should return the service unchanged when no service state exists', function () { + const config = { services: { api: { image: 'api', command: 'npm start' } } } + const state = { services: {} } + + const result = develop(config, state) + + expect(result.services.api).to.eql({ image: 'api', command: 'npm start' }) + }) + + it('should return the service unchanged when state has no _develop entry', function () { + const config = { services: { api: { image: 'api', command: 'npm start' } } } + const state = { services: { api: { unrelated: true } } } + + const result = develop(config, state) + + expect(result.services.api).to.eql({ image: 'api', command: 'npm start' }) + }) + + it('should set stdin_open and append _develop.mounts as volumes', function () { + const config = { + services: { + api: { + image: 'api', + volumes: ['./preexisting:/preexisting'], + command: 'npm start', + }, + }, + } + const state = { + services: { + api: { + _develop: { + mounts: { './local': '/app', './node_modules': '/app/node_modules' }, + }, + }, + }, + } + + const result = develop(config, state) + + expect(result.services.api.stdin_open).to.equal(true) + expect(result.services.api.volumes).to.include('./preexisting:/preexisting') + expect(result.services.api.volumes).to.include('./local:/app') + expect(result.services.api.volumes).to.include('./node_modules:/app/node_modules') + }) + + it('should override the command when _develop.command is set', function () { + const config = { services: { api: { image: 'api', command: 'npm start' } } } + const state = { + services: { + api: { _develop: { mounts: {}, command: 'npm run dev' } }, + }, + } + + const result = develop(config, state) + + expect(result.services.api.command).to.equal('npm run dev') + }) + + it('should keep the existing command when _develop.command is not set', function () { + const config = { services: { api: { image: 'api', command: 'npm start' } } } + const state = { + services: { api: { _develop: { mounts: {} } } }, + } + + const result = develop(config, state) + + expect(result.services.api.command).to.equal('npm start') + }) + +}) diff --git a/packages/navy/src/middleware/__tests__/helpers.js b/packages/navy/src/middleware/__tests__/helpers.js new file mode 100644 index 0000000..ca03e52 --- /dev/null +++ b/packages/navy/src/middleware/__tests__/helpers.js @@ -0,0 +1,133 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { middlewareHelpers } from '../helpers' + +describe('middlewareHelpers', function () { + + describe('rewriteServices', function () { + + it('should map every service in config.services through the mapper, preserving config', function () { + const config = { + version: '3', + services: { + api: { image: 'api:1', ports: ['80'] }, + web: { image: 'web:1' }, + }, + networks: { default: {} }, + } + + const result = middlewareHelpers.rewriteServices(config, (service, name) => ({ + ...service, + image: name + '-rewritten', + })) + + expect(result).to.have.property('version', '3') + expect(result).to.have.property('networks').that.eql({ default: {} }) + expect(result.services.api).to.eql({ image: 'api-rewritten', ports: ['80'] }) + expect(result.services.web).to.eql({ image: 'web-rewritten' }) + }) + + it('should treat a missing services property as an empty object', function () { + const result = middlewareHelpers.rewriteServices({}, () => ({})) + + expect(result).to.have.property('services').that.eql({}) + }) + + }) + + describe('rewriteServicesWithState', function () { + + it('should pass per-service state into the mapper', function () { + const config = { + services: { + api: { image: 'api' }, + }, + } + const state = { + services: { + api: { _ports: { 80: 8080 } }, + }, + } + + const result = middlewareHelpers.rewriteServicesWithState(config, state, (service, name, serviceState) => ({ + ...service, + meta: { name, hasState: !!serviceState, ports: serviceState && serviceState._ports }, + })) + + expect(result.services.api.meta).to.eql({ + name: 'api', + hasState: true, + ports: { 80: 8080 }, + }) + }) + + it('should pass undefined service state when the service is not in state', function () { + const config = { services: { web: { image: 'web' } } } + const state = { services: {} } + + const result = middlewareHelpers.rewriteServicesWithState(config, state, (service, name, serviceState) => ({ + ...service, + seenState: serviceState, + })) + + expect(result.services.web.seenState).to.equal(undefined) + }) + + it('should normalise a null state to an empty services map', function () { + const config = { services: { api: { image: 'api' } } } + + const result = middlewareHelpers.rewriteServicesWithState(config, null, (service, name, serviceState) => ({ + ...service, + seenState: serviceState, + })) + + expect(result.services.api.seenState).to.equal(undefined) + }) + + it('should preserve other keys on the config object', function () { + const config = { version: '3', services: {}, volumes: { v1: {} } } + + const result = middlewareHelpers.rewriteServicesWithState(config, { services: {} }, s => s) + + expect(result.version).to.equal('3') + expect(result.volumes).to.eql({ v1: {} }) + }) + + it('should treat a missing services property on config as an empty object', function () { + const result = middlewareHelpers.rewriteServicesWithState({}, { services: {} }, () => ({})) + + expect(result).to.have.property('services').that.eql({}) + }) + + }) + + describe('addVolumes', function () { + + it('should append the new volumes to existing service volumes', function () { + const result = middlewareHelpers.addVolumes( + { volumes: ['./local:/app'] }, + ['./extra:/extra'] + ) + + expect(result).to.eql(['./local:/app', './extra:/extra']) + }) + + it('should treat a missing volumes property as an empty array', function () { + const result = middlewareHelpers.addVolumes({}, ['./extra:/extra']) + + expect(result).to.eql(['./extra:/extra']) + }) + + it('should not mutate the existing volumes array on the service', function () { + const original = ['./local:/app'] + const service = { volumes: original } + + middlewareHelpers.addVolumes(service, ['./extra:/extra']) + + expect(original).to.eql(['./local:/app']) + }) + + }) + +}) diff --git a/packages/navy/src/middleware/__tests__/port-override.js b/packages/navy/src/middleware/__tests__/port-override.js new file mode 100644 index 0000000..95e7a6b --- /dev/null +++ b/packages/navy/src/middleware/__tests__/port-override.js @@ -0,0 +1,73 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import portOverride from '../port-override' + +describe('port-override middleware', function () { + + it('should leave service.ports untouched when no port state exists', function () { + const config = { services: { api: { ports: ['80:80'] } } } + const state = { services: {} } + + const result = portOverride(config, state) + + expect(result.services.api.ports).to.eql(['80:80']) + }) + + it('should leave ports untouched when state has the service but no _ports', function () { + const config = { services: { api: { ports: ['80:80'] } } } + const state = { services: { api: {} } } + + const result = portOverride(config, state) + + expect(result.services.api.ports).to.eql(['80:80']) + }) + + it('should override an internal port mapping with the configured external port', function () { + const config = { services: { api: { ports: ['80', '443'] } } } + const state = { services: { api: { _ports: { 80: 8080 } } } } + + const result = portOverride(config, state) + + expect(result.services.api.ports).to.include('443') + expect(result.services.api.ports).to.include('8080:80') + expect(result.services.api.ports).to.not.include('80') + }) + + it('should drop entries whose external port is falsy when port state exists', function () { + const config = { services: { api: { ports: ['80', '443'] } } } + const state = { services: { api: { _ports: { 80: undefined, 443: 4433 } } } } + + const result = portOverride(config, state) + + expect(result.services.api.ports).to.eql(['80', '4433:443']) + }) + + it('should produce an empty ports list when service.ports is missing and there are no internal overrides', function () { + const config = { services: { api: { } } } + const state = { services: { api: { _ports: { 80: undefined } } } } + + const result = portOverride(config, state) + + expect(result.services.api.ports).to.eql([]) + }) + + it('should set ports to an empty array when neither the service nor state declare any ports', function () { + const config = { services: { api: {} } } + const state = { services: {} } + + const result = portOverride(config, state) + + expect(result.services.api.ports).to.eql([]) + }) + + it('should preserve top-level config keys', function () { + const config = { version: '3', services: { api: {} } } + const state = { services: {} } + + const result = portOverride(config, state) + + expect(result).to.have.property('version', '3') + }) + +}) diff --git a/packages/navy/src/middleware/__tests__/set-env-vars.js b/packages/navy/src/middleware/__tests__/set-env-vars.js new file mode 100644 index 0000000..d4d06eb --- /dev/null +++ b/packages/navy/src/middleware/__tests__/set-env-vars.js @@ -0,0 +1,49 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import setEnvVars from '../set-env-vars' + +describe('set-env-vars middleware', function () { + + it('should leave the service environment unchanged when no state exists for it', function () { + const config = { services: { api: { environment: { FOO: 'bar' } } } } + const state = { services: {} } + + const result = setEnvVars(config, state) + + expect(result.services.api.environment).to.eql({ FOO: 'bar' }) + }) + + it('should merge state.services[name].environment over the config environment', function () { + const config = { services: { api: { environment: { FOO: 'bar', BAZ: 'qux' } } } } + const state = { services: { api: { environment: { FOO: 'overridden', NEW: 'value' } } } } + + const result = setEnvVars(config, state) + + expect(result.services.api.environment).to.eql({ + FOO: 'overridden', + BAZ: 'qux', + NEW: 'value', + }) + }) + + it('should produce an empty environment when neither config nor state defines one', function () { + const config = { services: { api: {} } } + const state = { services: {} } + + const result = setEnvVars(config, state) + + expect(result.services.api.environment).to.eql({}) + }) + + it('should preserve service config keys other than environment', function () { + const config = { services: { api: { image: 'api:1', environment: { A: '1' } } } } + const state = { services: { api: { environment: { B: '2' } } } } + + const result = setEnvVars(config, state) + + expect(result.services.api.image).to.equal('api:1') + expect(result.services.api.environment).to.eql({ A: '1', B: '2' }) + }) + +}) diff --git a/packages/navy/src/middleware/__tests__/set-image.js b/packages/navy/src/middleware/__tests__/set-image.js new file mode 100644 index 0000000..6fa7334 --- /dev/null +++ b/packages/navy/src/middleware/__tests__/set-image.js @@ -0,0 +1,44 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import setImage from '../set-image' + +describe('set-image middleware', function () { + + it('should leave the image unchanged when no state image is set', function () { + const config = { services: { api: { image: 'api:1' } } } + const state = { services: { api: {} } } + + const result = setImage(config, state) + + expect(result.services.api.image).to.equal('api:1') + }) + + it('should leave the image unchanged when there is no service state at all', function () { + const config = { services: { api: { image: 'api:1' } } } + const state = { services: {} } + + const result = setImage(config, state) + + expect(result.services.api.image).to.equal('api:1') + }) + + it('should override the image when state has one', function () { + const config = { services: { api: { image: 'api:1' } } } + const state = { services: { api: { image: 'api:override' } } } + + const result = setImage(config, state) + + expect(result.services.api.image).to.equal('api:override') + }) + + it('should preserve other service config keys', function () { + const config = { services: { api: { image: 'api:1', ports: ['80:80'] } } } + const state = { services: { api: { image: 'api:override' } } } + + const result = setImage(config, state) + + expect(result.services.api.ports).to.eql(['80:80']) + }) + +}) diff --git a/packages/navy/src/middleware/__tests__/set-logging-driver.js b/packages/navy/src/middleware/__tests__/set-logging-driver.js new file mode 100644 index 0000000..4d5cc99 --- /dev/null +++ b/packages/navy/src/middleware/__tests__/set-logging-driver.js @@ -0,0 +1,48 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import setLoggingDriver from '../set-logging-driver' + +describe('set-logging-driver middleware', function () { + + it('should produce an empty logging object when neither config nor state set one', function () { + const config = { services: { api: {} } } + const state = { services: {} } + + const result = setLoggingDriver(config, state) + + expect(result.services.api.logging).to.eql({}) + }) + + it('should pass the config logging through when state has no logging entry', function () { + const config = { services: { api: { logging: { driver: 'json-file' } } } } + const state = { services: { api: {} } } + + const result = setLoggingDriver(config, state) + + expect(result.services.api.logging).to.eql({ driver: 'json-file' }) + }) + + it('should merge state logging over config logging', function () { + const config = { services: { api: { logging: { driver: 'json-file', options: { 'max-size': '10m' } } } } } + const state = { services: { api: { logging: { driver: 'syslog' } } } } + + const result = setLoggingDriver(config, state) + + expect(result.services.api.logging).to.eql({ + driver: 'syslog', + options: { 'max-size': '10m' }, + }) + }) + + it('should preserve other service config keys', function () { + const config = { services: { api: { image: 'api:1' } } } + const state = { services: { api: { logging: { driver: 'syslog' } } } } + + const result = setLoggingDriver(config, state) + + expect(result.services.api.image).to.equal('api:1') + expect(result.services.api.logging).to.eql({ driver: 'syslog' }) + }) + +}) diff --git a/packages/navy/src/middleware/__tests__/tag-override.js b/packages/navy/src/middleware/__tests__/tag-override.js new file mode 100644 index 0000000..e649113 --- /dev/null +++ b/packages/navy/src/middleware/__tests__/tag-override.js @@ -0,0 +1,54 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import tagOverride from '../tag-override' + +describe('tag-override middleware', function () { + + it('should add the tag when service image has no tag', function () { + const config = { services: { api: { image: 'navy/api' } } } + const state = { services: { api: { _tag: 'v1.2.3' } } } + + const result = tagOverride(config, state) + + expect(result.services.api.image).to.equal('navy/api:v1.2.3') + }) + + it('should replace an existing tag with the override', function () { + const config = { services: { api: { image: 'navy/api:old' } } } + const state = { services: { api: { _tag: 'new' } } } + + const result = tagOverride(config, state) + + expect(result.services.api.image).to.equal('navy/api:new') + }) + + it('should leave the image untouched when state has no _tag for the service', function () { + const config = { services: { api: { image: 'navy/api:old' } } } + const state = { services: { api: {} } } + + const result = tagOverride(config, state) + + expect(result.services.api.image).to.equal('navy/api:old') + }) + + it('should ignore state services that have no matching service in config', function () { + const config = { services: { api: { image: 'api:1' } } } + const state = { services: { web: { _tag: 'lts' } } } + + const result = tagOverride(config, state) + + expect(result.services.api.image).to.equal('api:1') + expect(result.services).to.not.have.property('web') + }) + + it('should treat a missing state.services as an empty object', function () { + const config = { services: { api: { image: 'api:1' } } } + const state = {} + + const result = tagOverride(config, state) + + expect(result.services.api.image).to.equal('api:1') + }) + +}) diff --git a/packages/navy/src/middleware/add-service-proxy-config.js b/packages/navy/src/middleware/add-service-proxy-config.js index 4dc23d1..ce83f59 100644 --- a/packages/navy/src/middleware/add-service-proxy-config.js +++ b/packages/navy/src/middleware/add-service-proxy-config.js @@ -1,11 +1,11 @@ /* @flow */ -import {find} from 'lodash' -import {createHostForService} from '../util/service-host' +import { find } from 'lodash' +import { createHostForService } from '../util/service-host' import { createCert } from '../util/https' -import type {Navy} from '../navy' +import type { Navy } from '../navy' -const getServiceHTTPProxyConfig = (serviceName, navyFile) => { +const getServiceHTTPProxyConfig = (serviceName: string, navyFile: ?Object) => { if (navyFile && navyFile.httpProxy && navyFile.httpProxy[serviceName]) { return navyFile.httpProxy[serviceName] } @@ -13,7 +13,7 @@ const getServiceHTTPProxyConfig = (serviceName, navyFile) => { return null } -const serviceGetAutoProxyPortOr80 = (service, navyFile) => { +const serviceGetAutoProxyPortOr80 = (service: Object, navyFile: ?Object) => { const autoPorts: any[] = (navyFile && Array.isArray(navyFile.httpProxyAutoPorts) && navyFile.httpProxyAutoPorts) || ['80'] return service.ports && find(autoPorts, autoPort => { const autoPortString = autoPort.toString() @@ -32,10 +32,10 @@ const serviceGetAutoProxyPortOr80 = (service, navyFile) => { }) } -export default (navy: Navy) => - async (config: Object, state: Object) => { +export default (navy: Navy): (config: Object, state: Object) => Promise => + async (config: Object, state: Object): Promise => { const navyFile = await navy.getNavyFile() - const services = {} + const services: {[string]: Object} = {} const externalIP = await navy.externalIP() await Promise.all(Object.keys(config.services).map(async serviceName => { @@ -54,13 +54,13 @@ export default (navy: Navy) => if (proxyConfig) { const hostName = await createHostForService(serviceName, navy.normalisedName, externalIP) - if (proxyConfig.enableHttps) await createCert({hostName}) + if (proxyConfig.enableHttps) await createCert({ hostName }) return services[serviceName] = { ...service, environment: { - 'VIRTUAL_HOST': hostName, - 'VIRTUAL_PORT': proxyConfig.port, + VIRTUAL_HOST: hostName, + VIRTUAL_PORT: proxyConfig.port, ...service.environment, }, } diff --git a/packages/navy/src/middleware/develop.js b/packages/navy/src/middleware/develop.js index 56ed2bb..eeb412d 100644 --- a/packages/navy/src/middleware/develop.js +++ b/packages/navy/src/middleware/develop.js @@ -1,8 +1,8 @@ /* @flow */ -import {middlewareHelpers} from './helpers' +import { middlewareHelpers } from './helpers' -function rewriteService(service, serviceName, serviceState) { +function rewriteService(service: Object, serviceName: string, serviceState: ?Object) { if (!serviceState || !serviceState._develop) return service const _serviceState = serviceState @@ -19,5 +19,5 @@ function rewriteService(service, serviceName, serviceState) { } } -export default (config: Object, state: Object) => +export default (config: Object, state: Object): Object => middlewareHelpers.rewriteServicesWithState(config, state, rewriteService) diff --git a/packages/navy/src/middleware/helpers.js b/packages/navy/src/middleware/helpers.js index 3a7dc8f..49f5ec7 100644 --- a/packages/navy/src/middleware/helpers.js +++ b/packages/navy/src/middleware/helpers.js @@ -1,22 +1,22 @@ /* @flow */ -import {mapValues} from 'lodash' +import { mapValues } from 'lodash' type ServiceMapper = (service: Object, serviceName: string) => Object type ServiceMapperWithState = (service: Object, serviceName: string, serviceState: ?Object) => Object export const middlewareHelpers = { - rewriteServices(config: Object, serviceMapperFn: ServiceMapper) { + rewriteServices(config: Object, serviceMapperFn: ServiceMapper): Object { return { ...config, services: mapValues(config.services || {}, serviceMapperFn), } }, - rewriteServicesWithState(config: Object, state: Object, serviceMapperFn: ServiceMapperWithState) { + rewriteServicesWithState(config: Object, state: Object, serviceMapperFn: ServiceMapperWithState): Object { const normalisedState = state || { services: {} } - function mapperFn(service, serviceName) { + function mapperFn(service: Object, serviceName: string) { return serviceMapperFn(service, serviceName, normalisedState.services[serviceName]) } @@ -26,7 +26,7 @@ export const middlewareHelpers = { } }, - addVolumes(service: Object, volumes: Array) { + addVolumes(service: Object, volumes: Array): Array { const normalisedVolumes = service.volumes || [] return [ diff --git a/packages/navy/src/middleware/port-override.js b/packages/navy/src/middleware/port-override.js index 2884f0e..5e2fe9c 100644 --- a/packages/navy/src/middleware/port-override.js +++ b/packages/navy/src/middleware/port-override.js @@ -1,18 +1,17 @@ /* @flow */ -import {mapValues} from 'lodash' +import { mapValues } from 'lodash' -function getPortConfig(serviceName, state) { +function getPortConfig(serviceName: string, state: Object): {[string]: string} { return state.services[serviceName] ? (state.services[serviceName]._ports || {}) : {} } -export default (config: Object, state: Object) => ({ +export default (config: Object, state: Object): Object => ({ ...config, services: mapValues(config.services, (service, serviceName) => { const portConfig = getPortConfig(serviceName, state) - const hasPortConfig = !!portConfig const internalPorts = Object.keys(portConfig).filter(internal => !!portConfig[internal]) const inheritedPorts = service.ports @@ -21,10 +20,10 @@ export default (config: Object, state: Object) => ({ return { ...service, - ports: hasPortConfig ? [ + ports: [ ...inheritedPorts, ...internalPorts.map(internal => `${portConfig[internal]}:${internal}`), - ] : service.ports, + ], } }), }) diff --git a/packages/navy/src/middleware/set-env-vars.js b/packages/navy/src/middleware/set-env-vars.js index 1c28d36..845f3fc 100644 --- a/packages/navy/src/middleware/set-env-vars.js +++ b/packages/navy/src/middleware/set-env-vars.js @@ -1,9 +1,9 @@ /* @flow */ -import {mapValues} from 'lodash' +import { mapValues } from 'lodash' -export default (config: Object, state: Object) => ({ +export default (config: Object, state: Object): Object => ({ ...config, services: mapValues(config.services, (serviceConfig, serviceName) => { const serviceState = state.services[serviceName] || {} diff --git a/packages/navy/src/middleware/set-image.js b/packages/navy/src/middleware/set-image.js index b4347a9..c64cc34 100644 --- a/packages/navy/src/middleware/set-image.js +++ b/packages/navy/src/middleware/set-image.js @@ -1,9 +1,9 @@ /* @flow */ -import {mapValues} from 'lodash' +import { mapValues } from 'lodash' -export default (config: Object, state: Object) => ({ +export default (config: Object, state: Object): Object => ({ ...config, services: mapValues(config.services, (serviceConfig, serviceName) => { const serviceState = state.services[serviceName] || {} diff --git a/packages/navy/src/middleware/set-logging-driver.js b/packages/navy/src/middleware/set-logging-driver.js index c1677d3..b5ae454 100644 --- a/packages/navy/src/middleware/set-logging-driver.js +++ b/packages/navy/src/middleware/set-logging-driver.js @@ -1,9 +1,9 @@ /* @flow */ -import {mapValues} from 'lodash' +import { mapValues } from 'lodash' -export default (config: Object, state: Object) => ({ +export default (config: Object, state: Object): Object => ({ ...config, services: mapValues(config.services, (serviceConfig, serviceName) => { const serviceState = state.services[serviceName] || {} diff --git a/packages/navy/src/middleware/tag-override.js b/packages/navy/src/middleware/tag-override.js index 000626f..1b95360 100644 --- a/packages/navy/src/middleware/tag-override.js +++ b/packages/navy/src/middleware/tag-override.js @@ -1,6 +1,6 @@ /* @flow */ -export default (config: Object, state: Object) => { +export default (config: Object, state: Object): Object => { const newConfig = config Object.keys(state.services || {}).forEach(function (serviceName) { diff --git a/packages/navy/src/navy/__tests__/default-middleware.js b/packages/navy/src/navy/__tests__/default-middleware.js new file mode 100644 index 0000000..cbaf828 --- /dev/null +++ b/packages/navy/src/navy/__tests__/default-middleware.js @@ -0,0 +1,37 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import defaultMiddleware from '../default-middleware' +import developMiddleware from '../../middleware/develop' +import tagOverrideMiddleware from '../../middleware/tag-override' +import portOverrideMiddleware from '../../middleware/port-override' +import setEnvironmentVariables from '../../middleware/set-env-vars' +import setLoggingDriver from '../../middleware/set-logging-driver' +import setImage from '../../middleware/set-image' +import addServiceProxyMiddleware from '../../middleware/add-service-proxy-config' + +describe('default-middleware', function () { + + it('should return the standard middleware pipeline in the documented order', function () { + const fakeNavy = { name: 'env', normalisedName: 'env' } + const list = defaultMiddleware(fakeNavy) + + expect(list).to.have.lengthOf(7) + expect(list[0]).to.equal(developMiddleware) + expect(list[1]).to.equal(tagOverrideMiddleware) + expect(list[2]).to.equal(portOverrideMiddleware) + expect(list[3]).to.equal(setEnvironmentVariables) + expect(list[4]).to.equal(setLoggingDriver) + expect(list[5]).to.equal(setImage) + expect(list[6]).to.be.a('function') + }) + + it('should bind the navy through to the addServiceProxy middleware factory', function () { + const fakeNavy = { name: 'env', normalisedName: 'env' } + const list = defaultMiddleware(fakeNavy) + + const expected = addServiceProxyMiddleware(fakeNavy) + expect(typeof list[6]).to.equal(typeof expected) + }) + +}) diff --git a/packages/navy/src/navy/__tests__/index.js b/packages/navy/src/navy/__tests__/index.js new file mode 100644 index 0000000..eb3f756 --- /dev/null +++ b/packages/navy/src/navy/__tests__/index.js @@ -0,0 +1,1165 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError, NavyNotInitialisedError } from '../../errors' + +function loadNavyModule(stubs = {}) { + return proxyquire.noCallThru()('../', { + '../util/fs': { + readdirAsync: sinon.stub().resolves([]), + lstatSync: sinon.stub().returns({ isDirectory: () => true }), + ...stubs.fs, + }, + './state': { + getState: sinon.stub().resolves(null), + saveState: sinon.stub().resolves(), + deleteState: sinon.stub().resolves(), + pathToNavys: sinon.stub().returns('/home/test/.navy/navies'), + pathToNavy: sinon.stub().callsFake((n) => `/home/test/.navy/navies/${n}`), + ...stubs.state, + }, + '../driver': { resolveDriverFromName: sinon.stub().returns(null), ...stubs.driver }, + '../config-provider': { resolveConfigProviderFromName: sinon.stub().returns(null), ...stubs.configProvider }, + '../config': { getConfig: sinon.stub().returns({ externalIP: null }), ...stubs.config }, + './plugin-interface': { loadPlugins: sinon.stub().resolves([]), ...stubs.pluginInterface }, + './middleware': { middlewareRunner: sinon.stub().resolves(), ...stubs.middleware }, + '../http-proxy': { reconfigureHTTPProxy: sinon.stub().resolves(), ...stubs.httpProxy }, + '../util/external-ip': { getExternalIP: sinon.stub().resolves('127.0.0.1'), ...stubs.externalIP }, + '../util/service-host': { + createUrlForService: sinon.stub().resolves('http://svc.local'), + getUrlFromService: sinon.stub().returns(null), + ...stubs.serviceHost, + }, + }) +} + +function makeDriver(overrides = {}) { + return { + launch: sinon.stub().resolves(), + destroy: sinon.stub().resolves(), + ps: sinon.stub().resolves([]), + start: sinon.stub().resolves(), + stop: sinon.stub().resolves(), + restart: sinon.stub().resolves(), + kill: sinon.stub().resolves(), + rm: sinon.stub().resolves(), + update: sinon.stub().resolves(), + spawnLogStream: sinon.stub().resolves(), + port: sinon.stub().resolves(null), + writeConfig: sinon.stub().resolves(), + getConfig: sinon.stub().resolves({ services: {} }), + getLaunchedServiceNames: sinon.stub().resolves([]), + getAvailableServiceNames: sinon.stub().resolves([]), + ...overrides, + } +} + +describe('navy/index', function () { + + describe('Navy class', function () { + + it('should normalise the navy name and store it', function () { + const { Navy } = loadNavyModule() + const navy = new Navy('My Env-1') + expect(navy.name).to.equal('My Env-1') + expect(navy.normalisedName).to.equal('MyEnv1') + }) + + }) + + describe('getNavy', function () { + + it('should return a Navy instance for the given name', function () { + const { getNavy } = loadNavyModule() + const navy = getNavy('myenv') + expect(navy.name).to.equal('myenv') + }) + + it('should throw when navyName is not provided', function () { + const { getNavy } = loadNavyModule() + expect(() => getNavy()).to.throw(/NO_NAVY_PROVIDED/) + expect(() => getNavy(null)).to.throw(/NO_NAVY_PROVIDED/) + expect(() => getNavy('')).to.throw(/NO_NAVY_PROVIDED/) + }) + + }) + + describe('isInitialised', function () { + + it('should return true when state exists', async function () { + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + }) + expect(await new Navy('env').isInitialised()).to.equal(true) + }) + + it('should return false when state is null', async function () { + const { Navy } = loadNavyModule({ state: { getState: sinon.stub().resolves(null) } }) + expect(await new Navy('env').isInitialised()).to.equal(false) + }) + + }) + + describe('getState/saveState/initialise/delete', function () { + + it('should delegate getState to state module', async function () { + const stub = sinon.stub().resolves({ driver: 'docker-compose' }) + const { Navy } = loadNavyModule({ state: { getState: stub } }) + + const result = await new Navy('env').getState() + expect(result).to.eql({ driver: 'docker-compose' }) + expect(stub.firstCall.args[0]).to.equal('env') + }) + + it('saveState should write state then run middleware', async function () { + const saveStub = sinon.stub().resolves() + const middlewareStub = sinon.stub().resolves() + const { Navy } = loadNavyModule({ + state: { saveState: saveStub }, + middleware: { middlewareRunner: middlewareStub }, + }) + const navy = new Navy('env') + const state = { driver: 'docker-compose' } + + await navy.saveState(state) + + expect(saveStub.calledWith('env', state)).to.equal(true) + expect(middlewareStub.calledOnce).to.equal(true) + }) + + it('initialise should write state with driver=docker-compose and provided opts', async function () { + const saveStub = sinon.stub().resolves() + const { Navy } = loadNavyModule({ state: { saveState: saveStub } }) + + await new Navy('env').initialise({ services: { foo: {} }, configProvider: 'filesystem' }) + + const writtenState = saveStub.firstCall.args[1] + expect(writtenState).to.eql({ + services: { foo: {} }, + configProvider: 'filesystem', + driver: 'docker-compose', + }) + }) + + it('delete should call deleteState', async function () { + const stub = sinon.stub().resolves() + const { Navy } = loadNavyModule({ state: { deleteState: stub } }) + + await new Navy('env').delete() + expect(stub.calledWith('env')).to.equal(true) + }) + + }) + + describe('getDriver', function () { + + it('should return null when state is missing', async function () { + const { Navy } = loadNavyModule() + expect(await new Navy('env').getDriver()).to.equal(null) + }) + + it('should return null when state has no driver', async function () { + const { Navy } = loadNavyModule({ state: { getState: sinon.stub().resolves({}) } }) + expect(await new Navy('env').getDriver()).to.equal(null) + }) + + it('should return null when the driver name is unknown', async function () { + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'unknown' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(null) }, + }) + expect(await new Navy('env').getDriver()).to.equal(null) + }) + + it('should instantiate and return the driver from resolveDriverFromName', async function () { + const driverInstance = makeDriver() + const factory = sinon.stub().returns(driverInstance) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(factory) }, + }) + + const navy = new Navy('env') + expect(await navy.getDriver()).to.equal(driverInstance) + expect(factory.firstCall.args[0]).to.equal(navy) + }) + + }) + + describe('safeGetDriver', function () { + + it('should throw NavyNotInitialisedError when not initialised', async function () { + const { Navy } = loadNavyModule() + let caught + try { await new Navy('env').safeGetDriver() } catch (e) { caught = e } + expect(caught).to.be.instanceof(NavyNotInitialisedError) + }) + + it('should throw an invariant violation when state exists but no driver could be resolved', async function () { + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'unknown' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(null) }, + }) + let caught + try { await new Navy('env').safeGetDriver() } catch (e) { caught = e } + expect(caught.message).to.match(/NO_DRIVER/) + }) + + it('should return the driver when initialised and resolvable', async function () { + const driverInstance = makeDriver() + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driverInstance) }, + }) + + expect(await new Navy('env').safeGetDriver()).to.equal(driverInstance) + }) + + }) + + describe('getConfigProvider', function () { + + it('should return null when state has no configProvider', async function () { + const { Navy } = loadNavyModule({ state: { getState: sinon.stub().resolves({}) } }) + expect(await new Navy('env').getConfigProvider()).to.equal(null) + }) + + it('should return null when state is missing', async function () { + const { Navy } = loadNavyModule() + expect(await new Navy('env').getConfigProvider()).to.equal(null) + }) + + it('should return null when configProvider is unknown', async function () { + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ configProvider: 'unknown' }) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(null) }, + }) + expect(await new Navy('env').getConfigProvider()).to.equal(null) + }) + + it('should instantiate the config provider from resolveConfigProviderFromName', async function () { + const provider = { getNavyPath: async () => '/path' } + const factory = sinon.stub().returns(provider) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ configProvider: 'filesystem' }) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(factory) }, + }) + + expect(await new Navy('env').getConfigProvider()).to.equal(provider) + }) + + }) + + describe('getNavyFile', function () { + + it('should throw NavyNotInitialisedError when not initialised', async function () { + const { Navy } = loadNavyModule() + let caught + try { await new Navy('env').getNavyFile() } catch (e) { caught = e } + expect(caught).to.be.instanceof(NavyNotInitialisedError) + }) + + it('should throw NO_CONFIG_PROVIDER when initialised but no provider', async function () { + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({}) }, + }) + let caught + try { await new Navy('env').getNavyFile() } catch (e) { caught = e } + expect(caught.message).to.match(/NO_CONFIG_PROVIDER/) + }) + + it('should require the navy file path and return its module export', async function () { + const fakePath = '/abs/Navyfile.js' + const navyFile = { plugins: ['p'] } + const provider = { getNavyFilePath: async () => fakePath } + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ configProvider: 'filesystem' }) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + }) + + const navy = new Navy('env') + const proxiedRequire = require('proxyquire').noCallThru() + const NavyMod = proxiedRequire('../', { + '../util/fs': { readdirAsync: sinon.stub().resolves([]), lstatSync: sinon.stub().returns({ isDirectory: () => true }) }, + './state': { getState: sinon.stub().resolves({ configProvider: 'filesystem' }), saveState: sinon.stub(), deleteState: sinon.stub(), pathToNavys: sinon.stub().returns('/'), pathToNavy: sinon.stub() }, + '../driver': { resolveDriverFromName: sinon.stub().returns(null) }, + '../config-provider': { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + '../config': { getConfig: sinon.stub().returns({ externalIP: null }) }, + './plugin-interface': { loadPlugins: sinon.stub().resolves([]) }, + './middleware': { middlewareRunner: sinon.stub().resolves() }, + '../http-proxy': { reconfigureHTTPProxy: sinon.stub().resolves() }, + '../util/external-ip': { getExternalIP: sinon.stub().resolves('127.0.0.1') }, + '../util/service-host': { createUrlForService: sinon.stub(), getUrlFromService: sinon.stub() }, + [fakePath]: navyFile, + }) + + const fresh = new NavyMod.Navy('env') + expect(await fresh.getNavyFile()).to.equal(navyFile) + + // also check that not-required path returns null + provider.getNavyFilePath = async () => '/does-not-exist/Navyfile.js' + expect(await navy.getNavyFile()).to.equal(null) + }) + + }) + + describe('ensurePluginsLoaded', function () { + + it('should be a no-op the second time when plugins are already loaded', async function () { + const loadStub = sinon.stub().resolves([]) + const { Navy } = loadNavyModule({ + pluginInterface: { loadPlugins: loadStub }, + }) + + const navy = new Navy('env') + navy.getNavyFile = sinon.stub().resolves({ plugins: [] }) + + await navy.ensurePluginsLoaded() + await navy.ensurePluginsLoaded() + + expect(loadStub.calledOnce).to.equal(true) + expect(navy._pluginsLoaded).to.equal(true) + }) + + it('should not load plugins when navyFile is null', async function () { + const loadStub = sinon.stub().resolves([]) + const provider = { getNavyFilePath: async () => '/missing/Navyfile.js' } + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ configProvider: 'filesystem' }) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + pluginInterface: { loadPlugins: loadStub }, + }) + + await new Navy('env').ensurePluginsLoaded() + expect(loadStub.called).to.equal(false) + }) + + it('should call loadPlugins and mark _pluginsLoaded when navyFile is returned', async function () { + const loadStub = sinon.stub().resolves([]) + const { Navy } = loadNavyModule({ + pluginInterface: { loadPlugins: loadStub }, + }) + + const navy = new Navy('env') + const navyFile = { plugins: ['my-plugin'] } + navy.getNavyFile = sinon.stub().resolves(navyFile) + + await navy.ensurePluginsLoaded() + + expect(loadStub.calledOnce).to.equal(true) + expect(loadStub.firstCall.args[0]).to.equal(navy) + expect(loadStub.firstCall.args[1]).to.equal(navyFile) + expect(navy._pluginsLoaded).to.equal(true) + }) + + }) + + describe('registerCommand / invokeCommand', function () { + + it('should run the registered action when invoked', async function () { + const { Navy } = loadNavyModule() + const navy = new Navy('env') + const action = sinon.stub().resolves() + + navy.registerCommand('foo', action) + await navy.invokeCommand('foo', ['a', 'b']) + + expect(action.calledOnce).to.equal(true) + expect(action.firstCall.args[0]).to.eql(['a', 'b']) + }) + + it('should throw a NavyError for unknown commands', async function () { + const { Navy } = loadNavyModule() + let caught + try { await new Navy('env').invokeCommand('missing', []) } catch (e) { caught = e } + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain('Unknown command "missing"') + }) + + }) + + describe('registerMiddleware', function () { + + it('should append the middleware to _registeredMiddleware', function () { + const { Navy } = loadNavyModule() + const navy = new Navy('env') + const fn = () => null + + navy.registerMiddleware(fn) + expect(navy._registeredMiddleware).to.eql([fn]) + }) + + }) + + describe('launch', function () { + + function setupForLaunch({ available = ['api', 'web'], launched = [] } = {}) { + const driver = makeDriver({ + getAvailableServiceNames: sinon.stub().resolves(available), + getLaunchedServiceNames: sinon.stub().resolves(launched), + }) + const provider = { getNavyFilePath: async () => '/missing' } + const reconfigureHTTPProxy = sinon.stub().resolves() + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose', configProvider: 'filesystem' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + httpProxy: { reconfigureHTTPProxy }, + }) + return { driver, Navy, reconfigureHTTPProxy } + } + + it('should default to launching the currently launched services when no list is given', async function () { + const { driver, Navy } = setupForLaunch({ available: ['api'], launched: ['api'] }) + + await new Navy('env').launch() + + expect(driver.launch.calledOnce).to.equal(true) + expect(driver.launch.firstCall.args[0]).to.eql(['api']) + }) + + it('should filter out unknown service names with a warning', async function () { + const log = sinon.stub(console, 'log') + try { + const { driver, Navy } = setupForLaunch({ available: ['api'] }) + + await new Navy('env').launch(['api', 'unknown']) + + expect(driver.launch.firstCall.args[0]).to.eql(['api']) + expect(log.calledWith('Unknown service name: unknown')).to.equal(true) + } finally { + log.restore() + } + }) + + it('should return early without launching when all requested services are invalid', async function () { + const log = sinon.stub(console, 'log') + try { + const { driver, Navy } = setupForLaunch({ available: ['api'] }) + + await new Navy('env').launch(['unknown1', 'unknown2']) + + expect(driver.launch.called).to.equal(false) + } finally { + log.restore() + } + }) + + it('should reconfigure the HTTP proxy after launch', async function () { + const { Navy, reconfigureHTTPProxy } = setupForLaunch({ available: ['api'], launched: ['api'] }) + await new Navy('env').launch(['api']) + expect(reconfigureHTTPProxy.calledOnce).to.equal(true) + }) + + }) + + describe('reconfigure / relaunch', function () { + + it('reconfigure should be a no-op when no services are launched', async function () { + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { + resolveDriverFromName: sinon.stub().returns(() => makeDriver({ + getLaunchedServiceNames: sinon.stub().resolves([]), + })), + }, + }) + + await new Navy('env').reconfigure() + }) + + it('reconfigure should call launch when there are running services', async function () { + const driver = makeDriver({ + getLaunchedServiceNames: sinon.stub().resolves(['api']), + getAvailableServiceNames: sinon.stub().resolves(['api']), + }) + const provider = { getNavyFilePath: async () => '/missing' } + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose', configProvider: 'filesystem' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + }) + + await new Navy('env').reconfigure() + expect(driver.launch.calledOnce).to.equal(true) + }) + + it('relaunch should delegate to reconfigure', async function () { + const driver = makeDriver({ + getLaunchedServiceNames: sinon.stub().resolves([]), + }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + }) + + await new Navy('env').relaunch() + }) + + }) + + describe('destroy', function () { + + it('should throw NavyNotInitialisedError when not initialised', async function () { + const { Navy } = loadNavyModule() + let caught + try { await new Navy('env').destroy() } catch (e) { caught = e } + expect(caught).to.be.instanceof(NavyNotInitialisedError) + }) + + it('should reconfigure proxy excluding self, destroy the driver, and delete state', async function () { + const driver = makeDriver() + const provider = { getNavyFilePath: async () => '/missing' } + const reconfigureHTTPProxy = sinon.stub().resolves() + const deleteState = sinon.stub().resolves() + const { Navy } = loadNavyModule({ + state: { + getState: sinon.stub().resolves({ driver: 'docker-compose', configProvider: 'filesystem' }), + deleteState, + }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + httpProxy: { reconfigureHTTPProxy }, + fs: { readdirAsync: sinon.stub().resolves(['env', 'other']) }, + }) + + await new Navy('env').destroy() + + expect(reconfigureHTTPProxy.calledOnce).to.equal(true) + expect(reconfigureHTTPProxy.firstCall.args[0].navies).to.eql(['other']) + expect(driver.destroy.calledOnce).to.equal(true) + expect(deleteState.calledOnce).to.equal(true) + }) + + it('should pass navyFile from a remaining navy when reconfiguring the proxy', async function () { + const driver = makeDriver() + const envPath = '/abs/env/Navyfile.js' + const otherPath = '/abs/other/Navyfile.js' + const destroyedNavyFile = { httpProxyImage: 'destroyed/proxy:1' } + const remainingNavyFile = { + httpProxyImage: 'remaining/proxy:1', + httpProxyEnv: { FOO: 'bar' }, + } + const createProvider = (path) => ({ getNavyFilePath: async () => path }) + const resolveConfigProvider = sinon.stub().callsFake(() => (navy) => + createProvider(navy.normalisedName === 'other' ? otherPath : envPath)) + const reconfigureHTTPProxy = sinon.stub().resolves() + const deleteState = sinon.stub().resolves() + const { Navy } = proxyquire.noCallThru()('../', { + '../util/fs': { + readdirAsync: sinon.stub().resolves(['env', 'other']), + lstatSync: sinon.stub().returns({ isDirectory: () => true }), + }, + './state': { + getState: sinon.stub().resolves({ driver: 'docker-compose', configProvider: 'filesystem' }), + saveState: sinon.stub().resolves(), + deleteState, + pathToNavys: sinon.stub().returns('/home/test/.navy/navies'), + pathToNavy: sinon.stub().callsFake((n) => `/home/test/.navy/navies/${n}`), + }, + '../driver': { resolveDriverFromName: sinon.stub().returns(() => driver) }, + '../config-provider': { resolveConfigProviderFromName: resolveConfigProvider }, + '../config': { getConfig: sinon.stub().returns({ externalIP: null }) }, + './plugin-interface': { loadPlugins: sinon.stub().resolves([]) }, + './middleware': { middlewareRunner: sinon.stub().resolves() }, + '../http-proxy': { reconfigureHTTPProxy }, + '../util/external-ip': { getExternalIP: sinon.stub().resolves('127.0.0.1') }, + '../util/service-host': { + createUrlForService: sinon.stub().resolves('http://svc.local'), + getUrlFromService: sinon.stub().returns(null), + }, + [envPath]: destroyedNavyFile, + [otherPath]: remainingNavyFile, + }) + + await new Navy('env').destroy() + + expect(reconfigureHTTPProxy.calledOnce).to.equal(true) + expect(reconfigureHTTPProxy.firstCall.args[0].navies).to.eql(['other']) + expect(reconfigureHTTPProxy.firstCall.args[0].navyFile).to.eql(remainingNavyFile) + }) + + it('should skip uninitialised remaining navies when resolving navyFile for the proxy', async function () { + const driver = makeDriver() + const otherPath = '/abs/other/Navyfile.js' + const remainingNavyFile = { httpProxyImage: 'remaining/proxy:1' } + const createProvider = (path) => ({ getNavyFilePath: async () => path }) + const resolveConfigProvider = sinon.stub().callsFake(() => (navy) => + createProvider(navy.normalisedName === 'other' ? otherPath : '/abs/env/Navyfile.js')) + const reconfigureHTTPProxy = sinon.stub().resolves() + const deleteState = sinon.stub().resolves() + const getState = sinon.stub().callsFake((name) => { + if (name === 'uninit') return Promise.resolve(null) + return Promise.resolve({ driver: 'docker-compose', configProvider: 'filesystem' }) + }) + const { Navy } = proxyquire.noCallThru()('../', { + '../util/fs': { + readdirAsync: sinon.stub().resolves(['env', 'uninit', 'other']), + lstatSync: sinon.stub().returns({ isDirectory: () => true }), + }, + './state': { + getState, + saveState: sinon.stub().resolves(), + deleteState, + pathToNavys: sinon.stub().returns('/home/test/.navy/navies'), + pathToNavy: sinon.stub().callsFake((n) => `/home/test/.navy/navies/${n}`), + }, + '../driver': { resolveDriverFromName: sinon.stub().returns(() => driver) }, + '../config-provider': { resolveConfigProviderFromName: resolveConfigProvider }, + '../config': { getConfig: sinon.stub().returns({ externalIP: null }) }, + './plugin-interface': { loadPlugins: sinon.stub().resolves([]) }, + './middleware': { middlewareRunner: sinon.stub().resolves() }, + '../http-proxy': { reconfigureHTTPProxy }, + '../util/external-ip': { getExternalIP: sinon.stub().resolves('127.0.0.1') }, + '../util/service-host': { + createUrlForService: sinon.stub().resolves('http://svc.local'), + getUrlFromService: sinon.stub().returns(null), + }, + [otherPath]: remainingNavyFile, + }) + + await new Navy('env').destroy() + + expect(reconfigureHTTPProxy.calledOnce).to.equal(true) + expect(reconfigureHTTPProxy.firstCall.args[0].navies).to.eql(['uninit', 'other']) + expect(reconfigureHTTPProxy.firstCall.args[0].navyFile).to.eql(remainingNavyFile) + }) + + it('should still delete state even when driver.destroy throws', async function () { + const driver = makeDriver({ destroy: sinon.stub().rejects(new Error('boom')) }) + const provider = { getNavyFilePath: async () => '/missing' } + const deleteState = sinon.stub().resolves() + const { Navy } = loadNavyModule({ + state: { + getState: sinon.stub().resolves({ driver: 'docker-compose', configProvider: 'filesystem' }), + deleteState, + }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + httpProxy: { reconfigureHTTPProxy: sinon.stub().resolves() }, + }) + + await new Navy('env').destroy() + expect(deleteState.calledOnce).to.equal(true) + }) + + }) + + describe('start/stop/restart/kill/rm/update/spawnLogStream', function () { + + function setup(driverOverrides = {}) { + const driver = makeDriver(driverOverrides) + const provider = { getNavyFilePath: async () => '/missing' } + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose', configProvider: 'filesystem' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + }) + return { driver, navy: new Navy('env') } + } + + ;[ + { method: 'start', explicit: ['api'] }, + { method: 'stop', explicit: ['api'] }, + { method: 'restart', explicit: ['api'] }, + { method: 'kill', explicit: ['api'] }, + ].forEach(({ method, explicit }) => { + it(`${method} should pass the explicit list through to the driver`, async function () { + const { driver, navy } = setup() + await navy[method](explicit) + expect(driver[method].calledOnce).to.equal(true) + expect(driver[method].firstCall.args[0]).to.eql(explicit) + }) + + it(`${method} should default to currently launched services when none provided`, async function () { + const { driver, navy } = setup({ getLaunchedServiceNames: sinon.stub().resolves(['api', 'web']) }) + await navy[method]() + expect(driver[method].firstCall.args[0]).to.eql(['api', 'web']) + }) + }) + + it('rm should default to currently launched services when none provided', async function () { + const { driver, navy } = setup({ getLaunchedServiceNames: sinon.stub().resolves(['x']) }) + await navy.rm() + expect(driver.rm.firstCall.args[0]).to.eql(['x']) + }) + + it('rm should accept an explicit list', async function () { + const { driver, navy } = setup() + await navy.rm(['x']) + expect(driver.rm.firstCall.args[0]).to.eql(['x']) + }) + + it('update should default to all available services', async function () { + const { driver, navy } = setup({ getAvailableServiceNames: sinon.stub().resolves(['a', 'b']) }) + await navy.update() + expect(driver.update.firstCall.args[0]).to.eql(['a', 'b']) + }) + + it('update should accept an explicit list', async function () { + const { driver, navy } = setup() + await navy.update(['x']) + expect(driver.update.firstCall.args[0]).to.eql(['x']) + }) + + it('spawnLogStream should default to currently launched services when none provided', async function () { + const { driver, navy } = setup({ getLaunchedServiceNames: sinon.stub().resolves(['l']) }) + await navy.spawnLogStream() + expect(driver.spawnLogStream.firstCall.args[0]).to.eql(['l']) + }) + + it('spawnLogStream should accept an explicit list', async function () { + const { driver, navy } = setup() + await navy.spawnLogStream(['l']) + expect(driver.spawnLogStream.firstCall.args[0]).to.eql(['l']) + }) + + it('start should reconfigure the HTTP proxy', async function () { + const driver = makeDriver({ getLaunchedServiceNames: sinon.stub().resolves(['api']) }) + const provider = { getNavyFilePath: async () => '/missing' } + const reconfigure = sinon.stub().resolves() + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose', configProvider: 'filesystem' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + httpProxy: { reconfigureHTTPProxy: reconfigure }, + }) + + await new Navy('env').start(['api']) + expect(reconfigure.calledOnce).to.equal(true) + }) + + }) + + describe('useTag/resetTag/usePort/resetPort', function () { + + function setupTagPort({ initialState = { driver: 'docker-compose', configProvider: 'filesystem', services: {} } } = {}) { + const driver = makeDriver({ + getAvailableServiceNames: sinon.stub().resolves(['api']), + getLaunchedServiceNames: sinon.stub().resolves([]), + }) + let currentState = initialState + const getStateStub = sinon.stub().callsFake(async () => currentState) + const saveStub = sinon.stub().callsFake(async (envName, state) => { + currentState = state + }) + const provider = { getNavyFilePath: async () => '/missing' } + const { Navy } = loadNavyModule({ + state: { getState: getStateStub, saveState: saveStub }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + configProvider: { resolveConfigProviderFromName: sinon.stub().returns(() => provider) }, + }) + return { Navy, driver, saveStub } + } + + it('useTag should record the tag in state, kill the service, and update it', async function () { + const { Navy, driver, saveStub } = setupTagPort() + await new Navy('env').useTag('api', 'v2') + const written = saveStub.firstCall.args[1] + expect(written.services.api._tag).to.equal('v2') + expect(driver.kill.firstCall.args[0]).to.eql(['api']) + expect(driver.update.firstCall.args[0]).to.eql(['api']) + }) + + // NOTE: useTag/resetTag/usePort/resetPort all start with + // `(await this.getState()) || {}` and write the result back as the new + // state. If state was never initialised, the saved state has no `driver` + // key, and the subsequent kill/launch then fails with a NO_DRIVER invariant. + // We therefore exercise these methods only with a properly initialised state. + it('useTag should preserve other services in state.services when modifying one', async function () { + const initial = { + driver: 'docker-compose', + configProvider: 'filesystem', + services: { other: { _tag: 'keep-me' } }, + } + const { Navy, saveStub } = setupTagPort({ initialState: initial }) + + await new Navy('env').useTag('api', 'v2') + + const written = saveStub.firstCall.args[1] + expect(written.services.other).to.eql({ _tag: 'keep-me' }) + expect(written.services.api._tag).to.equal('v2') + }) + + it('resetTag should clear the tag and relaunch the service with noDeps', async function () { + const { Navy, driver, saveStub } = setupTagPort({ + initialState: { driver: 'docker-compose', configProvider: 'filesystem', services: { api: { _tag: 'old' } } }, + }) + + await new Navy('env').resetTag('api') + + expect(saveStub.firstCall.args[1].services.api._tag).to.equal(undefined) + expect(driver.launch.firstCall.args[1]).to.eql({ noDeps: true }) + }) + + it('resetTag should preserve services other than the one being reset', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { + driver: 'docker-compose', + configProvider: 'filesystem', + services: { api: { _tag: 'old' }, other: { _tag: 'keep' } }, + }, + }) + + await new Navy('env').resetTag('api') + + const written = saveStub.firstCall.args[1] + expect(written.services.other).to.eql({ _tag: 'keep' }) + expect(written.services.api._tag).to.equal(undefined) + }) + + it('usePort should record port mapping in state', async function () { + const { Navy, saveStub } = setupTagPort() + await new Navy('env').usePort('api', 80, 8080) + expect(saveStub.firstCall.args[1].services.api._ports).to.eql({ 80: 8080 }) + }) + + it('usePort should merge the new port mapping with existing ports for the service', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { + driver: 'docker-compose', + configProvider: 'filesystem', + services: { api: { _ports: { 443: 4433 } } }, + }, + }) + + await new Navy('env').usePort('api', 80, 8080) + + const ports = saveStub.firstCall.args[1].services.api._ports + expect(ports).to.eql({ 80: 8080, 443: 4433 }) + }) + + it('resetPort should set the port to undefined', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { + driver: 'docker-compose', + configProvider: 'filesystem', + services: { api: { _ports: { 80: 8080 } } }, + }, + }) + + await new Navy('env').resetPort('api', 80) + expect(saveStub.firstCall.args[1].services.api._ports[80]).to.equal(undefined) + }) + + it('resetPort should preserve other ports on the same service', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { + driver: 'docker-compose', + configProvider: 'filesystem', + services: { api: { _ports: { 80: 8080, 443: 4433 } } }, + }, + }) + + await new Navy('env').resetPort('api', 80) + + const ports = saveStub.firstCall.args[1].services.api._ports + expect(ports[80]).to.equal(undefined) + expect(ports[443]).to.equal(4433) + }) + + it('useTag should throw NavyNotInitialisedError when state is missing', async function () { + const { Navy } = loadNavyModule() + let caught + try { + await new Navy('env').useTag('api', 'v1') + } catch (e) { + caught = e + } + expect(caught).to.be.instanceof(NavyNotInitialisedError) + }) + + it('resetTag should throw NavyNotInitialisedError when state is missing', async function () { + const { Navy } = loadNavyModule() + let caught + try { + await new Navy('env').resetTag('api') + } catch (e) { + caught = e + } + expect(caught).to.be.instanceof(NavyNotInitialisedError) + }) + + it('usePort should throw NavyNotInitialisedError when state is missing', async function () { + const { Navy } = loadNavyModule() + let caught + try { + await new Navy('env').usePort('api', 80, 8080) + } catch (e) { + caught = e + } + expect(caught).to.be.instanceof(NavyNotInitialisedError) + }) + + it('resetPort should throw NavyNotInitialisedError when state is missing', async function () { + const { Navy } = loadNavyModule() + let caught + try { + await new Navy('env').resetPort('api', 80) + } catch (e) { + caught = e + } + expect(caught).to.be.instanceof(NavyNotInitialisedError) + }) + + it('useTag should treat missing state.services as an empty services map', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { driver: 'docker-compose', configProvider: 'filesystem' }, + }) + + await new Navy('env').useTag('api', 'v2') + + expect(saveStub.firstCall.args[1].services.api._tag).to.equal('v2') + }) + + it('resetTag should treat missing state.services as an empty services map', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { driver: 'docker-compose', configProvider: 'filesystem' }, + }) + + await new Navy('env').resetTag('api') + + expect(saveStub.firstCall.args[1].services.api._tag).to.equal(undefined) + }) + + it('usePort should treat missing state.services as an empty services map', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { driver: 'docker-compose', configProvider: 'filesystem' }, + }) + + await new Navy('env').usePort('api', 80, 8080) + + expect(saveStub.firstCall.args[1].services.api._ports).to.eql({ 80: 8080 }) + }) + + it('resetPort should treat missing state.services as an empty services map', async function () { + const { Navy, saveStub } = setupTagPort({ + initialState: { driver: 'docker-compose', configProvider: 'filesystem' }, + }) + + await new Navy('env').resetPort('api', 80) + + expect(saveStub.firstCall.args[1].services.api._ports[80]).to.equal(undefined) + }) + + }) + + describe('externalIP', function () { + + it('should return the IP from getExternalIP using config.externalIP', async function () { + const { Navy } = loadNavyModule({ + config: { getConfig: sinon.stub().returns({ externalIP: 'configured.host' }) }, + externalIP: { getExternalIP: sinon.stub().resolves('1.2.3.4') }, + }) + + expect(await new Navy('env').externalIP()).to.equal('1.2.3.4') + }) + + }) + + describe('port', function () { + + it('should delegate to driver.port with the privatePort and index defaulting to 1', async function () { + const driver = makeDriver({ port: sinon.stub().resolves(8080) }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + }) + + expect(await new Navy('env').port('api', 80)).to.equal(8080) + expect(driver.port.firstCall.args).to.eql(['api', 80, 1]) + }) + + }) + + describe('url', function () { + + it('should return getUrlFromService when there is a running service URL', async function () { + const driver = makeDriver({ ps: sinon.stub().resolves([{ name: 'api' }]) }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + serviceHost: { + getUrlFromService: sinon.stub().returns('http://from-service'), + createUrlForService: sinon.stub().resolves('http://fallback'), + }, + }) + + expect(await new Navy('env').url('api')).to.equal('http://from-service') + }) + + it('should fall back to createUrlForService when getUrlFromService returns null', async function () { + const driver = makeDriver({ ps: sinon.stub().resolves([{ name: 'api' }]) }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + serviceHost: { + getUrlFromService: sinon.stub().returns(null), + createUrlForService: sinon.stub().resolves('http://fallback'), + }, + externalIP: { getExternalIP: sinon.stub().resolves('1.2.3.4') }, + }) + + expect(await new Navy('env').url('api')).to.equal('http://fallback') + }) + + }) + + describe('ps / getLaunchedServiceNames / getAvailableServiceNames', function () { + + it('ps should delegate to the driver', async function () { + const driver = makeDriver({ ps: sinon.stub().resolves([{ name: 'api' }]) }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + }) + + expect(await new Navy('env').ps()).to.eql([{ name: 'api' }]) + }) + + it('getLaunchedServiceNames should delegate to driver', async function () { + const driver = makeDriver({ getLaunchedServiceNames: sinon.stub().resolves(['x']) }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + }) + + expect(await new Navy('env').getLaunchedServiceNames()).to.eql(['x']) + }) + + it('getAvailableServiceNames should delegate to driver', async function () { + const driver = makeDriver({ getAvailableServiceNames: sinon.stub().resolves(['x', 'y']) }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + }) + + expect(await new Navy('env').getAvailableServiceNames()).to.eql(['x', 'y']) + }) + + }) + + describe('waitForHealthy', function () { + + function setupHealth({ ps = [] } = {}) { + const driver = makeDriver({ ps: sinon.stub().resolves(ps) }) + const { Navy } = loadNavyModule({ + state: { getState: sinon.stub().resolves({ driver: 'docker-compose' }) }, + driver: { resolveDriverFromName: sinon.stub().returns(() => driver) }, + }) + return new Navy('env') + } + + it('should resolve true when all specified services are healthy', async function () { + const navy = setupHealth({ + ps: [{ name: 'api', raw: { State: { Health: { Status: 'healthy' } } } }], + }) + + const result = await navy.waitForHealthy(['api'], null, { factor: 1, retries: 1, minTimeout: 1 }) + expect(result).to.equal(true) + }) + + it('should default services to all containers with health checks when none provided', async function () { + const navy = setupHealth({ + ps: [ + { name: 'api', raw: { State: { Health: { Status: 'healthy' } } } }, + { name: 'noh', raw: { State: {} } }, + ], + }) + + const result = await navy.waitForHealthy(undefined, null, { factor: 1, retries: 1, minTimeout: 1 }) + expect(result).to.equal(true) + }) + + it('should call progressCallback with health status of each service', async function () { + const navy = setupHealth({ + ps: [{ name: 'api', raw: { State: { Health: { Status: 'healthy' } } } }], + }) + const cb = sinon.spy() + + await navy.waitForHealthy(['api'], cb, { factor: 1, retries: 1, minTimeout: 1 }) + expect(cb.calledOnce).to.equal(true) + expect(cb.firstCall.args[0]).to.eql([{ service: 'api', health: 'healthy' }]) + }) + + it('should throw a NavyError describing services missing health checks', async function () { + const navy = setupHealth({ + ps: [{ name: 'api', raw: { State: {} } }], + }) + + let caught + try { + await navy.waitForHealthy(['api'], null, { factor: 1, retries: 1, minTimeout: 1 }) + } catch (e) { + caught = e + } + expect(caught).to.be.instanceof(NavyError) + expect(caught.message).to.contain("don't have health checks") + expect(caught.message).to.contain('api') + }) + + // NOTE: Currently `waitForHealthy` calls `retry('Unhealthy services: ...')` + // with a string. After retries exhaust, that string is what is thrown, then + // `catch (e) { throw new NavyError(e.message) }` reads `.message` on the + // string, which is undefined. The NavyError that surfaces therefore has no + // message. This test asserts the type only and documents the lost message. + it('should throw a NavyError after retries exhausted with unhealthy services', async function () { + this.timeout(10000) + const navy = setupHealth({ + ps: [{ name: 'api', raw: { State: { Health: { Status: 'starting' } } } }], + }) + + let caught + try { + await navy.waitForHealthy(['api'], null, { factor: 1, retries: 2, minTimeout: 1 }) + } catch (e) { + caught = e + } + expect(caught).to.be.instanceof(NavyError) + }) + + }) + + describe('getLaunchedNavies / getLaunchedNavyNames', function () { + + it('getLaunchedNavyNames should return readdir entries', async function () { + const { getLaunchedNavyNames } = loadNavyModule({ + fs: { readdirAsync: sinon.stub().resolves(['env1', 'env2']) }, + }) + + expect(await getLaunchedNavyNames()).to.eql(['env1', 'env2']) + }) + + it('getLaunchedNavyNames should return [] when readdir fails', async function () { + const { getLaunchedNavyNames } = loadNavyModule({ + fs: { readdirAsync: sinon.stub().rejects(new Error('ENOENT')) }, + }) + + expect(await getLaunchedNavyNames()).to.eql([]) + }) + + it('getLaunchedNavies should return Navy instances for each navy directory', async function () { + const { getLaunchedNavies } = loadNavyModule({ + fs: { + readdirAsync: sinon.stub().resolves(['env1', 'env2', 'file.txt']), + lstatSync: sinon.stub().callsFake((p) => ({ isDirectory: () => !p.endsWith('file.txt') })), + }, + }) + + const navies = await getLaunchedNavies() + expect(navies.map(n => n.name)).to.eql(['env1', 'env2']) + }) + + it('getLaunchedNavies should return [] when readdir fails', async function () { + const { getLaunchedNavies } = loadNavyModule({ + fs: { readdirAsync: sinon.stub().rejects(new Error('ENOENT')) }, + }) + + expect(await getLaunchedNavies()).to.eql([]) + }) + + }) + +}) diff --git a/packages/navy/src/navy/__tests__/middleware.js b/packages/navy/src/navy/__tests__/middleware.js new file mode 100644 index 0000000..d4383d9 --- /dev/null +++ b/packages/navy/src/navy/__tests__/middleware.js @@ -0,0 +1,62 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import { middlewareRunner } from '../middleware' + +function makeNavy({ driver, registered = [] } = {}) { + return { + name: 'env', + normalisedName: 'env', + getDriver: sinon.stub().resolves(driver), + ensurePluginsLoaded: sinon.stub().resolves(), + getNavyFile: sinon.stub().resolves(null), + externalIP: sinon.stub().resolves('127.0.0.1'), + _registeredMiddleware: registered, + } +} + +function makeDriver() { + return { + getConfig: sinon.stub().resolves({ services: {} }), + writeConfig: sinon.stub().resolves(), + } +} + +describe('navy/middleware', function () { + + describe('middlewareRunner', function () { + + it('should be a no-op when the navy has no driver', async function () { + const navy = makeNavy({ driver: null }) + + await middlewareRunner(navy, { services: {} }) + + expect(navy.ensurePluginsLoaded.called).to.equal(false) + }) + + it('should ensure plugins are loaded before running middleware', async function () { + const driver = makeDriver() + const navy = makeNavy({ driver }) + + await middlewareRunner(navy, { services: {} }) + + expect(navy.ensurePluginsLoaded.calledOnce).to.equal(true) + }) + + it('should pipe the driver config through default + registered middleware and write the result', async function () { + const driver = makeDriver() + const tagged = sinon.stub().callsFake(async config => ({ ...config, _tagged: true })) + const navy = makeNavy({ driver, registered: [tagged] }) + + await middlewareRunner(navy, { services: {} }) + + expect(tagged.calledOnce).to.equal(true) + expect(driver.writeConfig.calledOnce).to.equal(true) + const written = driver.writeConfig.firstCall.args[0] + expect(written).to.have.property('_tagged', true) + }) + + }) + +}) diff --git a/packages/navy/src/navy/__tests__/plugin-interface.js b/packages/navy/src/navy/__tests__/plugin-interface.js new file mode 100644 index 0000000..af4f7cd --- /dev/null +++ b/packages/navy/src/navy/__tests__/plugin-interface.js @@ -0,0 +1,105 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import proxyquire from 'proxyquire' + +describe('navy/plugin-interface', function () { + + describe('loadPlugins', function () { + + function loadModule(stubs) { + return proxyquire.noCallThru()('../plugin-interface', stubs) + } + + it('should throw an invariant violation if the navy has no config provider', async function () { + const { loadPlugins } = loadModule({}) + const navy = { + name: 'env', + getConfigProvider: async () => null, + } + + let caught + try { + await loadPlugins(navy, { plugins: [] }) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.match(/NO_CONFIG_PROVIDER/) + }) + + it('should return an empty array when navyFile has no plugins entry', async function () { + const { loadPlugins } = loadModule({}) + const navy = { + getConfigProvider: async () => ({ getNavyPath: async () => '/some/path' }), + } + + expect(await loadPlugins(navy, {})).to.eql([]) + }) + + it('should resolve plugins by name relative to the navy path and instantiate them with the navy', async function () { + const fakePluginPath = '/abs/path/to/plugin' + const fakePluginInstance = { meta: 'instance' } + const PluginCtor = (navy) => ({ ...fakePluginInstance, navy }) + const { loadPlugins } = loadModule({ + resolve: (pluginName, opts, cb) => cb(null, fakePluginPath), + [fakePluginPath]: PluginCtor, + }) + + const navy = { + getConfigProvider: async () => ({ getNavyPath: async () => '/navy/path' }), + } + + const plugins = await loadPlugins(navy, { plugins: ['my-plugin'] }) + + expect(plugins).to.have.lengthOf(1) + expect(plugins[0]).to.have.property('meta', 'instance') + expect(plugins[0]).to.have.property('navy', navy) + }) + + it('should throw PLUGIN_RESOLVE_ERR with the joined plugin names when resolution fails', async function () { + const { loadPlugins } = loadModule({ + resolve: (pluginName, opts, cb) => cb(new Error('not found')), + }) + const navy = { + getConfigProvider: async () => ({ getNavyPath: async () => '/navy/path' }), + } + + let caught + try { + await loadPlugins(navy, { plugins: ['plugin-a', 'plugin-b'] }) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.match(/PLUGIN_RESOLVE_ERR/) + expect(caught.message).to.contain('plugin-a, plugin-b') + }) + + it('should throw PLUGIN_DOESNT_EXPORT_FUNCTION when a plugin module is not a function', async function () { + const fakePluginPath = '/abs/path/to/bad-plugin' + const { loadPlugins } = loadModule({ + resolve: (pluginName, opts, cb) => cb(null, fakePluginPath), + [fakePluginPath]: { notAFunction: true }, + }) + const navy = { + getConfigProvider: async () => ({ getNavyPath: async () => '/navy/path' }), + } + + let caught + try { + await loadPlugins(navy, { plugins: ['bad-plugin'] }) + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.match(/PLUGIN_DOESNT_EXPORT_FUNCTION/) + expect(caught.message).to.contain('bad-plugin') + }) + + }) + +}) diff --git a/packages/navy/src/navy/__tests__/state.js b/packages/navy/src/navy/__tests__/state.js new file mode 100644 index 0000000..da39437 --- /dev/null +++ b/packages/navy/src/navy/__tests__/state.js @@ -0,0 +1,141 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import path from 'path' +import { promises as fsp } from 'fs' +import fs from '../../util/fs' +import { + pathToNavyRoot, + pathToNavys, + pathToNavy, + pathToState, + getState, + saveState, + deleteState, +} from '../state' + +describe('navy/state', function () { + + let sandbox + let originalHome + + beforeEach(function () { + sandbox = sinon.createSandbox() + originalHome = process.env.HOME + process.env.HOME = '/home/test' + }) + + afterEach(function () { + sandbox.restore() + if (originalHome === undefined) { + delete process.env.HOME + } else { + process.env.HOME = originalHome + } + }) + + describe('pathToNavyRoot', function () { + + it('should return $HOME/.navy', function () { + expect(pathToNavyRoot()).to.equal(path.join('/home/test', '.navy')) + }) + + it('should throw when HOME is not set', function () { + delete process.env.HOME + expect(() => pathToNavyRoot()).to.throw(/NO_HOME_DIRECTORY/) + }) + + }) + + describe('pathToNavys', function () { + + it('should return $HOME/.navy/navies', function () { + expect(pathToNavys()).to.equal(path.join('/home/test', '.navy', 'navies')) + }) + + }) + + describe('pathToNavy', function () { + + it('should return $HOME/.navy/navies/', function () { + expect(pathToNavy('myenv')).to.equal(path.join('/home/test', '.navy', 'navies', 'myenv')) + }) + + }) + + describe('pathToState', function () { + + it('should return $HOME/.navy/navies//state.json', function () { + expect(pathToState('myenv')).to.equal( + path.join('/home/test', '.navy', 'navies', 'myenv', 'state.json') + ) + }) + + }) + + describe('getState', function () { + + it('should read and parse the state.json file', async function () { + const state = { driver: 'docker-compose', services: { api: {} } } + const buf = Buffer.from(JSON.stringify(state)) + sandbox.stub(fs, 'readFileAsync').resolves(buf) + + expect(await getState('myenv')).to.eql(state) + }) + + it('should return null when the state file cannot be read', async function () { + sandbox.stub(fs, 'readFileAsync').rejects(new Error('ENOENT')) + + expect(await getState('myenv')).to.equal(null) + }) + + it('should return null when the state file content is not valid JSON', async function () { + sandbox.stub(fs, 'readFileAsync').resolves(Buffer.from('not json')) + + expect(await getState('myenv')).to.equal(null) + }) + + }) + + describe('saveState', function () { + + it('should mkdir -p the navy directory and write the state JSON file', async function () { + const mkdirStub = sandbox.stub(fsp, 'mkdir').resolves() + const writeStub = sandbox.stub(fs, 'writeFileAsync').resolves() + + const state = { driver: 'docker-compose' } + await saveState('myenv', state) + + expect(mkdirStub.calledOnce).to.equal(true) + expect(mkdirStub.firstCall.args[0]).to.equal( + path.join('/home/test', '.navy', 'navies', 'myenv') + ) + expect(mkdirStub.firstCall.args[1]).to.eql({ recursive: true }) + + expect(writeStub.calledOnce).to.equal(true) + expect(writeStub.firstCall.args[0]).to.equal( + path.join('/home/test', '.navy', 'navies', 'myenv', 'state.json') + ) + expect(JSON.parse(writeStub.firstCall.args[1])).to.eql(state) + }) + + }) + + describe('deleteState', function () { + + it('should rm -rf the navy directory recursively', async function () { + const rmStub = sandbox.stub(fsp, 'rm').resolves() + + await deleteState('myenv') + + expect(rmStub.calledOnce).to.equal(true) + expect(rmStub.firstCall.args[0]).to.equal( + path.join('/home/test', '.navy', 'navies', 'myenv') + ) + expect(rmStub.firstCall.args[1]).to.eql({ recursive: true, force: true }) + }) + + }) + +}) diff --git a/packages/navy/src/navy/__tests__/util.js b/packages/navy/src/navy/__tests__/util.js new file mode 100644 index 0000000..7562ddb --- /dev/null +++ b/packages/navy/src/navy/__tests__/util.js @@ -0,0 +1,30 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import { normaliseNavyName } from '../util' + +describe('navy/util', function () { + + describe('normaliseNavyName', function () { + + it('should strip non-word characters from a navy name', function () { + expect(normaliseNavyName('my-navy')).to.equal('mynavy') + expect(normaliseNavyName('my navy')).to.equal('mynavy') + expect(normaliseNavyName('a.b.c')).to.equal('abc') + }) + + it('should preserve underscores and digits (which are word characters)', function () { + expect(normaliseNavyName('env_1_test_2')).to.equal('env_1_test_2') + }) + + it('should leave a name with no special characters unchanged', function () { + expect(normaliseNavyName('plain')).to.equal('plain') + }) + + it('should return an empty string for a name made entirely of special characters', function () { + expect(normaliseNavyName('!@#$%^&*()')).to.equal('') + }) + + }) + +}) diff --git a/packages/navy/src/navy/default-middleware.js b/packages/navy/src/navy/default-middleware.js index 6d3835f..36ba4b0 100644 --- a/packages/navy/src/navy/default-middleware.js +++ b/packages/navy/src/navy/default-middleware.js @@ -6,7 +6,7 @@ import setEnvironmentVariables from '../middleware/set-env-vars' import setLoggingDriver from '../middleware/set-logging-driver' import setImage from '../middleware/set-image' -import type {Navy} from './' +import type { Navy } from './' export default (navy: Navy) => ([ developMiddleware, diff --git a/packages/navy/src/navy/index.js b/packages/navy/src/navy/index.js index 9c74acb..09b8075 100644 --- a/packages/navy/src/navy/index.js +++ b/packages/navy/src/navy/index.js @@ -1,28 +1,28 @@ /* @flow */ import invariant from 'invariant' -import {EventEmitter2} from 'eventemitter2' +import { EventEmitter2 } from 'eventemitter2' import retryPromise from 'promise-retry' import fs from '../util/fs' -import {resolveDriverFromName} from '../driver' -import {resolveConfigProviderFromName} from '../config-provider' -import {normaliseNavyName} from './util' -import {getState, saveState, deleteState, pathToNavys, pathToNavy} from './state' -import {getConfig} from '../config' -import {NavyNotInitialisedError, NavyError} from '../errors' -import {loadPlugins} from './plugin-interface' -import {middlewareRunner} from './middleware' -import {reconfigureHTTPProxy} from '../http-proxy' -import {getExternalIP} from '../util/external-ip' -import {createUrlForService, getUrlFromService} from '../util/service-host' - -import type {Driver, CreateDriver} from '../driver' -import type {ConfigProvider, CreateConfigProvider} from '../config-provider' -import type {State} from './state' -import type {ServiceList} from '../service' - -export type {State} +import { resolveDriverFromName } from '../driver' +import { resolveConfigProviderFromName } from '../config-provider' +import { normaliseNavyName } from './util' +import { getState, saveState, deleteState, pathToNavys, pathToNavy } from './state' +import { getConfig } from '../config' +import { NavyNotInitialisedError, NavyError } from '../errors' +import { loadPlugins } from './plugin-interface' +import { middlewareRunner } from './middleware' +import { reconfigureHTTPProxy } from '../http-proxy' +import { getExternalIP } from '../util/external-ip' +import { createUrlForService, getUrlFromService } from '../util/service-host' + +import type { Driver, CreateDriver } from '../driver' +import type { ConfigProvider, CreateConfigProvider } from '../config-provider' +import type { State } from './state' +import type { ServiceList } from '../service' + +export type { State } export type RetryConfig = { factor?: number, @@ -40,17 +40,17 @@ export class Navy extends EventEmitter2 { * The name of the current Navy. * @public */ - name: string; + name: string /** * The normalised name of the current Navy (name without whitespaces). * @public */ - normalisedName: string; + normalisedName: string - _pluginsLoaded: boolean; - _registeredCommands: Object; - _registeredMiddleware: Array; + _pluginsLoaded: boolean + _registeredCommands: Object + _registeredMiddleware: Array constructor(name: string) { super({ @@ -151,7 +151,7 @@ export class Navy extends EventEmitter2 { const navyFilePath: string = await configProvider.getNavyFilePath() try { - // $FlowIgnore: entry point to Navyfile.js has to be dynamic + // $FlowFixMe[unsupported-syntax]: entry point to Navyfile.js has to be dynamic return require(navyFilePath) } catch (ex) { return null @@ -256,7 +256,7 @@ export class Navy extends EventEmitter2 { await (await this.safeGetDriver()).launch(validServiceNames, opts) - await reconfigureHTTPProxy() + await reconfigureHTTPProxy({ navyFile: await this.getNavyFile() }) } /** @@ -290,9 +290,12 @@ export class Navy extends EventEmitter2 { throw new NavyNotInitialisedError(this.name) } + const remainingNavyNames = (await getLaunchedNavyNames()) + .filter(navy => navy !== this.normalisedName) + await reconfigureHTTPProxy({ - navies: (await getLaunchedNavyNames()) - .filter(navy => navy !== this.normalisedName), + navies: remainingNavyNames, + navyFile: await getNavyFileFromNavies(remainingNavyNames), }) try { @@ -317,7 +320,7 @@ export class Navy extends EventEmitter2 { async start(services?: Array): Promise { if (!services) services = await this.getLaunchedServiceNames() - await reconfigureHTTPProxy() + await reconfigureHTTPProxy({ navyFile: await this.getNavyFile() }) await (await this.safeGetDriver()).start(services) } @@ -385,14 +388,16 @@ export class Navy extends EventEmitter2 { * @public */ async useTag(service: string, tag: string): Promise { - const state = (await this.getState()) || {} + const state = await this.getState() + if (!state) throw new NavyNotInitialisedError(this.name) + const stateServices: {[string]: Object} = state.services || {} await this.saveState({ ...state, services: { - ...state.services, + ...stateServices, [service]: { - ...(state.services || {})[service], + ...stateServices[service], _tag: tag, }, }, @@ -407,14 +412,16 @@ export class Navy extends EventEmitter2 { * @public */ async resetTag(service: string): Promise { - const state = (await this.getState()) || {} + const state = await this.getState() + if (!state) throw new NavyNotInitialisedError(this.name) + const stateServices: {[string]: Object} = state.services || {} await this.saveState({ ...state, services: { - ...state.services, + ...stateServices, [service]: { - ...(state.services || {})[service], + ...stateServices[service], _tag: undefined, }, }, @@ -425,16 +432,19 @@ export class Navy extends EventEmitter2 { } async usePort(service: string, privatePort: number, externalPort: number): Promise { - const state = (await this.getState()) || {} + const state = await this.getState() + if (!state) throw new NavyNotInitialisedError(this.name) + const stateServices: {[string]: Object} = state.services || {} + const existingService: Object = stateServices[service] || {} await this.saveState({ ...state, services: { - ...state.services, + ...stateServices, [service]: { - ...(state.services || {})[service], + ...existingService, _ports: { - ...((state.services || {})[service] || {})._ports, + ...existingService._ports, [privatePort]: externalPort, }, }, @@ -446,16 +456,19 @@ export class Navy extends EventEmitter2 { } async resetPort(service: string, privatePort: number): Promise { - const state = (await this.getState()) || {} + const state = await this.getState() + if (!state) throw new NavyNotInitialisedError(this.name) + const stateServices: {[string]: Object} = state.services || {} + const existingService: Object = stateServices[service] || {} await this.saveState({ ...state, services: { - ...state.services, + ...stateServices, [service]: { - ...(state.services || {})[service], + ...existingService, _ports: { - ...((state.services || {})[service] || {})._ports, + ...existingService._ports, [privatePort]: undefined, }, }, @@ -473,7 +486,7 @@ export class Navy extends EventEmitter2 { async waitForHealthy( services?: Array, progressCallback?: Function, - retryConfig?: RetryConfig = {factor: 1.1, retries: 30, minTimeout: 200} + retryConfig?: RetryConfig = { factor: 1.1, retries: 30, minTimeout: 200 } ): Promise { if (services == null) { services = (await this.ps()) @@ -574,6 +587,18 @@ export function getNavy(navyName: ?string): Navy { return new Navy(navyName) } +async function getNavyFileFromNavies(navyNames: Array): Promise { + for (const navyName of navyNames) { + const navy = getNavy(navyName) + if (!await navy.isInitialised()) continue + + const navyFile = await navy.getNavyFile() + if (navyFile) return navyFile + } + + return null +} + /** * Returns an array of `Navy` instances which are currently imported and launched. * @public diff --git a/packages/navy/src/navy/middleware.js b/packages/navy/src/navy/middleware.js index d5b26e5..3c5d0ae 100644 --- a/packages/navy/src/navy/middleware.js +++ b/packages/navy/src/navy/middleware.js @@ -3,9 +3,9 @@ import Bluebird from 'bluebird' import defaultMiddleware from './default-middleware' -import type {State} from './state' -import type {Driver} from '../driver' -import type {Navy} from './' +import type { State } from './state' +import type { Driver } from '../driver' +import type { Navy } from './' export async function middlewareRunner(navy: Navy, state: State): Promise { const driver: ?Driver = await navy.getDriver() diff --git a/packages/navy/src/navy/plugin-interface.js b/packages/navy/src/navy/plugin-interface.js index 7ca603a..0ca851b 100644 --- a/packages/navy/src/navy/plugin-interface.js +++ b/packages/navy/src/navy/plugin-interface.js @@ -3,8 +3,8 @@ import bluebird from 'bluebird' import invariant from 'invariant' -import type {ConfigProvider} from '../config-provider' -import type {Navy} from './' +import type { ConfigProvider } from '../config-provider' +import type { Navy } from './' const resolve = bluebird.promisify(require('resolve')) @@ -28,7 +28,7 @@ export async function loadPlugins(navy: Navy, navyFile: Object): Promise require(pluginPath)) return plugins.map((Plugin, index) => { diff --git a/packages/navy/src/navy/state.js b/packages/navy/src/navy/state.js index d9111cb..c878c3e 100644 --- a/packages/navy/src/navy/state.js +++ b/packages/navy/src/navy/state.js @@ -2,15 +2,12 @@ import path from 'path' import invariant from 'invariant' -import bluebird from 'bluebird' +import { promises as fsp } from 'fs' import fs from '../util/fs' const debug = require('debug')('navy:state') -const mkdirp = bluebird.promisify(require('mkdirp')) -const rimraf = bluebird.promisify(require('rimraf')) - export function pathToNavyRoot(): string { const home = process.env.HOME invariant(home, 'NO_HOME_DIRECTORY') @@ -46,7 +43,7 @@ export async function getState(normalisedEnvName: string): Promise { export async function saveState(normalisedEnvName: string, state: State): Promise { const statePath = pathToState(normalisedEnvName) - await mkdirp(path.dirname(statePath)) + await fsp.mkdir(path.dirname(statePath), { recursive: true }) debug('Writing state for env ' + normalisedEnvName, statePath, state) @@ -56,7 +53,7 @@ export async function saveState(normalisedEnvName: string, state: State): Promis export async function deleteState(normalisedEnvName: string): Promise { debug('Deleting state for env ' + normalisedEnvName) - await rimraf(path.dirname(pathToState(normalisedEnvName))) + await fsp.rm(path.dirname(pathToState(normalisedEnvName)), { recursive: true, force: true }) } /** @@ -75,5 +72,5 @@ export type State = { configProvider?: string, path?: string, npmPackage?: string, - services?: Object, + services?: {[string]: Object}, } diff --git a/packages/navy/src/util/__tests__/exec-async.js b/packages/navy/src/util/__tests__/exec-async.js new file mode 100644 index 0000000..f901f4f --- /dev/null +++ b/packages/navy/src/util/__tests__/exec-async.js @@ -0,0 +1,98 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import { EventEmitter } from 'events' +import childProcess from 'child_process' +import { execAsync } from '../exec-async' + +function createFakeChild() { + const child = new EventEmitter() + child.stdout = new EventEmitter() + child.stderr = new EventEmitter() + return child +} + +describe('exec-async', function () { + + describe('execAsync', function () { + + let sandbox + let execStub + let fakeChild + + beforeEach(function () { + sandbox = sinon.createSandbox() + fakeChild = createFakeChild() + + execStub = sandbox.stub(childProcess, 'exec').callsFake((cmd, opts, cb) => { + process.nextTick(() => { + fakeChild.stdout.emit('data', Buffer.from('hello')) + fakeChild.stderr.emit('data', Buffer.from('warn')) + cb(null, 'hello world', '') + }) + return fakeChild + }) + }) + + afterEach(function () { + sandbox.restore() + }) + + it('should resolve with stdout when the command succeeds', async function () { + const result = await execAsync('echo', ['hello', 'world']) + + expect(result).to.equal('hello world') + expect(execStub.calledOnce).to.equal(true) + expect(execStub.firstCall.args[0]).to.equal('echo hello world') + }) + + it('should default args to an empty array when not provided', async function () { + const result = await execAsync('echo') + + expect(result).to.equal('hello world') + expect(execStub.firstCall.args[0]).to.equal('echo ') + }) + + it('should pass opts through to child_process.exec', async function () { + const opts = { cwd: '/tmp', env: { FOO: 'bar' } } + + await execAsync('ls', ['-la'], null, opts) + + expect(execStub.firstCall.args[1]).to.equal(opts) + }) + + it('should invoke the callback with the spawned child process', async function () { + const callback = sinon.spy() + + await execAsync('echo', ['hi'], callback) + + expect(callback.calledOnce).to.equal(true) + expect(callback.firstCall.args[0]).to.equal(fakeChild) + }) + + it('should not invoke the callback when none is supplied', async function () { + await execAsync('echo', ['hi']) + }) + + it('should reject when the command fails', async function () { + execStub.restore() + const failure = new Error('boom') + execStub = sandbox.stub(childProcess, 'exec').callsFake((cmd, opts, cb) => { + process.nextTick(() => cb(failure)) + return fakeChild + }) + + let caught + try { + await execAsync('false') + } catch (err) { + caught = err + } + + expect(caught).to.equal(failure) + }) + + }) + +}) diff --git a/packages/navy/src/util/__tests__/external-ip.js b/packages/navy/src/util/__tests__/external-ip.js index c549169..250be08 100644 --- a/packages/navy/src/util/__tests__/external-ip.js +++ b/packages/navy/src/util/__tests__/external-ip.js @@ -1,7 +1,9 @@ /* eslint-env mocha */ -import {expect} from 'chai' -import {getExternalIP} from '../external-ip' +import { expect } from 'chai' +import sinon from 'sinon' +import dns from 'dns' +import { getExternalIP, dnsLookup } from '../external-ip' describe('getExternalIP', function () { @@ -27,3 +29,128 @@ describe('getExternalIP', function () { }) }) + +describe('external-ip (mocked)', function () { + + let sandbox + let originalEnv + + beforeEach(function () { + sandbox = sinon.createSandbox() + + originalEnv = { + DOCKER_HOST: process.env.DOCKER_HOST, + NAVY_HOST: process.env.NAVY_HOST, + NAVY_EXTERNAL_IP: process.env.NAVY_EXTERNAL_IP, + } + + delete process.env.DOCKER_HOST + delete process.env.NAVY_HOST + delete process.env.NAVY_EXTERNAL_IP + }) + + afterEach(function () { + sandbox.restore() + + for (const [name, value] of Object.entries(originalEnv)) { + if (value === undefined) { + delete process.env[name] + } else { + process.env[name] = value + } + } + }) + + describe('dnsLookup', function () { + + it('should resolve with the IPv4 address when dns returns family 4', async function () { + sandbox.stub(dns, 'lookup').callsFake((hostname, opts, cb) => { + cb(null, '10.20.30.40', 4) + }) + + const ip = await dnsLookup('example.com') + + expect(ip).to.equal('10.20.30.40') + }) + + it('should reject when dns.lookup returns an error', async function () { + sandbox.stub(dns, 'lookup').callsFake((hostname, opts, cb) => { + cb(new Error('ENOTFOUND')) + }) + + let caught + try { + await dnsLookup('does-not-exist') + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.equal('Failed to lookup hostname "does-not-exist"') + }) + + it('should reject when dns.lookup returns a non-ipv4 family', async function () { + sandbox.stub(dns, 'lookup').callsFake((hostname, opts, cb) => { + cb(null, '::1', 6) + }) + + let caught + try { + await dnsLookup('ipv6-only.example') + } catch (err) { + caught = err + } + + expect(caught).to.be.an('error') + expect(caught.message).to.equal('Failed to lookup hostname "ipv6-only.example"') + }) + + }) + + describe('getExternalIP (additional branches)', function () { + + it('should return NAVY_HOST (deprecated) when set', async function () { + process.env.NAVY_HOST = 'legacy.host' + + expect(await getExternalIP()).to.equal('legacy.host') + }) + + it('should give NAVY_HOST precedence over NAVY_EXTERNAL_IP', async function () { + process.env.NAVY_HOST = 'legacy.host' + process.env.NAVY_EXTERNAL_IP = '1.2.3.4' + + expect(await getExternalIP()).to.equal('legacy.host') + }) + + it('should DNS-resolve ipInConfig when provided', async function () { + sandbox.stub(dns, 'lookup').callsFake((hostname, opts, cb) => { + expect(hostname).to.equal('docker.internal') + cb(null, '172.16.0.5', 4) + }) + + expect(await getExternalIP('docker.internal')).to.equal('172.16.0.5') + }) + + it('should resolve a hostname embedded in DOCKER_HOST tcp:// using DNS', async function () { + process.env.DOCKER_HOST = 'tcp://my-docker-host.example:2375' + sandbox.stub(dns, 'lookup').callsFake((hostname, opts, cb) => { + expect(hostname).to.equal('my-docker-host.example') + cb(null, '203.0.113.7', 4) + }) + + expect(await getExternalIP()).to.equal('203.0.113.7') + }) + + it('should fall back to 127.0.0.1 when no env vars or config are set', async function () { + expect(await getExternalIP()).to.equal('127.0.0.1') + }) + + it('should fall back to 127.0.0.1 when DOCKER_HOST is set without tcp://', async function () { + process.env.DOCKER_HOST = 'unix:///var/run/docker.sock' + + expect(await getExternalIP()).to.equal('127.0.0.1') + }) + + }) + +}) diff --git a/packages/navy/src/util/__tests__/get-lan-ip.js b/packages/navy/src/util/__tests__/get-lan-ip.js new file mode 100644 index 0000000..be44093 --- /dev/null +++ b/packages/navy/src/util/__tests__/get-lan-ip.js @@ -0,0 +1,56 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import dns from 'dns' +import os from 'os' +import { getLANIP } from '../get-lan-ip' + +describe('get-lan-ip', function () { + + describe('getLANIP', function () { + + let sandbox + + beforeEach(function () { + sandbox = sinon.createSandbox() + }) + + afterEach(function () { + sandbox.restore() + }) + + it('should resolve with the looked-up address for the host name', async function () { + sandbox.stub(os, 'hostname').returns('my-laptop.local') + const dnsStub = sandbox.stub(dns, 'lookup').callsFake((host, opts, cb) => { + cb(null, '10.0.0.42') + }) + + const result = await getLANIP() + + expect(result).to.equal('10.0.0.42') + expect(dnsStub.calledOnce).to.equal(true) + expect(dnsStub.firstCall.args[0]).to.equal('my-laptop.local') + expect(dnsStub.firstCall.args[1]).to.equal(null) + }) + + it('should reject if dns.lookup fails', async function () { + sandbox.stub(os, 'hostname').returns('unknown.local') + const lookupError = new Error('lookup failed') + sandbox.stub(dns, 'lookup').callsFake((host, opts, cb) => { + cb(lookupError) + }) + + let caught + try { + await getLANIP() + } catch (err) { + caught = err + } + + expect(caught).to.equal(lookupError) + }) + + }) + +}) diff --git a/packages/navy/src/util/__tests__/has-update.js b/packages/navy/src/util/__tests__/has-update.js new file mode 100644 index 0000000..aff5512 --- /dev/null +++ b/packages/navy/src/util/__tests__/has-update.js @@ -0,0 +1,111 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +// NOTE: hasUpdate has a defect at line 17 in `../has-update`: when the +// supplied navyFile is null/undefined or has no +// `ignoreUnauthorizedRequestsForRegistries` array, `R.includes(registry, +// undefined)` throws (in current ramda). The tests below provide a valid +// navyFile shape to exercise the supported call patterns. +function withMocks({ inspect, getFatManifest = sinon.stub() }) { + const docker = { getImage: sinon.stub().returns({ inspect }) } + const stubs = { + './docker-client': docker, + '../client/registry/get-fat-manifest': getFatManifest, + } + return { + docker, + getFatManifest, + hasUpdate: proxyquire.noCallThru()('../has-update', stubs), + } +} + +describe('has-update', function () { + + it('should return false when the remote digest matches one of the local RepoDigests', async function () { + const inspect = sinon.stub().resolves({ + RepoDigests: ['library/node@sha256:abc', 'library/node@sha256:other'], + }) + const { hasUpdate } = withMocks({ + inspect, + getFatManifest: sinon.stub().resolves({ tag: 'sha256:abc' }), + }) + + const result = await hasUpdate('library/node:lts', 'image-id', { + ignoreUnauthorizedRequestsForRegistries: [], + }) + + expect(result).to.equal(false) + }) + + it('should return true when the remote digest is not in the local RepoDigests', async function () { + const inspect = sinon.stub().resolves({ RepoDigests: ['library/node@sha256:old'] }) + const { hasUpdate } = withMocks({ + inspect, + getFatManifest: sinon.stub().resolves({ tag: 'sha256:new' }), + }) + + const result = await hasUpdate('library/node:lts', 'image-id', { + ignoreUnauthorizedRequestsForRegistries: [], + }) + + expect(result).to.equal(true) + }) + + it('should return "INVALID_REMOTE" when getFatManifest fails', async function () { + const inspect = sinon.stub().resolves({ RepoDigests: [] }) + const { hasUpdate } = withMocks({ + inspect, + getFatManifest: sinon.stub().rejects(new Error('boom')), + }) + + const result = await hasUpdate('library/node:lts', 'image-id', { + ignoreUnauthorizedRequestsForRegistries: [], + }) + + expect(result).to.equal('INVALID_REMOTE') + }) + + it('should return "INVALID_REMOTE" when docker.getImage().inspect() fails', async function () { + const inspect = sinon.stub().rejects(new Error('no such image')) + const { hasUpdate } = withMocks({ inspect }) + + const result = await hasUpdate('library/node:lts', 'image-id', { + ignoreUnauthorizedRequestsForRegistries: [], + }) + + expect(result).to.equal('INVALID_REMOTE') + }) + + it('should pass allowUnauthorizedRequest=true when navyFile lists the registry as ignored', async function () { + const inspect = sinon.stub().resolves({ RepoDigests: ['someregistry.com/some/image@sha256:abc'] }) + const getFatManifest = sinon.stub().resolves({ tag: 'sha256:abc' }) + const { hasUpdate } = withMocks({ inspect, getFatManifest }) + + await hasUpdate('someregistry.com/some/image:1', 'image-id', { + ignoreUnauthorizedRequestsForRegistries: ['someregistry.com'], + }) + + expect(getFatManifest.firstCall.args[0]).to.eql({ + allowUnauthorizedRequest: true, + registry: 'someregistry.com', + repository: 'some/image', + tag: '1', + }) + }) + + it('should pass allowUnauthorizedRequest=false when registry is not in the ignore list', async function () { + const inspect = sinon.stub().resolves({ RepoDigests: [] }) + const getFatManifest = sinon.stub().resolves({ tag: 'sha256:abc' }) + const { hasUpdate } = withMocks({ inspect, getFatManifest }) + + await hasUpdate('someregistry.com/some/image:1', 'image-id', { + ignoreUnauthorizedRequestsForRegistries: ['otherregistry.com'], + }) + + expect(getFatManifest.firstCall.args[0].allowUnauthorizedRequest).to.equal(false) + }) + +}) diff --git a/packages/navy/src/util/__tests__/https.js b/packages/navy/src/util/__tests__/https.js new file mode 100644 index 0000000..c110d1c --- /dev/null +++ b/packages/navy/src/util/__tests__/https.js @@ -0,0 +1,325 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import proxyquire from 'proxyquire' +import { NavyError } from '../../errors' + +describe('util/https', function () { + + let sandbox + let getConfigStub + let getConfigDirStub + let DEFAULT_TLS_ROOT_CA_DIR + let getNavyStub + let navyStub + let fsStub + let pkiStub + let mdStub + let httpsModule + + function loadModule() { + httpsModule = proxyquire.noCallThru()('../https', { + '../config': { + getConfig: getConfigStub, + getConfigDir: getConfigDirStub, + DEFAULT_TLS_ROOT_CA_DIR, + }, + '../errors': { NavyError }, + '../navy': { getNavy: getNavyStub }, + fs: fsStub, + 'node-forge': { pki: pkiStub, md: mdStub }, + }) + } + + beforeEach(function () { + sandbox = sinon.createSandbox() + + getConfigStub = sandbox.stub().returns({}) + getConfigDirStub = sandbox.stub().returns('/cfg') + DEFAULT_TLS_ROOT_CA_DIR = '/default-ca-dir' + + navyStub = { + url: sandbox.stub().resolves('https://web.local'), + } + getNavyStub = sandbox.stub().returns(navyStub) + + fsStub = { + existsSync: sandbox.stub().returns(true), + mkdirSync: sandbox.stub(), + unlinkSync: sandbox.stub(), + readFileSync: sandbox.stub().returns('--PEM--'), + writeFileSync: sandbox.stub(), + } + + const certObj = { + publicKey: null, + serialNumber: null, + validity: { notBefore: new Date(), notAfter: new Date() }, + setSubject: sandbox.stub(), + setIssuer: sandbox.stub(), + setExtensions: sandbox.stub(), + sign: sandbox.stub(), + subject: { attributes: [] }, + } + + pkiStub = { + rsa: { + generateKeyPair: sandbox.stub().returns({ + publicKey: 'pub', + privateKey: 'priv', + }), + }, + createCertificate: sandbox.stub().returns(certObj), + privateKeyToPem: sandbox.stub().returns('priv-pem'), + publicKeyToPem: sandbox.stub().returns('pub-pem'), + certificateToPem: sandbox.stub().returns('cert-pem'), + privateKeyFromPem: sandbox.stub().returns('priv-key-obj'), + certificateFromPem: sandbox.stub().returns({ subject: { attributes: [{ name: 'commonName', value: 'ca' }] } }), + } + + mdStub = { sha256: { create: sandbox.stub().returns('digest') } } + + loadModule() + }) + + afterEach(function () { + sandbox.restore() + }) + + describe('getCertsPath', function () { + + it('should return the certs path when it exists', function () { + fsStub.existsSync.returns(true) + + const result = httpsModule.getCertsPath() + + expect(result).to.contain('tls-certs') + expect(fsStub.mkdirSync.called).to.equal(false) + }) + + it('should return an empty string when path does not exist and create is false', function () { + fsStub.existsSync.returns(false) + + const result = httpsModule.getCertsPath() + + expect(result).to.equal('') + expect(fsStub.mkdirSync.called).to.equal(false) + }) + + it('should create the path when create is true and it does not exist', function () { + fsStub.existsSync.returns(false) + + const result = httpsModule.getCertsPath(true) + + expect(fsStub.mkdirSync.calledOnce).to.equal(true) + expect(fsStub.mkdirSync.firstCall.args[0]).to.contain('tls-certs') + expect(fsStub.mkdirSync.firstCall.args[1]).to.eql({ recursive: true }) + expect(result).to.contain('tls-certs') + }) + + }) + + describe('removeCert', function () { + + it('should unlink each existing cert/key file', async function () { + fsStub.existsSync.callsFake(p => p === '/cfg/tls-certs' || p.endsWith('web.local.crt') || p.endsWith('web.local.key')) + navyStub.url.resolves('https://web.local') + + await httpsModule.removeCert({ navy: 'env-1', disable: 'web' }) + + expect(fsStub.unlinkSync.callCount).to.equal(2) + const paths = fsStub.unlinkSync.getCalls().map(c => c.args[0]) + expect(paths.some(p => p.endsWith('web.local.crt'))).to.equal(true) + expect(paths.some(p => p.endsWith('web.local.key'))).to.equal(true) + }) + + it('should skip files that do not exist', async function () { + fsStub.existsSync.callsFake(p => p === '/cfg/tls-certs') + + await httpsModule.removeCert({ navy: 'env-1', disable: 'web' }) + + expect(fsStub.unlinkSync.called).to.equal(false) + }) + + it('should wrap unlink errors in NavyError', async function () { + fsStub.existsSync.callsFake(p => p === '/cfg/tls-certs' || p.endsWith('.crt') || p.endsWith('.key')) + fsStub.unlinkSync.throws(new Error('permission denied')) + + let caught + try { + await httpsModule.removeCert({ navy: 'env-1', disable: 'web' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + }) + + }) + + describe('generateRootCa', function () { + + it('should create the root CA dir when missing', async function () { + fsStub.existsSync.callsFake(p => { + if (p === '/default-ca-dir') return false + return false + }) + + await httpsModule.generateRootCa() + + expect(fsStub.mkdirSync.calledWith('/default-ca-dir')).to.equal(true) + expect(fsStub.writeFileSync.calledThrice).to.equal(true) + }) + + it('should wrap mkdir errors in NavyError', async function () { + fsStub.existsSync.returns(false) + fsStub.mkdirSync.throws(new Error('permission denied')) + + let caught + try { + await httpsModule.generateRootCa() + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + }) + + it('should skip generation when CA already exists', async function () { + fsStub.existsSync.callsFake(p => p.endsWith('ca.crt') || p.endsWith('ca.key') || p === '/default-ca-dir') + + await httpsModule.generateRootCa() + + expect(pkiStub.rsa.generateKeyPair.called).to.equal(false) + expect(fsStub.writeFileSync.called).to.equal(false) + }) + + it('should generate, sign, and write CA files when missing', async function () { + fsStub.existsSync.callsFake(p => p === '/default-ca-dir') + + await httpsModule.generateRootCa() + + expect(pkiStub.rsa.generateKeyPair.calledWith(2048)).to.equal(true) + expect(pkiStub.createCertificate.calledOnce).to.equal(true) + expect(fsStub.writeFileSync.calledThrice).to.equal(true) + + const writtenPaths = fsStub.writeFileSync.getCalls().map(c => c.args[0]) + expect(writtenPaths.some(p => p.endsWith('ca.key'))).to.equal(true) + expect(writtenPaths.some(p => p.endsWith('ca.pub.key'))).to.equal(true) + expect(writtenPaths.some(p => p.endsWith('ca.crt'))).to.equal(true) + }) + + it('should use a custom root CA dir when supplied via config', async function () { + getConfigStub.returns({ tlsRootCaDir: '/custom-ca' }) + fsStub.existsSync.callsFake(p => p === '/custom-ca') + + await httpsModule.generateRootCa() + + const writtenPaths = fsStub.writeFileSync.getCalls().map(c => c.args[0]) + expect(writtenPaths.every(p => p.startsWith('/custom-ca/'))).to.equal(true) + }) + + it('should wrap signing errors in NavyError', async function () { + fsStub.existsSync.callsFake(p => p === '/default-ca-dir') + const cert = pkiStub.createCertificate() + cert.sign = sandbox.stub().throws(new Error('sign failure')) + pkiStub.createCertificate.returns(cert) + + let caught + try { + await httpsModule.generateRootCa() + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + }) + + }) + + describe('createCert', function () { + + it('should skip creation when the cert already exists', async function () { + fsStub.existsSync.callsFake(p => p === '/cfg/tls-certs' || p === '/cfg/tls-certs/web.local.crt') + + await httpsModule.createCert({ serviceUrl: 'https://web.local' }) + + expect(fsStub.writeFileSync.called).to.equal(false) + }) + + it('should generate, sign, and write a service cert', async function () { + fsStub.existsSync.callsFake(p => { + if (p === '/cfg/tls-certs') return true + if (p === '/default-ca-dir') return true + if (p === '/default-ca-dir/ca.crt' || p === '/default-ca-dir/ca.key') return true + return false + }) + + await httpsModule.createCert({ serviceUrl: 'https://web.local' }) + + expect(pkiStub.privateKeyFromPem.calledOnce).to.equal(true) + expect(pkiStub.certificateFromPem.calledOnce).to.equal(true) + expect(fsStub.writeFileSync.calledTwice).to.equal(true) + + const writtenPaths = fsStub.writeFileSync.getCalls().map(c => c.args[0]) + expect(writtenPaths.some(p => p.endsWith('web.local.key'))).to.equal(true) + expect(writtenPaths.some(p => p.endsWith('web.local.crt'))).to.equal(true) + }) + + it('should use opts.hostName when supplied', async function () { + fsStub.existsSync.callsFake(p => { + if (p === '/cfg/tls-certs') return true + if (p === '/default-ca-dir') return true + if (p === '/default-ca-dir/ca.crt' || p === '/default-ca-dir/ca.key') return true + return false + }) + + await httpsModule.createCert({ hostName: 'custom-host' }) + + const writtenPaths = fsStub.writeFileSync.getCalls().map(c => c.args[0]) + expect(writtenPaths.some(p => p.endsWith('custom-host.key'))).to.equal(true) + expect(writtenPaths.some(p => p.endsWith('custom-host.crt'))).to.equal(true) + }) + + it('should use a custom tlsRootCaDir from config', async function () { + getConfigStub.returns({ tlsRootCaDir: '/custom-ca' }) + fsStub.existsSync.callsFake(p => { + if (p === '/cfg/tls-certs') return true + if (p === '/custom-ca') return true + if (p === '/custom-ca/ca.crt' || p === '/custom-ca/ca.key') return true + return false + }) + + await httpsModule.createCert({ serviceUrl: 'https://web.local' }) + + const readPaths = fsStub.readFileSync.getCalls().map(c => c.args[0]) + expect(readPaths.some(p => p === '/custom-ca/ca.crt')).to.equal(true) + expect(readPaths.some(p => p === '/custom-ca/ca.key')).to.equal(true) + }) + + it('should wrap signing errors in NavyError', async function () { + fsStub.existsSync.callsFake(p => { + if (p === '/cfg/tls-certs') return true + if (p === '/default-ca-dir') return true + if (p === '/default-ca-dir/ca.crt' || p === '/default-ca-dir/ca.key') return true + return false + }) + + const cert = pkiStub.createCertificate() + cert.sign = sandbox.stub().throws(new Error('sign fail')) + pkiStub.createCertificate.returns(cert) + + let caught + try { + await httpsModule.createCert({ serviceUrl: 'https://web.local' }) + } catch (err) { + caught = err + } + + expect(caught).to.be.instanceof(NavyError) + }) + + }) + +}) diff --git a/packages/navy/src/util/__tests__/navyrc.js b/packages/navy/src/util/__tests__/navyrc.js new file mode 100644 index 0000000..b48822f --- /dev/null +++ b/packages/navy/src/util/__tests__/navyrc.js @@ -0,0 +1,53 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import sinon from 'sinon' +import path from 'path' +import fs from '../fs' +import getNavyRc from '../navyrc' + +describe('navyrc', function () { + + describe('getNavyRc', function () { + + let sandbox + + beforeEach(function () { + sandbox = sinon.createSandbox() + }) + + afterEach(function () { + sandbox.restore() + }) + + it('should read and parse the .navyrc JSON file from the given directory', async function () { + const config = { services: ['api', 'web'], plugins: ['nodejs'] } + const readStub = sandbox.stub(fs, 'readFileAsync').resolves(JSON.stringify(config)) + + const result = await getNavyRc('/some/dir') + + expect(result).to.eql(config) + expect(readStub.calledOnce).to.equal(true) + expect(readStub.firstCall.args[0]).to.equal(path.join('/some/dir', '.navyrc')) + }) + + it('should return null when the file cannot be read', async function () { + const err = Object.assign(new Error('not found'), { code: 'ENOENT' }) + sandbox.stub(fs, 'readFileAsync').rejects(err) + + const result = await getNavyRc('/missing/dir') + + expect(result).to.equal(null) + }) + + it('should return null when the file content is not valid JSON', async function () { + sandbox.stub(fs, 'readFileAsync').resolves('not json {{{') + + const result = await getNavyRc('/dir') + + expect(result).to.equal(null) + }) + + }) + +}) diff --git a/packages/navy/src/util/__tests__/service-host.js b/packages/navy/src/util/__tests__/service-host.js index bd864fe..ebebaf6 100644 --- a/packages/navy/src/util/__tests__/service-host.js +++ b/packages/navy/src/util/__tests__/service-host.js @@ -1,10 +1,32 @@ /* eslint-env mocha */ -import {expect} from 'chai' -import {getNIPSubdomain, getUrlFromService, createHostForService, createUrlForService} from '../service-host' +import { expect } from 'chai' +import sinon from 'sinon' +import fs from 'fs' +import * as httpsModule from '../https' +import { getNIPSubdomain, getUrlFromService, createHostForService, createUrlForService } from '../service-host' describe('service-host', function () { + let sandbox + const originalSubdomain = process.env.NAVY_EXTERNAL_SUBDOMAIN + + beforeEach(function () { + sandbox = sinon.createSandbox() + sandbox.stub(httpsModule, 'getCertsPath').returns('/fake/certs') + sandbox.stub(fs, 'existsSync').returns(false) + }) + + afterEach(function () { + sandbox.restore() + + if (originalSubdomain === undefined) { + delete process.env.NAVY_EXTERNAL_SUBDOMAIN + } else { + process.env.NAVY_EXTERNAL_SUBDOMAIN = originalSubdomain + } + }) + describe('getNIPSubdomain', function () { it('should return an nip.io domain with the correct IP address', async function () { @@ -14,6 +36,11 @@ describe('service-host', function () { it('should fallback to localhost when a hostname is passed instead of an IP address', async function () { process.env.NAVY_EXTERNAL_IP = 'somehostname' expect(await getNIPSubdomain('somehostname')).to.equal('127.0.0.1.nip.io') + delete process.env.NAVY_EXTERNAL_IP + }) + + it('should treat malformed IPs (out-of-range octets) as invalid', async function () { + expect(await getNIPSubdomain('999.0.0.1')).to.equal('127.0.0.1.nip.io') }) }) @@ -25,13 +52,30 @@ describe('service-host', function () { expect(await createHostForService('someservice', 'mynavy', '192.168.1.10')).to.equal('someservice.mynavy.192.168.1.10.nip.io') }) + it('should use NAVY_EXTERNAL_SUBDOMAIN when set, in preference to nip.io', async function () { + process.env.NAVY_EXTERNAL_SUBDOMAIN = 'dev.example.com' + expect(await createHostForService('api', 'env', '10.0.0.1')).to.equal('api.env.dev.example.com') + }) + }) describe('createUrlForService', function () { - it('should return the correct url for a service', async function () { - expect(await createUrlForService('someservice', 'mynavy', '192.168.99.100')).to.equal('http://someservice.mynavy.192.168.99.100.nip.io') + it('should return an http URL when no certificate exists', async function () { + expect(await createUrlForService('someservice', 'mynavy', '192.168.99.100')) + .to.equal('http://someservice.mynavy.192.168.99.100.nip.io') }) + + it('should return an https URL when a matching .crt exists in the certs path', async function () { + fs.existsSync.restore() + sandbox.stub(fs, 'existsSync').callsFake(filePath => + filePath === '/fake/certs/someservice.mynavy.192.168.99.100.nip.io.crt' + ) + + expect(await createUrlForService('someservice', 'mynavy', '192.168.99.100')) + .to.equal('https://someservice.mynavy.192.168.99.100.nip.io') + }) + }) describe('getUrlFromService', function () { @@ -50,16 +94,49 @@ describe('service-host', function () { expect(getUrlFromService(service)).to.equal('http://myservice.coolnavy.127.0.0.1.nip.io') }) - it('should return null when the service object is not valid', function () { + it('should return https when a certificate exists for the VIRTUAL_HOST', function () { + fs.existsSync.restore() + sandbox.stub(fs, 'existsSync').callsFake(filePath => + filePath === '/fake/certs/myservice.coolnavy.127.0.0.1.nip.io.crt' + ) + + const service = { + raw: { + Config: { + Env: [ + 'OTHER=value', + 'VIRTUAL_HOST=myservice.coolnavy.127.0.0.1.nip.io', + ], + }, + }, + } + + expect(getUrlFromService(service)).to.equal('https://myservice.coolnavy.127.0.0.1.nip.io') + }) + + it('should return null when env contains no VIRTUAL_HOST entry', function () { const service = { raw: { - Config: {}, + Config: { + Env: [ + 'FOO=bar', + 'BAZ=qux', + ], + }, }, } expect(getUrlFromService(service)).to.equal(null) + }) + + it('should return null when the service object is not valid', function () { + expect(getUrlFromService({ raw: { Config: {} } })).to.equal(null) + expect(getUrlFromService({ raw: {} })).to.equal(null) + expect(getUrlFromService({})).to.equal(null) expect(getUrlFromService(undefined)).to.equal(null) + expect(getUrlFromService(null)).to.equal(null) }) + }) }) diff --git a/packages/navy/src/util/__tests__/table.js b/packages/navy/src/util/__tests__/table.js new file mode 100644 index 0000000..10f23e4 --- /dev/null +++ b/packages/navy/src/util/__tests__/table.js @@ -0,0 +1,68 @@ +/* eslint-env mocha */ + +import { expect } from 'chai' +import stripAnsi from 'strip-ansi' +import table from '../table' + +describe('table', function () { + + it('should return an empty string when given no rows', function () { + expect(table([])).to.equal('') + }) + + it('should render a single-row table padded by 2 spaces', function () { + const result = table([['a', 'bb']]) + + expect(result).to.equal('a bb ') + }) + + it('should pad each column to the longest value in that column plus 2', function () { + const result = table([ + ['name', 'status'], + ['api', 'running'], + ['web', 'stopped'], + ]) + + const lines = result.split('\n') + expect(lines).to.have.lengthOf(3) + expect(lines[0]).to.equal('name status ') + expect(lines[1]).to.equal('api running ') + expect(lines[2]).to.equal('web stopped ') + }) + + it('should treat null/undefined cells in the header as empty strings when sizing', function () { + const result = table([ + [null, 'b'], + ['xx', 'yyy'], + ]) + + const lines = result.split('\n') + expect(lines[0]).to.equal(' b ') + expect(lines[1]).to.equal('xx yyy ') + }) + + it('should only render the cells that exist on each row (shorter rows are not back-padded)', function () { + const result = table([ + ['a', 'b'], + ['x'], + ]) + + const lines = result.split('\n') + expect(lines[0]).to.equal('a b ') + expect(lines[1]).to.equal('x ') + }) + + it('should size columns by visible (ANSI-stripped) length', function () { + const ansiCell = '\u001b[31mhello\u001b[0m' + const result = table([ + ['col1'], + [ansiCell], + ]) + + const lines = result.split('\n') + + expect(stripAnsi(lines[0])).to.equal('col1 ') + expect(stripAnsi(lines[1])).to.equal('hello ') + }) + +}) diff --git a/packages/navy/src/util/docker-client.js b/packages/navy/src/util/docker-client.js index b43388c..9e614da 100644 --- a/packages/navy/src/util/docker-client.js +++ b/packages/navy/src/util/docker-client.js @@ -1,8 +1,5 @@ import Docker from 'dockerode' -import bluebird from 'bluebird' -const dockerClient = new Docker({ - Promise: bluebird, -}) +const dockerClient = new Docker() export default dockerClient diff --git a/packages/navy/src/util/exec-async.js b/packages/navy/src/util/exec-async.js index da210de..007b48d 100644 --- a/packages/navy/src/util/exec-async.js +++ b/packages/navy/src/util/exec-async.js @@ -1,6 +1,6 @@ /* @flow */ -import {exec} from 'child_process' +import { exec } from 'child_process' const debug = require('debug')('navy:exec') diff --git a/packages/navy/src/util/external-ip.js b/packages/navy/src/util/external-ip.js index 32f18dc..3851751 100644 --- a/packages/navy/src/util/external-ip.js +++ b/packages/navy/src/util/external-ip.js @@ -6,7 +6,7 @@ const IPV4_FAMILY = 4 export async function dnsLookup(hostname: string): Promise { return await new Promise((resolve, reject) => { - dns.lookup(hostname, null, (err, ip, ipFamily) => { + dns.lookup(hostname, { family: IPV4_FAMILY }, (err, ip, ipFamily) => { if (err || ipFamily !== IPV4_FAMILY) { reject(new Error('Failed to lookup hostname "' + hostname + '"')) } else { diff --git a/packages/navy/src/util/get-lan-ip.js b/packages/navy/src/util/get-lan-ip.js index 7e1725a..0e96ff0 100644 --- a/packages/navy/src/util/get-lan-ip.js +++ b/packages/navy/src/util/get-lan-ip.js @@ -3,7 +3,7 @@ import dns from 'dns' import os from 'os' -export async function getLANIP() { +export async function getLANIP(): Promise { return await new Promise((resolve, reject) => { dns.lookup(os.hostname(), null, (err, addr) => { if (err) { diff --git a/packages/navy/src/util/has-update.js b/packages/navy/src/util/has-update.js index feb8efa..19f7b4f 100644 --- a/packages/navy/src/util/has-update.js +++ b/packages/navy/src/util/has-update.js @@ -1,7 +1,7 @@ import * as R from 'ramda' import docker from './docker-client' import getFatManifest from '../client/registry/get-fat-manifest' -import {getImageFromImageWithTag, getRepositoryFromImage, getTagFromImageWithTag, getRegistryFromImage} +import { getImageFromImageWithTag, getRepositoryFromImage, getTagFromImageWithTag, getRegistryFromImage } from '../domain/container-image' const hasUpdate = async ( @@ -19,7 +19,7 @@ const hasUpdate = async ( ) try { - const {RepoDigests} = await docker.getImage(currentImageId).inspect() + const { RepoDigests } = await docker.getImage(currentImageId).inspect() const manifest = await getFatManifest({ allowUnauthorizedRequest, diff --git a/packages/navy/src/util/https.js b/packages/navy/src/util/https.js index dc38390..ef00dc9 100644 --- a/packages/navy/src/util/https.js +++ b/packages/navy/src/util/https.js @@ -15,7 +15,6 @@ export function getCertsPath(create: boolean = false): string { if (!fs.existsSync(certsPath)) { if (create) { debug(`Create ${certsPath} dir`) - // $FlowIgnore fs.mkdirSync(certsPath, { recursive: true }) } else { return '' @@ -50,7 +49,6 @@ export async function generateRootCa(): Promise { if (!fs.existsSync(tlsRootCaDir)) { debug(`Creating ${tlsRootCaDir} Root CA dir`) try { - // $FlowIgnore fs.mkdirSync(tlsRootCaDir, { recursive: true }) } catch (err) { throw new NavyError(err) @@ -58,7 +56,7 @@ export async function generateRootCa(): Promise { } if (fs.existsSync(`${tlsRootCaDir}/ca.crt`) && fs.existsSync(`${tlsRootCaDir}/ca.key`)) { - debug(`Root CA already exists, skipping generation`) + debug('Root CA already exists, skipping generation') return } @@ -103,12 +101,12 @@ export async function generateRootCa(): Promise { certificate: pki.certificateToPem(cert), } - fs.writeFileSync(tlsRootCaDir + '/ca.key', pem.privateKey, {mode: 0o400}) - fs.writeFileSync(tlsRootCaDir + '/ca.pub.key', pem.publicKey, {mode: 0o640}) - fs.writeFileSync(tlsRootCaDir + '/ca.crt', pem.certificate, {mode: 0o640}) + fs.writeFileSync(tlsRootCaDir + '/ca.key', pem.privateKey, { mode: 0o400 }) + fs.writeFileSync(tlsRootCaDir + '/ca.pub.key', pem.publicKey, { mode: 0o640 }) + fs.writeFileSync(tlsRootCaDir + '/ca.crt', pem.certificate, { mode: 0o640 }) console.log(chalk.green(`✅ CA Certificate created at ${tlsRootCaDir}/ca.crt`)) - console.log(chalk.yellow(`⚠️ Importing a self-signed CA into a browser/truststore/keychain is not advisable ⚠️`)) + console.log(chalk.yellow('⚠️ Importing a self-signed CA into a browser/truststore/keychain is not advisable ⚠️')) } catch (e) { throw new NavyError(e) } diff --git a/packages/navy/src/util/service-host.js b/packages/navy/src/util/service-host.js index 466ad9e..5fedd87 100644 --- a/packages/navy/src/util/service-host.js +++ b/packages/navy/src/util/service-host.js @@ -1,15 +1,15 @@ /* @flow */ -import type {Service} from '../service' -import {getCertsPath} from './https' +import type { Service } from '../service' +import { getCertsPath } from './https' import fs from 'fs' const BASE = 'nip.io' -function isValidIpv4Addr(ip) { +function isValidIpv4Addr(ip: string) { return /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g.test(ip) } -export async function getNIPSubdomain(externalIP: string) { +export async function getNIPSubdomain(externalIP: string): Promise { if (!isValidIpv4Addr(externalIP)) { // invalid IP address, fallback to local return `127.0.0.1.${BASE}` @@ -18,11 +18,11 @@ export async function getNIPSubdomain(externalIP: string) { return `${externalIP}.${BASE}` } -export async function createHostForService(service: string, navyNormalisedName: string, externalIP: string) { +export async function createHostForService(service: string, navyNormalisedName: string, externalIP: string): Promise { return `${service}.${navyNormalisedName}.${process.env.NAVY_EXTERNAL_SUBDOMAIN || await getNIPSubdomain(externalIP)}` } -export async function createUrlForService(service: string, navyNormalisedName: string, externalIP: string) { +export async function createUrlForService(service: string, navyNormalisedName: string, externalIP: string): Promise { const certsPath = getCertsPath() let proto = 'http' const baseUrl = await createHostForService(service, navyNormalisedName, externalIP) @@ -32,7 +32,7 @@ export async function createUrlForService(service: string, navyNormalisedName: s return `${proto}://${await createHostForService(service, navyNormalisedName, externalIP)}` } -export function getUrlFromService(service: Service) { +export function getUrlFromService(service: ?Service): ?string { if (!service || !service.raw || !service.raw.Config || !service.raw.Config.Env) { return null } diff --git a/packages/navy/src/util/table.js b/packages/navy/src/util/table.js index 252eab0..366a555 100644 --- a/packages/navy/src/util/table.js +++ b/packages/navy/src/util/table.js @@ -3,7 +3,7 @@ import pad from 'pad' import stripAnsi from 'strip-ansi' -export default function table(rows: Array>) { +export default function table(rows: Array>): string { if (rows.length === 0) { return '' } diff --git a/scripts/integration.sh b/scripts/integration.sh index bd14f51..3d60a18 100755 --- a/scripts/integration.sh +++ b/scripts/integration.sh @@ -1,62 +1,53 @@ +#!/bin/sh set -e -echo "" -echo "SETTING UP ENVIRONMENT" -echo "This may take several minutes to build the necessary docker containers..." -echo "This will only take a while the first time you run the tests, subsequent runs should be faster" -echo "" -echo "" - -DOCKER_TAG=${DOCKER_TAG:-19.03.14-dind} -DOCKER_COMPOSE_VERSION=${DOCKER_COMPOSE_VERSION:-1.29.2} -NODE_VERSION=${GITHUB_NODE_VERSION:-16} - -DOCKER_TLS_CERTDIR="" +if ! docker info >/dev/null 2>&1; then + echo "Docker is not running on the host. Start Docker before running integration tests." >&2 + exit 1 +fi -DOCKER_SHARED_DIR=$(mktemp -d) +if ! command -v docker-compose >/dev/null 2>&1 && ! docker compose version >/dev/null 2>&1; then + echo "docker compose (v1 or v2) must be installed on PATH." >&2 + exit 1 +fi -if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then +if [ -n "${DOCKERHUB_PULL_USERNAME:-}" ]; then echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin fi -echo "Integration environment docker --version:" -docker --version -docker run -d --name navy-test-runner-daemon --privileged \ - -v $(pwd):/usr/src/app \ - -v $DOCKER_SHARED_DIR:/root/.navy/tls-certs \ - -e DOCKER_TLS_CERTDIR \ - docker:$DOCKER_TAG --storage-driver=overlay - -docker build \ - -t navy-test-runner \ - -f test/integration/runner/Dockerfile \ - --build-arg DOCKER_COMPOSE_VERSION=$DOCKER_COMPOSE_VERSION \ - --build-arg NODE_VERSION=$NODE_VERSION \ - --build-arg DOCKERHUB_PULL_USERNAME=$DOCKERHUB_PULL_USERNAME \ - --build-arg DOCKERHUB_PULL_PASSWORD=$DOCKERHUB_PULL_PASSWORD \ - . +NAVY_TEST_HOME="$(mktemp -d -t navy-integration-XXXXXX)" +trap 'rm -rf "$NAVY_TEST_HOME"' EXIT + +# Preserve the real Docker config so the `docker compose` plugin (typically +# installed under $HOME/.docker/cli-plugins) remains discoverable when we +# point HOME at the temporary test directory below. +REAL_DOCKER_CONFIG="${DOCKER_CONFIG:-$HOME/.docker}" + +# Optionally restrict the run to scenarios whose name matches the given +# regular expression. Useful for iterating on a single scenario, e.g. +# SCENARIO='Stopping a service' npm run integration +# Prepending to "$@" via `set --` keeps `$SCENARIO` as a single argument +# even if it contains whitespace. +if [ -n "${SCENARIO:-}" ]; then + set -- --name "$SCENARIO" "$@" +fi echo "" -echo "" -echo "RUNNING TESTS" -echo "" +echo "RUNNING INTEGRATION TESTS" +echo "Using isolated HOME: $NAVY_TEST_HOME" +echo "Using DOCKER_CONFIG: $REAL_DOCKER_CONFIG" +if [ -n "${SCENARIO:-}" ]; then + echo "Filtering scenarios by name: $SCENARIO" +fi echo "" -docker run --rm --link navy-test-runner-daemon:docker \ - --name navy-test-runner \ - -v $DOCKER_SHARED_DIR:/root/.navy/tls-certs \ - -v $(pwd)/packages:/usr/src/app/packages \ - -v $(pwd)/test:/usr/src/app/test \ - -v $(pwd)/resources:/usr/src/app/resources \ - -v $(pwd)/babel.config.js:/usr/src/app/babel.config.js \ - --workdir /usr/src/app navy-test-runner \ - ./node_modules/.bin/cucumber-js --fail-fast --publish-quiet \ - -r ./test/integration/preload.js \ - -r ./test/integration/environment.js \ - -r ./test/integration/hooks.js \ - -r ./test/integration/chai.js \ - -r ./test/integration/features \ - -r ./test/integration/steps \ - ./test/integration/features "$@" - -docker rm --force navy-test-runner-daemon +HOME="$NAVY_TEST_HOME" \ +DOCKER_CONFIG="$REAL_DOCKER_CONFIG" \ + ./node_modules/.bin/cucumber-js \ + -r ./test/integration/preload.js \ + -r ./test/integration/environment.js \ + -r ./test/integration/hooks.js \ + -r ./test/integration/chai.js \ + -r ./test/integration/features \ + -r ./test/integration/steps \ + ./test/integration/features "$@" diff --git a/scripts/test.sh b/scripts/test.sh index 0d9b0bd..a3faad1 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -3,5 +3,5 @@ set -e npm run lint npm run flow -npm run unit +npm run coverage npm run integration diff --git a/test/integration/README.md b/test/integration/README.md index ee2171d..0232638 100644 --- a/test/integration/README.md +++ b/test/integration/README.md @@ -1,4 +1,32 @@ Navy has a comprehensive suite of integration tests. -These tests are supposed to be run inside an isolated environment as it will hijack the home directory and simulate a users environment. -When running the tests with `npm run integration`, `scripts/integration.sh` will build a Docker container to run the tests in. This container is linked to another Docker container. This other container uses the `docker:dind` image, which has a Docker Daemon running inside of it. This essentially means that the entire test suite is testing against an isolated, disposable Docker instance, which means your local Docker won't get hijacked. +These tests run directly on the host via `npm run integration`. The script (`scripts/integration.sh`) creates a fresh temporary directory and points `HOME` at it for the lifetime of the run, so navy's state directory (`~/.navy`) is isolated and your real `~/.navy` is never touched. The tests do, however, talk to your host's Docker daemon directly - any test navies / containers will be created and torn down against that daemon. + +## Prerequisites + +- Node.js matching the version range in `package.json` (`engines.node`). +- A running Docker daemon reachable from your shell (Docker Desktop, Colima, or a native daemon). +- `docker compose` v2 (preferred) or `docker-compose` v1 available on `PATH`. + +## Running + +```sh +npm ci +npm run integration +``` + +Any extra arguments are forwarded to `cucumber-js`, for example to run a single feature: + +```sh +npm run integration -- ./test/integration/features/config.feature +``` + +To run a single scenario, set the `SCENARIO` environment variable to a regular expression that matches the scenario name (this maps to `cucumber-js --name`): + +```sh +SCENARIO='Stopping a service should stop it' npm run integration +``` + +## CI + +In GitHub Actions, the matrix in `.github/workflows/build.yaml` drives the Node, Docker engine, and Docker Compose versions via `actions/setup-node`, `docker/setup-docker-action`, and `docker/setup-compose-action` respectively, and then runs `npm test` directly on the runner. diff --git a/test/integration/chai.js b/test/integration/chai.js index 27163ff..a5ebae0 100644 --- a/test/integration/chai.js +++ b/test/integration/chai.js @@ -1,8 +1,8 @@ /* eslint-disable no-unused-expressions */ /* eslint-enable chai-friendly/no-unused-expressions */ -import chai, {expect, Assertion} from 'chai' -import {find} from 'lodash/fp' +import chai, { expect, Assertion } from 'chai' +import { find } from 'lodash/fp' chai.use(require('chai-properties')) diff --git a/test/integration/features/plugins/step_definitions/commands.js b/test/integration/features/plugins/step_definitions/commands.js index 8ad3022..748a45c 100644 --- a/test/integration/features/plugins/step_definitions/commands.js +++ b/test/integration/features/plugins/step_definitions/commands.js @@ -1,7 +1,7 @@ -import {expect} from 'chai' +import { expect } from 'chai' import Automator from '../../../util/cli-automator' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' When(/I run the custom command on the CLI$/, async function () { this.output = await Automator.spawn(['run', 'test-command']).waitForDone() diff --git a/test/integration/features/plugins/step_definitions/middleware.js b/test/integration/features/plugins/step_definitions/middleware.js index 18e3cd2..218f7fa 100644 --- a/test/integration/features/plugins/step_definitions/middleware.js +++ b/test/integration/features/plugins/step_definitions/middleware.js @@ -1,13 +1,13 @@ /* eslint-disable no-unused-expressions */ /* eslint-enable chai-friendly/no-unused-expressions */ -import {expect, use} from 'chai' -import {find} from 'lodash/fp' -import {Service} from '../../../../../packages/navy/lib' +import { expect, use } from 'chai' +import { find } from 'lodash/fp' +import { Service } from '../../../../../packages/navy/lib' -import {TEST_SERVICE_NAME} from '../../../environment' +import { TEST_SERVICE_NAME } from '../../../environment' -import {Then} from '@cucumber/cucumber' +import { Then } from '@cucumber/cucumber' use(require('chai-like')) use(require('chai-things')) diff --git a/test/integration/features/step_definitions/config.js b/test/integration/features/step_definitions/config.js index 356ee7c..63099db 100644 --- a/test/integration/features/step_definitions/config.js +++ b/test/integration/features/step_definitions/config.js @@ -1,9 +1,12 @@ -import {expect} from 'chai' -import {execSync} from 'child_process' +import path from 'path' +import { expect } from 'chai' import Automator from '../../util/cli-automator' -import {setUpNavy} from '../../util/setup-navy' +import { setUpNavy } from '../../util/setup-navy' +import { getExternalIP } from '../../../../packages/navy/src/util/external-ip' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' + +const expectedTlsCaDir = path.join(process.env.HOME, '.navy', 'tls-root-ca') When(/I get the current config$/, async function () { this.config = await Automator.spawn(['config', 'json']).waitForDone() @@ -13,7 +16,7 @@ When(/I should see the current config$/, async function () { expect(JSON.parse(this.config)).to.eql({ defaultNavy: 'dev', externalIP: null, - tlsRootCaDir: '/root/.navy/tls-root-ca', + tlsRootCaDir: expectedTlsCaDir, }) }) @@ -39,7 +42,7 @@ Then(/I should see that the default navy is something else$/, async function () expect(JSON.parse(this.config)).to.eql({ defaultNavy: 'someothernavy', externalIP: null, - tlsRootCaDir: '/root/.navy/tls-root-ca', + tlsRootCaDir: expectedTlsCaDir, }) expect(this.status).to.not.contain('dev (default)') @@ -49,11 +52,11 @@ Then(/I should see that the default navy is something else$/, async function () Then(/I should see that the default external IP is connect$/, async function () { const output = await Automator.spawn(['external-ip']).waitForDone() - // find IP of "docker" hostname and assert against that. - // when running the integration tests, the docker daemon is available at hostname "docker", - // so resolving that to an IP will give us the correct external IP. this is an ever changing - // value so cannot be hard coded in the tests - expect(output.trim()).to.equal(execSync("getent hosts docker | awk '{ print $1 }'").toString().trim()) + // The CLI must return whatever getExternalIP() computes from the current + // DOCKER_HOST environment. On a default Linux host (unix socket, no DOCKER_HOST) + // this will be 127.0.0.1; on Docker Desktop / docker-machine it'll be the + // resolved daemon IP. + expect(output.trim()).to.equal(await getExternalIP(null)) }) When(/I override the external IP using an environment variable$/, async function () { @@ -89,9 +92,8 @@ Then(/I should see that all services were reconfigured with the new external IP/ expect(JSON.parse(this.config)).to.eql({ defaultNavy: 'dev', externalIP: '192.168.3.105', - tlsRootCaDir: '/root/.navy/tls-root-ca', + tlsRootCaDir: expectedTlsCaDir, }) expect(this.ip.trim()).to.equal('192.168.3.105') }) - diff --git a/test/integration/features/step_definitions/develop.js b/test/integration/features/step_definitions/develop.js index a36e566..a18dbc9 100644 --- a/test/integration/features/step_definitions/develop.js +++ b/test/integration/features/step_definitions/develop.js @@ -1,11 +1,11 @@ import fetch from 'node-fetch' -import {expect} from 'chai' +import { expect } from 'chai' -import {TEST_SERVICE_NAME} from '../../environment' +import { TEST_SERVICE_NAME } from '../../environment' import Automator from '../../util/cli-automator' -import {retry} from '../../util' +import { retry } from '../../util' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' When(/I put the service into development$/, async function () { this.cmd = Automator.spawn(['develop'], { diff --git a/test/integration/features/step_definitions/http-proxy.js b/test/integration/features/step_definitions/http-proxy.js index 3f2bbac..c979860 100644 --- a/test/integration/features/step_definitions/http-proxy.js +++ b/test/integration/features/step_definitions/http-proxy.js @@ -1,10 +1,10 @@ -import {expect} from 'chai' +import { expect } from 'chai' import fetch from 'node-fetch' -import {retry} from '../../util' -import {TEST_SERVICE_NAME} from '../../environment' +import { retry } from '../../util' +import { TEST_SERVICE_NAME } from '../../environment' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' When(/I launch a service which exposes port 80$/, async function () { await this.navy.launch([TEST_SERVICE_NAME]) diff --git a/test/integration/features/step_definitions/https-proxy.js b/test/integration/features/step_definitions/https-proxy.js index 32d41a9..51aa0ab 100644 --- a/test/integration/features/step_definitions/https-proxy.js +++ b/test/integration/features/step_definitions/https-proxy.js @@ -1,13 +1,13 @@ -import {expect} from 'chai' +import { expect } from 'chai' import fetch from 'node-fetch' -import {mkdtempSync, readFileSync} from 'fs' -import {tmpdir} from 'os' +import { mkdtempSync, readFileSync } from 'fs' +import { tmpdir } from 'os' import https from 'https' -import {When, Then, Given} from '@cucumber/cucumber' +import { When, Then, Given } from '@cucumber/cucumber' import Automator from '../../util/cli-automator' -import {retry} from '../../util' -import {TEST_SERVICE_NAME} from '../../environment' +import { retry } from '../../util' +import { TEST_SERVICE_NAME } from '../../environment' Given(/I set the tlsCa-dir config/, async function () { this.tlsRootCaDirPath = mkdtempSync(`${tmpdir()}/navy-tls-root-ca`) @@ -46,7 +46,7 @@ Then(/I should be able to make a HTTPS request$/, async function () { }) await retry(async () => { const url = await this.navy.url(this.serviceForProxy) - const res = await fetch(url, {agent}) + const res = await fetch(url, { agent }) const body = await res.text() diff --git a/test/integration/features/step_definitions/launch-cli.js b/test/integration/features/step_definitions/launch-cli.js index 48aac6b..2d020fb 100644 --- a/test/integration/features/step_definitions/launch-cli.js +++ b/test/integration/features/step_definitions/launch-cli.js @@ -1,9 +1,9 @@ import path from 'path' -import {TEST_SERVICE_NAME} from '../../environment' +import { TEST_SERVICE_NAME } from '../../environment' import Automator from '../../util/cli-automator' -import {expect} from 'chai' +import { expect } from 'chai' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' When(/I launch a service from the CLI prompt$/, async function () { await Automator.spawn(['import']).waitForDone() diff --git a/test/integration/features/step_definitions/launch.js b/test/integration/features/step_definitions/launch.js index 42ab219..735efa3 100644 --- a/test/integration/features/step_definitions/launch.js +++ b/test/integration/features/step_definitions/launch.js @@ -1,12 +1,12 @@ /* eslint-disable no-unused-expressions */ /* eslint-enable chai-friendly/no-unused-expressions */ -import {expect, use} from 'chai' -import {Service} from '../../../../packages/navy/lib' +import { expect, use } from 'chai' +import { Service } from '../../../../packages/navy/lib' -import {TEST_SERVICE_NAME, TEST_SERVICE_IMAGE} from '../../environment' +import { TEST_SERVICE_NAME, TEST_SERVICE_IMAGE } from '../../environment' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' use(require('chai-like')) use(require('chai-things')) diff --git a/test/integration/features/step_definitions/port-cli.js b/test/integration/features/step_definitions/port-cli.js index d234e9e..163175d 100644 --- a/test/integration/features/step_definitions/port-cli.js +++ b/test/integration/features/step_definitions/port-cli.js @@ -1,16 +1,11 @@ -import {expect} from 'chai' -import {TEST_SERVICE_NAME} from '../../environment' +import { expect } from 'chai' +import { ENV_NAME, TEST_SERVICE_NAME } from '../../environment' import Automator from '../../util/cli-automator' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' When(/I get the internal port for port ([0-9]*) for the service using the CLI$/, async function (port) { - this.port = await Automator.spawn(['port', TEST_SERVICE_NAME, port], { - env: { - ...process.env, - NAVY_DEBUG: 'null', - }, - }).waitForDone() + this.port = await Automator.spawn(['port', '-e', ENV_NAME, TEST_SERVICE_NAME, port]).waitForDone() }) Then(/I should see the port using the CLI$/, function () { diff --git a/test/integration/features/step_definitions/port.js b/test/integration/features/step_definitions/port.js index c58344c..293b857 100644 --- a/test/integration/features/step_definitions/port.js +++ b/test/integration/features/step_definitions/port.js @@ -1,10 +1,10 @@ /* eslint-disable no-unused-expressions */ /* eslint-enable chai-friendly/no-unused-expressions */ -import {expect} from 'chai' -import {TEST_SERVICE_NAME} from '../../environment' +import { expect } from 'chai' +import { TEST_SERVICE_NAME } from '../../environment' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' When(/I get the internal port for port ([0-9]*) for the service$/, async function (port) { this.port = await this.navy.port(TEST_SERVICE_NAME, port) diff --git a/test/integration/features/step_definitions/start-stop-cli.js b/test/integration/features/step_definitions/start-stop-cli.js index 3e705c3..9011578 100644 --- a/test/integration/features/step_definitions/start-stop-cli.js +++ b/test/integration/features/step_definitions/start-stop-cli.js @@ -1,23 +1,23 @@ -import {expect, use} from 'chai' -import {TEST_SERVICE_NAME} from '../../environment' +import { expect, use } from 'chai' +import { ENV_NAME, TEST_SERVICE_NAME } from '../../environment' import Automator from '../../util/cli-automator' -import {Service} from '../../../../packages/navy/lib' +import { Service } from '../../../../packages/navy/lib' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' use(require('chai-like')) use(require('chai-things')) When(/I stop the service via the CLI$/, async function () { - this.result = await Automator.spawn(['stop', TEST_SERVICE_NAME]).waitForDone() + this.result = await Automator.spawn(['stop', '-e', ENV_NAME, TEST_SERVICE_NAME]).waitForDone() }) When(/I start the service via the CLI$/, async function () { - this.result = await Automator.spawn(['start', TEST_SERVICE_NAME]).waitForDone() + this.result = await Automator.spawn(['start', '-e', ENV_NAME, TEST_SERVICE_NAME]).waitForDone() }) When(/I start the navy via the CLI$/, async function () { - this.result = await Automator.spawn(['start']).waitForDone() + this.result = await Automator.spawn(['start', '-e', ENV_NAME]).waitForDone() }) Then(/I should see that just that service is running$/, async function () { diff --git a/test/integration/features/step_definitions/use-tag.js b/test/integration/features/step_definitions/use-tag.js index 696a684..3dfdc55 100644 --- a/test/integration/features/step_definitions/use-tag.js +++ b/test/integration/features/step_definitions/use-tag.js @@ -1,8 +1,8 @@ -import {expect} from 'chai' -import {TEST_SERVICE_NAME} from '../../environment' +import { expect } from 'chai' +import { TEST_SERVICE_NAME } from '../../environment' import Automator from '../../util/cli-automator' -import {Then, When} from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' When(/I change the tag of the service to a custom one$/, async function () { await this.navy.useTag(TEST_SERVICE_NAME, 'latest') diff --git a/test/integration/hooks.js b/test/integration/hooks.js index 7b554d3..2953cbf 100644 --- a/test/integration/hooks.js +++ b/test/integration/hooks.js @@ -1,8 +1,8 @@ -import rimraf from 'rimraf' -import {cleanUpNavies} from './util/setup-navy' -import {setConfig} from '../../packages/navy/src/config' +import { rimrafSync } from 'rimraf' +import { cleanUpNavies } from './util/setup-navy' +import { setConfig } from '../../packages/navy/src/config' -import {After, setDefaultTimeout} from '@cucumber/cucumber' +import { After, setDefaultTimeout } from '@cucumber/cucumber' setDefaultTimeout(2 * 60 * 1000) @@ -10,7 +10,7 @@ After(async function () { await cleanUpNavies() if (this.localCopyPath) { - rimraf.sync(this.localCopyPath) + rimrafSync(this.localCopyPath) } // reset config diff --git a/test/integration/runner/Dockerfile b/test/integration/runner/Dockerfile deleted file mode 100644 index 9a37260..0000000 --- a/test/integration/runner/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM ubuntu:18.04 - -ARG DOCKER_COMPOSE_VERSION -ARG NODE_VERSION -ARG DOCKERHUB_PULL_USERNAME -ARG DOCKERHUB_PULL_PASSWORD -ARG DOCKER_TLS_CERTDIR - -RUN apt-get update -y && apt-get install -y build-essential git curl - -RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - && apt-get install -y nodejs software-properties-common python - -RUN apt-get install -y apt-transport-https ca-certificates gnupg lsb-release -RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg -RUN echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null -RUN apt-get update -y && apt-get install -y docker-ce-cli - -RUN curl -L https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose -RUN chmod +x /usr/local/bin/docker-compose - -ADD ./test/integration/runner/docker-entrypoint.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-entrypoint.sh - -ENV DOCKERHUB_PULL_USERNAME $DOCKERHUB_PULL_USERNAME -ENV DOCKERHUB_PULL_PASSWORD $DOCKERHUB_PULL_PASSWORD -ENV DOCKER_TLS_CERTDIR $DOCKER_TLS_CERTDIR - -ADD ./test/integration/runner/docker-login.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-login.sh - -WORKDIR /usr/src/app -ADD package.json ./ -RUN npm i - -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] -CMD ["sh"] diff --git a/test/integration/runner/docker-entrypoint.sh b/test/integration/runner/docker-entrypoint.sh deleted file mode 100644 index 2ef330a..0000000 --- a/test/integration/runner/docker-entrypoint.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -set -e - -# if we have "--link some-docker:docker" and not DOCKER_HOST, let's set DOCKER_HOST automatically -if [ -z "$DOCKER_HOST" -a "$DOCKER_PORT_2375_TCP" ]; then - export DOCKER_HOST='tcp://docker:2375' -fi - -/usr/local/bin/docker-login.sh - -exec "$@" diff --git a/test/integration/runner/docker-login.sh b/test/integration/runner/docker-login.sh deleted file mode 100644 index 0e63166..0000000 --- a/test/integration/runner/docker-login.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -set -e - -if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then - echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin -fi diff --git a/test/integration/steps/develop.js b/test/integration/steps/develop.js index 4477c0c..10b9ead 100644 --- a/test/integration/steps/develop.js +++ b/test/integration/steps/develop.js @@ -1,14 +1,14 @@ import path from 'path' import fs from 'fs' -import rimraf from 'rimraf' +import { rimrafSync } from 'rimraf' -import {Given} from '@cucumber/cucumber' +import { Given } from '@cucumber/cucumber' Given(/I have a local copy of the source code of the launched service$/, function () { // create dummy local copy in temp directory this.localCopyPath = path.join(__dirname, '../../', '.navytestdir/') - rimraf.sync(this.localCopyPath) + rimrafSync(this.localCopyPath) fs.mkdirSync(this.localCopyPath) fs.writeFileSync(path.join(this.localCopyPath, '.navyrc'), ` diff --git a/test/integration/steps/navy.js b/test/integration/steps/navy.js index 8b4e36a..cf9710f 100644 --- a/test/integration/steps/navy.js +++ b/test/integration/steps/navy.js @@ -1,7 +1,7 @@ -import {getNavy} from '../../../packages/navy' -import {setUpNavy} from '../util/setup-navy' +import { getNavy } from '../../../packages/navy' +import { setUpNavy } from '../util/setup-navy' -import {Given} from '@cucumber/cucumber' +import { Given } from '@cucumber/cucumber' Given(/I am working with a test navy$/, async function () { this.navy = await setUpNavy('dev') diff --git a/test/integration/test-projects/http-proxy-https-enabled/Navyfile.js b/test/integration/test-projects/http-proxy-https-enabled/Navyfile.js index 969aa98..b6adea5 100644 --- a/test/integration/test-projects/http-proxy-https-enabled/Navyfile.js +++ b/test/integration/test-projects/http-proxy-https-enabled/Navyfile.js @@ -1,5 +1,5 @@ module.exports = { httpProxy: { - 'helloworld': { enableHttps: true }, + helloworld: { enableHttps: true }, }, } diff --git a/test/integration/test-projects/with-labels-middleware/middleware-plugin.js b/test/integration/test-projects/with-labels-middleware/middleware-plugin.js index f74de66..653f48b 100644 --- a/test/integration/test-projects/with-labels-middleware/middleware-plugin.js +++ b/test/integration/test-projects/with-labels-middleware/middleware-plugin.js @@ -1,4 +1,4 @@ -import {mapValues} from 'lodash' +import { mapValues } from 'lodash' export default navy => { diff --git a/test/integration/util/cli-automator.js b/test/integration/util/cli-automator.js index 4a55835..0fe8241 100644 --- a/test/integration/util/cli-automator.js +++ b/test/integration/util/cli-automator.js @@ -1,17 +1,17 @@ import path from 'path' import * as pty from 'node-pty' -import {execSync} from 'child_process' +import { execSync } from 'child_process' import stripAnsi from 'strip-ansi' -import {ENV_NAME} from '../environment' +import { ENV_NAME } from '../environment' // from http://stackoverflow.com/questions/17470554/how-to-capture-the-arrow-keys-in-node-js const keyCodes = { - 'up': '\u001b[A', - 'down': '\u001b[B', - 'right': '\u001b[C', - 'left': '\u001b[D', - 'enter': '\n', - 'space': ' ', + up: '\u001b[A', + down: '\u001b[B', + right: '\u001b[C', + left: '\u001b[D', + enter: '\n', + space: ' ', } const SYNTHETIC_DELAY_MS = 150 @@ -46,9 +46,16 @@ export default class Automator { cols: 130, rows: 30, cwd, + // node-pty merges stdout and stderr into a single stream that we + // capture and assert against, so any `debug()` output from the CLI + // ends up in the captured output and breaks JSON parsing / equality + // checks. CI exports `NAVY_DEBUG=navy:*` to aid test diagnosis, and + // step definitions commonly spread `process.env` when adding their + // own variables, so we unconditionally silence the spawned CLI here. env: { NAVY_NAME: ENV_NAME, ...(this.opts.env || process.env), + NAVY_DEBUG: 'null', }, }) diff --git a/test/integration/util/setup-navy.js b/test/integration/util/setup-navy.js index 40c53b3..8217873 100644 --- a/test/integration/util/setup-navy.js +++ b/test/integration/util/setup-navy.js @@ -1,5 +1,5 @@ import path from 'path' -import {getNavy, getLaunchedNavies} from '../../../packages/navy' +import { getNavy, getLaunchedNavies } from '../../../packages/navy' export async function setUpNavy(name = 'dev', testProjectName = 'basic') { const navy = getNavy(name) @@ -12,8 +12,25 @@ export async function setUpNavy(name = 'dev', testProjectName = 'basic') { return navy } +// Best-effort cleanup. We swallow errors here because cleanup must never mask +// the real assertion failure of a scenario, and because some scenarios leave +// the navy in a partially-initialised state where `destroy()` cannot fully +// reconfigure the shared HTTP proxy. Falling back to `delete()` ensures the +// on-disk navy state is still removed between scenarios so they remain +// independent. export async function cleanUpNavies() { - const navies = await getLaunchedNavies() + let navies = [] + try { + navies = await getLaunchedNavies() + } catch (e) { + return + } - await Promise.all(navies.map(navy => navy.destroy())) + await Promise.all(navies.map(async navy => { + try { + await navy.destroy() + } catch (e) { + try { await navy.delete() } catch (deleteErr) {} + } + })) } diff --git a/website/Gulpfile.js b/website/Gulpfile.js index 964eda7..837ee14 100644 --- a/website/Gulpfile.js +++ b/website/Gulpfile.js @@ -1,5 +1,5 @@ const gulp = require('gulp') -const {execSync} = require('child_process') +const { execSync } = require('child_process') const exec = (cmd) => execSync(cmd, { stdio: 'inherit' }) diff --git a/website/index.js b/website/index.js index 73f9a33..3e298f7 100644 --- a/website/index.js +++ b/website/index.js @@ -1,4 +1,4 @@ -import {glob} from './util/fs' +import { glob } from './util/fs' import { getContent, convertMarkdown, diff --git a/website/util/pipeline.js b/website/util/pipeline.js index 86f7a46..ff4fe97 100644 --- a/website/util/pipeline.js +++ b/website/util/pipeline.js @@ -2,7 +2,7 @@ import path from 'path' import nunjucks from 'nunjucks' import showdown from 'showdown' import frontMatter from 'front-matter' -import {fs, mkdirp} from './fs' +import { fs, mkdirp } from './fs' const showdownConverter = new showdown.Converter()