From 05d39292a4d5b5e668d9b4c17df8b2efbf9708cf Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 18 Jun 2024 15:54:53 -0400 Subject: [PATCH 01/42] chore(docs): Cleanup readmes (#302) - Remove references to opentdf/opentdf and backend repos - rename tdf3 to ztdf in at least one place - clarify that nodejs is *not* a supported runtime - update howto run the sample web app to reflect what we are doing in ci --- README.md | 22 ++++--- cli/README.md | 4 +- lib/README.md | 17 ++---- lib/tdf3/README.md | 86 --------------------------- remote-store/README.md | 1 - web-app/tests/README.md | 54 ++++++++++------- web-app/tests/tests/roundtrip.spec.ts | 4 +- 7 files changed, 58 insertions(+), 130 deletions(-) delete mode 100644 lib/tdf3/README.md diff --git a/README.md b/README.md index fdd040f8..51afafc8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # OpenTDF Web Browser Client opentdf -This project is focused on providing web client support for OpenTDF. +This project is focused on providing web client support for the OpenTDF platform. +This includes encrypting and decrypting TDF content, +and some management tasks for ABAC. -### Usage +## Usage ```typescript // currently we support only ESM import @@ -20,10 +22,10 @@ This project is focused on providing web client support for OpenTDF. const clearText = await client.decrypt(cipherText); ``` -## Distribute +## Build and Test ```shell -make dist +make ``` ## Contribute @@ -31,6 +33,8 @@ make dist ### Prerequisites Developing with this code requires a recent version of `npm` and `node`. +We develop using [nvm](https://github.com/nvm-sh/nvm#readme), +which allows us to pin to the same version of `npm` easily. - Install [nvm](https://github.com/nvm-sh/nvm#readme) - see https://github.com/nvm-sh/nvm#installing-and-updating @@ -48,16 +52,20 @@ make start ## Use the platform +Version 2 of this library adds support for ABAC management tasks. +This is provided with the [opentdf Platform](https://github.com/opentdf/platform). + ### Generate Typescript code from platform protobufs -``` + +```sh scripts/platform.sh ``` + This will clone the platform repo and generate Typescript code in `lib/src/platform`. ### Import Typescript code -``` - +```ts import { GetAttributeRequest } from './lib/src/platform/policy/attributes/attributes_pb'; import { Attribute, AttributeRuleTypeEnum } from './lib/src/platform/policy/objects_pb'; import { diff --git a/cli/README.md b/cli/README.md index acc2dfa6..de0a5dac 100644 --- a/cli/README.md +++ b/cli/README.md @@ -8,7 +8,7 @@ A sample application using node & ESM to import and test a project opentdf.mjs [encrypt|decrypt] [input file] ``` -For example, to use the quickstart test, we should do something like: +Sample round trip execution: ```sh echo hello-world >sample.txt @@ -28,8 +28,6 @@ bin/opentdf.mjs \ decrypt sample.tdf ``` -This is a placeholder for working through build and CI issues. - ### References - [yargs](http://yargs.js.org) diff --git a/lib/README.md b/lib/README.md index 18566d4a..0c4b908b 100644 --- a/lib/README.md +++ b/lib/README.md @@ -1,12 +1,12 @@ -# An OpenTDF Library for Browsers and NodeJS Clients +# An OpenTDF Library for Browser Applications -This project packages a set of javascript modules that can write and read -a variety of OpenTDF data formats, including NanoTDF, Dataset TDF, and the -TDF3 with JSON envelopes. +This project presents client code to write and read a OpenTDF data formats. +This included NanoTDF, Dataset TDF, and ZTDF. ## Usage ### NanoTDF + ```typescript const oidcCredentials: RefreshTokenCredentials = { clientId: keycloakClientId, @@ -20,7 +20,7 @@ TDF3 with JSON envelopes. const clearText = await client.decrypt(cipherText); ``` -### TDF3 +### ZTDF ```typescript const client = new TDF3Client({ @@ -45,13 +45,8 @@ TDF3 with JSON envelopes. console.log(`deciphered text :${plaintext}`); ``` -## Examples - -Review examples to see how to integrate. See [Examples](https://github.com/opentdf/opentdf/tree/main/examples) - ## Upgrading from 1.x -- The 'RemoteStorage' features have been moved into a separate library, @opentdf/remote-storage. - For an example refactor, see https://github.com/opentdf/opentdf/pull/256 +- The 'RemoteStorage' features have been moved into a separate library, @opentdf/remote-storage. - We have replaced all usages of node's `Buffer` with the web-friendlier `UInt8Array`. You will most likely see this in the return types of some functions. diff --git a/lib/tdf3/README.md b/lib/tdf3/README.md deleted file mode 100644 index 819d5109..00000000 --- a/lib/tdf3/README.md +++ /dev/null @@ -1,86 +0,0 @@ -[![CI Status](https://github.com/opentdf/tdf3-js/actions/workflows/build.yaml/badge.svg)](https://github.com/opentdf/tdf3-js/actions/workflows/build.yaml) - -# tdf3-js - -A JavaScript client library that can be used to encrypt and decypt files using the TDF3 -specification. - -## Install & Build - -First install all packages required: - -`npm ci` - -Build: - -`npm run build`. The built file can be found in `/build` - -Note: If running tests, the build is run automatically. - -## Running Tests - -1. Download, and run a KAS (Key Access Server): `npm run setup` -1. Start the KAS: `npm start` -1. Build tdf3-js: `npm run build` -1. Then: `npm test` - -Note: Step 1 grabs `main` branch of the kas. If you'd like to get a different branch do the -following: - -`BRANCH= npm run setup.` - -To terminate the running kas: `npm stop` - -## Example -### node.js - -```js -const { TDF3Client } = require("@opentdf/client"); - -(async function() { - const client = new TDF3Client({ - clientId: "tdf-client", - kasEndpoint: 'http://localhost/kas', - clientSecret: 'someSecret', - oidcOrigin: 'http://localhost/oidc', - }); - const source = new ReadableStream({ - pull(controller) { - controller.enqueue(new TextEncoder().encode(string)); - controller.close(); - }, - }); - const ct = await client.encrypt({ - source, - offline: true, - }); - const ciphertext = await ct.toString(); // could be also ct.toFile('img.jpg.html') - console.log(`ciphered text :${ciphertext}`); - - const decryptParams = new Client.DecryptParamsBuilder() - .withStringSource(ciphertext) // could be also withFileSource('img.jpg.html') - .build(); - const plaintextStream = await client.decrypt(decryptParams); - const plaintext = await plaintextStream.toString(); // could be also ct.toFile('img.jpg'); - console.log(`deciphered text :${plaintext}`); -})(); -``` - -### browser -```js - const client = new Client.Client({ - clientId: "tdf-client", - kasEndpoint: 'http://localhost/kas', - refreshToken: 'token', // Here is only difference in usage, browser build needs oidc tocken - oidcOrigin: 'http://localhost/oidc', - }); -``` -Rest is the same, you could use `withArrayBufferSource` for files in browser. For generating file in browser you could do -```js - const plainString = await plainStream.toString('base64'); - const a = document.getElementById("download_link"); - a.download = "filenName.html"; - a.href = "data:text/html;charset=utf-8," + encodeURIComponent(plainString); -``` - -clicking on that line allows you to download the file diff --git a/remote-store/README.md b/remote-store/README.md index f40ffb1e..12fee5ba 100644 --- a/remote-store/README.md +++ b/remote-store/README.md @@ -1,4 +1,3 @@ # @opentdf/remote-store This library extends the @opentdf/client library with functions to enable streaming to and from S3 buckets and other storage services that implement the S3 API. - diff --git a/web-app/tests/README.md b/web-app/tests/README.md index 69a385fb..46a5e9e9 100644 --- a/web-app/tests/README.md +++ b/web-app/tests/README.md @@ -1,35 +1,50 @@ -This folder container playwright, e2e tests for web-app, +# Web App Test Harness + +This folder contains playwright, e2e tests for web-app, running against a local or remote backend in proxy mode. +## Bring up the platform behind local (vite dev server) proxy -## Bring up backend behind local (vite dev server) proxy +Bring up test backend services (identity provider, database, etc.): -To configure backend, you can either use the opentdf quickstart -or the backend repository directly. +```sh +cd .github/workflows/roundtrip/ +docker compose up -d +``` -### Quickstart +> You can leave off the `-d` to track the logs; +> if you do this, open a new terminal +> and continue with the instructions below. -First, connect to your cluster or spin up a local cluster (e.g. using kind or minikube). +Configure the identity provider with some test users. +Please remain in the `roundtrip` test directory. -Next, check out the opentdf repository and start the quickstart. -``` -git clone https://github.com/opentdf/opentdf.git -cd opentdf/quickstart -export OPENTDF_INGRESS_HOST_PORT=5432 -export OPENTDF_LOAD_FRONTEND= -tilt up +```sh +go run github.com/opentdf/platform/service@latest provision keycloak +./config-demo-idp.sh ``` -Finally, bring up the web app: +If you haven't already done so, initialize your service keys. +Be careful! +If you lose these keys you will lose access to all TDFs encrypted with them. +These will be stored in place in the folder you create them, +with names like `kas-[type].pem`. +```sh +./init-temp-keys.sh ``` -cd web-app -npm run dev + +Start the platform and its key access service: + +```sh +go run github.com/opentdf/platform/service@latest start ``` ## Run Tests -``` +Once the platform is running, you may: + +```sh cd web-app/tests npm i npm test @@ -37,16 +52,15 @@ npm test To enable the large file tests, set -``` +```sh PLAYWRIGHT_TESTS_TO_RUN=huge roundtrip ``` - ## Running with test server for local URL streaming tests To try encrypting some of your own files via HTTP: -``` +```sh cd web-app/tests npm i ./run-server.js ~/Downloads diff --git a/web-app/tests/tests/roundtrip.spec.ts b/web-app/tests/tests/roundtrip.spec.ts index c0cfdde4..3017dad8 100644 --- a/web-app/tests/tests/roundtrip.spec.ts +++ b/web-app/tests/tests/roundtrip.spec.ts @@ -64,7 +64,7 @@ for (const [name, { encryptSelector, decryptSelector }] of Object.entries(scenar } const text = await readFile(plainTextPath, 'utf8'); expect(text, `Looking for clone command in ${plainTextPath}`).toContain( - 'git clone https://github.com/opentdf/opentdf.git' + 'try encrypting some of your own files' ); }); } @@ -107,7 +107,7 @@ test('Remote Source Streaming', async ({ page }) => { } expect(download2.suggestedFilename()).toContain('.decrypted'); const text = await readFile(plainTextPath, 'utf8'); - expect(text).toContain('git clone https://github.com/opentdf/opentdf.git'); + expect(text).toContain('try encrypting some of your own files'); } finally { server.close(); } From 5e6a35f128c39acb0319af7db91d93ff1c3ad58b Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 15 Jul 2024 15:13:55 -0400 Subject: [PATCH 02/42] chore(ci): Update opentdf platform config (#308) --- .github/workflows/build.yaml | 3 +- .../workflows/roundtrip/docker-compose.yaml | 37 ++--- .github/workflows/roundtrip/opentdf.yaml | 154 +++++------------- 3 files changed, 55 insertions(+), 139 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 94f120c9..16a85bbc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -242,8 +242,7 @@ jobs: go-version: '1.22' - name: Git clone backend run: | - git clone --single-branch --branch PLAT-3082-nanotdf-encrypt --depth 1 https://github.com/opentdf/platform.git \ - || git clone --depth 1 https://github.com/opentdf/platform.git + git clone --depth 1 https://github.com/opentdf/platform.git go work init for x in platform/{protocol/go,lib/{fixtures,ocrypto},sdk,service}; do go work use "$x"; done - run: docker compose up -d --wait --wait-timeout 240 diff --git a/.github/workflows/roundtrip/docker-compose.yaml b/.github/workflows/roundtrip/docker-compose.yaml index 1f432dd8..e478270f 100644 --- a/.github/workflows/roundtrip/docker-compose.yaml +++ b/.github/workflows/roundtrip/docker-compose.yaml @@ -1,14 +1,12 @@ services: keycloak: # This is kc 24.0.1 with opentdf protocol mapper on board - image: quay.io/keycloak/keycloak:24.0 - restart: - always - # To enable debugging, use this CMD and also set and expose the DEBUG_PORT - # command: ["--debug", "start-dev", "--log-level=DEBUG"] - command: ['start-dev'] + image: cgr.dev/chainguard/keycloak@sha256:37895558d2e0e93ffff75da5900f9ae7e79ec6d1c390b18b2ecea6cee45ec26f + restart: always + command: + - "start-dev" + - "--verbose" environment: - # DEBUG_PORT: "*:30012" KC_DB_VENDOR: postgres KC_DB_URL_HOST: keycloakdb KC_DB_URL_PORT: 5432 @@ -31,27 +29,14 @@ services: KEYCLOAK_ADMIN_PASSWORD: changeme ports: - '8888:8888' - # - "30012:30012" healthcheck: - test: - - CMD-SHELL - - >- - [ -f /tmp/HealthCheck.java ] - || echo "public class HealthCheck { - public static void main(String[] args) throws java.lang.Throwable { - System.exit( - java.net.HttpURLConnection.HTTP_OK == - ((java.net.HttpURLConnection) new java.net.URL(args[0]).openConnection()) - .getResponseCode() ? 0 : 1); - } - }" >/tmp/HealthCheck.java - && java /tmp/HealthCheck.java http://localhost:8888/auth/health/live + test: ['CMD-SHELL', '[ -f /tmp/HealthCheck.java ] || echo "public class HealthCheck { public static void main(String[] args) throws java.lang.Throwable { System.exit(java.net.HttpURLConnection.HTTP_OK == ((java.net.HttpURLConnection)new java.net.URL(args[0]).openConnection()).getResponseCode() ? 0 : 1); } }" > /tmp/HealthCheck.java && java /tmp/HealthCheck.java http://localhost:8888/auth/health/live'] interval: 5s timeout: 10s retries: 3 start_period: 2m keycloakdb: - image: postgres + image: postgres:15-alpine restart: always user: postgres environment: @@ -59,12 +44,12 @@ services: POSTGRES_USER: postgres POSTGRES_DB: keycloak healthcheck: - test: ['CMD-SHELL', 'pg_isready'] + test: ["CMD-SHELL", "pg_isready"] interval: 5s timeout: 5s retries: 10 opentdfdb: - image: public.ecr.aws/docker/library/postgres:15-alpine + image: postgres:15-alpine restart: always user: postgres environment: @@ -72,9 +57,9 @@ services: POSTGRES_PASSWORD: changeme POSTGRES_DB: opentdf healthcheck: - test: ['CMD-SHELL', 'pg_isready'] + test: ["CMD-SHELL", "pg_isready"] interval: 5s timeout: 5s retries: 10 ports: - - '5432:5432' + - "5432:5432" diff --git a/.github/workflows/roundtrip/opentdf.yaml b/.github/workflows/roundtrip/opentdf.yaml index bbc01b33..124576e3 100644 --- a/.github/workflows/roundtrip/opentdf.yaml +++ b/.github/workflows/roundtrip/opentdf.yaml @@ -2,7 +2,7 @@ logger: level: debug type: text output: stdout -# DB and Server confgurations are defaulted for local development +# DB and Server configurations are defaulted for local development # db: # host: localhost # port: 5432 @@ -11,118 +11,57 @@ logger: services: kas: enabled: true - eccertid: '123' + keyring: + - kid: e1 + alg: ec:secp256r1 + - kid: r1 + alg: rsa:2048 + - kid: r1 + alg: rsa:2048 + legacy: true policy: enabled: true authorization: enabled: true - url: http://localhost:65432 - client: 'tdf-entity-resolution' - secret: 'secret' + ersurl: http://localhost:65432/entityresolution/resolve + clientid: tdf-authorization-svc + clientsecret: secret + tokenendpoint: http://localhost:65432/auth/realms/opentdf/protocol/openid-connect/token + entityresolution: + enabled: true + url: http://localhost:65432/auth + clientid: 'tdf-entity-resolution' + clientsecret: 'secret' realm: 'opentdf' - legacy: true + legacykeycloak: true + inferid: + from: + email: true + username: true server: auth: enabled: true audience: 'http://localhost:65432' issuer: http://localhost:65432/auth/realms/opentdf - clients: - - 'opentdf' - - 'opentdf-sdk' policy: ## Default policy for all requests - default: #"role:readonly" + default: #"role:standard" ## Dot notation is used to access nested claims (i.e. realm_access.roles) claim: # realm_access.roles ## Maps the external role to the opentdf role ## Note: left side is used in the policy, right side is the external role map: - readonly: opentdf-readonly - admin: opentdf-admin - user: default-roles-opentdf - org-admin: opentdf-org-admin + # standard: opentdf-standard + # admin: opentdf-admin + # org-admin: opentdf-org-admin ## Custom policy (see examples https://github.com/casbin/casbin/tree/master/examples) - csv: | - ## Roles (prefixed with role:) - # org-admin - organization admin - # admin - admin - # readonly - readonly - # user - rewrap - # unknown - unknown role or no role - ## Actions - # read - read the resource - # write - write to the resource - # delete - delete the resource - # unsafe - unsafe actions - - # Role: user - p, role:user, kas.AccessService/PublicKey, read, allow - p, role:user, kas.AccessService/Rewrap, write, allow - p, role:user, /, read, allow - p, role:user, /kas/kas_public_key, read, allow - p, role:user, /kas/v2/kas_public_key, read, allow - p, role:user, /kas/v2/rewrap, write, allow - - # Role: Org-Admin - ## gRPC routes - p, role:org-admin, policy.*, *, allow - p, role:org-admin, kasregistry.*, *, allow - p, role:org-admin, kas.AccessService/LegacyPublicKey, *, allow - p, role:org-admin, kas.AccessService/PublicKey, *, allow - p, role:org-admin, kas.AccessService/Rewrap, *, allow - ## HTTP routes - p, role:org-admin, /health, *, allow - p, role:org-admin, /attributes*, *, allow - p, role:org-admin, /namespaces*, *, allow - p, role:org-admin, /subject-mappings*, *, allow - p, role:org-admin, /resource-mappings*, *, allow - p, role:org-admin, /key-access-servers*, *, allow - p, role:org-admin, /kas.AccessService/LegacyPublicKey, *, allow - # add unsafe actions to the org-admin role - - # Role: Admin - ## gRPC routes - p, role:admin, policy.*, *, allow - p, role:admin, kasregistry.*, *, allow - p, role:admin, kas.AccessService/Info, *, allow - p, role:admin, kas.AccessService/Rewrap, *, allow - p, role:admin, kas.AccessService/LegacyPublicKey, *, allow - p, role:admin, kas.AccessService/PublicKey, *, allow - ## HTTP routes - p, role:admin, /health, *, allow - p, role:admin, /attributes*, *, allow - p, role:admin, /namespaces*, *, allow - p, role:admin, /subject-mappings*, *, allow - p, role:admin, /resource-mappings*, *, allow - p, role:admin, /key-access-servers*, *, allow - p, role:admin, /kas.AccessService/LegacyPublicKey, *, allow - - ## Role: Readonly - ## gRPC routes - p, role:readonly, policy.*, read, allow - p, role:readonly, kasregistry.*, read, allow - p, role:readonly, kas.AccessService/Info, *, allow - p, role:readonly, kas.AccessService/Rewrap, *, allow - p, role:readonly, kas.AccessService/LegacyPublicKey, *, allow - p, role:readonly, kas.AccessService/PublicKey, *, allow - ## HTTP routes - p, role:readonly, /health, read, allow - p, role:readonly, /attributes*, read, allow - p, role:readonly, /namespaces*, read, allow - p, role:readonly, /subject-mappings*, read, allow - p, role:readonly, /resource-mappings*, read, allow - p, role:readonly, /key-access-servers*, read, allow - p, role:readonly, /kas.AccessService/LegacyPublicKey, read, allow - - # Public routes - ## gRPC routes - p, role:unknown, kas.AccessService/LegacyPublicKey, other, allow - p, role:unknown, kas.AccessService/PublicKey, other, allow - ## HTTP routes - p, role:unknown, /health, read, allow - p, role:unknown, /kas/v2/kas_public_key, read, allow - p, role:unknown, /kas/kas_public_key, read, allow + csv: #| + # p, role:org-admin, policy:attributes, *, *, allow + # p, role:org-admin, policy:subject-mappings, *, *, allow + # p, role:org-admin, policy:resource-mappings, *, *, allow + # p, role:org-admin, policy:kas-registry, *, *, allow + # p, role:org-admin, policy:unsafe, *, *, allow ## Custom model (see https://casbin.org/docs/syntax-for-models/) model: #| @@ -140,25 +79,18 @@ server: # # [matchers] # m = g(r.sub, p.sub) && globOrRegexMatch(r.res, p.res) && globOrRegexMatch(r.act, p.act) && globOrRegexMatch(r.obj, p.obj) - grpc: reflectionEnabled: true # Default is false cryptoProvider: - hsm: - enabled: false - pin: + type: standard standard: - rsa: - 123: - private_key_path: kas-private.pem - public_key_path: kas-cert.pem - 456: - private_key_path: kas-private.pem - public_key_path: kas-cert.pem - ec: - 123: - private_key_path: kas-ec-private.pem - public_key_path: kas-ec-cert.pem + keys: + - kid: r1 + alg: rsa:2048 + private: kas-private.pem + cert: kas-cert.pem + - kid: e1 + alg: ec:secp256r1 + private: kas-ec-private.pem + cert: kas-ec-cert.pem port: 8080 -opa: - embedded: true # Only for local development From 0e1426bbd735bc1645c9341fbf66f447992ce34d Mon Sep 17 00:00:00 2001 From: Elizabeth Healy <35498075+elizabethhealy@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:41:22 -0400 Subject: [PATCH 03/42] Use offline mode in cli for TDF3 (#306) * making cli use offline mode for tdf3 * fix file reading tdf3 --- cli/src/cli.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/src/cli.ts b/cli/src/cli.ts index 22ffc0f4..cb315568 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -115,9 +115,11 @@ async function tdf3EncryptParamsFor(argv: Partial): Promise Date: Wed, 17 Jul 2024 12:04:12 -0400 Subject: [PATCH 04/42] fix(logs): Improves on decrypt unsafe fail (#303) This is a failure before rewrap, not upsert. --- lib/tdf3/src/tdf.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 6876f562..a41d5638 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -41,6 +41,7 @@ import { TdfDecryptError, TdfError, TdfPayloadExtractionError, + UnsafeUrlError, } from '../../src/errors.js'; import { htmlWrapperTemplate } from './templates/index.js'; @@ -824,7 +825,12 @@ async function unwrapKey({ const rewrappedKeys = await Promise.all( keyAccess.map(async (keySplitInfo) => { if (!allowedKases.includes(keySplitInfo.url)) { - throw new KasUpsertError(`Unexpected KAS url: [${keySplitInfo.url}]`); + throw new UnsafeUrlError( + `cannot decrypt TDF: [${keySplitInfo.url}] not on allowlist ${JSON.stringify( + allowedKases + )}`, + keySplitInfo.url + ); } const url = `${keySplitInfo.url}/${isAppIdProvider ? '' : 'v2/'}rewrap`; From 632864fae0c5ab23f25ea53dd1cfa6aacaef4530 Mon Sep 17 00:00:00 2001 From: Elizabeth Healy <35498075+elizabethhealy@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:43:11 -0400 Subject: [PATCH 05/42] Add xtest workflow trigger on PR (#310) * trigger xtest workflow * fix workflow naming * re-trigger * rm comment * comment out, trigger * trigger * xtest working on main --- .github/workflows/build.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 16a85bbc..7106ce44 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -251,6 +251,12 @@ jobs: run: |- ./wait-and-test.sh platform + platform-xtest: + needs: platform-roundtrip + uses: opentdf/tests/.github/workflows/xtest.yml@main + with: + js-ref: ${{ github.ref }} + deliver-ghp: needs: - lib @@ -259,6 +265,7 @@ jobs: - scripts - backend-roundtrip - platform-roundtrip + - platform-xtest runs-on: ubuntu-latest timeout-minutes: 5 # To publish from a release or feature branch, remove the ref == condition below From 5e234ee0ae013e91b98bf6ca7341377e12565ca4 Mon Sep 17 00:00:00 2001 From: Elizabeth Healy <35498075+elizabethhealy@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:48:15 -0400 Subject: [PATCH 06/42] fix: use new policy binding format (#312) * policy binding updates * don't fail on old backend roundtrip --- .github/workflows/build.yaml | 2 +- lib/tdf3/src/models/key-access.ts | 15 ++++++++++++--- lib/tests/mocks/client/default_manifest.json | 5 ++++- lib/tests/mocks/tdf/0.manifest.json | 5 ++++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7106ce44..6f8fe1d3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -263,9 +263,9 @@ jobs: - cli - web-app - scripts - - backend-roundtrip - platform-roundtrip - platform-xtest + # - backend-roundtrip runs-on: ubuntu-latest timeout-minutes: 5 # To publish from a release or feature branch, remove the ref == condition below diff --git a/lib/tdf3/src/models/key-access.ts b/lib/tdf3/src/models/key-access.ts index 27e9282c..951c7ddf 100644 --- a/lib/tdf3/src/models/key-access.ts +++ b/lib/tdf3/src/models/key-access.ts @@ -43,7 +43,10 @@ export class Wrapped { protocol: 'kas', wrappedKey: base64.encode(wrappedKeyBinary.asString()), encryptedMetadata: base64.encode(encryptedMetadataStr), - policyBinding: base64.encode(policyBinding), + policyBinding: { + alg: 'HS256', + hash: base64.encode(policyBinding), + }, }; if (this.kid) { this.keyAccessObject.kid = this.kid; @@ -91,7 +94,10 @@ export class Remote { protocol: 'kas', wrappedKey: this.wrappedKey, encryptedMetadata: base64.encode(encryptedMetadataStr), - policyBinding: base64.encode(policyBinding), + policyBinding: { + alg: 'HS256', + hash: base64.encode(policyBinding), + }, }; if (this.kid) { this.keyAccessObject.kid = this.kid; @@ -108,6 +114,9 @@ export type KeyAccessObject = { kid?: string; protocol: 'kas'; wrappedKey?: string; - policyBinding?: string; + policyBinding?: { + alg: string; + hash: string; + }; encryptedMetadata?: string; }; diff --git a/lib/tests/mocks/client/default_manifest.json b/lib/tests/mocks/client/default_manifest.json index 067f0480..7c42a01c 100644 --- a/lib/tests/mocks/client/default_manifest.json +++ b/lib/tests/mocks/client/default_manifest.json @@ -13,7 +13,10 @@ "url": "http://kas.gsk.com:5000", "protocol": "kas", "wrappedKey": "OqnOETpwyGE3PVpUpwwWZoJTNW24UMhnXIif0mSnqLVCUPKAAhrjeue11uAXWpb9sD7ZDsmrc9ylmnSKP9vWel8ST68tv6PeVO+CPYUND7cqG2NhUHCLv5Ouys3Klurykvy8/O3cCLDYl6RDISosxFKqnd7LYD7VnxsYqUns4AW5/odXJrwIhNO3szZV0JgoBXs+U9bul4tSGNxmYuPOj0RE0HEX5yF5lWlt2vHNCqPlmSBV6+jePf7tOBBsqDq35GxCSHhFZhqCgA3MvnBLmKzVPArtJ1lqg3WUdnWV+o6BUzhDpOIyXzeKn4cK2mCxOXGMP2ck2C1a0sECyB82uw==", - "policyBinding": "BzmgoIxZzMmIF42qzbdD4Rw30GtdaRSQL2Xlfms1OPs=", + "policyBinding": { + "alg": "HS256", + "hash": "BzmgoIxZzMmIF42qzbdD4Rw30GtdaRSQL2Xlfms1OPs=" + }, "encryptedMetadata": "ZoJTNW24UMhnXIif0mSnqLVCU=" } ], diff --git a/lib/tests/mocks/tdf/0.manifest.json b/lib/tests/mocks/tdf/0.manifest.json index 5740cb0c..80f1d9a0 100644 --- a/lib/tests/mocks/tdf/0.manifest.json +++ b/lib/tests/mocks/tdf/0.manifest.json @@ -11,7 +11,10 @@ "url": "http://127.0.0.1:4000", "protocol": "kas", "wrappedKey": "x8lk9Nxhx+zv+DVpCz89XLbMwbeeoNMhWIRO7CKdTNEWRWI9T+Ubkdvvi+SgrTJLQeEFBJspLQdombPI8Li1SVGD3pyfMNGXQ/FDoYIp2JHfyVKETfksU4q4gnNU3G63bTvCdQ41FeJJP26DIm63dKbF8BJQ/iSpXIPFalvMy/E9lR6kEv7ShKrwCKThFzynsg37ProbSmaYtTab+8J1/37oxm39PAUUfOOta9JA0mn8dz7f7a3nMVcXcyqrCTZSYbWKqhTowPeK2QiIfGJ1+K4F0V2UXMVuxIw6SEVbNL2hRkZ6+OSQd+kWMZTuneXtZeOHfBuOFRRzVzIEawagdA==", - "policyBinding": "fNPuURQu6ZpZk26TglgJxG1E7HiOynaFoyajj+8V1xg=" + "policyBinding": { + "alg": "HS256", + "hash": "fNPuURQu6ZpZk26TglgJxG1E7HiOynaFoyajj+8V1xg=" + } } ] ] From bc574f7878e5583b90ca5bab2f80a1a111df7b99 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 2 Aug 2024 16:33:02 -0400 Subject: [PATCH 07/42] fix(audit): npm audit fix (#318) - Also updates to latest backend for tests (1.6.1) --- .github/workflows/roundtrip/Tiltfile | 2 +- remote-store/package-lock.json | 2620 ++++++++++++++------------ 2 files changed, 1449 insertions(+), 1173 deletions(-) diff --git a/.github/workflows/roundtrip/Tiltfile b/.github/workflows/roundtrip/Tiltfile index cdc95d44..178a0769 100644 --- a/.github/workflows/roundtrip/Tiltfile +++ b/.github/workflows/roundtrip/Tiltfile @@ -1,7 +1,7 @@ load("ext://helm_remote", "helm_remote") load("ext://helm_resource", "helm_resource", "helm_repo") -BACKEND_CHART_TAG = "0.0.0-sha-dbfcea7" +BACKEND_CHART_TAG = "1.6.1" EXTERNAL_URL = os.getenv("OPENTDF_EXTERNAL_URL", "http://localhost:65432") INGRESS_HOST_PORT = os.getenv("OPENTDF_INGRESS_HOST_PORT", "65432") diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index 9d3e9c9c..bee04472 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -44,129 +44,190 @@ } }, "node_modules/@aws-crypto/crc32": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", - "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", "dependencies": { - "@aws-crypto/util": "^3.0.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-crypto/crc32/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/@aws-crypto/crc32c": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", - "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", "dependencies": { - "@aws-crypto/util": "^3.0.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/crc32c/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/ie11-detection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", - "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", + "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", "dependencies": { - "tslib": "^1.11.1" + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/@aws-crypto/sha1-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", - "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } }, "node_modules/@aws-crypto/sha256-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", - "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/sha256-js": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } }, "node_modules/@aws-crypto/sha256-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", - "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", "dependencies": { - "@aws-crypto/util": "^3.0.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/@aws-crypto/supports-web-crypto": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", - "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", "dependencies": { - "tslib": "^1.11.1" + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/@aws-crypto/util": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", - "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", "dependencies": { "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } }, "node_modules/@aws-sdk/abort-controller": { "version": "3.374.0", @@ -182,438 +243,528 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.382.0.tgz", - "integrity": "sha512-7s5DI1dw5HUF9+tHuZzkJaZBcaE3kuGsMw17/enEa8YdF0CtL5rW46FlzQ3/7NYIKc9rhDtb0UMakEej1cWFtg==", - "dependencies": { - "@aws-crypto/sha1-browser": "3.0.0", - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.382.0", - "@aws-sdk/credential-provider-node": "3.382.0", - "@aws-sdk/middleware-bucket-endpoint": "3.378.0", - "@aws-sdk/middleware-expect-continue": "3.378.0", - "@aws-sdk/middleware-flexible-checksums": "3.378.0", - "@aws-sdk/middleware-host-header": "3.379.1", - "@aws-sdk/middleware-location-constraint": "3.379.1", - "@aws-sdk/middleware-logger": "3.378.0", - "@aws-sdk/middleware-recursion-detection": "3.378.0", - "@aws-sdk/middleware-sdk-s3": "3.379.1", - "@aws-sdk/middleware-signing": "3.379.1", - "@aws-sdk/middleware-ssec": "3.378.0", - "@aws-sdk/middleware-user-agent": "3.382.0", - "@aws-sdk/signature-v4-multi-region": "3.378.0", - "@aws-sdk/types": "3.378.0", - "@aws-sdk/util-endpoints": "3.382.0", - "@aws-sdk/util-user-agent-browser": "3.378.0", - "@aws-sdk/util-user-agent-node": "3.378.0", - "@aws-sdk/xml-builder": "3.310.0", - "@smithy/config-resolver": "^2.0.1", - "@smithy/eventstream-serde-browser": "^2.0.1", - "@smithy/eventstream-serde-config-resolver": "^2.0.1", - "@smithy/eventstream-serde-node": "^2.0.1", - "@smithy/fetch-http-handler": "^2.0.1", - "@smithy/hash-blob-browser": "^2.0.1", - "@smithy/hash-node": "^2.0.1", - "@smithy/hash-stream-node": "^2.0.1", - "@smithy/invalid-dependency": "^2.0.1", - "@smithy/md5-js": "^2.0.1", - "@smithy/middleware-content-length": "^2.0.1", - "@smithy/middleware-endpoint": "^2.0.1", - "@smithy/middleware-retry": "^2.0.1", - "@smithy/middleware-serde": "^2.0.1", - "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.1", - "@smithy/node-http-handler": "^2.0.1", - "@smithy/protocol-http": "^2.0.1", - "@smithy/smithy-client": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/url-parser": "^2.0.1", - "@smithy/util-base64": "^2.0.0", - "@smithy/util-body-length-browser": "^2.0.0", - "@smithy/util-body-length-node": "^2.0.0", - "@smithy/util-defaults-mode-browser": "^2.0.1", - "@smithy/util-defaults-mode-node": "^2.0.1", - "@smithy/util-retry": "^2.0.0", - "@smithy/util-stream": "^2.0.1", - "@smithy/util-utf8": "^2.0.0", - "@smithy/util-waiter": "^2.0.1", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.621.0.tgz", + "integrity": "sha512-YhGkd2HQTM4HCYJIAVWvfbUMpOF7XUr1W/e2LN3CFP0WTF4zcCJKesJ2iNHrExqC0Ek1+qarMxiXBK95itfjYQ==", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.621.0", + "@aws-sdk/client-sts": "3.621.0", + "@aws-sdk/core": "3.621.0", + "@aws-sdk/credential-provider-node": "3.621.0", + "@aws-sdk/middleware-bucket-endpoint": "3.620.0", + "@aws-sdk/middleware-expect-continue": "3.620.0", + "@aws-sdk/middleware-flexible-checksums": "3.620.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-location-constraint": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-sdk-s3": "3.621.0", + "@aws-sdk/middleware-signing": "3.620.0", + "@aws-sdk/middleware-ssec": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/signature-v4-multi-region": "3.621.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@aws-sdk/xml-builder": "3.609.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.1", + "@smithy/eventstream-serde-browser": "^3.0.5", + "@smithy/eventstream-serde-config-resolver": "^3.0.3", + "@smithy/eventstream-serde-node": "^3.0.4", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-blob-browser": "^3.1.2", + "@smithy/hash-node": "^3.0.3", + "@smithy/hash-stream-node": "^3.1.2", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/md5-js": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.13", + "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-stream": "^3.1.3", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/client-s3/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.382.0.tgz", - "integrity": "sha512-ge11t4hJllOF8pBNF0p1X52lLqUsLGAoey24fvk3fyvvczeLpegGYh2kdLG0iwFTDgRxaUqK+kboH5Wy9ux/pw==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.379.1", - "@aws-sdk/middleware-logger": "3.378.0", - "@aws-sdk/middleware-recursion-detection": "3.378.0", - "@aws-sdk/middleware-user-agent": "3.382.0", - "@aws-sdk/types": "3.378.0", - "@aws-sdk/util-endpoints": "3.382.0", - "@aws-sdk/util-user-agent-browser": "3.378.0", - "@aws-sdk/util-user-agent-node": "3.378.0", - "@smithy/config-resolver": "^2.0.1", - "@smithy/fetch-http-handler": "^2.0.1", - "@smithy/hash-node": "^2.0.1", - "@smithy/invalid-dependency": "^2.0.1", - "@smithy/middleware-content-length": "^2.0.1", - "@smithy/middleware-endpoint": "^2.0.1", - "@smithy/middleware-retry": "^2.0.1", - "@smithy/middleware-serde": "^2.0.1", - "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.1", - "@smithy/node-http-handler": "^2.0.1", - "@smithy/protocol-http": "^2.0.1", - "@smithy/smithy-client": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/url-parser": "^2.0.1", - "@smithy/util-base64": "^2.0.0", - "@smithy/util-body-length-browser": "^2.0.0", - "@smithy/util-body-length-node": "^2.0.0", - "@smithy/util-defaults-mode-browser": "^2.0.1", - "@smithy/util-defaults-mode-node": "^2.0.1", - "@smithy/util-retry": "^2.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.621.0.tgz", + "integrity": "sha512-xpKfikN4u0BaUYZA9FGUMkkDmfoIP0Q03+A86WjqDWhcOoqNA1DkHsE4kZ+r064ifkPUfcNuUvlkVTEoBZoFjA==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.621.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.1", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.13", + "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.382.0.tgz", - "integrity": "sha512-hTfvB1ftbrqaz7qiEkmRobzUQwG34oZlByobn8Frdr5ZQbJk969bX6evQAPyKlJEr26+kL9TnaX+rbLR/+gwHQ==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.379.1", - "@aws-sdk/middleware-logger": "3.378.0", - "@aws-sdk/middleware-recursion-detection": "3.378.0", - "@aws-sdk/middleware-user-agent": "3.382.0", - "@aws-sdk/types": "3.378.0", - "@aws-sdk/util-endpoints": "3.382.0", - "@aws-sdk/util-user-agent-browser": "3.378.0", - "@aws-sdk/util-user-agent-node": "3.378.0", - "@smithy/config-resolver": "^2.0.1", - "@smithy/fetch-http-handler": "^2.0.1", - "@smithy/hash-node": "^2.0.1", - "@smithy/invalid-dependency": "^2.0.1", - "@smithy/middleware-content-length": "^2.0.1", - "@smithy/middleware-endpoint": "^2.0.1", - "@smithy/middleware-retry": "^2.0.1", - "@smithy/middleware-serde": "^2.0.1", - "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.1", - "@smithy/node-http-handler": "^2.0.1", - "@smithy/protocol-http": "^2.0.1", - "@smithy/smithy-client": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/url-parser": "^2.0.1", - "@smithy/util-base64": "^2.0.0", - "@smithy/util-body-length-browser": "^2.0.0", - "@smithy/util-body-length-node": "^2.0.0", - "@smithy/util-defaults-mode-browser": "^2.0.1", - "@smithy/util-defaults-mode-node": "^2.0.1", - "@smithy/util-retry": "^2.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.621.0.tgz", + "integrity": "sha512-mMjk3mFUwV2Y68POf1BQMTF+F6qxt5tPu6daEUCNGC9Cenk3h2YXQQoS4/eSyYzuBiYk3vx49VgleRvdvkg8rg==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.621.0", + "@aws-sdk/credential-provider-node": "3.621.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.1", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.13", + "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" }, - "engines": { - "node": ">=14.0.0" + "peerDependencies": { + "@aws-sdk/client-sts": "^3.621.0" } }, "node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/client-sso/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.382.0.tgz", - "integrity": "sha512-G5wgahrOqmrljjyLVGASIZUXIIdalbCo0z4PuFHdb2R2CVfwO8renfgrmk4brT9tIxIfen5bRA7ftXMe7yrgRA==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/credential-provider-node": "3.382.0", - "@aws-sdk/middleware-host-header": "3.379.1", - "@aws-sdk/middleware-logger": "3.378.0", - "@aws-sdk/middleware-recursion-detection": "3.378.0", - "@aws-sdk/middleware-sdk-sts": "3.379.1", - "@aws-sdk/middleware-signing": "3.379.1", - "@aws-sdk/middleware-user-agent": "3.382.0", - "@aws-sdk/types": "3.378.0", - "@aws-sdk/util-endpoints": "3.382.0", - "@aws-sdk/util-user-agent-browser": "3.378.0", - "@aws-sdk/util-user-agent-node": "3.378.0", - "@smithy/config-resolver": "^2.0.1", - "@smithy/fetch-http-handler": "^2.0.1", - "@smithy/hash-node": "^2.0.1", - "@smithy/invalid-dependency": "^2.0.1", - "@smithy/middleware-content-length": "^2.0.1", - "@smithy/middleware-endpoint": "^2.0.1", - "@smithy/middleware-retry": "^2.0.1", - "@smithy/middleware-serde": "^2.0.1", - "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.1", - "@smithy/node-http-handler": "^2.0.1", - "@smithy/protocol-http": "^2.0.1", - "@smithy/smithy-client": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/url-parser": "^2.0.1", - "@smithy/util-base64": "^2.0.0", - "@smithy/util-body-length-browser": "^2.0.0", - "@smithy/util-body-length-node": "^2.0.0", - "@smithy/util-defaults-mode-browser": "^2.0.1", - "@smithy/util-defaults-mode-node": "^2.0.1", - "@smithy/util-retry": "^2.0.0", - "@smithy/util-utf8": "^2.0.0", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.621.0.tgz", + "integrity": "sha512-707uiuReSt+nAx6d0c21xLjLm2lxeKc7padxjv92CIrIocnQSlJPxSCM7r5zBhwiahJA6MNQwmTl2xznU67KgA==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.621.0", + "@aws-sdk/core": "3.621.0", + "@aws-sdk/credential-provider-node": "3.621.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.1", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.13", + "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sts/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-sts/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "node_modules/@aws-sdk/core": { + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.621.0.tgz", + "integrity": "sha512-CtOwWmDdEiINkGXD93iGfXjN0WmCp9l45cDWHHGa8lRgEDyhuL7bwd/pH5aSzj0j8SiQBG2k0S7DHbd5RaqvbQ==", "dependencies": { - "tslib": "^2.5.0" + "@smithy/core": "^2.3.1", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/signature-v4": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.378.0.tgz", - "integrity": "sha512-B2OVdO9kBClDwGgWTBLAQwFV8qYTYGyVujg++1FZFSFMt8ORFdZ5fNpErvJtiSjYiOOQMzyBeSNhKyYNXCiJjQ==", + "version": "3.620.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.620.1.tgz", + "integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-env/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.621.0.tgz", + "integrity": "sha512-/jc2tEsdkT1QQAI5Dvoci50DbSxtJrevemwFsm0B73pwCcOQZ5ZwwSdVqGsPutzYzUVx3bcXg3LRL7jLACqRIg==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.382.0.tgz", - "integrity": "sha512-31pi44WWri2WQmagqptUv7x3Nq8pQ6H06OCQx5goEm77SosSdwQwyBPrS9Pg0yI9aljFAxF+rZ75degsCorbQg==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.378.0", - "@aws-sdk/credential-provider-process": "3.378.0", - "@aws-sdk/credential-provider-sso": "3.382.0", - "@aws-sdk/credential-provider-web-identity": "3.378.0", - "@aws-sdk/types": "3.378.0", - "@smithy/credential-provider-imds": "^2.0.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.621.0.tgz", + "integrity": "sha512-0EWVnSc+JQn5HLnF5Xv405M8n4zfdx9gyGdpnCmAmFqEDHA8LmBdxJdpUk1Ovp/I5oPANhjojxabIW5f1uU0RA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.620.1", + "@aws-sdk/credential-provider-http": "3.621.0", + "@aws-sdk/credential-provider-process": "3.620.1", + "@aws-sdk/credential-provider-sso": "3.621.0", + "@aws-sdk/credential-provider-web-identity": "3.621.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.621.0" } }, "node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.382.0.tgz", - "integrity": "sha512-q6AWCCb0E0cH/Y5Dtln0QssbCBXDbV4PoTV3EdRuGoJcHyNfHJ8X0mqcc7k44wG4Piazu+ufZThvn43W7W9a4g==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.378.0", - "@aws-sdk/credential-provider-ini": "3.382.0", - "@aws-sdk/credential-provider-process": "3.378.0", - "@aws-sdk/credential-provider-sso": "3.382.0", - "@aws-sdk/credential-provider-web-identity": "3.378.0", - "@aws-sdk/types": "3.378.0", - "@smithy/credential-provider-imds": "^2.0.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.621.0.tgz", + "integrity": "sha512-4JqpccUgz5Snanpt2+53hbOBbJQrSFq7E1sAAbgY6BKVQUsW5qyXqnjvSF32kDeKa5JpBl3bBWLZl04IadcPHw==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.620.1", + "@aws-sdk/credential-provider-http": "3.621.0", + "@aws-sdk/credential-provider-ini": "3.621.0", + "@aws-sdk/credential-provider-process": "3.620.1", + "@aws-sdk/credential-provider-sso": "3.621.0", + "@aws-sdk/credential-provider-web-identity": "3.621.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.378.0.tgz", - "integrity": "sha512-KFTIy7u+wXj3eDua4rgS0tODzMnXtXhAm1RxzCW9FL5JLBBrd82ymCj1Dp72217Sw5Do6NjCnDTTNkCHZMA77w==", - "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.620.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.620.1.tgz", + "integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-process/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.382.0.tgz", - "integrity": "sha512-tKCQKqxnAHeRD7pQNmDmLWwC7pt5koo6yiQTVQ382U+8xx7BNsApE1zdC4LrtrVN1FYqVbw5kXjYFtSCtaUxGA==", - "dependencies": { - "@aws-sdk/client-sso": "3.382.0", - "@aws-sdk/token-providers": "3.382.0", - "@aws-sdk/types": "3.378.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.621.0.tgz", + "integrity": "sha512-Kza0jcFeA/GEL6xJlzR2KFf1PfZKMFnxfGzJzl5yN7EjoGdMijl34KaRyVnfRjnCWcsUpBWKNIDk9WZVMY9yiw==", + "dependencies": { + "@aws-sdk/client-sso": "3.621.0", + "@aws-sdk/token-providers": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.378.0.tgz", - "integrity": "sha512-GWjydOszhc4xDF8xuPtBvboglXQr0gwCW1oHAvmLcOT38+Hd6qnKywnMSeoXYRPgoKfF9TkWQgW1jxplzCG0UA==", + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.621.0.tgz", + "integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.621.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.378.0.tgz", - "integrity": "sha512-3o+AYU6JWUsPM49bWglCUOgNvySiHkbIma0J6F9a68e30vEDD0FUQtKzyHPZkF7iYDyesEl166gYjwVNAmASzw==", - "dependencies": { - "@aws-sdk/types": "3.378.0", - "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/util-config-provider": "^2.0.0", - "tslib": "^2.5.0" + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.620.0.tgz", + "integrity": "sha512-eGLL0W6L3HDb3OACyetZYOWpHJ+gLo0TehQKeQyy2G8vTYXqNTeqYhuI6up9HVjBzU9eQiULVQETmgQs7TFaRg==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-endpoint": { @@ -690,284 +841,265 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.378.0.tgz", - "integrity": "sha512-8maaNQvza3/IGDbIyVQkUbGlo+Oc6SY1gVG50UMcTUX8nwZrD1/ko+ft+pd2EDb2n+0JritoDj4bjr6pdesNBg==", + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.620.0.tgz", + "integrity": "sha512-QXeRFMLfyQ31nAHLbiTLtk0oHzG9QLMaof5jIfqcUwnOkO8YnQdeqzakrg1Alpy/VQ7aqzIi8qypkBe2KXZz0A==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-expect-continue/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.378.0.tgz", - "integrity": "sha512-pHkcVTu2T+x/1fpPHMpRDpXY5zxDsjijv3C6Nz/nm3gQrZvQ3fYDrQdV3Oj6Xeg40B3kkcp/bzgDo7MDzG088A==", - "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@aws-crypto/crc32c": "3.0.0", - "@aws-sdk/types": "3.378.0", - "@smithy/is-array-buffer": "^2.0.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.620.0.tgz", + "integrity": "sha512-ftz+NW7qka2sVuwnnO1IzBku5ccP+s5qZGeRTPgrKB7OzRW85gthvIo1vQR2w+OwHFk7WJbbhhWwbCbktnP4UA==", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-sdk/types": "3.609.0", + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-flexible-checksums/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.379.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.379.1.tgz", - "integrity": "sha512-LI4KpAFWNWVr2aH2vRVblr0Y8tvDz23lj8LOmbDmCrzd5M21nxuocI/8nEAQj55LiTIf9Zs+dHCdsyegnFXdrA==", + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.620.0.tgz", + "integrity": "sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-host-header/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.379.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.379.1.tgz", - "integrity": "sha512-+bmy8DjX9jtqJk8WiDaHoP9M5ZcqjHSJf4mkv8IUZ/FNTUl9j6Dll//bG/JxuAw5e5shtCDjmZ027W5d9ITp0g==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.609.0.tgz", + "integrity": "sha512-xzsdoTkszGVqGVPjUmgoP7TORiByLueMHieI1fhQL888WPdqctwAx3ES6d/bA9Q/i8jnc6hs+Fjhy8UvBTkE9A==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-location-constraint/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.378.0.tgz", - "integrity": "sha512-l1DyaDLm3KeBMNMuANI3scWh8Xvu248x+vw6Z7ExWOhGXFmQ1MW7YvASg/SdxWkhlF9HmkkTif1LdMB22x6QDA==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", + "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-logger/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.378.0.tgz", - "integrity": "sha512-mUMfHAz0oGNIWiTZHTVJb+I515Hqs2zx1j36Le4MMiiaMkPW1SRUF1FIwGuc1wh6E8jB5q+XfEMriDjRi4TZRA==", + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.620.0.tgz", + "integrity": "sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.379.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.379.1.tgz", - "integrity": "sha512-NVHRpNLfkHCqr3CE1Bmlf8Fhys8lL78kDX7UONnTZXvSiSXmCS7EbNtGDghZ8IKi+V9S/ifB4sLsX3tfzY0i6Q==", - "dependencies": { - "@aws-sdk/types": "3.378.0", - "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.621.0.tgz", + "integrity": "sha512-CJrQrtKylcqvyPkRR16JmPZkHroCkWwLErQrg30ZcBPNNok8xbfX6cYqG16XDTnu4lSYzv2Yqc4w4oOBv8xerQ==", "dependencies": { - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/signature-v4": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-stream": "^3.1.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.379.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.379.1.tgz", - "integrity": "sha512-SK3gSyT0XbLiY12+AjLFYL9YngxOXHnZF3Z33Cdd4a+AUYrVBV7JBEEGD1Nlwrcmko+3XgaKlmgUaR5s91MYvg==", - "dependencies": { - "@aws-sdk/middleware-signing": "3.379.1", - "@aws-sdk/types": "3.378.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-sdk-sts/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.379.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.379.1.tgz", - "integrity": "sha512-kBk2ZUvR84EM4fICjr8K+Ykpf8SI1UzzPp2/UVYZ0X+4H/ZCjfSqohGRwHykMqeplne9qHSL7/rGJs1H3l3gPg==", - "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.0.2", - "@smithy/util-middleware": "^2.0.0", - "tslib": "^2.5.0" + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.620.0.tgz", + "integrity": "sha512-gxI7rubiaanUXaLfJ4NybERa9MGPNg2Ycl/OqANsozrBnR3Pw8vqy3EuVImQOyn2pJ2IFvl8ZPoSMHf4pX56FQ==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/signature-v4": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-signing/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.378.0.tgz", - "integrity": "sha512-WDT2LOd6OxlY1zkrRG9ZtW2vFms/dsqMg9VyE88RKG2oATxSXEhkr5zLbNVh3TyuUKnV9jydate56d/ECwHOHg==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.609.0.tgz", + "integrity": "sha512-GZSD1s7+JswWOTamVap79QiDaIV7byJFssBW68GYjyRS5EBjNfwA/8s+6uE6g39R3ojyTbYOmvcANoZEhSULXg==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-ssec/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.382.0.tgz", - "integrity": "sha512-LFRW1jmXOrOAd3911ktn6oaYmuurNnulbdRMOUdwz99GGdLVFipQhOi9idKswb8IOhPa4jEVQt25Kcv7ctvu0A==", - "dependencies": { - "@aws-sdk/types": "3.378.0", - "@aws-sdk/util-endpoints": "3.382.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.620.0.tgz", + "integrity": "sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/protocol-http": { @@ -995,38 +1127,58 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.378.0.tgz", - "integrity": "sha512-gtuABS7EeYZQeNzTrabY3Ruv4wWmoz4u8OMSGl47gYPDWA70WYEZ0aoi4zSGuKhXiqtVvTsO9wGEMIInwV5phQ==", - "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/protocol-http": "^2.0.1", - "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", + "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" }, - "peerDependencies": { - "@aws-sdk/signature-v4-crt": "^3.118.0" + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.621.0.tgz", + "integrity": "sha512-u+ulCaHFveqHaTxgiYrEAyfBVP6GRKjnmDut67CtjhjslshPWYpo/ndtlCW1zc0RDne3uUeK13Pqp7dp7p1d6g==", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.621.0", + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/signature-v4": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, - "peerDependenciesMeta": { - "@aws-sdk/signature-v4-crt": { - "optional": true - } + "engines": { + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/smithy-client": { @@ -1207,123 +1359,138 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.382.0.tgz", - "integrity": "sha512-axn4IyPpHdkXi8G06KCB3tPz79DipZFFH9N9YVDpLMnDYTdfX36HGdYzINaQc+z+XPbEpa1ZpoIzWScHRjFjdg==", - "dependencies": { - "@aws-sdk/client-sso-oidc": "3.382.0", - "@aws-sdk/types": "3.378.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", + "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.614.0" } }, "node_modules/@aws-sdk/token-providers/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.378.0.tgz", - "integrity": "sha512-qP0CvR/ItgktmN8YXpGQglzzR/6s0nrsQ4zIfx3HMwpsBTwuouYahcCtF1Vr82P4NFcoDA412EJahJ2pIqEd+w==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", + "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/types/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz", - "integrity": "sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==", + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.568.0.tgz", + "integrity": "sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.382.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.382.0.tgz", - "integrity": "sha512-flajPyjmjNG67fXk7l4GoTB/7J11VBqtFZXuuAZKhKU07Ia3IQupsFqNf5lV8D44ZgjnKH0fTGnv3dUALjW7Wg==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", + "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "@smithy/util-endpoints": "^2.0.5", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", - "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", + "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.378.0.tgz", - "integrity": "sha512-FSCpagzftK1W+m7Ar6lpX7/Gr9y5P56nhFYz8U4EYQ4PkufS6czWX9YW+/FA5OYV0vlQ/SvPqMnzoHIPUNhZrQ==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", + "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/types": "^2.0.2", + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", "bowser": "^2.11.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-browser/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.378.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.378.0.tgz", - "integrity": "sha512-IdwVJV0E96MkJeFte4dlWqvB+oiqCiZ5lOlheY3W9NynTuuX0GGYNC8Y9yIsV8Oava1+ujpJq0ww6qXdYxmO4A==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", + "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", "dependencies": { - "@aws-sdk/types": "3.378.0", - "@smithy/node-config-provider": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" }, "peerDependencies": { "aws-crt": ">=1.0.0" @@ -1335,33 +1502,37 @@ } }, "node_modules/@aws-sdk/util-user-agent-node/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "node_modules/@aws-sdk/xml-builder": { + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.609.0.tgz", + "integrity": "sha512-l9XxNcA4HX98rwCC2/KoiWcmEiRfZe4G+mYwDbCFT87JIMj6GBhLDkAzr/W8KAaA2IDr8Vc6J8fZPgVulxxfMA==", "dependencies": { - "tslib": "^2.3.1" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/xml-builder": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz", - "integrity": "sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==", + "node_modules/@aws-sdk/xml-builder/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@babel/runtime": { @@ -1664,18 +1835,6 @@ "uuid": "~9.0.0" } }, - "node_modules/@opentdf/client/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1699,687 +1858,749 @@ } }, "node_modules/@smithy/chunked-blob-reader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-2.0.0.tgz", - "integrity": "sha512-k+J4GHJsMSAIQPChGBrjEmGS+WbPonCXesoqP9fynIqjn7rdOThdH8FAeCmokP9mxTYKQAKoHCLPzNlm6gh7Wg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-3.0.0.tgz", + "integrity": "sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-2.0.0.tgz", - "integrity": "sha512-HM8V2Rp1y8+1343tkZUKZllFhEQPNmpNdgFAncbTsxkZ18/gqjk23XXv3qGyXWp412f3o43ZZ1UZHVcHrpRnCQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.0.tgz", + "integrity": "sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==", "dependencies": { - "@smithy/util-base64": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/config-resolver": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.1.tgz", - "integrity": "sha512-l83Pm7hV+8CBQOCmBRopWDtF+CURUJol7NsuPYvimiDhkC2F8Ba9T1imSFE+pD1UIJ9jlsDPAnZfPJT5cjnuEw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", + "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", "dependencies": { - "@smithy/types": "^2.0.2", - "@smithy/util-config-provider": "^2.0.0", - "@smithy/util-middleware": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/config-resolver/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.1.tgz", + "integrity": "sha512-BC7VMXx/1BCmRPCVzzn4HGWAtsrb7/0758EtwOGFJQrlSwJBEjCcDLNZLFoL/68JexYa2s+KmgL/UfmXdG6v1w==", + "dependencies": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/core/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/credential-provider-imds": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.1.tgz", - "integrity": "sha512-8VxriuRINNEfVZjEFKBY75y9ZWAx73DZ5K/u+3LmB6r8WR2h3NaFxFKMlwlq0uzNdGhD1ouKBn9XWEGYHKiPLw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz", + "integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==", "dependencies": { - "@smithy/node-config-provider": "^2.0.1", - "@smithy/property-provider": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/url-parser": "^2.0.1", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-codec": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.1.tgz", - "integrity": "sha512-/IiNB7gQM2y2ZC/GAWOWDa8+iXfhr1g9Xe5979cQEOdCWDISvrAiv18cn3OtIQUhbYOR3gm7QtCpkq1to2takQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.2.tgz", + "integrity": "sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==", "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.0.2", - "@smithy/util-hex-encoding": "^2.0.0", - "tslib": "^2.5.0" + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^3.3.0", + "@smithy/util-hex-encoding": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/eventstream-codec/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.1.tgz", - "integrity": "sha512-9E1/6ZGF7nB/Td3G1kcatU7VjjP8eZ/p/Q+0KsZc1AUPyv4lR15pmWnWj3iGBEGYI9qZBJ/7a/wPEPayabmA3Q==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.5.tgz", + "integrity": "sha512-dEyiUYL/ekDfk+2Ra4GxV+xNnFoCmk1nuIXg+fMChFTrM2uI/1r9AdiTYzPqgb72yIv/NtAj6C3dG//1wwgakQ==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/eventstream-serde-universal": "^3.0.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-browser/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.1.tgz", - "integrity": "sha512-J8a+8HH8oDPIgq8Px/nPLfu9vpIjQ7XUPtP3orbs8KUh0GznNthSTy1xZP5RXjRqGQEkxPvsHf1po2+QOsgNFw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.3.tgz", + "integrity": "sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-config-resolver/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.1.tgz", - "integrity": "sha512-wklowUz0zXJuqC7FMpriz66J8OAko3z6INTg+iMJWYB1bWv4pc5V7q36PxlZ0RKRbj0u+EThlozWgzE7Stz2Sw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.4.tgz", + "integrity": "sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/eventstream-serde-universal": "^3.0.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-node/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.1.tgz", - "integrity": "sha512-WPPylIgVZ6wOYVgpF0Rs1LlocYyj248MRtKEEehnDvC+0tV7wmGt7H/SchCh10W4y4YUxuzPlW+mUvVMGmLSVg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.4.tgz", + "integrity": "sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==", "dependencies": { - "@smithy/eventstream-codec": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/eventstream-codec": "^3.1.2", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-universal/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/fetch-http-handler": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.0.1.tgz", - "integrity": "sha512-/SoU/ClazgcdOxgE4zA7RX8euiELwpsrKCSvulVQvu9zpmqJRyEJn8ZTWYFV17/eHOBdHTs9kqodhNhsNT+cUw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", "dependencies": { - "@smithy/protocol-http": "^2.0.1", - "@smithy/querystring-builder": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/util-base64": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/fetch-http-handler/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/hash-blob-browser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.1.tgz", - "integrity": "sha512-i/o2+sHb4jDRz5nf2ilTTbC0nVmm4LO//FbODCAB7pbzMdywxbZ6z+q56FmEa8R+aFbtApxQ1SJ3umEiNz6IPg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.2.tgz", + "integrity": "sha512-hAbfqN2UbISltakCC2TP0kx4LqXBttEv2MqSPE98gVuDFMf05lU+TpC41QtqGP3Ff5A3GwZMPfKnEy0VmEUpmg==", "dependencies": { - "@smithy/chunked-blob-reader": "^2.0.0", - "@smithy/chunked-blob-reader-native": "^2.0.0", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/chunked-blob-reader": "^3.0.0", + "@smithy/chunked-blob-reader-native": "^3.0.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/hash-blob-browser/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/hash-node": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.1.tgz", - "integrity": "sha512-oTKYimQdF4psX54ZonpcIE+MXjMUWFxLCNosjPkJPFQ9whRX0K/PFX/+JZGRQh3zO9RlEOEUIbhy9NO+Wha6hw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", + "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", "dependencies": { - "@smithy/types": "^2.0.2", - "@smithy/util-buffer-from": "^2.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/hash-node/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/hash-stream-node": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.0.1.tgz", - "integrity": "sha512-AequnQdPRuXf4AuvvFlSjnkWI460xxhAd6y362gFtOE4jjJLLXblbMAXVFrkV8/pDMGNjpVegVSpRmHXZsbKhg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.1.2.tgz", + "integrity": "sha512-PBgDMeEdDzi6JxKwbfBtwQG9eT9cVwsf0dZzLXoJF4sHKHs5HEo/3lJWpn6jibfJwT34I1EBXpBnZE8AxAft6g==", "dependencies": { - "@smithy/types": "^2.0.2", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/hash-stream-node/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/invalid-dependency": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.1.tgz", - "integrity": "sha512-2q/Eb0AE662zwyMV+z+TL7deBwcHCgaZZGc0RItamBE8kak3MzCi/EZCNoFWoBfxgQ4jfR12wm8KKsSXhJzJtQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", + "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/invalid-dependency/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/is-array-buffer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz", - "integrity": "sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/md5-js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.0.1.tgz", - "integrity": "sha512-8WWOtwWMmIDgTkRv1o3opy3ABsRXs4/XunETK53ckxQRAiOML1PlnqLBK9Uwk9bvOD6cpmsC6dioIfmKGpJ25w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.3.tgz", + "integrity": "sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==", "dependencies": { - "@smithy/types": "^2.0.2", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/md5-js/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-content-length": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.1.tgz", - "integrity": "sha512-IZhRSk5GkVBcrKaqPXddBS2uKhaqwBgaSgbBb1OJyGsKe7SxRFbclWS0LqOR9fKUkDl+3lL8E2ffpo6EQg0igw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz", + "integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==", "dependencies": { - "@smithy/protocol-http": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-content-length/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-endpoint": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.1.tgz", - "integrity": "sha512-uz/KI1MBd9WHrrkVFZO4L4Wyv24raf0oR4EsOYEeG5jPJO5U+C7MZGLcMxX8gWERDn1sycBDqmGv8fjUMLxT6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz", + "integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==", "dependencies": { - "@smithy/middleware-serde": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/url-parser": "^2.0.1", - "@smithy/util-middleware": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/middleware-serde": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-endpoint/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.1.tgz", - "integrity": "sha512-NKHF4i0gjSyjO6C0ZyjEpNqzGgIu7s8HOK6oT/1Jqws2Q1GynR1xV8XTUs1gKXeaNRzbzKQRewHHmfPwZjOtHA==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.13.tgz", + "integrity": "sha512-zvCLfaRYCaUmjbF2yxShGZdolSHft7NNCTA28HVN9hKcEbOH+g5irr1X9s+in8EpambclGnevZY4A3lYpvDCFw==", "dependencies": { - "@smithy/protocol-http": "^2.0.1", - "@smithy/service-error-classification": "^2.0.0", - "@smithy/types": "^2.0.2", - "@smithy/util-middleware": "^2.0.0", - "@smithy/util-retry": "^2.0.0", - "tslib": "^2.5.0", - "uuid": "^8.3.2" + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/service-error-classification": "^3.0.3", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "tslib": "^2.6.2", + "uuid": "^9.0.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-retry/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-serde": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.1.tgz", - "integrity": "sha512-uKxPaC6ItH9ZXdpdqNtf8sda7GcU4SPMp0tomq/5lUg9oiMa/Q7+kD35MUrpKaX3IVXVrwEtkjCU9dogZ/RAUA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", + "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-serde/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-stack": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.0.tgz", - "integrity": "sha512-31XC1xNF65nlbc16yuh3wwTudmqs6qy4EseQUGF8A/p2m/5wdd/cnXJqpniy/XvXVwkHPz/GwV36HqzHtIKATQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", + "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", "dependencies": { - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-stack/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/node-config-provider": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.0.1.tgz", - "integrity": "sha512-Zoel4CPkKRTQ2XxmozZUfqBYqjPKL53/SvTDhJHj+VBSiJy6MXRav1iDCyFPS92t40Uh+Yi+Km5Ch3hQ+c/zSA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", + "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", "dependencies": { - "@smithy/property-provider": "^2.0.1", - "@smithy/shared-ini-file-loader": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/node-config-provider/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/node-http-handler": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.0.1.tgz", - "integrity": "sha512-Zv3fxk3p9tsmPT2CKMsbuwbbxnq2gzLDIulxv+yI6aE+02WPYorObbbe9gh7SW3weadMODL1vTfOoJ9yFypDzg==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz", + "integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==", "dependencies": { - "@smithy/abort-controller": "^2.0.1", - "@smithy/protocol-http": "^2.0.1", - "@smithy/querystring-builder": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/abort-controller": "^3.1.1", + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/node-http-handler/node_modules/@smithy/abort-controller": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.1.tgz", - "integrity": "sha512-0s7XjIbsTwZyUW9OwXQ8J6x1UiA1TNCh60Vaw56nHahL7kUZsLhmTlWiaxfLkFtO2Utkj8YewcpHTYpxaTzO+w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", + "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/node-http-handler/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/property-provider": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.1.tgz", - "integrity": "sha512-pmJRyY9SF6sutWIktIhe+bUdSQDxv/qZ4mYr3/u+u45riTPN7nmRxPo+e4sjWVoM0caKFjRSlj3tf5teRFy0Vg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", + "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/property-provider/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/protocol-http": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-2.0.1.tgz", - "integrity": "sha512-mrkMAp0wtaDEIkgRObWYxI1Kun1tm6Iu6rK+X4utb6Ah7Uc3Kk4VIWwK/rBHdYGReiLIrxFCB1rq4a2gyZnSgg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/protocol-http/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/querystring-builder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.1.tgz", - "integrity": "sha512-bp+93WFzx1FojVEIeFPtG0A1pKsFdCUcZvVdZdRlmNooOUrz9Mm9bneRd8hDwAQ37pxiZkCOxopSXXRQN10mYw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", "dependencies": { - "@smithy/types": "^2.0.2", - "@smithy/util-uri-escape": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/querystring-builder/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/querystring-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.1.tgz", - "integrity": "sha512-h+e7k1z+IvI2sSbUBG9Aq46JsgLl4UqIUl6aigAlRBj+P6ocNXpM6Yn1vMBw5ijtXeZbYpd1YvCxwDgdw3jhmg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", + "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/querystring-parser/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/service-error-classification": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.0.tgz", - "integrity": "sha512-2z5Nafy1O0cTf69wKyNjGW/sNVMiqDnb4jgwfMG8ye8KnFJ5qmJpDccwIbJNhXIfbsxTg9SEec2oe1cexhMJvw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", + "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", + "dependencies": { + "@smithy/types": "^3.3.0" + }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/service-error-classification/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.1.tgz", - "integrity": "sha512-a463YiZrPGvM+F336rIF8pLfQsHAdCRAn/BiI/EWzg5xLoxbC7GSxIgliDDXrOu0z8gT3nhVsif85eU6jyct3A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", + "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/shared-ini-file-loader/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/signature-v4": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.1.tgz", - "integrity": "sha512-jztv5Mirca42ilxmMDjzLdXcoAmRhZskGafGL49sRo5u7swEZcToEFrq6vtX5YMbSyTVrE9Teog5EFexY5Ff2Q==", - "dependencies": { - "@smithy/eventstream-codec": "^2.0.1", - "@smithy/is-array-buffer": "^2.0.0", - "@smithy/types": "^2.0.2", - "@smithy/util-hex-encoding": "^2.0.0", - "@smithy/util-middleware": "^2.0.0", - "@smithy/util-uri-escape": "^2.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz", + "integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/signature-v4/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/smithy-client": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.0.1.tgz", - "integrity": "sha512-LHC5m6tYpEu1iNbONfvMbwtErboyTZJfEIPoD78Ei5MVr36vZQCaCla5mvo36+q/a2NAk2//fA5Rx3I1Kf7+lQ==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.11.tgz", + "integrity": "sha512-l0BpyYkciNyMaS+PnFFz4aO5sBcXvGLoJd7mX9xrMBIm2nIQBVvYgp2ZpPDMzwjKCavsXu06iuCm0F6ZJZc6yQ==", "dependencies": { - "@smithy/middleware-stack": "^2.0.0", - "@smithy/types": "^2.0.2", - "@smithy/util-stream": "^2.0.1", - "tslib": "^2.5.0" + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/smithy-client/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/types": { @@ -2394,252 +2615,303 @@ } }, "node_modules/@smithy/url-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.1.tgz", - "integrity": "sha512-NpHVOAwddo+OyyIoujDL9zGL96piHWrTNXqltWmBvlUoWgt1HPyBuKs6oHjioyFnNZXUqveTOkEEq0U5w6Uv8A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", + "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", "dependencies": { - "@smithy/querystring-parser": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/querystring-parser": "^3.0.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/url-parser/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-base64": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.0.0.tgz", - "integrity": "sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", "dependencies": { - "@smithy/util-buffer-from": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-body-length-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz", - "integrity": "sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@smithy/util-body-length-node": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.0.0.tgz", - "integrity": "sha512-ZV7Z/WHTMxHJe/xL/56qZwSUcl63/5aaPAGjkfynJm4poILjdD4GmFI+V+YWabh2WJIjwTKZ5PNsuvPQKt93Mg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-buffer-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz", - "integrity": "sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", "dependencies": { - "@smithy/is-array-buffer": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-config-provider": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz", - "integrity": "sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.1.tgz", - "integrity": "sha512-w72Qwsb+IaEYEFtYICn0Do42eFju78hTaBzzJfT107lFOPdbjWjKnFutV+6GL/nZd5HWXY7ccAKka++C3NrjHw==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.13.tgz", + "integrity": "sha512-ZIRSUsnnMRStOP6OKtW+gCSiVFkwnfQF2xtf32QKAbHR6ACjhbAybDvry+3L5qQYdh3H6+7yD/AiUE45n8mTTw==", "dependencies": { - "@smithy/property-provider": "^2.0.1", - "@smithy/types": "^2.0.2", + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", "bowser": "^2.11.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.1.tgz", - "integrity": "sha512-dNF45caelEBambo0SgkzQ0v76m4YM+aFKZNTtSafy7P5dVF8TbjZuR2UX1A5gJABD9XK6lzN+v/9Yfzj/EDgGg==", - "dependencies": { - "@smithy/config-resolver": "^2.0.1", - "@smithy/credential-provider-imds": "^2.0.1", - "@smithy/node-config-provider": "^2.0.1", - "@smithy/property-provider": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.13.tgz", + "integrity": "sha512-voUa8TFJGfD+U12tlNNLCDlXibt9vRdNzRX45Onk/WxZe7TS+hTOZouEZRa7oARGicdgeXvt1A0W45qLGYdy+g==", + "dependencies": { + "@smithy/config-resolver": "^3.0.5", + "@smithy/credential-provider-imds": "^3.2.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.11", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", + "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-endpoints/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/util-hex-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz", - "integrity": "sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-middleware": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.0.tgz", - "integrity": "sha512-eCWX4ECuDHn1wuyyDdGdUWnT4OGyIzV0LN1xRttBFMPI9Ff/4heSHVxneyiMtOB//zpXWCha1/SWHJOZstG7kA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", + "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", "dependencies": { - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-middleware/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/util-retry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.0.tgz", - "integrity": "sha512-/dvJ8afrElasuiiIttRJeoS2sy8YXpksQwiM/TcepqdRVp7u4ejd9C4IQURHNjlfPUT7Y6lCDSa2zQJbdHhVTg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", + "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", "dependencies": { - "@smithy/service-error-classification": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/service-error-classification": "^3.0.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-retry/node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/util-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.1.tgz", - "integrity": "sha512-2a0IOtwIKC46EEo7E7cxDN8u2jwOiYYJqcFKA6rd5rdXqKakHT2Gc+AqHWngr0IEHUfW92zX12wRQKwyoqZf2Q==", - "dependencies": { - "@smithy/fetch-http-handler": "^2.0.1", - "@smithy/node-http-handler": "^2.0.1", - "@smithy/types": "^2.0.2", - "@smithy/util-base64": "^2.0.0", - "@smithy/util-buffer-from": "^2.0.0", - "@smithy/util-hex-encoding": "^2.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz", + "integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==", + "dependencies": { + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-stream/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-uri-escape": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz", - "integrity": "sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-utf8": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.0.tgz", - "integrity": "sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", "dependencies": { - "@smithy/util-buffer-from": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-waiter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.1.tgz", - "integrity": "sha512-bSyGFicPRYuGFFWAr72UvYI7tE7KmEeFJJ5iaLuTTdo8RGaNBZ2kE25coGtzrejYh9AhwSfckBvbxgEDxIxhlA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.2.tgz", + "integrity": "sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==", "dependencies": { - "@smithy/abort-controller": "^2.0.1", - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/abort-controller": "^3.1.1", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-waiter/node_modules/@smithy/abort-controller": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.1.tgz", - "integrity": "sha512-0s7XjIbsTwZyUW9OwXQ8J6x1UiA1TNCh60Vaw56nHahL7kUZsLhmTlWiaxfLkFtO2Utkj8YewcpHTYpxaTzO+w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", + "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", "dependencies": { - "@smithy/types": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-waiter/node_modules/@smithy/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz", - "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@tsconfig/node10": { @@ -3628,17 +3900,17 @@ "dev": true }, "node_modules/fast-xml-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", - "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" } ], "dependencies": { @@ -5332,9 +5604,9 @@ } }, "node_modules/tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/type-check": { "version": "0.4.0", @@ -5380,9 +5652,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } From c2121ca13a7932051c9435b99c9d43173c7cab5d Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 5 Aug 2024 09:50:59 -0400 Subject: [PATCH 08/42] ci(make): Fix directly building cli from checkout (#317) --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5ad88eb3..409f19db 100644 --- a/Makefile +++ b/Makefile @@ -24,13 +24,13 @@ i: all: ci lib/opentdf-client-$(version).tgz remote-store/opentdf-remote-store-$(version).tgz web-app/opentdf-web-app-$(version).tgz cli/opentdf-cli-$(version).tgz: lib/opentdf-client-$(version).tgz $(shell find cli -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') - (cd cli && npm ci ../lib/opentdf-client-$(version).tgz && npm pack) + (cd cli && npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-$(version).tgz && npm pack) remote-store/opentdf-remote-store-$(version).tgz: lib/opentdf-client-$(version).tgz $(shell find remote-store -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') - (cd remote-store && npm ci ../lib/opentdf-client-$(version).tgz && npm pack) + (cd remote-store && npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-$(version).tgz && npm pack) web-app/opentdf-web-app-$(version).tgz: lib/opentdf-client-$(version).tgz $(shell find web-app -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') - (cd web-app && npm ci ../lib/opentdf-client-$(version).tgz && npm pack && npm run build) + (cd web-app && npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-$(version).tgz && npm pack && npm run build) lib/opentdf-client-$(version).tgz: $(shell find lib -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') (cd lib && npm ci --including=dev && npm pack) From 7d9b13064dc470280d3f4cbfa0a529c13469e2c4 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 5 Aug 2024 16:39:38 -0400 Subject: [PATCH 09/42] refactor(cli): cleanup of aliases (#316) standardize on camelCase for cli option names (while still supporting existing names with aliases) --- .github/workflows/build.yaml | 3 ++- cli/src/cli.ts | 18 ++++++++++-------- remote-store/tests/index.test.ts | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6f8fe1d3..2469388c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -138,10 +138,11 @@ jobs: path: lib/ - run: npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-*.tgz - run: npm install - - run: npm test - run: npm audit --omit dev && npm audit --audit-level high --omit dev - run: npm run license-check - run: npm run lint + - run: npx playwright install + - run: npm test - run: npm pack scripts: diff --git a/cli/src/cli.ts b/cli/src/cli.ts index cb315568..2a596133 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -95,8 +95,8 @@ function addParams(client: AnyNanoClient, argv: Partial) { if (argv.attributes?.length) { client.dataAttributes = argv.attributes.split(','); } - if (argv['users-with-access']?.length) { - client.dissems = argv['users-with-access'].split(','); + if (argv.usersWithAccess?.length) { + client.dissems = argv.usersWithAccess.split(','); } log('SILLY', `Built encrypt params dissems: ${client.dissems}, attrs: ${client.dataAttributes}`); } @@ -112,8 +112,8 @@ async function tdf3EncryptParamsFor(argv: Partial): Promise { .middleware((argv) => { if (argv.silent) { log.level = 'CRITICAL'; - } else if (argv['log-level']) { - const ll = argv['log-level'] as string; + } else if (argv.logLevel) { + const ll = argv.logLevel as string; log.level = ll.toUpperCase() as Level; } }) @@ -230,7 +230,8 @@ export const handleArgs = (args: string[]) => { // POLICY .options({ - 'users-with-access': { + usersWithAccess: { + alias: 'users-with-access', group: 'Policy Options', desc: 'Add users to the policy', type: 'string', @@ -248,7 +249,8 @@ export const handleArgs = (args: string[]) => { // COMMANDS .options({ - 'log-level': { + logLevel: { + alias: 'log-level', type: 'string', default: 'info', desc: 'Set logging level', diff --git a/remote-store/tests/index.test.ts b/remote-store/tests/index.test.ts index 5944cca8..fc573b7c 100644 --- a/remote-store/tests/index.test.ts +++ b/remote-store/tests/index.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@esm-bundle/chai'; +import { expect } from 'chai'; import { setRemoteStoreAsStream } from '../src/index.js'; From ac1f634df2db559f895ac1317dad8c5af14da680 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Thu, 8 Aug 2024 13:34:42 -0400 Subject: [PATCH 10/42] fix(client): Normalize allowlist to origins (#321) --- cli/package-lock.json | 26 +++++++++++++------------- lib/tdf3/src/client/index.ts | 7 ++++--- lib/tdf3/src/tdf.ts | 4 +++- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index f0b45cac..b78af2d8 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -36,9 +36,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -371,7 +371,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-9vExrKuqDY1CHmyy2Z7umlwZRFSI08JjkStzkkTrKRF91hEcBEHRvthuFIplNyX5NRZ85i8AXJCcCoDZLgshsg==", + "integrity": "sha512-C+R3AaydaZH21ODyr/DiMtmydWsyqjurecc8+Ai8jRwVyn3Cel+jGinu7rda1rPIBx1mOgkDg7HYdt3QKcZ8SA==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -877,9 +877,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", + "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1256,9 +1256,9 @@ } }, "node_modules/dpop": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.0.tgz", - "integrity": "sha512-r//f6g3uaDdomkz+3M0NdcEAxSGUVMIhF7lxf06aJZjCFhkH//GeZo6JWpz7Uv025s1w/+M5RDNRGxAGNIzm0g==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", + "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2023,9 +2023,9 @@ } }, "node_modules/jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", "funding": { "url": "https://github.com/sponsors/panva" } diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index bcfc5f07..44b53a27 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -271,9 +271,10 @@ export class Client { this.kasEndpoint = clientConfig.keyRewrapEndpoint.replace(/\/rewrap$/, ''); } + const kasOrigin = new URL(this.kasEndpoint).origin; if (clientConfig.allowedKases) { - this.allowedKases = [...clientConfig.allowedKases]; - if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.includes(this.kasEndpoint)) { + this.allowedKases = clientConfig.allowedKases.map((a) => new URL(a).origin); + if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.includes(kasOrigin)) { throw new TdfError(`Invalid KAS endpoint [${this.kasEndpoint}]`); } this.allowedKases.forEach(validateSecureUrl); @@ -283,7 +284,7 @@ export class Client { `Invalid KAS endpoint [${this.kasEndpoint}]; to force, please list it among allowedKases` ); } - this.allowedKases = [this.kasEndpoint]; + this.allowedKases = [kasOrigin]; } this.authProvider = config.authProvider; diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index a41d5638..0db40f71 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -145,6 +145,7 @@ export type EncryptConfiguration = { }; export type DecryptConfiguration = { + // Normalized KAS origins to connect to allowedKases: string[]; authProvider: AuthProvider | AppIdAuthProvider; cryptoService: CryptoService; @@ -824,7 +825,8 @@ async function unwrapKey({ // Get key access information to know the KAS URLS const rewrappedKeys = await Promise.all( keyAccess.map(async (keySplitInfo) => { - if (!allowedKases.includes(keySplitInfo.url)) { + const kaoOrigin = new URL(keySplitInfo.url).origin; + if (!allowedKases.includes(kaoOrigin)) { throw new UnsafeUrlError( `cannot decrypt TDF: [${keySplitInfo.url}] not on allowlist ${JSON.stringify( allowedKases From fe0f66321e21cecd29d2223ff955884d6c8dd0b6 Mon Sep 17 00:00:00 2001 From: Paul Flynn <43211074+pflynn-virtru@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:52:11 -0400 Subject: [PATCH 11/42] Refactor protocol assignment in getUrl method (#322) Refactor the protocol determination logic to use bitwise operations for extracting protocol index. This change simplifies the code by directly using the lower four bits of the protocol to check for HTTP or HTTPS. Additionally, enhanced the error message formatting for better readability. --- lib/src/nanotdf/models/ResourceLocator.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index 772251ed..a7f5461a 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -106,13 +106,15 @@ export default class ResourceLocator { * Construct URL from ResourceLocator or throw error */ getUrl(): string | never { - let protocol; - if (this.protocol === ProtocolEnum.Http) { + let protocol: string; + // protocolIndex get the first four bits + const protocolIndex: number = this.protocol & 0xf; + if (protocolIndex === ProtocolEnum.Http) { protocol = 'http'; - } else if (this.protocol === ProtocolEnum.Https) { + } else if (protocolIndex === ProtocolEnum.Https) { protocol = 'https'; } else { - throw new Error(`Cannot create URL from protocol, ${ProtocolEnum[this.protocol]}`); + throw new Error(`Cannot create URL from protocol, "${ProtocolEnum[this.protocol]}"`); } return `${protocol}://${this.body}`; From 536c528b050fdc198717fa8476b576f3b05cb6a8 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 12 Aug 2024 10:54:02 -0400 Subject: [PATCH 12/42] chore(cli): Adds mimeType option (#323) this matches the go command line tool --- cli/src/cli.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cli/src/cli.ts b/cli/src/cli.ts index 2a596133..46e78f2b 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -115,6 +115,9 @@ async function tdf3EncryptParamsFor(argv: Partial): Promise { .options({ usersWithAccess: { alias: 'users-with-access', - group: 'Policy Options', + group: 'Encrypt Options', desc: 'Add users to the policy', type: 'string', default: '', validate: (users: string) => users.split(','), }, attributes: { - group: 'Policy Options', + group: 'Encrypt Options', desc: 'Data attributes for the policy', type: 'string', default: '', validate: (attributes: string) => attributes.split(','), }, + mimeType: { + group: 'Encrypt Options', + desc: 'Mime type for the plain text file (only supported for ztdf)', + type: 'string', + default: '', + }, }) // COMMANDS From 6d01eff5bdf2f9fde688b3dab4e57470fb255c88 Mon Sep 17 00:00:00 2001 From: Paul Flynn <43211074+pflynn-virtru@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:27:44 -0400 Subject: [PATCH 13/42] feat(core): KID in NanoTDF (#325) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Squashed commit of the following: commit e4d19e21036413c17b1d01303d893f6a8bfb95ad Author: Paul Flynn Date: Thu Aug 15 16:38:37 2024 -0400 Refactor ResourceLocator identifier handling Streamline the identifier extraction by removing padding bytes before decoding. This change accounts for null byte padding that was previously being included in the identifier, ensuring cleaner and more accurate decoding. commit 0b587f6cc213c1248652531b7d50a954201358fa Author: pflynn-virtru Date: Thu Aug 15 19:46:19 2024 +0000 🤖 🎨 Autoformat Signed-off-by: Paul Flynn commit 47fcabadbde4f8433284b843b827d7ee88193f89 Author: Paul Flynn Date: Thu Aug 15 15:44:39 2024 -0400 Add tests for ResourceLocator identifier parsing Included new test cases to verify the parsing logic of the ResourceLocator identifiers in different byte formats such as two bytes, eight bytes, and thirty-two bytes. This ensures that the identifier type and value are correctly parsed and validated. commit aa8a011f34f7a73190e975c4c80116ef09f6c104 Author: Paul Flynn Date: Thu Aug 15 14:25:26 2024 -0400 Update buffer allocation in toBuffer method Changed the allocation of the buffer to use identifierType.valueOf() instead of this.identifier.length. This ensures accurate buffer sizing based on the identifier type's value. Signed-off-by: Paul Flynn commit b216fbdccfeab2e1d2a4cc96169d66ce738b95e0 Author: Paul Flynn Date: Thu Aug 15 14:19:47 2024 -0400 Update buffer allocation in toBuffer method Changed the allocation of the buffer to use identifierType.valueOf() instead of this.identifier.length. This ensures accurate buffer sizing based on the identifier type's value. commit bcef48d4145fc500391025a93dca24875265a4e5 Author: Paul Flynn Date: Thu Aug 15 14:11:32 2024 -0400 Set default identifierType to None in ResourceLocator Initialized `identifierType` to `ResourceLocatorIdentifierEnum.None` by default in the `ResourceLocator` model. Removed redundant assignment in constructor and adjusted identifier length calculation accordingly. Signed-off-by: Paul Flynn commit 3ef76702990c63f485c9c09d6c85467312d08eb5 Author: pflynn-virtru Date: Thu Aug 15 18:08:15 2024 +0000 🤖 🎨 Autoformat commit a5958c4aeeb97bd9f4d716bbd37eec990d6c8459 Author: Paul Flynn Date: Thu Aug 15 14:06:17 2024 -0400 Refactor identifier type initialization in ResourceLocator Initialize `identifierType` to `None` explicitly before evaluating the protocol nibble. This simplifies the conditional logic by setting a default value upfront and adjusting it only when specific conditions are met. commit a83e22db4c49d170ebf0242574cf4a072fd74c48 Author: Paul Flynn Date: Thu Aug 15 14:01:19 2024 -0400 Fix identifier type detection in ResourceLocator.ts Corrected the bitwise operation for identifier type nibble check to accurately detect the 'None' type. Also removed an outdated TODO comment related to padding in identifier decoding. commit 8262fbd8308606ff97d6188e0d214c29ae59186f Author: pflynn-virtru Date: Thu Aug 15 17:23:36 2024 +0000 🤖 🎨 Autoformat Signed-off-by: Paul Flynn commit d4b53d05c9c6ffc42c83bd49cd624fb98449523c Author: Paul Flynn Date: Thu Aug 15 13:19:22 2024 -0400 Add identifier handling to ResourceLocator Introduces a new enum for identifier length and modifies the ResourceLocator class to include this identifier and its encoding/decoding logic. This enhances the resource locator functionality by supporting identifiers of varying lengths. * Update kasUrl to accept ResourceLocator type Modified the `encrypt` function to allow `kasUrl` parameter to accept either a string or a `ResourceLocator` type, enhancing flexibility. Added type checks and adjusted usage of `ResourceLocator` accordingly. --- cli/package-lock.json | 66 ++++++--- lib/package-lock.json | 62 +++++---- lib/src/nanotdf/encrypt.ts | 14 +- lib/src/nanotdf/enum/ProtocolEnum.ts | 7 +- .../enum/ResourceLocatorIdentifierEnum.ts | 8 ++ lib/src/nanotdf/models/ResourceLocator.ts | 102 +++++++++++--- .../nanotdf/ntdf-spec-basic-example.test.ts | 18 ++- remote-store/package-lock.json | 55 +++++--- web-app/package-lock.json | 126 ++++++++++++------ 9 files changed, 324 insertions(+), 134 deletions(-) create mode 100644 lib/src/nanotdf/enum/ResourceLocatorIdentifierEnum.ts diff --git a/cli/package-lock.json b/cli/package-lock.json index b78af2d8..fe0b171c 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -39,6 +39,7 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -371,7 +372,8 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-C+R3AaydaZH21ODyr/DiMtmydWsyqjurecc8+Ai8jRwVyn3Cel+jGinu7rda1rPIBx1mOgkDg7HYdt3QKcZ8SA==", + "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", + "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -874,12 +876,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -890,6 +894,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -918,7 +923,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -942,12 +948,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -956,7 +963,8 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", + "license": "Apache-2.0" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -982,6 +990,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -991,6 +1000,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } @@ -1134,6 +1144,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1218,6 +1229,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1259,6 +1271,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1473,7 +1486,8 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -1543,10 +1557,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "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", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1609,6 +1624,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1638,6 +1654,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1843,7 +1860,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.1", @@ -1953,6 +1971,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -1979,6 +1998,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -2026,6 +2046,7 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2222,6 +2243,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2230,6 +2252,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -2635,7 +2658,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", @@ -2746,7 +2770,8 @@ "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==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", @@ -3030,7 +3055,8 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ] + ], + "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", @@ -3119,6 +3145,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -3268,6 +3295,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } diff --git a/lib/package-lock.json b/lib/package-lock.json index 85bb2af5..7fd7f565 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -67,12 +67,13 @@ } }, "node_modules/@75lb/deep-merge": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", - "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.2.tgz", + "integrity": "sha512-08K9ou5VNbheZFxM5tDWoqjA3ImC50DiuuJ2tj1yEPRfkp8lLLg6XAaJ4On+a0yAXor/8ay5gHnAIshRM44Kpw==", "dev": true, + "license": "MIT", "dependencies": { - "lodash.assignwith": "^4.2.0", + "lodash": "^4.17.21", "typical": "^7.1.1" }, "engines": { @@ -2481,10 +2482,12 @@ } }, "node_modules/axios": { - "version": "1.6.1", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -3746,7 +3749,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.0", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", "dev": true, "license": "MIT", "dependencies": { @@ -3758,15 +3763,17 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.1.0", - "ws": "~8.11.0" + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/engine.io-parser": { - "version": "5.1.0", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, "license": "MIT", "engines": { @@ -3774,7 +3781,9 @@ } }, "node_modules/engine.io/node_modules/ws": { - "version": "8.11.0", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "license": "MIT", "engines": { @@ -3782,7 +3791,7 @@ }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -6118,7 +6127,9 @@ } }, "node_modules/jsdom/node_modules/ws": { - "version": "8.13.0", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "license": "MIT", "engines": { @@ -6691,12 +6702,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.assignwith": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", - "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==", - "dev": true - }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -8941,15 +8946,20 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.2", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, "license": "MIT", "dependencies": { - "ws": "~8.11.0" + "debug": "~4.3.4", + "ws": "~8.17.1" } }, "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.11.0", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "license": "MIT", "engines": { @@ -8957,7 +8967,7 @@ }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -10232,7 +10242,9 @@ } }, "node_modules/ws": { - "version": "7.5.9", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "license": "MIT", "engines": { diff --git a/lib/src/nanotdf/encrypt.ts b/lib/src/nanotdf/encrypt.ts index e87769a6..2c5d0db1 100644 --- a/lib/src/nanotdf/encrypt.ts +++ b/lib/src/nanotdf/encrypt.ts @@ -20,15 +20,16 @@ import { * Encrypt the plain data into nanotdf buffer * * @param policy Policy that will added to the nanotdf - * @param kasPubCrtAsPem KAS public crt in pem format - * @param kasUrl KAS url as string + * @param kasPub + * @param kasUrl KAS url as string or ResourceLocator * @param ephemeralKeyPair SDK ephemeral key pair to generate symmetric key + * @param iv * @param data The data to be encrypted */ export default async function encrypt( policy: string, kasPub: CryptoKey, - kasUrl: string, + kasUrl: string | ResourceLocator, ephemeralKeyPair: CryptoKeyPair, iv: Uint8Array, data: string | TypedArray | ArrayBuffer @@ -45,7 +46,12 @@ export default async function encrypt( ); // Construct the kas locator - const kasResourceLocator = ResourceLocator.parse(kasUrl); + let kasResourceLocator; + if (kasUrl instanceof ResourceLocator) { + kasResourceLocator = kasUrl; + } else { + kasResourceLocator = ResourceLocator.parse(kasUrl); + } // Auth tag length for policy and payload const authTagLengthInBytes = authTagLengthForCipher(DefaultParams.symmetricCipher) / 8; diff --git a/lib/src/nanotdf/enum/ProtocolEnum.ts b/lib/src/nanotdf/enum/ProtocolEnum.ts index 7ce880f3..9295fee7 100644 --- a/lib/src/nanotdf/enum/ProtocolEnum.ts +++ b/lib/src/nanotdf/enum/ProtocolEnum.ts @@ -1,8 +1,7 @@ enum ProtocolEnum { - Http, - Https, - Unreserverd, - SharedResourceDirectory = 0xff, + Http = 0, + Https = 1, + SharedResourceDirectory = 0xf, } export default ProtocolEnum; diff --git a/lib/src/nanotdf/enum/ResourceLocatorIdentifierEnum.ts b/lib/src/nanotdf/enum/ResourceLocatorIdentifierEnum.ts new file mode 100644 index 00000000..b6fc37c3 --- /dev/null +++ b/lib/src/nanotdf/enum/ResourceLocatorIdentifierEnum.ts @@ -0,0 +1,8 @@ +enum ResourceLocatorIdentifierEnum { + None = 0, + TwoBytes = 2, + EightBytes = 8, + ThirtyTwoBytes = 32, +} + +export default ResourceLocatorIdentifierEnum; diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index a7f5461a..ef635963 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -1,4 +1,5 @@ import ProtocolEnum from '../enum/ProtocolEnum.js'; +import ResourceLocatorIdentifierEnum from '../enum/ResourceLocatorIdentifierEnum.js'; /** * @@ -10,6 +11,7 @@ import ProtocolEnum from '../enum/ProtocolEnum.js'; * | Protocol Enum | 1 | 1 | * | Body Length | 1 | 1 | * | Body | 1 | 255 | + * | Identifier | 0 | n | * * @link https://github.com/virtru/nanotdf/blob/master/spec/index.md#3312-kas * @link https://github.com/virtru/nanotdf/blob/master/spec/index.md#341-resource-locator @@ -18,6 +20,8 @@ export default class ResourceLocator { readonly protocol: ProtocolEnum; readonly lengthOfBody: number; readonly body: string; + readonly identifier: string; + readonly identifierType: ResourceLocatorIdentifierEnum = ResourceLocatorIdentifierEnum.None; readonly offset: number = 0; static readonly PROTOCOL_OFFSET = 0; @@ -26,39 +30,90 @@ export default class ResourceLocator { static readonly LENGTH_LENGTH = 1; static readonly BODY_OFFSET = 2; - static parse(url: string): ResourceLocator { + static parse(url: string, identifier: string = ''): ResourceLocator { const [protocol, body] = url.split('://'); - - // Buffer to hold the protocol, length of body, body - const buffer = new Uint8Array(1 + 1 + body.length); - buffer.set([body.length], 1); - buffer.set(new TextEncoder().encode(body), 2); - + const bodyLength = body.length; + const identifierLength = identifier.length; + let identifierPaddedLength = 0; + // protocol and identifier byte + const protocolIdentifierByte = new Uint8Array(1); if (protocol.toLowerCase() == 'http') { - buffer.set([ProtocolEnum.Http], 0); + protocolIdentifierByte[0] = protocolIdentifierByte[0] & 0x0f; } else if (protocol.toLowerCase() == 'https') { - buffer.set([ProtocolEnum.Https], 0); + protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0x0f) | 0b0010; } else { throw new Error('Resource locator protocol is not supported.'); } - + if (identifierLength === 0) { + protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b0000; + } else if (identifierLength <= 2) { + protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b0010; + identifierPaddedLength = ResourceLocatorIdentifierEnum.TwoBytes.valueOf(); + } else if (identifierLength <= 8) { + protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b0100; + identifierPaddedLength = ResourceLocatorIdentifierEnum.EightBytes.valueOf(); + } else if (identifierLength <= 32) { + protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b1000; + identifierPaddedLength = ResourceLocatorIdentifierEnum.ThirtyTwoBytes.valueOf(); + } else { + throw new Error('Unsupported identifier length: ' + identifierLength); + } + // Buffer to hold the protocol, length of body, body, and identifierPadded + const buffer = new Uint8Array(1 + 1 + bodyLength + identifierPaddedLength); + buffer.set(protocolIdentifierByte, 0); + buffer.set([bodyLength], 1); + buffer.set(new TextEncoder().encode(body), 2); + // add padded identifier + if (identifierPaddedLength > 0) { + const identifierArray = new Uint8Array(identifierPaddedLength); + const encodedIdentifier = new TextEncoder() + .encode(identifier) + .subarray(0, identifierPaddedLength); + identifierArray.set(encodedIdentifier); + buffer.set(identifierArray, 2 + bodyLength); + } return new ResourceLocator(buffer); } constructor(buff: Uint8Array) { // Protocol this.protocol = buff[ResourceLocator.PROTOCOL_OFFSET]; - // Length of body this.lengthOfBody = buff[ResourceLocator.LENGTH_OFFSET]; - // Body as utf8 string const decoder = new TextDecoder(); this.body = decoder.decode( buff.subarray(ResourceLocator.BODY_OFFSET, ResourceLocator.BODY_OFFSET + this.lengthOfBody) ); + // identifier + const identifierTypeNibble = this.protocol & 0xf; + if ((identifierTypeNibble & 0b0010) !== 0) { + this.identifierType = ResourceLocatorIdentifierEnum.TwoBytes; + } else if ((identifierTypeNibble & 0b0100) !== 0) { + this.identifierType = ResourceLocatorIdentifierEnum.EightBytes; + } else if ((identifierTypeNibble & 0b1000) !== 0) { + this.identifierType = ResourceLocatorIdentifierEnum.ThirtyTwoBytes; + } + switch (this.identifierType) { + case ResourceLocatorIdentifierEnum.None: + // noop + break; + case ResourceLocatorIdentifierEnum.TwoBytes: + case ResourceLocatorIdentifierEnum.EightBytes: + case ResourceLocatorIdentifierEnum.ThirtyTwoBytes: + const start = ResourceLocator.BODY_OFFSET + this.lengthOfBody; + const end = start + this.identifierType.valueOf(); + const subarray = buff.subarray(start, end); + // Remove padding (assuming the padding is null bytes, 0x00) + const trimmedSubarray = subarray.filter((byte) => byte !== 0x00); + this.identifier = decoder.decode(trimmedSubarray); + break; + } this.offset = - ResourceLocator.PROTOCOL_LENGTH + ResourceLocator.LENGTH_LENGTH + this.lengthOfBody; + ResourceLocator.PROTOCOL_LENGTH + + ResourceLocator.LENGTH_LENGTH + + this.lengthOfBody + + this.identifierType.valueOf(); } /** @@ -73,7 +128,9 @@ export default class ResourceLocator { // Length of the body( 1 byte) 1 + // Content length - this.body.length + this.body.length + + // Identifier length + this.identifierType.valueOf() ); } @@ -92,11 +149,13 @@ export default class ResourceLocator { * Return the contents of the Resource Locator in buffer */ toBuffer(): Uint8Array { - const buffer = new Uint8Array(2 + this.body.length); + const buffer = new Uint8Array(2 + this.body.length + this.identifierType.valueOf()); buffer.set([this.protocol], 0); buffer.set([this.lengthOfBody], 1); buffer.set(new TextEncoder().encode(this.body), 2); - + if (this.identifier) { + buffer.set(new TextEncoder().encode(this.identifier), 2 + this.body.length); + } return buffer; } @@ -116,7 +175,16 @@ export default class ResourceLocator { } else { throw new Error(`Cannot create URL from protocol, "${ProtocolEnum[this.protocol]}"`); } - return `${protocol}://${this.body}`; } + + /** + * Get Identifier + * + * Returns the identifier of the ResourceLocator or an empty string if no identifier is present. + * @returns { string } Identifier of the resource locator. + */ + getIdentifier(): string { + return this.identifier || ''; + } } diff --git a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts index d1fc440a..adb58753 100644 --- a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts +++ b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@esm-bundle/chai'; +import { assert, expect } from '@esm-bundle/chai'; import { NanoTDF } from '../../../src/nanotdf/index.js'; import PolicyTypeEnum from '../../../src/nanotdf/enum/PolicyTypeEnum.js'; import bufferToHex from './helpers/bufferToHex.js'; @@ -7,8 +7,24 @@ import * as remoteFixture from '../../__fixtures__/nanotdf-spec-remote-example.j import * as embeddedFixture from '../../__fixtures__/nanotdf-spec-embedded-example.js'; import * as plainEmbeddedFixture from '../../__fixtures__/nanotdf-spec-plain-embedded-example.js'; import { EmbeddedHeader, PlainEmbeddedHeader, RemoteHeader } from '../../../src/types/index.js'; +import ResourceLocator from '../../../src/nanotdf/models/ResourceLocator.js'; +import ResourceLocatorIdentifierEnum from '../../../src/nanotdf/enum/ResourceLocatorIdentifierEnum.js'; describe('NanoTDF', () => { + it('should parse the ResourceLocator Identifier', () => { + let rl = ResourceLocator.parse('http://localhost:8080', 'e0'); + assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.TwoBytes); + assert.equal(rl.getIdentifier(), 'e0'); + rl = ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0'); + assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.EightBytes); + assert.equal(rl.getIdentifier(), 'e0e0e0e0'); + rl = ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0'); + assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.ThirtyTwoBytes); + assert.equal(rl.getIdentifier(), 'e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0'); + rl = ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0e0e0e0e0'); + assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.ThirtyTwoBytes); + assert.equal(rl.getIdentifier(), 'e0e0e0e0e0e0e0e0'); + }); for (const { policyType, fixture } of [ { policyType: PolicyTypeEnum.Remote, fixture: remoteFixture }, { policyType: PolicyTypeEnum.EmbeddedText, fixture: embeddedFixture }, diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index bee04472..cf07ea14 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1536,9 +1536,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1820,7 +1821,8 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-9vExrKuqDY1CHmyy2Z7umlwZRFSI08JjkStzkkTrKRF91hEcBEHRvthuFIplNyX5NRZ85i8AXJCcCoDZLgshsg==", + "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", + "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -3286,11 +3288,12 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", - "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -3299,6 +3302,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -3327,7 +3331,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -3368,7 +3373,8 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", + "license": "Apache-2.0" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -3394,6 +3400,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -3403,6 +3410,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } @@ -3633,9 +3641,10 @@ } }, "node_modules/dpop": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.0.tgz", - "integrity": "sha512-r//f6g3uaDdomkz+3M0NdcEAxSGUVMIhF7lxf06aJZjCFhkH//GeZo6JWpz7Uv025s1w/+M5RDNRGxAGNIzm0g==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", + "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -3863,7 +3872,8 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -4240,7 +4250,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.2.4", @@ -4377,6 +4388,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -4421,9 +4433,10 @@ } }, "node_modules/jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -5183,7 +5196,8 @@ "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==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", @@ -5427,7 +5441,8 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ] + ], + "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 4e14e0cb..c351d80a 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -350,9 +350,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -606,7 +607,8 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-9vExrKuqDY1CHmyy2Z7umlwZRFSI08JjkStzkkTrKRF91hEcBEHRvthuFIplNyX5NRZ85i8AXJCcCoDZLgshsg==", + "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", + "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -1184,12 +1186,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1200,6 +1204,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -1238,11 +1243,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1251,7 +1258,8 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", + "license": "Apache-2.0" }, "node_modules/browserslist": { "version": "4.21.10", @@ -1310,6 +1318,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } @@ -1411,6 +1420,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1490,6 +1500,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1534,9 +1545,10 @@ } }, "node_modules/dpop": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.0.tgz", - "integrity": "sha512-r//f6g3uaDdomkz+3M0NdcEAxSGUVMIhF7lxf06aJZjCFhkH//GeZo6JWpz7Uv025s1w/+M5RDNRGxAGNIzm0g==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", + "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1839,7 +1851,8 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -1929,7 +1942,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", + "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", "dependencies": { @@ -1981,6 +1996,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1994,6 +2010,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -2227,6 +2244,8 @@ }, "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", "engines": { @@ -2245,6 +2264,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -2258,9 +2278,10 @@ "license": "ISC" }, "node_modules/jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2464,6 +2485,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2472,6 +2494,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -2903,7 +2926,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.0", @@ -3015,7 +3039,8 @@ "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==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.1", @@ -3256,7 +3281,8 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ] + ], + "license": "MIT" }, "node_modules/strip-ansi": { "version": "6.0.1", @@ -3349,6 +3375,8 @@ }, "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, "license": "MIT", "dependencies": { @@ -3482,6 +3510,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -3496,10 +3525,11 @@ } }, "node_modules/vite": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", - "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", @@ -3921,9 +3951,9 @@ } }, "@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -4081,7 +4111,7 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-9vExrKuqDY1CHmyy2Z7umlwZRFSI08JjkStzkkTrKRF91hEcBEHRvthuFIplNyX5NRZ85i8AXJCcCoDZLgshsg==", + "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -4429,9 +4459,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "requires": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -4463,10 +4493,12 @@ } }, "braces": { - "version": "3.0.2", + "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": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-fs-access": { @@ -4631,9 +4663,9 @@ } }, "dpop": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.0.tgz", - "integrity": "sha512-r//f6g3uaDdomkz+3M0NdcEAxSGUVMIhF7lxf06aJZjCFhkH//GeZo6JWpz7Uv025s1w/+M5RDNRGxAGNIzm0g==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", + "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==" }, "electron-to-chromium": { "version": "1.4.477", @@ -4884,7 +4916,9 @@ } }, "fill-range": { - "version": "7.0.1", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -5055,6 +5089,8 @@ }, "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 }, "is-path-inside": { @@ -5071,9 +5107,9 @@ "dev": true }, "jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==" }, "js-tokens": { "version": "4.0.0" @@ -5726,6 +5762,8 @@ }, "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": { "is-number": "^7.0.0" @@ -5800,9 +5838,9 @@ } }, "vite": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", - "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", "dev": true, "requires": { "esbuild": "^0.18.10", From fd1b38677b309083a54c0818b316d9e39d7aa649 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Wed, 21 Aug 2024 17:15:41 -0500 Subject: [PATCH 14/42] feat(sdk): Allow custom KAO array templates (#307) - Adds the ability to share and split DEKs - Reconstructs keys using share ids This will allow opening of files with multi-kas splits. Step 1 of #314 While I'm here I also: 1. Lets platform-xtest job run in parallel with other e2e tests 2. Updates config for platform-roundtrip job, since the `provision fixture keycloak` needs a new config file 3. Adds a new phony make target to simplify development, you can now `make cli` to get the cli without having to guess the version number 4. Adds a `prettier ignore` directive so `make format` no longer formats the generated protocol buffer code 5. Updates the fetching of KAS public keys to happen during encrypt, not during client creation. This makes more sense now that we don't know at client start time which kases will actually be involved in the encrypt step --- Co-authored-by: Patrick Bacon-Blaber --- .github/workflows/build.yaml | 4 +- .../workflows/roundtrip/keycloak_data.yaml | 114 ++++++++++++++++++ .github/workflows/roundtrip/opentdf.yaml | 14 +-- .github/workflows/roundtrip/wait-and-test.sh | 2 +- Makefile | 4 +- cli/package-lock.json | 42 ++----- lib/.prettierignore | 1 + lib/src/{kas.ts => access.ts} | 12 ++ lib/src/index.ts | 17 +-- lib/src/nanotdf/Client.ts | 2 +- lib/src/tdf/AttributeObject.ts | 4 +- lib/tdf3/index.ts | 2 + lib/tdf3/src/client/builders.ts | 6 + lib/tdf3/src/client/index.ts | 35 ++++-- lib/tdf3/src/models/encryption-information.ts | 20 ++- lib/tdf3/src/models/key-access.ts | 10 +- lib/tdf3/src/tdf.ts | 62 ++++++++-- lib/tests/mocha/unit/tdf.spec.ts | 80 +++++++++++- remote-store/package-lock.json | 28 ++--- web-app/package-lock.json | 37 ++---- 20 files changed, 350 insertions(+), 146 deletions(-) create mode 100644 .github/workflows/roundtrip/keycloak_data.yaml create mode 100644 lib/.prettierignore rename lib/src/{kas.ts => access.ts} (75%) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2469388c..02372cb1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -253,7 +253,9 @@ jobs: ./wait-and-test.sh platform platform-xtest: - needs: platform-roundtrip + needs: + - cli + - lib uses: opentdf/tests/.github/workflows/xtest.yml@main with: js-ref: ${{ github.ref }} diff --git a/.github/workflows/roundtrip/keycloak_data.yaml b/.github/workflows/roundtrip/keycloak_data.yaml new file mode 100644 index 00000000..006a326b --- /dev/null +++ b/.github/workflows/roundtrip/keycloak_data.yaml @@ -0,0 +1,114 @@ +baseUrl: &baseUrl http://localhost:8888 +serverBaseUrl: &serverBaseUrl http://localhost:8080 +customAudMapper: &customAudMapper + name: audience-mapper + protocol: openid-connect + protocolMapper: oidc-audience-mapper + config: + included.custom.audience: *serverBaseUrl + access.token.claim: "true" + id.token.claim: "true" +realms: + - realm_repepresentation: + realm: opentdf + enabled: true + custom_realm_roles: + - name: opentdf-org-admin + - name: opentdf-admin + - name: opentdf-standard + custom_client_roles: + tdf-entity-resolution: + - name: entity-resolution-test-role + custom_groups: + - name: mygroup + attributes: + mygroupattribute: + - mygroupvalue + clients: + - client: + clientID: opentdf + enabled: true + name: opentdf + serviceAccountsEnabled: true + clientAuthenticatorType: client-secret + secret: secret + protocolMappers: + - *customAudMapper + sa_realm_roles: + - opentdf-org-admin + - client: + clientID: opentdf-sdk + enabled: true + name: opentdf-sdk + serviceAccountsEnabled: true + clientAuthenticatorType: client-secret + secret: secret + protocolMappers: + - *customAudMapper + sa_realm_roles: + - opentdf-standard + - client: + clientID: tdf-entity-resolution + enabled: true + name: tdf-entity-resolution + serviceAccountsEnabled: true + clientAuthenticatorType: client-secret + secret: secret + protocolMappers: + - *customAudMapper + sa_client_roles: + realm-management: + - view-clients + - query-clients + - view-users + - query-users + - client: + clientID: tdf-authorization-svc + enabled: true + name: tdf-authorization-svc + serviceAccountsEnabled: true + clientAuthenticatorType: client-secret + secret: secret + protocolMappers: + - *customAudMapper + - client: + clientID: opentdf-public + enabled: true + name: opentdf-public + serviceAccountsEnabled: false + publicClient: true + redirectUris: + - 'http://localhost:9000/*' # otdfctl CLI tool + protocolMappers: + - *customAudMapper + users: + - username: sample-user + enabled: true + firstName: sample + lastName: user + email: sampleuser@sample.com + credentials: + - value: testuser123 + type: password + attributes: + superhero_name: + - thor + superhero_group: + - avengers + groups: + - mygroup + realmRoles: + - opentdf-org-admin + clientRoles: + realm-management: + - view-clients + - query-clients + - view-users + - query-users + tdf-entity-resolution: + - entity-resolution-test-role + token_exchanges: + - start_client: opentdf + target_client: opentdf-sdk + + \ No newline at end of file diff --git a/.github/workflows/roundtrip/opentdf.yaml b/.github/workflows/roundtrip/opentdf.yaml index 124576e3..c5424a62 100644 --- a/.github/workflows/roundtrip/opentdf.yaml +++ b/.github/workflows/roundtrip/opentdf.yaml @@ -10,25 +10,18 @@ logger: # password: changeme services: kas: - enabled: true keyring: - kid: e1 alg: ec:secp256r1 + - kid: e1 + alg: ec:secp256r1 + legacy: true - kid: r1 alg: rsa:2048 - kid: r1 alg: rsa:2048 legacy: true - policy: - enabled: true - authorization: - enabled: true - ersurl: http://localhost:65432/entityresolution/resolve - clientid: tdf-authorization-svc - clientsecret: secret - tokenendpoint: http://localhost:65432/auth/realms/opentdf/protocol/openid-connect/token entityresolution: - enabled: true url: http://localhost:65432/auth clientid: 'tdf-entity-resolution' clientsecret: 'secret' @@ -41,6 +34,7 @@ services: server: auth: enabled: true + public_client_id: 'opentdf-public' audience: 'http://localhost:65432' issuer: http://localhost:65432/auth/realms/opentdf policy: diff --git a/.github/workflows/roundtrip/wait-and-test.sh b/.github/workflows/roundtrip/wait-and-test.sh index 223b12a5..ec87959a 100755 --- a/.github/workflows/roundtrip/wait-and-test.sh +++ b/.github/workflows/roundtrip/wait-and-test.sh @@ -106,7 +106,7 @@ _init_platform() { if [ -f go.work ]; then svc=github.com/opentdf/platform/service fi - if ! go run "${svc}" provision keycloak; then + if ! go run "${svc}" provision keycloak -f "${APP_DIR}/keycloak_data.yaml"; then echo "[ERROR] unable to provision keycloak" return 1 fi diff --git a/Makefile b/Makefile index 409f19db..bbbbb3ac 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,13 @@ version=2.0.0 extras=cli remote-store web-app pkgs=lib $(extras) -.PHONY: all audit license-check lint test ci i start format clean +.PHONY: all audit ci clean cli format i license-check lint start test start: all (cd web-app && npm run dev) +cli: cli/opentdf-cli-$(version).tgz + clean: rm -f *.tgz rm -f */*.tgz diff --git a/cli/package-lock.json b/cli/package-lock.json index fe0b171c..76a0e705 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -39,7 +39,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", - "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -372,8 +371,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", - "license": "BSD-3-Clause-Clear", + "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -876,14 +874,12 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -894,7 +890,6 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", - "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -923,8 +918,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -963,8 +957,7 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", - "license": "Apache-2.0" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -990,7 +983,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -1000,7 +992,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", "engines": { "node": "*" } @@ -1144,7 +1135,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1229,7 +1219,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1271,7 +1260,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1486,8 +1474,7 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -1624,7 +1611,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1654,7 +1640,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1860,8 +1845,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/ignore": { "version": "5.3.1", @@ -1998,7 +1982,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -2046,7 +2029,6 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2243,7 +2225,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2252,7 +2233,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -2658,8 +2638,7 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/punycode": { "version": "2.3.1", @@ -2770,8 +2749,7 @@ "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==", - "license": "MIT" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/require-directory": { "version": "2.1.1", @@ -3055,8 +3033,7 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ], - "license": "MIT" + ] }, "node_modules/string-width": { "version": "4.2.3", @@ -3295,7 +3272,6 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } diff --git a/lib/.prettierignore b/lib/.prettierignore new file mode 100644 index 00000000..6bee855e --- /dev/null +++ b/lib/.prettierignore @@ -0,0 +1 @@ +/src/platform \ No newline at end of file diff --git a/lib/src/kas.ts b/lib/src/access.ts similarity index 75% rename from lib/src/kas.ts rename to lib/src/access.ts index 54fef60e..ca8bee01 100644 --- a/lib/src/kas.ts +++ b/lib/src/access.ts @@ -1,4 +1,5 @@ import { type AuthProvider } from './auth/auth.js'; +import { pemToCryptoPublicKey } from './utils.js'; export class RewrapRequest { signedRequestToken = ''; @@ -48,3 +49,14 @@ export async function fetchWrappedKey( return response.json(); } + +export async function fetchECKasPubKey(kasEndpoint: string): Promise { + const kasPubKeyResponse = await fetch(`${kasEndpoint}/kas_public_key?algorithm=ec:secp256r1`); + if (!kasPubKeyResponse.ok) { + throw new Error( + `Unable to validate KAS [${kasEndpoint}]. Received [${kasPubKeyResponse.status}:${kasPubKeyResponse.statusText}]` + ); + } + const pem = await kasPubKeyResponse.json(); + return pemToCryptoPublicKey(pem); +} diff --git a/lib/src/index.ts b/lib/src/index.ts index 18eeddf3..b2c39ca0 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -10,19 +10,8 @@ import { } from './nanotdf/index.js'; import { keyAgreement } from './nanotdf-crypto/index.js'; import { TypedArray, createAttribute, Policy } from './tdf/index.js'; +import { fetchECKasPubKey } from './access.js'; import { ClientConfig } from './nanotdf/Client.js'; -import { pemToCryptoPublicKey } from './utils.js'; - -async function fetchKasPubKey(kasUrl: string): Promise { - const kasPubKeyResponse = await fetch(`${kasUrl}/kas_public_key?algorithm=ec:secp256r1`); - if (!kasPubKeyResponse.ok) { - throw new Error( - `Unable to validate KAS [${kasUrl}]. Received [${kasPubKeyResponse.status}:${kasPubKeyResponse.statusText}]` - ); - } - const pem = await kasPubKeyResponse.json(); - return pemToCryptoPublicKey(pem); -} /** * NanoTDF SDK Client @@ -132,7 +121,7 @@ export class NanoTDFClient extends Client { delete this.iv; if (!this.kasPubKey) { - this.kasPubKey = await fetchKasPubKey(this.kasUrl); + this.kasPubKey = await fetchECKasPubKey(this.kasUrl); } // Create a policy for the tdf @@ -259,7 +248,7 @@ export class NanoTDFDatasetClient extends Client { const ephemeralKeyPair = await this.ephemeralKeyPair; if (!this.kasPubKey) { - this.kasPubKey = await fetchKasPubKey(this.kasUrl); + this.kasPubKey = await fetchECKasPubKey(this.kasUrl); } // Create a policy for the tdf diff --git a/lib/src/nanotdf/Client.ts b/lib/src/nanotdf/Client.ts index 8a5049da..44760a87 100644 --- a/lib/src/nanotdf/Client.ts +++ b/lib/src/nanotdf/Client.ts @@ -3,7 +3,7 @@ import * as base64 from '../encodings/base64.js'; import { generateKeyPair, keyAgreement } from '../nanotdf-crypto/index.js'; import getHkdfSalt from './helpers/getHkdfSalt.js'; import DefaultParams from './models/DefaultParams.js'; -import { fetchWrappedKey } from '../kas.js'; +import { fetchWrappedKey } from '../access.js'; import { AuthProvider, isAuthProvider, reqSignature } from '../auth/providers.js'; import { cryptoPublicToPem, diff --git a/lib/src/tdf/AttributeObject.ts b/lib/src/tdf/AttributeObject.ts index 510b1ce2..3e9b20f3 100644 --- a/lib/src/tdf/AttributeObject.ts +++ b/lib/src/tdf/AttributeObject.ts @@ -17,11 +17,11 @@ export async function createAttribute( kasUrl: string ): Promise { return { - attribute: attribute, + attribute, isDefault: false, displayName: '', pubKey: await cryptoPublicToPem(pubKey), - kasUrl: kasUrl, + kasUrl, schemaVersion: '1.1.0', }; } diff --git a/lib/tdf3/index.ts b/lib/tdf3/index.ts index b906ee7f..bad39aa8 100644 --- a/lib/tdf3/index.ts +++ b/lib/tdf3/index.ts @@ -10,6 +10,7 @@ import { type DecryptKeyMiddleware, type DecryptStreamMiddleware, EncryptParamsBuilder, + type SplitStep, } from './src/client/builders.js'; import { type ClientConfig, createSessionKeys } from './src/client/index.js'; import { @@ -56,6 +57,7 @@ export type { EncryptStreamMiddleware, DecryptKeyMiddleware, DecryptStreamMiddleware, + SplitStep, }; export { diff --git a/lib/tdf3/src/client/builders.ts b/lib/tdf3/src/client/builders.ts index 007d65d1..6efb899d 100644 --- a/lib/tdf3/src/client/builders.ts +++ b/lib/tdf3/src/client/builders.ts @@ -26,6 +26,11 @@ export type EncryptStreamMiddleware = ( stream: DecoratedReadableStream ) => Promise; +export type SplitStep = { + kas: string; + sid?: string; +}; + export type EncryptParams = { source: ReadableStream; opts?: { keypair: PemKeyPair }; @@ -40,6 +45,7 @@ export type EncryptParams = { eo?: EntityObject; payloadKey?: Binary; keyMiddleware?: EncryptKeyMiddleware; + splitPlan?: SplitStep[]; streamMiddleware?: EncryptStreamMiddleware; }; diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index 44b53a27..ed65256a 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -40,6 +40,7 @@ import { DecryptStreamMiddleware, EncryptKeyMiddleware, EncryptStreamMiddleware, + SplitStep, } from './builders.js'; import { DecoratedReadableStream } from './DecoratedReadableStream.js'; @@ -221,7 +222,7 @@ export class Client { */ readonly allowedKases: string[]; - readonly kasPublicKey: Promise; + readonly kasKeys: Record> = {}; readonly easEndpoint?: string; @@ -329,13 +330,11 @@ export class Client { dpopKeys: clientConfig.dpopKeys, }); if (clientConfig.kasPublicKey) { - this.kasPublicKey = Promise.resolve({ + this.kasKeys[this.kasEndpoint] = Promise.resolve({ url: this.kasEndpoint, algorithm: 'rsa:2048', publicKey: clientConfig.kasPublicKey, }); - } else { - this.kasPublicKey = fetchKasPublicKey(this.kasEndpoint); } } @@ -366,9 +365,10 @@ export class Client { eo, keyMiddleware = defaultKeyMiddleware, streamMiddleware = async (stream: DecoratedReadableStream) => stream, + splitPlan, }: EncryptParams): Promise { const dpopKeys = await this.dpopKeys; - const kasPublicKey = await this.kasPublicKey; + const policyObject = asPolicy(scope); validatePolicyObject(policyObject); @@ -384,14 +384,23 @@ export class Client { eo.attributes.forEach((attr) => s.addJwtAttribute(attr)); attributeSet = s; } - encryptionInformation.keyAccess.push( - await buildKeyAccess({ - attributeSet, - type: offline ? 'wrapped' : 'remote', - url: kasPublicKey.url, - kid: kasPublicKey.kid, - publicKey: kasPublicKey.publicKey, - metadata, + + const splits: SplitStep[] = splitPlan || [{ kas: this.kasEndpoint }]; + encryptionInformation.keyAccess = await Promise.all( + splits.map(async ({ kas, sid }) => { + if (!(kas in this.kasKeys)) { + this.kasKeys[kas] = fetchKasPublicKey(kas); + } + const kasPublicKey = await this.kasKeys[kas]; + return buildKeyAccess({ + attributeSet, + type: offline ? 'wrapped' : 'remote', + url: kasPublicKey.url, + kid: kasPublicKey.kid, + publicKey: kasPublicKey.publicKey, + metadata, + sid, + }); }) ); const { keyForEncryption, keyForManifest } = await (keyMiddleware as EncryptKeyMiddleware)(); diff --git a/lib/tdf3/src/models/encryption-information.ts b/lib/tdf3/src/models/encryption-information.ts index 22ad0cc2..700ff73c 100644 --- a/lib/tdf3/src/models/encryption-information.ts +++ b/lib/tdf3/src/models/encryption-information.ts @@ -24,8 +24,10 @@ export type Segment = { readonly encryptedSegmentSize?: number; }; +export type SplitType = 'split'; + export type EncryptionInformation = { - readonly type: string; + readonly type: SplitType; readonly keyAccess: KeyAccessObject[]; readonly integrityInformation: { readonly rootSignature: { @@ -75,19 +77,25 @@ export class SplitKey { } async getKeyAccessObjects(policy: Policy, keyInfo: KeyInfo): Promise { + const splitIds = [...new Set(this.keyAccess.map(({ sid }) => sid))].sort((a, b) => + a.localeCompare(b) + ); const unwrappedKeySplitBuffers = await keySplit( new Uint8Array(keyInfo.unwrappedKeyBinary.asByteArray()), - this.keyAccess.length, + splitIds.length, this.cryptoService ); + const splitsByName = Object.fromEntries( + splitIds.map((sid, index) => [sid, unwrappedKeySplitBuffers[index]]) + ); const keyAccessObjects = []; - for (let i = 0; i < this.keyAccess.length; i++) { + for (const item of this.keyAccess) { // use the key split to encrypt metadata for each key access object - const unwrappedKeySplitBuffer = unwrappedKeySplitBuffers[i]; + const unwrappedKeySplitBuffer = splitsByName[item.sid]; const unwrappedKeySplitBinary = Binary.fromArrayBuffer(unwrappedKeySplitBuffer.buffer); - const metadata = this.keyAccess[i].metadata || ''; + const metadata = item.metadata || ''; const metadataStr = ( typeof metadata === 'object' ? JSON.stringify(metadata) @@ -112,7 +120,7 @@ export class SplitKey { }; const encryptedMetadataStr = JSON.stringify(encryptedMetadataOb); - const keyAccessObject = await this.keyAccess[i].write( + const keyAccessObject = await item.write( policy, unwrappedKeySplitBuffer, encryptedMetadataStr diff --git a/lib/tdf3/src/models/key-access.ts b/lib/tdf3/src/models/key-access.ts index 951c7ddf..efc8b1da 100644 --- a/lib/tdf3/src/models/key-access.ts +++ b/lib/tdf3/src/models/key-access.ts @@ -17,7 +17,8 @@ export class Wrapped { public readonly url: string, public readonly kid: string | undefined, public readonly publicKey: string, - public readonly metadata: unknown + public readonly metadata: unknown, + public readonly sid: string ) {} async write( @@ -51,6 +52,9 @@ export class Wrapped { if (this.kid) { this.keyAccessObject.kid = this.kid; } + if (this.sid?.length) { + this.keyAccessObject.sid = this.sid; + } return this.keyAccessObject; } @@ -66,7 +70,8 @@ export class Remote { public readonly url: string, public readonly kid: string | undefined, public readonly publicKey: string, - public readonly metadata: unknown + public readonly metadata: unknown, + public readonly sid: string ) {} async write( @@ -109,6 +114,7 @@ export class Remote { export type KeyAccess = Remote | Wrapped; export type KeyAccessObject = { + sid?: string; type: KeyAccessType; url: string; kid?: string; diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 0db40f71..acdad7d8 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -18,6 +18,8 @@ import { UpsertResponse, Wrapped as KeyAccessWrapped, KeyAccess, + KeyAccessObject, + SplitType, } from './models/index.js'; import { base64 } from '../../src/encodings/index.js'; import { @@ -70,7 +72,7 @@ export type EncryptionOptions = { /** * Defaults to `split`, the currently only implmented key wrap algorithm. */ - type?: string; + type?: SplitType; // Defaults to AES-256-GCM for the encryption. cipher?: string; }; @@ -92,6 +94,7 @@ export type BuildKeyAccess = { publicKey: string; attributeUrl?: string; metadata?: Metadata; + sid?: string; }; type Segment = { @@ -341,6 +344,7 @@ export async function buildKeyAccess({ kid, attributeUrl, metadata, + sid = '', }: BuildKeyAccess): Promise { /** Internal function to keep it DRY */ function createKeyAccess( @@ -352,9 +356,9 @@ export async function buildKeyAccess({ ) { switch (type) { case 'wrapped': - return new KeyAccessWrapped(kasUrl, kasKeyIdentifier, pubKey, metadata); + return new KeyAccessWrapped(kasUrl, kasKeyIdentifier, pubKey, metadata, sid); case 'remote': - return new KeyAccessRemote(kasUrl, kasKeyIdentifier, pubKey, metadata); + return new KeyAccessRemote(kasUrl, kasKeyIdentifier, pubKey, metadata, sid); default: throw new KeyAccessError(`buildKeyAccess: Key access type ${type} is unknown`); } @@ -801,6 +805,40 @@ async function loadTDFStream( return { manifest, zipReader, centralDirectory }; } +export function splitLookupTableFactory( + keyAccess: KeyAccessObject[], + allowedKases: string[] +): Record> { + const origin = (u: string): string => new URL(u).origin; + const allowed = (k: KeyAccessObject) => allowedKases.includes(origin(k.url)); + const splitIds = new Set(keyAccess.map(({ sid }) => sid ?? '')); + + const accessibleSplits = new Set(keyAccess.filter(allowed).map(({ sid }) => sid)); + if (splitIds.size > accessibleSplits.size) { + const disallowedKases = new Set(keyAccess.filter((k) => !allowed(k)).map(({ url }) => url)); + throw new KasDecryptError( + `Unreconstructable key - disallowed KASes include: ${JSON.stringify([ + ...disallowedKases, + ])} from splitIds ${JSON.stringify([...splitIds])}` + ); + } + const splitPotentials: Record> = Object.fromEntries( + [...splitIds].map((s) => [s, {}]) + ); + for (const kao of keyAccess) { + const disjunction = splitPotentials[kao.sid ?? '']; + if (kao.url in disjunction) { + throw new KasDecryptError( + `TODO: Fallback to no split ids. Repetition found for [${kao.url}] on split [${kao.sid}]` + ); + } + if (allowed(kao)) { + disjunction[kao.url] = kao; + } + } + return splitPotentials; +} + async function unwrapKey({ manifest, allowedKases, @@ -817,23 +855,25 @@ async function unwrapKey({ cryptoService: CryptoService; }) { if (authProvider === undefined) { - throw new Error('Upsert can be done without auth provider'); + throw new KasDecryptError('Upsert can be done without auth provider'); } const { keyAccess } = manifest.encryptionInformation; + const splitPotentials = splitLookupTableFactory(keyAccess, allowedKases); + let responseMetadata; const isAppIdProvider = authProvider && isAppIdProviderCheck(authProvider); // Get key access information to know the KAS URLS const rewrappedKeys = await Promise.all( - keyAccess.map(async (keySplitInfo) => { - const kaoOrigin = new URL(keySplitInfo.url).origin; - if (!allowedKases.includes(kaoOrigin)) { + Object.entries(splitPotentials).map(async ([splitId, potentials]) => { + if (!potentials || !Object.keys(potentials).length) { throw new UnsafeUrlError( - `cannot decrypt TDF: [${keySplitInfo.url}] not on allowlist ${JSON.stringify( - allowedKases - )}`, - keySplitInfo.url + `Unreconstructable key - no valid KAS found for split ${JSON.stringify(splitId)}`, + '' ); } + // If we have multiple ways of getting a value, try the 'best' way + // or maybe retry across all potential ways? Currently, just tries them all + const [keySplitInfo] = Object.values(potentials); const url = `${keySplitInfo.url}/${isAppIdProvider ? '' : 'v2/'}rewrap`; const ephemeralEncryptionKeys = await cryptoService.cryptoToPemPair( diff --git a/lib/tests/mocha/unit/tdf.spec.ts b/lib/tests/mocha/unit/tdf.spec.ts index fe989825..64f9861e 100644 --- a/lib/tests/mocha/unit/tdf.spec.ts +++ b/lib/tests/mocha/unit/tdf.spec.ts @@ -1,7 +1,8 @@ import { expect } from 'chai'; import * as TDF from '../../../tdf3/src/tdf.js'; -import { TdfError } from '../../../src/errors.js'; +import { KasDecryptError, TdfError } from '../../../src/errors.js'; +import { KeyAccessObject } from 'tdf3/src/models/key-access.js'; const sampleCert = ` -----BEGIN CERTIFICATE----- @@ -92,3 +93,80 @@ describe('fetchKasPublicKey', async () => { expect(pk2.kid).to.equal('kid-a'); }); }); + +describe('splitLookupTableFactory', () => { + it('should return a correct split table for valid input', () => { + const keyAccess: KeyAccessObject[] = [ + { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, + { sid: 'split2', type: 'remote', url: 'https://kas2', protocol: 'kas' }, + ]; + const allowedKases = ['https://kas1', 'https://kas2']; + + const result = TDF.splitLookupTableFactory(keyAccess, allowedKases); + + expect(result).to.deep.equal({ + split1: { 'https://kas1': keyAccess[0] }, + split2: { 'https://kas2': keyAccess[1] }, + }); + }); + + it('should throw KasDecryptError for disallowed KASes', () => { + const keyAccess: KeyAccessObject[] = [ + { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, + { sid: 'split2', type: 'remote', url: 'https://kas3', protocol: 'kas' }, // kas3 is not allowed + ]; + const allowedKases = ['https://kas1']; + + expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( + KasDecryptError, + 'Unreconstructable key - disallowed KASes include: ["https://kas3"] from splitIds ["split1","split2"]' + ); + }); + + it('should throw KasDecryptError for duplicate URLs in the same splitId', () => { + const keyAccess: KeyAccessObject[] = [ + { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, + { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, // duplicate URL in same splitId + ]; + const allowedKases = ['https://kas1']; + + expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( + KasDecryptError, + 'TODO: Fallback to no split ids. Repetition found for [https://kas1] on split [split1]' + ); + }); + + it('should handle empty keyAccess array', () => { + const keyAccess: KeyAccessObject[] = []; + const allowedKases: string[] = []; + + const result = TDF.splitLookupTableFactory(keyAccess, allowedKases); + + expect(result).to.deep.equal({}); + }); + + it('should handle empty allowedKases array', () => { + const keyAccess: KeyAccessObject[] = [ + { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, + ]; + const allowedKases: string[] = []; + + expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( + KasDecryptError, + 'Unreconstructable key - disallowed KASes include: ["https://kas1"]' + ); + }); + + it('should handle cases where sid is undefined', () => { + const keyAccess: KeyAccessObject[] = [ + { sid: undefined, type: 'remote', url: 'https://kas1', protocol: 'kas' }, + ]; + const allowedKases = ['https://kas1']; + + const result = TDF.splitLookupTableFactory(keyAccess, allowedKases); + + expect(result).to.deep.equal({ + '': { 'https://kas1': keyAccess[0] }, + }); + }); +}); diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index cf07ea14..8fd068bd 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1539,7 +1539,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", - "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1821,8 +1820,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", - "license": "BSD-3-Clause-Clear", + "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -3302,7 +3300,6 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", - "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -3331,8 +3328,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -3373,8 +3369,7 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", - "license": "Apache-2.0" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -3400,7 +3395,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -3410,7 +3404,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", "engines": { "node": "*" } @@ -3644,7 +3637,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -3872,8 +3864,7 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -4250,8 +4241,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/ignore": { "version": "5.2.4", @@ -4388,7 +4378,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -4436,7 +4425,6 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -5196,8 +5184,7 @@ "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==", - "license": "MIT" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/require-directory": { "version": "2.1.1", @@ -5441,8 +5428,7 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ], - "license": "MIT" + ] }, "node_modules/string-width": { "version": "4.2.3", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index c351d80a..5c0280da 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -353,7 +353,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", - "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -607,8 +606,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", - "license": "BSD-3-Clause-Clear", + "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -1186,14 +1184,12 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1204,7 +1200,6 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", - "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -1258,8 +1253,7 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", - "license": "Apache-2.0" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" }, "node_modules/browserslist": { "version": "4.21.10", @@ -1318,7 +1312,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", "engines": { "node": "*" } @@ -1420,7 +1413,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1500,7 +1492,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1548,7 +1539,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1851,8 +1841,7 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -1996,7 +1985,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -2010,7 +1998,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -2264,7 +2251,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -2281,7 +2267,6 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2485,7 +2470,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2494,7 +2478,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -2926,8 +2909,7 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/punycode": { "version": "2.3.0", @@ -3039,8 +3021,7 @@ "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==", - "license": "MIT" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/resolve": { "version": "1.22.1", @@ -3281,8 +3262,7 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ], - "license": "MIT" + ] }, "node_modules/strip-ansi": { "version": "6.0.1", @@ -3510,7 +3490,6 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -4111,7 +4090,7 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-0BJzWle4f2xoBKXYmifx0XLmYCn5A60cMuUBNG5inwKaLl+ES8gYgSHjx5ivsKsvv4dA8hW7SUPdjDeuxujchA==", + "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", From 69e0a8156f747c27aa185f0cb22498b0a9ed8e53 Mon Sep 17 00:00:00 2001 From: sujankota Date: Thu, 22 Aug 2024 13:30:58 -0400 Subject: [PATCH 15/42] fix(sdk): calculate the length of ecdsa binding (#327) * Fix one test and disabled the other for later --------- Co-authored-by: David Mihalcik --- .github/workflows/build.yaml | 2 +- .../nanotdf/models/Policy/AbstractPolicy.ts | 43 +++++++++++++++++- .../nanotdf/models/Policy/EmbeddedPolicy.ts | 6 +-- .../nanotdf/models/Policy/PolicyFactory.ts | 6 +-- lib/src/nanotdf/models/Policy/RemotePolicy.ts | 6 +-- lib/tests/__fixtures__/dummy.txt.ntdf | Bin 65759 -> 65724 bytes lib/tests/web/nanotdf/large-file.test.ts | 2 +- .../nanotdf/ntdf-spec-basic-example.test.ts | 2 +- 8 files changed, 53 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 02372cb1..9bbf3d5b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -77,7 +77,7 @@ jobs: - run: npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-*.tgz - run: npm install - run: npm test - - run: npm audit + - run: npm audit --omit dev && npm audit --audit-level high - run: npm run license-check - run: npm run lint - run: npm pack diff --git a/lib/src/nanotdf/models/Policy/AbstractPolicy.ts b/lib/src/nanotdf/models/Policy/AbstractPolicy.ts index a9417d44..c0d8cf58 100644 --- a/lib/src/nanotdf/models/Policy/AbstractPolicy.ts +++ b/lib/src/nanotdf/models/Policy/AbstractPolicy.ts @@ -9,6 +9,8 @@ abstract class AbstractPolicy implements PolicyInterface { static readonly BODY_BYTE_MAX_LEN = 257; static readonly BINDING_BYTE_MIN_LEN = 8; static readonly BINDING_BYTE_MAX_LEN = 132; + static readonly SIZE_OF_LENGTH_FIELD = 1; // 1 byte for each length field (R and S) + static readonly GMAC_BINDING_LEN = 8; readonly type: PolicyType; readonly binding: Uint8Array; @@ -18,7 +20,7 @@ abstract class AbstractPolicy implements PolicyInterface { // eslint-disable-next-line @typescript-eslint/no-unused-vars buff: Uint8Array, // eslint-disable-next-line @typescript-eslint/no-unused-vars - bindingLength: number, + useECDSABinding: boolean, // eslint-disable-next-line @typescript-eslint/no-unused-vars type?: PolicyType ): { policy: PolicyInterface; offset: number } { @@ -43,6 +45,45 @@ abstract class AbstractPolicy implements PolicyInterface { toBuffer(): Uint8Array | never { throw new Error('toBuffer() was not implemented'); } + + /** + * Parses an ECDSA binding from a given buffer. + * + * @param {Uint8Array} buff - The buffer containing the ECDSA binding. + * @returns {{ bindingLength: number; binding: Uint8Array }} - An object containing the binding length and the binding subarray. + */ + static parseECDSABinding(buff: Uint8Array): { bindingLength: number; binding: Uint8Array } { + const lengthOfR = buff[0]; + const lengthOfS = buff[this.SIZE_OF_LENGTH_FIELD + lengthOfR]; + + const bindingLength = + this.SIZE_OF_LENGTH_FIELD + lengthOfR + this.SIZE_OF_LENGTH_FIELD + lengthOfS; + const binding = buff.subarray(0, bindingLength); + + return { bindingLength, binding }; + } + + /** + * Parses a binding from a given buffer based on the specified binding type. + * + * @param {Uint8Array} buff - The buffer containing the binding. + * @param {boolean} useEcdsaBinding - Flag indicating whether to use ECDSA binding. + * @param {number} offset - The starting offset in the buffer. + * @returns {{ binding: Uint8Array; newOffset: number }} - An object containing the binding and the new offset. + */ + static parseBinding( + buff: Uint8Array, + useEcdsaBinding: boolean, + offset: number + ): { binding: Uint8Array; newOffset: number } { + if (useEcdsaBinding) { + const ecdsaBinding = this.parseECDSABinding(buff.subarray(offset)); + return { binding: ecdsaBinding.binding, newOffset: offset + ecdsaBinding.bindingLength }; + } else { + const binding = buff.subarray(offset, offset + this.GMAC_BINDING_LEN); + return { binding, newOffset: offset + this.GMAC_BINDING_LEN }; + } + } } export default AbstractPolicy; diff --git a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts index e0a9dca9..92f4b649 100644 --- a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts +++ b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts @@ -19,7 +19,7 @@ class EmbeddedPolicy extends AbstractPolicy implements EmbeddedPolicyInterface { static override parse( buff: Uint8Array, - bindingLength: number, + useEcdsaBinding: boolean, type: PolicyTypes ): { offset: number; policy: EmbeddedPolicy } { let offset = 0; @@ -32,8 +32,8 @@ class EmbeddedPolicy extends AbstractPolicy implements EmbeddedPolicyInterface { const content = buff.subarray(offset, offset + length); offset += length; - const binding = buff.subarray(offset, offset + bindingLength); - offset += bindingLength; + const { binding, newOffset: bindingOffset } = this.parseBinding(buff, useEcdsaBinding, offset); + offset = bindingOffset; return { policy: new EmbeddedPolicy(type, binding, content), diff --git a/lib/src/nanotdf/models/Policy/PolicyFactory.ts b/lib/src/nanotdf/models/Policy/PolicyFactory.ts index e8c51cde..7402524c 100644 --- a/lib/src/nanotdf/models/Policy/PolicyFactory.ts +++ b/lib/src/nanotdf/models/Policy/PolicyFactory.ts @@ -2,7 +2,6 @@ import AbstractPolicy from './AbstractPolicy.js'; import EmbeddedPolicy from './EmbeddedPolicy.js'; import RemotePolicy from './RemotePolicy.js'; import PolicyTypeEnum from '../../enum/PolicyTypeEnum.js'; -import { lengthOfBinding } from '../../helpers/calculateByCipher.js'; import { InvalidPolicyTypeError } from '../../../errors.js'; import CurveNameEnum from '../../enum/CurveNameEnum.js'; @@ -12,7 +11,6 @@ function parse( curve: CurveNameEnum ): { policy: AbstractPolicy; offset: number } | never { const type = buff[AbstractPolicy.TYPE_BYTE_OFF]; - const bindingLength = lengthOfBinding(useEcdsaBinding, curve); let policy: AbstractPolicy; let offset: number; @@ -20,7 +18,7 @@ function parse( if (type === PolicyTypeEnum.Remote) { ({ policy, offset } = RemotePolicy.parse( buff.subarray(AbstractPolicy.TYPE_BYTE_LEN), - bindingLength + useEcdsaBinding )); } else if ( [ @@ -32,7 +30,7 @@ function parse( ) { ({ policy, offset } = EmbeddedPolicy.parse( buff.subarray(AbstractPolicy.TYPE_BYTE_LEN), - bindingLength, + useEcdsaBinding, type )); } else { diff --git a/lib/src/nanotdf/models/Policy/RemotePolicy.ts b/lib/src/nanotdf/models/Policy/RemotePolicy.ts index c6ab1f80..a181e8cf 100644 --- a/lib/src/nanotdf/models/Policy/RemotePolicy.ts +++ b/lib/src/nanotdf/models/Policy/RemotePolicy.ts @@ -15,14 +15,14 @@ class RemotePolicy extends AbstractPolicy implements RemotePolicyInterface { static override parse( buff: Uint8Array, - bindingLength: number + useEcdsaBinding: boolean ): { offset: number; policy: RemotePolicy } { let offset = 0; const resource = new ResourceLocator(buff); offset += resource.offset; - const binding = buff.subarray(offset, offset + bindingLength); - offset += bindingLength; + const { binding, newOffset: bindingOffset } = this.parseBinding(buff, useEcdsaBinding, offset); + offset = bindingOffset; return { policy: new RemotePolicy(PolicyTypeEnum.Remote, binding, resource), diff --git a/lib/tests/__fixtures__/dummy.txt.ntdf b/lib/tests/__fixtures__/dummy.txt.ntdf index 6be5b43620dc63c5d734496dc1d02d92d305d3e5..ae263ad343c441990e9192adc9968a1b3f487217 100644 GIT binary patch literal 65724 zcmV(lK=i*%F-!mwY;R*>Y-n$DbUHXNI5013VRHZh0sv?!2UR(PNJa>gzYE)I)$Jx! z)tvZldI#xpc)(Ju$P2Rcr98*#Jc`Keg4j`Y>Q!bA>m?5m)4ep`NuSW@|0!tTh17;j z-M=HDx}bBJs{6Etv^PV+K%b_1Q%!+6Lp)6%f{7u+VLDxXYu`L{{`33;2WM9vlB8N8 zP4yjKhSB$(Kq|)8i;2cPGj1OFe|b-{0RRl67*sYKpWbGBJE$8iA0Ia>ec>R+0Qp)< z)vifLc61fQu1G=-Wa(nZcko?#BU4^hxVqvFjCK;6GrSX@v~dO51bzwgv!*sr4XD^2 zgeUm~6h0juhZH(ULBd?q^!)vzo?)*qw0WY5J{~9yI0`?!;r?KaqepZQ4}uS_wCSpQ zK$$~ymAL-CtuV}su=K_>R9hm%_!-1G@A&VZxLf^$YoUUskL!GC^YH%+`!qaoYcU$= z0-(((u4y50(C}(!9)}k)0Zg4ZFO=Q2jweT`b`E8cG=|)bi~H5y<&B~1^fC8FT3(GB+aoInQU81sr@ko(sGh_IdBgq&X!#(zp?x1IrGFNNpLL}iN2jqA@ zM)8iuqFWIc*lcGv_z1ezs67I8x88u+8TI}5#d!~HSo)E7|GRQHpE^m|g0xl@RF_+^ zpi4OZ9-`-I-3sDjk(Cx?6Ilwfx}$o=!Lkhs=|CI^tt=|?SNM}p(v>FCgPRRRXAWaT z+_{EwpsvUxCG>1s+Wm_YQCdZd-awJ72KO0;9b*`3YnH#-`z-E|v?M3~zLbbI zzSs;qmF{&r$M|RADt59)m{i$tm~vS+NBXj6Ms9L`6>R$;_{3c`&|E6}JVOk; z0!t64aecmsc-?85&1~uk|C7n4%EkUro#%)U0zX(6VvpDRM_RRU4bIO!`u`{br~l(` zD4Hjt2n4OtoS^|nYYF?-yS8W*M?JvAI98T-BDskSz}RQA=U=X~d^d>S`qVbIw;Den zgHe%wA8Jg3s3EpV9-_>IS5sx$g0bIvg$Bxciy-}$3dlQv`CB_wEptLj4^Ek0J{bqbAYp1xGm z-R4S?{YoBHX#aj|@Q!8xsve@|#d;@7w9PQgu7O%N)o_$z!>DQ6K(w4yur>hia@i5V_8D=>T1kAx@QA-y#B;;j8C zSee#?zIBQFtN7zjEG;6xt5;w=3%~z?7_{&^d{F z_Ew0T+8s#7Z=FW|;ZyS9Hb8c*mLC9_xdGykjb)$W*1du2qKH-Z{z`Camj-6<*)!^f zhM*5~QX3yU*4~*atuW?1uhmUY##PyFiW0i&A8)@~Q?e7zRd@BdN*as0NUehBJ zU@VFYW^RM|InUe8&4K9KrXk#PZQPFrG{WVT4JjVsW;Ld_`{i_&UH<(WcE*a`lVYhz z^}g-3r!|v-p4F^19I#-_96yo22XfrAQI&D5bp$%PFxbHf^rw`_)BCzY+Wp58JreH+ z|2d?qJ+KHCg$7ybCAO+>QlC9|phfHw?;K&0Pt5?XpC)&Czqqb_={pE;G4He8sMs@M z!?YG<)DuKczHXS^Hv-5@P>&F4jE%Oj-p7+FbIsmoV0MqbGRjO1l()`KG7fUlDur7w zoOsbeyMs}(Qm-f@lQbWp*Y(`2wA3O*SxJr2D?y-AjA7Fm3gaqQPbJdWP=){yX*T<_ zxGqRnfX|;RLVN0Klz!lg@zP7`GPKc<>0!YO~{JV~#a-3RI7EjhtGP=-(FYN|U?0LpiSzHkTZu^lmbrM_)(;(3&oZIp4 zy)B940Z~+x0kEblbGSyUiREPZ@58k*_1@qsL79Z3XxACfB2pH>J=jh)Dkc<$1}M@; zICA!DqyXACQNM03=GpUWda6G%OyhoZu_AflpAYKRP_!@7ymP{>b1d0bp<((hS*9$d(`7o`>QF70@SZ_ zwxBC}#to)?IXI*xlE%a&ctTww7xU{;PSFM)R=bnKgb)ro(}lBm%;4iWQM|GECexRQ z)2W&#Sd~4*M4qnbq_g`Dh~{KO^p_8UDx6oM}{>X-kF;@Uni zuIvK97e{#b6CdJY9+>`Pv%i7(`(-lCCnASm3m?X9dG5}HPYW=x9XqNsg*UR!u}C3C zK0~8!jC`F2hLc6QD)a)u|C!s6UD4vT^*^EI3xVH81AZhJ)NLj4mux^##X29OlH-Yl z0uxym!|wYvUV1xrAyTMTtrN;-Pd{R-NU_&x^r9Kwz_;#uzn$8_4=dMfB31(M?AMxX8b;s^l%!qsefMfkV;_(prmo zgWJ_*j<#0iBQq$5LM<}dUU zT&DNw;7?wN`s`)L54N}m!ZlGE>S3djkLR3bwTI=PX>f|wRtLXSuR7)6>RKFlyTauCuo>(fmkTaNHctg;(oQsx3g`;i29R!~)p4J&`uJf&}pVFv;%BN?SE2%r5Vrw`1yhRCvwe5=p}0#p zS+81hd>Q2PT%qx1mcv`AFnH@WTQIdQ5Dn3l45sLDVjYPuE0i%nHA>ge@cMdN9V17c z-W61feb2+`I64OdBFvFeY*Ez84>c55bVx)BoElIa%Q~RnKt)#1MZm7J*}L+6HwKz5 z>|#JMm>m)SSM06BBA@di4*nEY$MX?Wx@k=6kUC-Y{aH?AURcE^Cj+Q~SP%u{$Ed4< zJ#T-K1%Zg7$OF&$OA_wRu{q2)^j74kQ0@dq4LZdV#lW*Y&vOI{xg2UC z(#2S|t;uQbfg_c5V~Hh@U!9SHu6d^}Ef#k&xgaS}umt6JM#j=24(H4_^2}d9+&8w+ zB!%KG{{EPNMP1=pxb6PaKiKgNwDBAz8HC#F6zZ3@UVosvx3}|uXBq+rK8I0@)78twWq~zrY>|+>iBiF{ zwT5fVr-e1lQb%H0N~>DRGV3@d8ITiEpK1Gpi9dGW7M?`Q-Q_*a`RROeMw~Tc{&L0- zEC`SlK=1s0WJM?p=uaF9QthT8q|4 z@a`pxClz0WfWx&uFfhDC>_x*hWV@a|gTgMi77tC8MA7+K5SW!r0s2QDcW=D*GuD+# z95U=FQE?-qze3mGXJ6FTjY*-?jTR%A%RPM6fp{Y&V+7##iZhu z_#dmMr`96oo{7`gfj$X;tY<@Ugrp8#&M`@F`o+HFJpPnZ&y9krS?+)%S#RS+LxpMY z%=`NPUt?k;FV-(*b#VD(VY!pBvb)Wh@QP|q>8*2z@0qdcmD#_%Lbl}9)TY3CawzT#ve}oS zOG|rFP7~Zo<0=-MrXfVf=$e(k?yXToZ=cLRT=;+Yf8xR|v>CdId53nn9Os{SSSM z$(FNL{$m4GFR5uyO&X!vTQwegH0Ykmp3Pp;y>#_J7B82E= z@;sV zk{ms8@p}1-Wf^d`>}z=}!=HRyUL6BRl{xPMV6y@V;??v+OD73D|4yH>G&P5n*dTku`lV0-MPCGQ-FNh^CJ-bd_T z)SBdefKDv;*4rwfi|qYrk+%&2LesMBuHseew5qU7X*)MtLQ6sm^kU9A3zQk*&y<)O z-L`J`GIpxp|97ra<0j#fb*`Ov!J{ZR*NTTFZXNncr($15>$3q6C0VOxbGlZwu-4B9 zz>$1vECBp7o^QZ55hJ{P4}seuuvZ?q$fE>9*fZ;le9EeF^yrKY|0fHib#=t~F! zYNv<@iu0V~ztU!eoFnBdLx3J*w21bUw#1W)*3C!y=msTVc8l*ap<=9dm`^!hk8P?2 zp0V+2+^Z3>V9y~hw?#eK7%Zt5cJ+m1={+tq!sHsigPID_g$c9FWapn~7;UfNHu-2e ziSxDD%3Nhvo_z`Rl#fqzF=NU~6sF-`^_2s1G`sVL%&;JGS)S5T&qGy8#|jV;L-7ye z1;0CtgxGbQZ=BL-PXa@2Kg`c&mKx30xAcbD(*#Z;$bg5WUNrG=H>4ldDpB=Ci5-XN z6U9-S3Q%jAQ05k6*{CadKi^#XX+#U*i>MquAUxwS=T~~4I9|dFe(>r}MnODB`SsdL zDGZind26~!nV3e}Qu;WPodzY9lk=6LLA0vPRPjSPtEIa`u?2yz@my`@Nr-qIdLm@6 zR4zc%Jj$n2Ky6w#5Le-bRD$2gOz^n)0n)Io9!rs3FGVpG{lr$?H?SllsrffKm17h4 z-TUx)s;x01vdoPEVX|S1#E!mZR6?89Lto9lo3` zav$p_Oks~-z-~xAF+qXL#6(>e#XYK<3D=Xe$Y!08y`9nGXxP08B7;3>B~bJac;hhC zt*<)AUw_cCK^$!}f(4Up?9@f3{n1N4E2(Fi^F`Q;T3YnJEUG}SWv-vqXRJR@?&t*{ zU+s-)+8t^m*#hmC??mDHfzT_b5`N4%J6b0swc9Z@TqEvonggy$mF505SwDqY_DuFH zD9y(DJxa=g>O8{QvVwo_0FHfb%8|Dq#Us2Cq2Z5a%C$+39xw1KXt;3(to-xa2C4H7 z`Dy?s(L0z-4;rz|=r6ie0_X>ocOX*wvzj$)ZiZW3`VSZ~i^-m>5^OTKAcrb~-D;tQ z(+IOTj*ya&NDrkL@4*8gk-h2ZmmM1&I`~xzUF&9`0NgxCT~K_pu>^i!ab>=A<8qForFT|-;p*;^Q2nP!HX7lywILXrZp@Z3MhTJ3QRl?dc!FpM4vHu zs2+f!;^w!|(~kDVsR7rzQmE(p@@&64{7=1L@7=y-{CYQo96(dR1 z+UO*nr7mmpYZUn0XNjmv%>u^mqGlTowb?~~R)uVTwTWXX4R3fH}_@4x?u)ZHQ84S$%&~G}gO20i%H|J{< zGPEbn5vgl>K1mTII)!|F(yO01iVt3K3MYQ6>2e9bH=}tNIG|we2;Y$i*Kuy|89&g` znoYO!DaR7>r~h^ndgTbDkCcp((}1MlC#rMUzlP0EqXfW=5+%%UJw-|(Eh*N^ z(nz}ogZ<)S&gYpsgQN7PpAJ-#*B~Iz$d7i*;E8s(Rvr~_M@ljy`SZ31#Kn+W;mSj9 z*OG1ZlSejVbig%n)$jqBlE+*R^@p~hTk$`bfbRNqe-Cpr^ybiH<3u~Sje{0yG%YBx zf`#+6c9RI-N^Z1AAU=>ffKzDZ?0P}K$HpU34=7(2O7SI}Nb{s$neK}(Nlxd(9%+26X^C?lh1AzDTL8PyFMs+}4MDjB;!oe- zuPMngp_~qJ&lD4zWCmFCw2&HB1ZJ#eh*%Oj(7Muq>RX5%Y*05D&Q#>W34n-i9@(xw9-sHy_2Z~obq0(36_*i&I$Ip(^Ac8R?O$NHE|zv^Iu3BZTJ z!*mtB|NPb|lWYR!JgOX{Sd%fGFIWt(3wD$r?}EmV5~MTGpNl1g*cy*vxN z8$`y)rs8M#MLaHC;aF#Nk~t_d)Bu!8(h+W(?edJm?biLUg5EwH3+n z)k*k(b1p9weQZ5v8O_{?X9=k`5nMg^>ndW11*1hh6!rr%$yqHyqYmP7{4>Mmr52G02x`9v|VnW;L4S(*skxwqjXk9-V~cr5nFyF2K# zt_S%QmC$SBM3CcZp-}q`;2)H`_1e{Fo+O$WN}%3OzXlws7CmNBMt|ml7q1@{JH#-* zTNF0eXD6qWkz^Sg9FcUup3@#3+C6cZ4nczfXvC;WZK}KD96ZN7qhO|`BMu&~RNb26 zL_%CS&57j%f~JaRgYX&VVvE;#zh1jD;E#Dx86kMknT4i3`z-bNhoqkUQtc;FO^L!5P zq2zBAhyHhH8K{wBG2T{=Ptg-WdHK!aOn+D!=DHL;)1kCE%~D+28HyVE!W`A-A}Guj z(?kncjrIPU@^02OUUcfRmhw$@^$rC(sdWVmZDttmRUFaHOEvoAZ6hg1QEudgsNR>&6SB z@*7#wKR&KKq68SctP*fF!{a+ic=y5p3Or+HS(Dda*JbYfaJ`8O&sS@GEGzVN-&XF= z-2h0SD-ZsTxQrvx!U53hZ<(L5~R^<$g@o}f&j&!}7pQF)-} z-xu?qR4vfb_x;{a{|hOvuy1)`F-O&;uw_bLMn{B(o`J znFyl!o#OG27a4F!7*aID+zUC&hep?>YE8)WiD+qKkVnbdb|4XKCNY0r$IdBU-p1To z^`OYy?XKN#9w$D~VhY^c2yU#l+#5yvz)Pl2e;|b#&~jVeqe;WIt4MS)ct@SpU%DWi zy*)_cXl4#2L$J?Oy(OtGvwgu({ZP&2RR>uVd=xzvH(kJx7 zI;Kg&W#HhZmOPkqUGVe%C3S&>Au(B$0K=VVW_+P;0EM3utGQ)FVamHS7jCBK7o^ga zB7j#^_bbpash4_xGe#XfJdK?s`&{QdjgdcIJwzlra1o>qQ^yuy(8>=tXxDtE3CAk5 z92qY|zh=*EyEFyQAc(lACF&r?)Zu5!H$!`JUgp-6!_QD{739C5o_Mncrpuy^LvNkD zqtq#t5ZdrtGsp4xrCn{TeC!Ju9r$m<@Cr7&>igaXo-YYgza3$3Zxo)Ne%wabp53~bltjecrrTLHqY_+?34aC(WK~}; z6pwn@f{Y;s>LH=Wx_?jlln%!2!h=>dXWPIV%?E6xJwzbp&-U#-ZX@ zeQ#4@$+@>*=mGtdoV98f52p&zpOjqHAb$!$a`v~z4Nr&OgPzyjNMGQvfg^Z2!H-;~ zUwPAipfNr}AobmV_vAP=BQ$w_WHXL2{rzx8;G)o%p(?RcG%i%7)KU3S)#+Rm7>U;$ znwn*a)X!s%{z!iPwv4_iMy(3AyR<9hDGoHcERT!&Td%@f?n;4c2e3$TPK1${u{QZi zP#~*4h{#$74CE7hXr{(}Q|XjSKH|QKYo$QZlWx+ek^skP^Iykg_??T{MBQ<4Xpi>Z zx~fqqW`%b75?8`oM|;8z1?Ww83E_d*^>D%7{-jj!xH3QA{oQ{qLFjwS8h1mQ)P9kd z)p^!yF+(`_UreS|ucKCeQb~%ne1=z3=esJ0x*bc(1P2mCwVC8ep#YvjI1GE@j-$9+ z!0Q^$0+sO77e{0T^UvObP(}gvlA+e&YaaiuTTLCkiYu~ZUEV>sFPcYWagux}AORre z6Je>7>oLl>>guC$)Cbu{_B5=jGI_=WUsc6QtN7F2b|EV_Bm5kiPOXy=ffl zf*oyKj`og&YnGOr*81X)CiZk5o$0rlWFU)=^oq$fRJM3bLW1$VHMfLdp^1=~qCMpY6(emAX%)LO)ZO#qAPMxds!Z6x%;Yx3 zGa!6ed^0eL!qzsokrwO<9PBnR=e3^{cPTqXt{!2=$xN=9sS&wC+kC_dW~g=R6741@ zLbqhiTOuC_*KwRW2+s9v#3uq-49@5=M~UDdhGHlZ)wk-&g^d6MG1Zdb2hMbVbLzWg z@QzLa`A2t&K9(R)`7z+EZugYP#vywIpKT*$0y`eXFnaBAQ}m}lRh7ge4XKs(itImB zg3`_#G~`w~PEXul(agl7CX8i87)8wm7Qon*HsYC_jZ*^?98tBg=;FL$5p*+-Sf^F_ z&KUxA{8oc)`~P%m-z%K=D_Zl~Qf4>$HI0{n%c0}iCW}G#j)0V%8+AX01yjE^9vl@k zDhY`;Zuup>YpVFzX)=inr}r;#G=jX?ky(j%W!jCD{`AI^-F-$GY+)V=?a0_0AXMYH z?~pET6CYtg6e^U$w7wE6h>8Wg=0CjUHbvX@Mz%@1*bO6P&f3awOI7 zCytT{G`h!oTu3>#o7wRJ1*$Y$TkN?`XfsQklpp9I#45~qf&kB7ozqV`q|-zT{pF;_ zv_ro*wn(VRNnph@*grgr_8Pw!kGMSJI`T8bzYWd>a7T7(V~qw(H>F+5s50ifJO6~x zyfJlkVG4p-!C{3O_)@ERCCzMh6~MC}kH`BjtCo$(jv;A(Eaq8%0!YjyG}5k2&ISti zh)Tm<%}TQh-3}KIjES~g&AKQb|FNxVV&TynY+IkaxC`z|HA~WW9X=D}7iGo;GhaAx z9>&S*N=4eCxHWUP&{TO59==MT$Ii)o97EJ=2C3#aFQ`u1%v|j2eVOB8x_;+)cLFz7 zjRDqPdp8mx7+|WAET4oaHKP8iG!%->7iP^X%ej_qONA4UL|X{n_o39kHYTUx52Oj7nAf8GHCftRvs zjCOGBVmc7dvp1pbx)$Kkb0_ZXDdtG&c@h!gYw1M2_6aD=c^qMw?CI!H7XU(gNTH)nfi$E zOeu!WQ`;6*I{QWji1)4ZBu`$ewN^$j>`;|PB{8bpiOW-MGqQlZQHGY45 zq0TW(sJ?L186fNa>^TQ~^BIqJH4TKiR1{zf^4y(0N@lg`9ho;eOd%;3wK1tT9MwFn zxCwd5fKf6MTCm`-X9Y-?nLddHCTG)jFaDGp!fHx&nfv{S`JBL?MQ+Ov!Ntr8Exp*@ zM{|w-a`Ov@d{ZIy(?BVJXN^yk7v6OP*agF2ef>HCngTb#Nn{fJ58@?_D4W=pf3WHx?ws&I4@q+=$$0vzBLB4XSe6Eht3bj3>-6ral zts~&t34ynaHs^MnN!>V5bg{78xxPRTi}CjBgw zXyJv97gM?=P&W9HSMFhtE;hkOiMgpZ&%)!nW9NxPc@`p#C>N>+%Eh&CQP{-IAB;vB z5((}q{IHD7ie=-W))y1p6$JcFA_a;jp^vuB@DUtAj4OKHqH*rP#`qOxk5tpj|y#%SZC>Vk3nH6~*C0FX=?8MuGBye2Y4a7JEH`9|rOaX{G|)O@w!Q+>@7 zSI`M3uKeFFft1PxIn>tzVr^Xhz1E_~z*`4!)PK}AEOO;ZjpNdBdbKkQNDdp^kb|*c zW^=w1F)R@A24Bh1j)T}630lx+@nq2fvMT35uW3LFWJzrrZAt!YaIpW!F$K9+!1Cj# zbjReb8E*uV(K*d}oh2Qh$OmYN=&do(9b@exG_BuUw4|6iIZNL7uWdfNJFto)nZ3dV zxFjrBBB_HmXO74v!PT^d@}{d7tE4l=6=o)F!Yt@0*p%DBk~!4AnLf!r(&$+qg+)=W zf?9KAT??nnLI;Dqofm%&^{V`XH~gB`Fs%DKO0h(+At&Qom_*<=^Q{2{nH!edD|BWd zEW^NtlxNRxEt7N-i%l>;i{CXF6Fx~;V)bo)yaWIQgVZxlB_P@@QsC1?uaqlrY8?nN@fLvyV(??Qz@ zMMhIm5X)Z-;bpY8D2qCGBbvs<`WM&=@mXVv!{>8jurgqizCvDsPY8K#GRLXJ{$eBE znVxZi{*r`M^biV%3AV9gGs67?zRq<#!>n|UaHj8(QQtIw8>Vx4cdSZl4$`?~@40n9 zfu{vMoJc!+uo!#7Q$G1XK1LBNzxAka$XFL)WA$-htCY#d2SMy3weyCd#iW57Lz1~> zC=Esxt@sZ0kE(f6I)dFh8pbNLVHkH6ozsaP6rO-rk%&N(3xFU0nA)7aHKSoIfO{}? z{d;WlL{&ZIHsa7}#5=H&qcc>AowFqu!T13K@s)cCqBi$OFT1>67piLz;l;Ki7&H{r zKm5*2Lig7|YEf9Mff!JKW`T=d4Q#bAR{N#%T9|ANrDR*6Y5)t0m7r&DH*;91MF$Lq zu>yUxE#6vCSX5Kx^Vh%RlohL##sLtHhtiK3%8yuw?^5kX(8EeHKj@1SSB3xVu##MW zZ=-oCI^a}awA;=uTiZP|#L)#CQxy9;7po79$F6f9i00E=N*X%Zy2)bNA#tx=0p@CS zEA@IQbM&XS@xiI#-_w@f}($wA$c@2TL95Tpm#jFS8Zm zG%8>Vz}n`Ijl`Yf^$+nR(Zj>z#o^A7sI^1}qgx^c+ZqfnH#KekLU+IhrCrdnx3U{Q z-Ay@_IExx<>#QxkL0s$jr_PY`y)%!r5u748+|@c) z9&C3LCl~#Q&{qrm$npg|A|?H1TA6zJoH{aI!((>SBQI`*r~BeyPe#-Nb0fPxBX8ue zpGcmM^3&|$%b&QP5axpAtsru#Q1Kdvs})a)j~gJ^vIEuG&H%xgUTh>%WjXY#R~!C@w-NW4A+rzxtl~O z!WbDikhZsH)h(r1l5Bl=C*jQ$;^#m@C9b;mXzczFGBK1kv`GSubAtk*S#b>{k>U7r z`vNIUhB;<7hbhD&Idf~Qj3;a86#f;4*hK!5xkf%2bO!P zwObeEOqAks)nA5Aj6zzrGy*AsBe`(B*|YP*_FeD4^;YMe5G3NxWSh&2kC7sew^B>p zpqSHtlDf46y^W@EP6!-iiarxjw=Ts}HUO+1E&eu(nwzC%F9LfR78`t~BWI^llrks( ze$nrWf6Q^1+evYos zrrq$cQdlLqg^7CsU8#no=_2%DjH|1~>z1s*U!W<`M`wnktM|s=2zqZ1p%8!Y#jNiL3I;`My_$)#3oHP}a(2XK~Z) z*(xbZ(YKLrp&bryz2Feqm}k%e#SB9RT5W*RhmrD4&fVnZ+O!{S>tvRV#jH_mRN@~; zzgnK*z@LW3W}}u|_|+>>_mzZ}Cz=c#iBTC1-ngsQY3U|A>DV|QH_rRq3$;By(LdVVDs%w2xWnAV)tA$R!L!ct6)NYjOL_!q@le zoci$_@Z)#stnef0vzi&xTk9C`s$$a>w`sFvO(M!@YRya5ko+(s0mv=59Y*u4NyY?NLK%GO>Nc8ZQA5?|!9P zEZ?OY4c$88`D6NlkBqLH2SCecPsI6D=wlgK&1G(J9K3r<8WOrO!#W!WE#sI{)rT!X;NN8{yT*X` z>Lymp$}P;vl~?BeXYzp3E7NG1k}wK(R}zGaRN}voTMM=E6yy~m3Y_!YQ2vCsb=WKab}K`*_xamA%;dWWT)##tsVIK4fZaPLKKm&dc z5o@|iYfE`~HCR1*DJxHnd>2qI(O#o;+LaQ-2dU>bkNR_3o~>;bwQ^=-+=B$CQ3 zK?3aG)(!*co>acIAF8umseusN?I5nS>c%M%Mm63j0F)IVyUUv22-+x z>*xAVWk+u3l|lvMT;q%ibRM04Uf(Y}xe_YjJfQG6&E6(MaQ8;kcAhq#AQ3e^C~)H# zilI@!$^0w8OAd_IX%pkPAC;Lo+ySIY)F&N~slA%aE>Q2}L><++E=FjU-$oMPY5)@p z7j7{(j!cv|4Z`~{v=Kv>zURI;uF#P-@!uuf)dmgIc9*s4!DW4P+l*@z81WezAn1^7 z5Ge{Fq!J>&@1E@+Rj)!1PFekaphZ@n;!NvtbQQ0sDE4;gxR2)K>XyYQXJt-Q8LBd3 z6Vp6=a_L={?*W2~gc64o5Re0Sl_zHIiXIP8Su7RrR4|oUX_lPB*{dkEDDi#t4UXR> z9CzK^vK2p8U+BL&M;pJ@mEj|qS;{>H3>Fo(7*aUBM%?7k)=A$Wd{kwAtn%&g6%vqr zXKD9{adM}cJ6;`Fag$%+ou`%M{XnL+AlW5?fS^5zd7kifZKuSW7Z)L)a#y0(gqng#3hNiIUMESC;5>W6A!8zb%R!mvvwG zI1Q2(njlBjw2tHzZU_){8y_jkQreUi&Hm!{7T#A0yKiAW#Go`k&wm2+M8Q5_&W>{5aSt*#m&7H3Iy+hneoqMf&d@vSNKb5ekVm1( zsQak*w&bp!yft#u?d><>Gr#v+%-)Xi5I`O1P!WeH@2nLW* zJR4vkgR`}33df0gY7FgWNUf)hH==a>LC|*02gO~|J;P*~SA}JNOx)R%=^-AT@UXr^VFHwUSPh1ZdwR*y8uWYb!b`~d7$jqOi{m7!oD7ho5VwZ1OzeW@& zkRXWRWSz!RNe5HgclAZi6Kuz(ED1t|+UBLa?Ys*UaIJT}EuWkK;4t8k{V%)L<6{$M zFVwI>F`@14X&`(JTJ4RMT1P7UJhm2VGr^vXWZVBI={AY1`ie_XB*5-)9p!Y87KgZV zuXS^{O^4@}H;8Ej7^ka=x;n6H;rbIR94xDq^cFL&0@zUWo3x2JvU|KCPp)rR_Zc`u z5H1-Kv}=?qd5nkhA^sVBOqf}d8d#%!K{&$zPCsuAZo)dlL_o%3sPcv*4lipe8=;ZO z)FdF$^R?)r-PhV8?CMcq9{!aKBs^1j1~KXXsBAq*mG>EZMt|L3iZ)ymViRS3T*KN3 zRlhfc0ov`aiO(x(rT<#3Bk|Zf=Kn^9#{DMeeOarKioc(P$c&?Y;Xas%K?Bv6^sC4= zk^g62ZqxL5U9$q)Mvn*E0bHRC2{~ObMbHw=dqB@q9|T?6!j7aQr71`zeWqt%2V|l< zn*j$JVpIsAAsLg=$qK&O22U%ExX?ChtBeqt%7by#bNKiv=Zf>1qMq%b0O$jkJ7rB7 znfv)6$=2~rU_5b~BsUldc<|xg!LBCL=`hUnwZ=)c%a?414$!efPKTXEnZ7{EiQl|X zIuedo@n%q;saR*v)|VoiGGHD-$c2AOD^R)XYy4A>=p*s6&cS8b4`_{oi!iNuuwELg z$3;2{*UUSs8ajRme=*-sQk+mUiL7pvsu{k2gG~|?3rS)a0Y$9_Do&%#hKPeFu!zD8bOY+12Mf>H$ z;fMKtMRigBcvt|Th+?o!uYE}u4NET9owpd%DL-HR3m7YTS+Vt$K}y8(18#lPy6*3( zVI0`3s0}(Dw82fDenZ}*QmPgC@Pr-joJS(l#Tq`yzd&5uhU?a0WL+(Ov9C(0gSfAYRrFakbWA&K3=RNg6w%~Q!l zO#u?|2Jw6`(_ezq3bss0$f%5|jVVwJ4&dM6SHvex%l%@}8yZ4dlYpY1iAY&Cfe*kK zXldhA_*(NP!}-8MlxNP1O+Z`_kmkRHp=L4xJ`1iY5H`9jxy6KLP+s?p3Y52g+1zMg ztXwZ;8#)I4Zj6@Q_`^`_mFusH;%p|_#XP9>{ap5zrQ4Hput$>De&37JXQq&v8o28H zi1R%E%Gi##`MMljHUBeW$41iQ3T+qnRQZ%R#F@*xqXAgjmPu@W#u~fhbK#dD$bRNl zJ&_{zh>Jhe3JC4PNbVlK6i>v`vXK2Fdu5!$rvAg(J6AsaKm-cQJ53ub!qNvgQN+XX zDy&_{RUf84BZle2KcCj!=*mrwS+wD@ZE#pEvU4^+N<_Ssx*CVNM&MBP#joG*iGHhs z&R#`r79H`98|UEFJO0NH3MwCANl?Pj))2{DVPi+X;hE2GGkCToTU8K$@Gv>P3E8PI z0mtmSh|u@o2dBI^v4FLng;S!&){|8z ztnW2YjH9yhC^(0@p7|knp&XP2F!&0p z#$32q>yESh2B)@%KL^5yJ%@}I46i6c5t=zx&d$ytHK=*(&An;1=qbhmjuS;#VcwO@ zA7{k&I!9Vye7r34KtU4LlUL_;hEdm4`U*lSrpmP=?8#s|Vx)R4}4| zJMz}J!b-#OrRQwIM^8Zba+;hBvLJu_?Y;t=x6X>~yV*Fgva7%p-HCs&jSWOAq`6=d|M#&De-XHmgl#sACy&^~qJ{@fe9aA_&T zG)vnIV6OtUI*au(+3Sn4O*4&BjxedU7%kUk?_(rpH<`_xOHku&If6@skzxU>iMB4l zj}Ho#%y9ByoXS~ipQ8o+y`b8>08Id$gj3HDllC6?E1p4 z+PJ7jr&x920q%IIdJSx0p=Bcv!r7C{-yo@Khr7LV6ho?>AkL1{R@f&@kVnL-6 zxxfX5;yl~M1>_@vYzJU%W!0v%={s|-Up|&p!z0%?c7%QCvJS%M7n-DDGat#l-KH0< z`UHDRh|^MAs`ER!ZEL!mkpsjnU84qilQvK)xshGRR^oZa98yIZnL-5eIKguBKIxq! zSF|QKuvM$qMv7AK*^|A zZMT@*|1%O``mjexpUY05Y5&7#B1|S{r-hWo)h@bh&l9U%P!eeXch zLah|zHZ8vP4aL8m#%c;e4#JTA;;uR^!f7`EKM595=WW@YrAukqB6%J3^iatRqu`i| zt*`9-6D^yY_4D){AZp!WhVvut+1}lPoJnwd_i}%ka~TFJ(KA|$EEbB`Coi1#*7>GF zyWLC}|1po0Jcf%E78ydLP2J0M&>fhwM=e}=Tg$sx11njpuTU}BF`Js0TL0-y3$818 zHQ+X7Bhy#)=voQ$wP=rAgpVlGyFd6-sPcz+l^{pDA&vYgl&1S^pK71&GxyPlLPlsa zT3hR_i<6oPv$eikZ)>ll1H>5AlJMl+Wi;D+(W@Odj4>uQJ?kncFNsLh;Z-&2It!2H z9`l$C-;!U*AJ>1P*l=6@z_8@hWNmwT>X6de5OmH4i5Gu#$?1L8JNQ&p=ku$n#kBKIbKPex~|~SYz1CMXnTZx!+YzBA!J^{c zg5Q+JP@uENWn4{MK!m;UE#^m16@r`-p0s&pZkR#zSE-7yf50;XZKh^;LOby456lY`%y z@u8gz#`ThSjI~kNyI5ro-LNx1{A;D44mE{oOjiZ*Kcht$ueW%X3T%`|)|bR~+RxWG zmLOd^vV%6?5e0e7<_-hj(10q<*7lz=yLe}RRZb}lr#Q~MjCkb$6_9qv(caU|(eVa` z*?1qW-hcn(6MBfh+MGaTf?*{A(?y!m%m`e+J>&kHjt2YizT1I||2@&e@)V^^4Q5@J zUfbvSX<)O;8q0YaXUPU67p)`5sC-?Bmyo{pN8DtDEyfS(X~ze~7L3h5m;Ez8>T&_d z1(AQN9llu@2Y52WFU14Bh@}_GJx~yOCxN4|jbxv*=Qjlga zaF809QzF_FpCs703u}quhAaiyclcM=#gGjFF3Gw;<>`_g1wkm5qr0g~+G^91pnAH- zvz>J=r2xg0lG|Xm`u{S$na`O^cj`6fN>aEV+BnFR-pm9h1Mq&H3B;4?bHWan ztlPZeU(;>SQ23DZL+H`fysVMhQS|*hvs|;E$#V49&%q$f?|&oHWYV;xnX+MDe2 ze1~KT``O9gV&=-KHV~9RH^Rn*AtCb$DNwvUQ(fS;2sccJ;Oii!Ej^=)N$W?$mFA#R z<7Yt$%4XvyE)`1K|2KmFfTblXOt=oI?b}WyT`suTau%s|Ij|&RQ;SJ5XcyaOT2h<3 zXS(?%#6-vK5#H&jSs@XbVjBOI`DY$qUriE}eEg-%AQ<3wFz9Rg+$zM%=tyO|{FMffUU2)xlO;7%#1|^1IwQ~N(^SPCITF*ucmRfe z{|SL&pVhX;$@#YNlizw-8?1AAZ4rbHP8bAS@O=*XWYL>vYnJ#eLXqbxr? z%>!4o1Jc3-Z9clzDB)W%dLLBygK+G!$m?oqGcjf+!A|t5I>V?3=nT#>s!ysD$e+|W zT=odmXhR4vySr~1a2Tk5k4LHxyN38%Pgg< zk4jTSrNeH0*#A~HMMO^24BvI_YZJOkz9}J#OIM+UAy2Y!_fuB5)5=H>Z~u?wFG;2> zakh^#-EQ{S&t8PCihif3^-%E!IQR&T!|zSnxwsD1P>!5FY7cOf=_3eyyDd=?;54er zu#yUuNvB*)>sP3D&_M%aOtH(`DH4GS{@@ZDK9bj&eiuY3*@%G%LpT_Rlo$Bs56W?B zO=Fp;A#rQLLf6dtF10nf$PAswCr!k82%h^Kn(iB2B+R$b9%o;o?!%z7J0T2}Rw zQ~u;RqPh1^5teIMk7VL_9?kGwRQ$&h_EAgtO;;hNp(L)>y(#IF4%vT+7Wg4Zz=aoJ zqHtt>2qL2R4kU=uu0BrVUOf_|!1U2Bk*b#Hv=m;Z)eU)M0%T#VMTZ|RrV;LnbG#m1 z?DrXwHmH86aqwiJzSRU^q3^;0mXwS`s@v+IhEiLAZIxweFh(>hA5ggUT!Vj%1m$GG zP-XBry+@jbgM;>gLKnA1TOU@%iu8`(*Yx4a25`Yy1Z$~-5?*H4V>0&KU zCptIAg9Sa|q4^6HF;N(>^sCbPkJh{W2=k$+Z|2*;SEj?;AxR|ZvgI2Wi40nK;qF)~ zQ*&SNt7i6UxFmxwgI1y$g7^6!ZCX8itIpU50l~V`uCn2WlM4!MN$>O!k=%{`J;taV zX0=Yk`h)CaZZQLEE(2bFPu3^}h_6#M%F=xS@Wm&PM-N!l3+kU{fgOpwA$X5^x^}J` zOYv+Fuayd$Y5++cGx1ep$+l?z zW^*gj&~n2Z>_teag(tKkq3_KepblmC{RWW_n@i)A**1i7k8Zq8r~JhCY01`*T66_W z9sg1q$_||nd~jJ>%2_M5D$3d@T!th-`lu$Tsi}o}w{n6-bsJL<(wYFI^T2-K^;N z;M`SHHmRFX%9MxV@Cs*6wBkr7_)_)C1<{>~0Fe{@s+E>s9nIbYK^PjbH2I4*7z@Nu z?m+lc_I&Y}+-Xwo?XmS#TZt)3d(H|B$8mn8(H4&Pny|7O^72)FRZc09sG{=eU2cG=ZT5q0*nJ zv(w`a*;oH1$4$z6eQV)bS%n0n)oV$lI9%+F57~&GMedfkH{TxoOQeYGlsnXkFey74 zpgJ(Z53iq9U+*A;r~e0l8M_SPc8rx6l31o|+POlZ`U%b5XpdMa5@;5#JdNj-qMyhI zj0ZOCj!onO1w^S#?FcDxQN}OlMIJl+N92XXD1cZhi^l+*m1=3c$~>QiAGwDCQ!T&q zB4Fb@!OT@a3e*nPR;dPVhBm!>*`=i+U)C;fS(VSbT{I477>9TZKJQg}ssN^Cy1#@S zPQm$dbbZ@djS9U=bPLS9X${B6B->8}dq|UHZK~XtuRi%~Av89hH%sg91T7rn~MMcKZ65bB7owuAQA<(>$J9 z@9_#Xg>f&UiWJtb;qox#b3J#Fx`sIepA6<*vc98vk{<3FjHI6E8D};B#F`MgXgll; zeHf;cRIPge7gKK`i`@b4IT4=!H3sNWADk+h^CFW^UGjda;Im?{%+P`K<1AwrN^+<6 zvCVx<_=FN#b2}$y0QByQRaO+}+uHDfDie^(gHztB#tj?<+sy2kLH3WG1u*Ex@<=qr zFPt`*xR(b@4iBH31}3liG<*GT^~ij1ZIXn;`c%;+!))o4?Amy-g&vY4E`~)~DU6?{SA5S<8#-EsfUW+H zbZT+1Yly-4!|=bA_4LPaC=&nf!h#+EumNGkv!1F`U#H{Ggt`PkQ7Eb?vHap6*0F7< zFU|;FSKJKv%Kp;I_IM{0@F>n@F*A<@ND=1M3az+~3h6hdr#?)ULYO`>@pIb<-*CSG z@npNg;YHoB4cm9g3ZoIHS0(N?qDM-q7-~FhP+t7ON!sQ)Z3&j>CvbXy zx=fu{d%wwVn{7Q(K-43{x0OA0!~aV4$mczH!A|;1?av6$s?>VvNd41P-Gr?1F5nm| zyIBBGPUA9_Kt*i;FceJm5A{~LEc8>cYFX?tf1Oey`0{8Y+aLxIBvKylui<6^QBkfx zWEIXB4up0AhNY|W`aLw~Sa_8y#_zp1d$AxvSOGM51C!^A1U3ev<)NE!2a%_0*GA7E z97mbY#@}c3@BnTguJbm&9?K9OP}F=-jvW_f7?*D#^Dt2fvlaMlOG(YE1uO-kCzDQ~ zRY)Y)hD3fx#(}}Gm>*q(4_>9u^km#L@6xy%oHft^y@FY;k@6~IRSy(RjY{RtJJad$ zD2tTMi-y??Xofg|WewP}!X>v#=?HA?7E?R5=FsQ7N{H1&@t0ftx!k9t|DD%bI;)+cRwxIc+itafe%`iHV$pilQpd?z)y@9*Ol@w?iv2;6wI{C^ zT`B9H<*>qVWP=49+4!_KJ!pOpg(@N$yI+43<&9PjaEFX8G$Go|s0j^9cIFv>#J3&H z7W!3T5#OELsMhUs?!2iqTjcCJuu|^#h$<+2B$n`k5M2B|yNg&khFD-Cd?DukfKjlP$U4>rst~-b=B*HEYeG5VQnQ_safeqT>&nF0mK$>GCHLob0a~*S~U% z-Z`2->(3iW99fpXXKz36YA!-F@u()6(L^B#IxIg<(06A60v0Vq=ZKSED=nkMaa}8; z+g&|=*!|6tlG#{#F||q9b>D)~5%_>OkA1aLHvLnVBiz&}p@7>4%q9*H8JO!}u7K9? zWAO(uI+~-@B^Bh`&o_XqWx?cvdQ;x?`WOejGykpyp&eZPwi51;{R+|w7-{ImBnUPt zFIWx+Nm&e*?iQabuX=oHl4frx-FJr=)sQ_$5Yuxze$>4_D*|_h$c&H#xONOS@M5NF z>GJX{qfuGcy_(*|U?@9ym@{|GG+N^7_fw7!OX^rSZFk*nTl;^b_+aG9j@ATLd0(c$ z$-xnsJZYAN{e(`G9s%`USok}$f5i?^Y+hOPGsNJ;_o$f8)MQfxTU54c85t_=A;HlQ zN}zaM=)o^;={gatwUG`t4C^sE1mJi7E7`%a{Rag>h=R#hixhC>@=cRg>16D4YbgK- zwB6h{@G(BpZ8mXKISecLf8{MgA!J9GlYWUit?Klwqz?yBb2!rXhSYvg(Yb$C>4!Nu zTW1rtL+`bQn@<1BVNU6simMNdN?&+xjKeBumetu8EFib>g0TkZ zgnkPnOS`I?-h-MvnFY65!%xmY`RR;hgnmo%4=E99EKV<)b_fuo7Z9ucFOhm08Ejnh zZHCPgEb)n3NMXo;xcX&r=$p;7EY@*^b;X_qJ>3jDV>B9(!vCWmRO@QN6G#nvjn|}{ zfl>F&6j1#`1o!2=f&A`qNr%O9&Q3I`G`GIAo@p=vH!h4E;hfb0SNB^a#O5c@@(O5ZlLB^)R(HxIhv0r17=)0(N z+?Rd(GPUD7fuM1b__TClsI4X(XL5M!1FLmpN<59b z+xoA5&8U=MK48c!?i2Suv~HhpzYU;T_~gtO^(qw2fD4osp&xZQ!=V+JN-XAG*;^Sp zTZWO0U%-m+6JStSBN;Loq%|IVf$&_0+$^aIdTSl za%SDmU2DiV@d4i%i`dsn6RSgjbv6RpD*_XeWY|!OTd@HzDGhY_XY}lu(_YiBV{=$* zHJtDSB$|Lm7>9!{UI6ot5znOD5|XvZVtDAB@;Qvw@MN#dw7RIERhfCNjOES_`SO;vOV>j;R5F%mFycRHptS*} za);X*6U6>F+-^nMFFZA>Jis^t{rw%bId}__6%7D0Cbc0W7{qyZ0FK{%U0a*ftkQg^ zc)kr=?G6`$oT55_PcJ@0yLg*)z)p_Vb&u_r9IC6YCrp{)?Wt+;#`Yn+!!9Srx4Ru| z-*SRY=RaaZ$6Y>ZH9%oV?ZW(1Xam)9OidMo0J>D_7U;rRU)A>}&$Fsx_PJix#}A6K z5|~d{rJS8C9T6(24W&O>2jw8)Ax0JGSy3q$AxBu26@&gG%9tymbuW7`LdnsZ7vcWy-nlY6E1T zxDy5e5pi=^wpdP+6|S!&t|Oi-T#!M%52Pn7p-h;oYz&K3N~;azO&e=?&03)o;;)3K zSLmLc5y-gn()Iqjreg1!8*}IsR)cq<1gIo8Q>D(uAmLQS|F`jkVQdno?6|d?x{j9$ zFm*6xj@|#82MZ>n#l1CR-gA+6a}4V3b^`^Jx*v;P25y5(kstQHi2Tb;!(rAJ=ZNH1 zshKpNu}zu(ma8O_4oH-pbs~M(9Fh7>-E&-jr3WZ zUucnO-hK+7Ti+I4WOJhNRvjLbKQYJm)={J9jQ^p;rSO z!24)yGwO`-7z6xwp7o2Y+8?0d@y`SnA$fQVN2`jNM67v@^$}nIml^Aqq)OJ+xlE!R<<6m39x)UpUZ(Km{L4h>Yxdoe#r~Q*kQ%7 zWGN&Eq5$wC(~Ls~5L4yqN2AG@(-uN`; z^~u@Lt4suwo}P;h$QS#}tLew8{o0cO#anK!`QbwsxG#-Xzpz~URh{v~29@-NUTo;H zs*m(*?hK(#8F_$-M(o%K(2VyoOre^i(+6FiYPo6)`QTET?F(muxn_g9Y4ibec-1K1 ziKx(Y`VFaKN12AI4A`mw0QFm#i;@naN-UbORpeot2(y~eHBtCD=!q#CdCKaledU1F zg;DhEWePOfdVGcf0>%o&q5%xaV?%f&(S2SSp%AD`E1Sq9vJDUG%s@=>(}=k0=Hqzi zt|VZ}7{Cd|!}@h-nY3FRUyMUPUu8Wf0LeiGf}LSd*oCUp+Cw7jzsN$Upf8(%mm%b6 znLSpsrv$O{j2#)6V}f1APzoWM%H!&$M`WZgLRbw_Yd59HlhPi*Onw`pC8G5rxBj{B z9;8W^+^-BEF*m-!ORKwpGj1&KrD(jz>qzsDEeCRnHG=Nx7L{Cwx`$(W5-gZVc0X1F zF`pNXI`jrlK6C_IzoeF5WnVuMA2RD>>iF@FrvQf`zOhtfyOuY0KSSJ;U?DKuaqiLN zA*S~(Od-0vBtH(f37!Qji!p=UYata!Hp@T9KmZwc!UrxsDDxpXBx8QuxX$D6ehDo(ipE6`8 zd2ar*;r#&@ra`B(w?_apw;1V6EHi^ZuWTu6t=b1DWE6UJ8S~#^=r!EnxKdmjweVy1 zW?1i`c!ajmMM)3?xL&2{#z`uju5u}iMov^wG>jjv5EasraI zjg`msFF@t9LIvUk@@FV$Tm4rkcrWtE{W2%wdXoz?5)8sy06$9_dh% z15f(KM5XNjA@=Q}eZlExs4I=Dt9=lC1Zn_cWaK#R;@xpo&4`H0NmCbvH3PHI6qTRy zHrw$=t+{`+f(fz;yD*qnyalVhQhzKmcOQ3D#ki*Rjdu@uwWpGT5k&o7n;}K*o_jp5rV3fyg3lr3nMREmB*j7H|4#`hnurz%slqh^yR3I|R2fYOP;g#`@{= z|FRBwMsS1{MQIo`F>`)#8L%zQUAHopv96@mRfyWptO(Mmh6;h1?i~T;4=P-C#pq1Y z8iAHR8b?z9KaK^q?a=Za1R;BFux6LCqUFMF+0IUV+e5=O5KBEopuXGFt4ZS@-Xdb5 z=u(Hwmly{w+x?XjrehXw<#Kn;t~>rvoM)nn9@irENs~lZ_(^E9+XpOJ*w>rf^D13z zLqVM$D9eA#kjx5Sq3zsrliFWL1(^XT2e@L4>@SmYh0&W(H{XU9j?A@&7xd2OUU91A z>KhYaIU6jitUq7)->>Ndg*^<;elzE8RxJlB+RGi{&@fx7#%0ZN+u~8L_Eb-vtE1O+ zkFQo}0__8>&hf1KQ-~x&CTLcW9qp&%Z%42b!0*oS#jA`L!^jX>4TUO^Y%5Eme7qr7 zv3>EYzX=uJw%o_@Mc_}ij6|D-ZK-hF&6BKrXAY7bKNL;IrfIFid6FWS&jP|H1C`}> z?3_19P|LE=li=)xkLeKTbXlTG&FU@*i!JyJe)60Or{2P-Vr2%V5)Nk*e!jm638q_M zaG2l0C)t&r!I}yM)H5IHdsY<)n&SP;0rKx{hz}^&MI|bi>3WP%+SMSG$&nk7Lbs9Z zF#5>EmJ{kO5@6rs(!yWT!dQ_SO5qZlNfSa>Qu`-W4c%t>AXAH2Z3{E0uPdCXS^))K zyi(snRyK>-(F48T%2aC;{an|B;DhUNjsxJD_F`_XLev^p%fE_h=CZ5EEu&(A%^orn zm$*SZvvXl#6LV&w=@9txZA2BC!6rs2mLMxuEG8P& zbD@GOBA_1-Wx}2R&oct+=v5UD8cn=8Cx2Gz&fX8c6C_SFvx@O1Kg-A#Is(d9H7ec7 zT&)vIKA@i4Gp28CxXnio06Oby8L-ZkLF2mj998k6aQPxAtsj4dCg z{(5{CAawrTTpWuww=|#cgNus{YG;UOU|rTcU40FftzUmSuikl&f*$!PXr6bL_KKGE zujy|4R4ijj8_<&RJw?CI({_#pFg2`boc%MG|919UCv-+`4gF{q6$I$!&5r7=| z{t{F3B)_@<2E9yf5G1E;%4zpaS-8kgYY{@+96cK=%qR`ss7S1oP$7c-l7Xkr?Q{xNuqkbZQ= zpi$+(ia!YXBnz)o>>-|koR&G?wDC2OpkFG@o8rEA-^u8J&Qk=g#MvkC)&aoe?E=@F z0iyZbkC6VYuBGKxLbKUv2yG+=pf*>r0@@MTFB`rKyJlZS`)P!ei}AUl|2{Np_du2# zv121U{0V7$_rlJCweh=(a#M_Z`BK(FUIw^@$Z9c#ebIa>XfxkJBf$vjg4EDL;v;fr z8?~WT0-VAqU3%05LLkn)M3#Mmfvh&9Ikb$dXjaL={lSXu3HBPw)abB$$@&qu22mHg zWmzC^sXABIEu&>(e>Am-7;Qm)e_kRJA+KS2Zn(kpHhiby)(#U&2&Lm@b1-g2?Xr=b z2iK@$jrbTOe~XEg#0bL0mCD+SGvq{!yWr1+2h!_5v1+_jYBH7@zEPd;2cKU(>PwG0 zQ=55|m~t1K{K=X=wVH~P`8u-Va35Q)L=Z`QcY<)~kGfiOO-S(J2W)H)T+{L#Acs4G zWuU=ZmQm*QKWN(%l`?`KXt|_}qEgh`2Z<3}v~Sin7s{5T z*F+P`GdOiVWLq~E6341yRLDmT?D?x7QSh1sgfs}O9qS5wu1Ml9fM_auIgsGORM06g z=oY-F;}-Aq%$1{AYP;c$X)hsT!TD3GMNY}jJAMlZ+#4yVJx*AgS1QwUT^BX^hZL(O zS!Y1!n-(ujH}9!fog^;Z!gQaOdow|>kz7Hq&tgL|@t)dJ_%|Lc{f5go$jMJc2;vr2CaIiRpGT>r7?;e5JIoDd@ZcU{!R zLnA(>1EZPnuE0C$ao!~!nAEA49TloPQ1S&AqlD;#A=4GOiVZzf^&vyT>}U$MlCM{v zP36Z`v1lQrQP%VDHT$Oupl(3nOKWWU1${o|E(A3hVoeqn=R^t+MGd-d0q{4JR1q*Q zEtiY!R7u#554^gc(2>`tRRBE|$|j=k9?S;)_j|gPw#2=zUDm35j2P!=Ar#jz_DT!z zx=~fVe$$1Vj5<6#t;2y6SP-L8*Kbi?6uMY|WQogF&U!raO&^9&lYe82=@6x)*Q|?P zT$o1A;!UxToRC&$28{W!89tP7TFB8O2=lVNJIoD9FFZFqRmEY5OtT(@KTUmuzm%=> zM-fBj$-S{o4@}ws9ue&~%+b?>6jw|X2m8P1K-93$P%_(kb1_t#_bsRzUN5@x zB%~COypvK)M{D~fFNE3H%33Xv+BXeqmPTnKx2^VtoL}%(j>ej-WSbso7BzG-g>X=IV zwRaM_v>?R4!fA%!dozepQO=PfRj#2`2A;AY~V@J!}d=z*SP0OIpR0 zDrp8H7+i7( zTg}@~ngW+4>aY7xP(GI+P`5in9sJszuFT>?XoI6~C$r z_nrw>MDSRVUnV3dF8Oiy zMkMTOi9ek_4h$)&oCg!2ltAj zruJqDegs(Yf!d$G4}t-+uUgf13$CoZnDQW(k~Yb?$PDI);7{iLH2+@8=JEbq!c|+R zmMYZJ^U=St>PQdzo%w}ssii#jd8I~meQlrL()j1rCHYOl#2s}uP)Qz91V3%VpW*5< zc{*hG7ul}8n46hm{l<5)(jWNhEWzwfSDdlF2vei#Kg&j~V}*LiqAMk$V7F_|X?4AH zi#1QF5uKS-OdKUAH^_TP!39eg>Ddc6k9rq`N%Y^C8)Cg5yi#5MAwt2vF(T%>56WOs zY|i!bvj0$wlql4b-QhlcdnjGWnj9LNaxh!qA8F#7poGZ$b^f^^wnAnJBy*K`Gw(SU z_F7|$=r~YfRgy^2{F}E_`3&ir^6w%wC^K*Hoc<#-$xGyz#A(21D{fjyV!EgW$Cs?z zeR%ZsX71}c&yNm0QMW2ElOOp2hTI`upWAgbNqkR`Z`65`-$XUFYuFM6b0oDl4$|@@ znXkCk2pmZBUzxXvL{mn_1{3N$KquHs_A8|3LS9jA-cwz$^xCq6CX;F3SpSZ>8~&pc z7A!d3SXG&0vGd!XS8TsOr8Y}X>Wx!!cTrkd@E7Tp%mtERKR{&sV%u zn?FcH*t@*HuK8`6+0WhPG>uqAA(5XXh!032A8kAn)fXsneE9GF;Hs%DR77h>Q}WeV zK!V8lpx<^LRhhNYKAMlHi7Y(UcTVTs?^AKbq;!^w<`#34j(^WU;Ir&|y{`@bX2$jx z`u>Eb^) z44Saib-{}iDecVSY zk>d+ED$sKKv`aI;^Dekl0eB!u`DF6AtQ-|2e_m z`$>UfxC3k5znvdzuHs?HVs8P5!oRznwoC6lIM#HqQHrpI{?3GN>!8}~U2&sPwp!FG z4(Zp0ObLQpE%zK0cELLQQvo9P*KzuLGdAlqJY;EZXU{RZ+09>x0!q=ho3o1T#m;x5 zm?_yv$xLk<3K{(L^3W~?bJYgUD2M37Eu-`Rrz7Nm;Xv%Y=!PAI_Bby_o&i*kXszE5DCZ`a(FGU|0TD zV$Ew3cNAGtQYo=w%>m?37%@qET;>E+OBsNrZ9^&{@WCw4F4Pc#-!^RKFWi;i?)$C2 zKlEI8;Ga6L5EjC|Sa+wHZ^nCRd@2Dno{BSrgaAc~{#*zZbV`V)lUO#in*ASucbn9m zSJCaYAQGdSM~oO`Q$x1IBPce>nZ7t^TlN|~adKDjkpA+K?D7;PcprJ{f6erp=w%Zw zaDs?kiZ>MpOghB(|Hi*x58tdJP5yY^@_D4^JA|+O0e;3NM;p&-sG4fE{2gNzQ~TxDw!W^fbwms;aJC@AQ82fg;e z%Ql5Ofrud17BF|!IOO5`Zuw54@dbGlkvaSPDOvc_;yLifiPWW<{MMzR>mF&qdGfWS9!Ji;@@qZ~4_wp_qxc>{beaLrjtkVe4~F1q8ZkBSu+ z-f8YO2b@`{G|nm2S&C+E>Ew;;>RZ!We`G=URC~6q){_E~YdeG7hY3{*-NEj+TP|9M z+^ok{`&N{+sEl^K^C+R1+7TUj))V%V*z>*1B*gM_;EF;VrdXuT4vR^VyIU8|n}czR z?~XowN)Xr2|K@^5FoGy_nJQ&)y;NiP)kX2*zV&#zF*I>ro!0@@n$lV?0#~nYR6>2G zV32S*j$L+>33Ds(u#yqel|Tt4&QX;5SmnHHEHO`rQpt-(n<|BS2a?o~G^)-bI#rk&xN%m#lQL)^5W4bsLr8@~XB9W-?+u&Ye2%+6@K+iq4I z%3K*`eph|XBlmB}JR#NUZI@JZ*WW|$d2JakA z;M!y&X6(m+J;_*|)tN*F0xeC!Cfn~nVUOPm1n4PSu`Y-NLm2CC9Ddcs6+pNyZPkQq zT8`d_NL52}xr;|}Qc@>8YY4+4WB-1-&Iyx;@qNV22x`hUC9@U7DBmdV<$O zIa;kFmZ1m0vz%G*k#9ni$pB~Vr zfK{TFD=AkN>>nkd_iZ{b`_W-R+^I>52NbxHO$erXrliTZ38KQ>wQU6#FJyfjFZ8;g zY&AaZC4q;*nr7+m=nD5xZd^X~`%l{Ybqq(=6OLV?y%B`X$Au}wNeQEF&qG_9mC%>( zLc4nF<!d@2c0ocV8_1bWLO5rooWYav-Onos*tG_ z!mj=WrvZuPVtL;uG#YlJ*hyL2`Gy_ds4O~P*vOclZ7ZyLB!}S0kQ=BN)|1eY&}$To z9St7*XB9<^xg!#Q=|VUU@)jjY!E;m%yd4S)(hz@bDYP?RO^HqFfr8-GR9gB}V1+;a z=4`o+!#Ev#^lau`j~!t1OktC(_tiWzg5NGVj235Pj~LJA6eO-RA7CRu*tR~Tns#=S zD4gk;6N0eEYdjaE$e&d(1^ zE}Q&&{8Q$V2L`OcWndo^s1_Z|CV4<%`TH0iung&_l@Qx-+U>s^GcZoGsD3PMdYODKG=-0E0VU(pV@CHqiG)#%Pt?y;>?}w^-ad-WGwp8;+%$ zicBr7R=|;|wvs_mR#lQXWQ@T`jwEcQ8fZ#+av}zd{h^KMtHJ0g`My~9p+k-u^4fVl z&8>7@=p&lxB=&>LpDU9>cB0V@V<5k!e1C0p+Hq>6w5M5SiY{Clkr?w7ADWyhdr0^K z+MLcDSJzALF9BS}v>3@3!Vb0mnw_5|dH28?=AVHE=Sh!H|EoZ!fYTJ=W#U=x$ddKW>w!~g0m z>svslA-RkI9oleFLpBk+%61JJ327y84{A2HOm~_~_;;04LdEK0YRx8n|bWy(-zBJ|J9^2FRJuCxz)cs%RWdNDqL3Y&zh0~^#yQc&mAP?5d=Wn?rpQz@?T9QycS_&ZF{Yg#fhjA=vZ>FiKtB9Q zTJ_(G9H;xGBuyZv&)SpSzC0qOPPaPUaQP&3K(b-RTLM6X8Ul{pveAFI5~J86VuFTN z_QPut;3DSTLYwKQh$y||m` z()A^1F@-K>03?9RKm^U9`(2R=L<#I}gy87m=%6z2W^kI(V1vg5$-WuYhuih>?tXsv z>hN7T8qZ&w?-ByWN?6YKSdiybAaO^!3}J$nRH>=?@O4TV&GmHb>V|MW7`CcsqVIik zQn*9*jJ_hwihFsG`-(+RKyz^TK1{rs^68m+#VH7~G%3DI|EChFkNdkVZNNFJKU# zT10Ej`&)6p%s<8_5NO)XOS@l9QeZty-Nz7nNMa4tT}415!4^O@t>)@Z=FEYK!`0Q;?jsU9Yfjv*~^3|Sqc%_y(oZCrcpB)i$)K8h6XCilPoEU zNMG6{or40nVPqj`Ll~vL^P}{usafu>ZSg53TuSL>aWD!2IPUYKIa_`r&dLAuRYLEd zt!C!-+`GPcmT@$<8EWr)A@Q+tvfQ;amW>w(J6~CJRR)RZR7i){YnIfYR2Wmu9ogyJ zkZJ-}gXMG7_b0ZSk11#k4N#vcXL!aAUWQ4%?RxLU@wUK9HA;xJ|NX8`7Z(39ePll> zibw47G%qaQ9($f?TQvR3+U!HAjVy>PULd~BC0sL_6zE87mx?~rtSOGN#Z(Obj^V+# zA494Q;g5WWhuNvJ1E#oO?fkVQJTq;>V+8>|XFz)+!}sBLhPXoA9I$j+MppK z+bjIYJxSA=X~e<1P4rm)akl;J_S0zPW!*=4GuicGiv5&qfC+@IX|n4kY7PrHQB*~4 zL@rBm#|OGr3$xr5cPK;yytnf)e{`d1@D=v$5Dt{PtZ*I^ulT3$+4(g5o`!9uQl5o4 z7ELdY^NBkpmw-=#jVXZs&gYva97s^CGrBvKbXO8@s~Z$?Db~!4qMMOcJqj$|`tvs!463ou%!_XB z@zMd&)=0o*$ijvnjPq6(VU*_h!0p;AyznW+d8P+>g#?#+3Zc6%fC^@d#1YUG%7hn> zBFdRkPe3Y2WF7V#^r!tO=B2nZGb|_o2a4Kh>7UFsh~Aps=O?f@d>?^l=u2_{GINg- zjAS;4Yj^KPO8IqN#j0Y!^Amp=3>gyW=W8BzDl4yY@JKFmtH6gt-6*(ZH5ycy{mWVl zx@Ader4f6U*MgJJ>V$V@yAp0H?_PhKf7A&8;63C}zqNq5xdS*y-|`0zGlpc-nP#<_ za#0D>-lW3A_v)T#)LcfJI;z_N;_{n3Y@ggt!AoQ@Jmay@*Kddy`=|%e~f9-<# zs;_o(oe|*l{CbM!KJTiJ+~W$x7rEE$r#8fn^p!v?$dVlcFv+q%9v@j&XpPSrj`+3S zNAwC7jZ-7cHsmT$!z5O-DO_(*!n!Q!F5=>Zhv;J0?rm3sWYz;$QWqgnFUCc{0!>Jj z{_L}c{$0D;GT&!VX90QOP!f`d?~Wn3h~osEf0+6~t#HUKRj_ClWm|J>7e>BorD`&#`9m|z~ki^o-R)*4{sJto$>rP^Pg+d^g(r> zZt~leasD2t_kp*o3_1t=RwM&QU|O`Z&A#-cO{CmDXD_5h-(0SU$F4Cf9$*|f==|$B zILBQ`H~Y1-61uv*2L;?yafFU|KIMHR@))rq!CXRp29HqID1MDYMI*!R7aq_qvNRTN zbFvTIIRnSIgVcEZwRydDLTa1hU48Q#`=^2WPofS68Z{CgDh9a9?{~}3DamY-67hBx zPn*vEL4Z3p#7y3Us`kBgRZQQe7dyTyk?x;=XKt!uZG|zDmX8P8cbt*AB(|I{zq9KD zzu_gDkhNNHBWr)FuAZOb)T4^<1SGL{&(*o7`w3UqQmcC!g_;?il52llgwCK1>lC;E`VZOWK z^sL~flQRFiOp5;-91DKz>+&ae9F7HB3LmL%5cSw(izzV<6P$$E%uZ&%iX<6Ic_&o%CKs5CR|ax;X8Uz~82 zU+Gtin&42xRZ%%NT|l0mr(;aifE+`{X9*%;6vW>9-j0-!YY&c$ZIbnT7TY!=8T~{!yI58-WzAOx3C!y@JXn{eB=zFf~ho6O>tLe|Dq%N6vWQ z%b{!Bu?627f3ykp+RfJwg@Nn?Zu*9M_X>sC{28&(1E*@|!2x(g*!JKos%H2+ zRFYh0-ja=UMUJI)=Q*`q`_#SY@*-IGir~m{D&_R00jWO%-3-}QZl$;-`)WMQLd1Em zhhvXzTKLH?vfQP$^m>DGb4gaGzDPtRfX_S#DvirRkPI=-Z>cjqm)pYnp}rzh2TVZR z)rQLEP(Xn|Mo?!mTTL zbRrksE0GElU3l@fBo|WYBnfEC{~&&1srg=d@X(-YK0V93a&-+qf{RTR&pEvyL+7gx z-wl%wylE%4Y{xB5XQCUzGV(BAW!W`|Du$qM5v(5*uF*OWK8KutA3Yc;y)y{J*yRrPj2{m?Zzb>P%m0y|kHA})Z&f3w z1t%3B{%)r3y;}eP4!jSIxP(~PW4U%`T68<_~k?@S5n`zp@@A=E0!zmYpfgHGY6h; zSV#1u_PHaZn+~icm;_8c|Cy>2~Q^Nu~W3*M`fatcqg&)N^gNF-r> zD*<)&t&JmMPLq4Bi&@&UCXe1mkWasiSOfvJQr1Y?)ZO~Tth!QCU936+_R^+#LPFan$o=HC1l!d^%5xILXN%SG?TTZUG~U){qZNc`>5MWpqB_>{IvyIM({x z*Z0MwdNhHI-l=iX#Y7I|XloB;RX(n;C+2B-L9T+*b4ruexf-syg<+rbC*<6js$pfVC_{+JPtp;tI$@&Vh z&^^~R!HooV;-@@CB@q1wAD-tG8YsLIQus*`!&}TjsPRsX zH+|cnPTG^~L`9LmELgJi9r|Asu zW;SSYu8OO#r}Zmn+?2m_Z*4t8 z*Iz|5f!%)~m=X|)osys3E8_vBJk);G$)hTdBF9mia;v+@CyMrH@VdmB$nsnL{b>_B zBQfO?HwjDcw9qqQHnJGl@Q>aa;`1?Rkcz_+Y zlLot(c#b&5DztfXX>8f`DipHBra|~;^{?!bmw>kbIX+^Z?RxKF9%5~?8AJ=%63x0^ zwvu4F?b`@x!A2v-s^6awv&OJln+drzI6<`qYMN4lG2we3evZTrp&xZPO{4ICGh{+Q z>WEpYS~H#dJ-HHNLDGX-A$)8c4#1Ykr?nc9rdU262=PQUwES{gKd8+dgjt*1=sinF z=TXyt&P6T205(8SEB|A^oaWgmu+c7ARuG<48CQrqvAB;FQcN}UESGx`tIX&diDnXy zg?K+FzX|~bkd;QhMf*P+m1vX~<2JgB*>dgdi=$QrI*VU|XUoEZwo>@X!tdc@`j|BH zB9KrK7&^>3YxNL*P~L?0y5WqWp_XO-8baTNzmeSD{$)DD{GV)t0vENs$67^vS#`E5 z0p=l*YI;dEMUe8d7-!X7Tu#$j@YD-Nry8C@dfr5ek~5FqxZX+S!|(&S8R};BSw1>M z0syNW-_2Wy8^p=EZ0{~W$$QE`?z3wsM;jw|QIy;HY>Og_Wx!ecZd71fl|}p24QlxB z*e{-CB+jKP*T@s)8UqC=7`Vw`ki8^f+jxG{J91K|%yK@Zfk$upi#8|8ILI1L%bKh!y5~7u zs;YE13AnM7EbQe_W4~riTrXgIA9r1nAUI)A>)&6hB$jd%Q=)WkFl%?CrxzunihRsW zIhFE=YEGI)wfRO*zoj4!2T7t@d(Ff*d;Lq`_R&8d5cFx7=XJTX<)-CRjqs;>u2I`` z(Od0<^Ng6h29kGAJ&WK<@Sz}Gv+^Lz$hosid?uP?w^kTOt;_I<7rR{5fUe=ca4&TA zT*-}-DJhnj2bpKZZns3Oo{)yo`pCI7@z{wc_gGQt<8`iyUo0~YDYApT#NtUBX$h5h z_F{(g<#9%ntfL0v)Vs(2$nxj>f~Ok^GbEDIV~te1q#VaRV7o760sc`rwLJhAahG1D z#ok=bPN4m!FM~Kfk>Lc2A&jSD%pi6zRJkSNv)PYJ4>Y@qrH$p9xlh7t@5_cX3Lh+b}Y4FZZ9BGDY@Sfz~=Kdy|{n6YDI_$nzmFv`QW z9hi{3Aej!~SfekPqGnp?S_pFoJZgyhhp=9*P^eothfDfQ?$xyB_El}NPa=;aIYm~Z zX;CI6DPFv5u^boKb9T1zHLXQqS(0a<5|w|=?GDVMBZDziPq^N1L+=Q0BUnDA{x(4k zN75ove{r#`mst(^e;hx2x`R0d;RQL4ONgA%1+|8)Bu$TuWy||(?D>=lH@M$O(RI(W zb4TA`cKEb>lxij3&L9t5MKtI1$@4xaCQD@(|4t;f-yrXkPj~XaoimXyyf)DHFp7Yv zho_Vg7@=4-*mgeTzIUx%a-@`uqJ^s2N$}G`9;RhmG zHjdYnpo#lxRetWm|1^3#DcY^V0NlBlNA_zVhe>oppe-zLKjVjlJVV{ZH(vj_{1;^9 zGQeSz$r17UP^+~LkZ7z-SaNJ(@L_ zSaH&QGKLpVOst3z)r*{!C=Pd_HdSYf4@vr#orkWUq~$^+21}zSegW%tt)ijem6LuP zAD21oSjM^;m-i_}9#P5||qV8iVGBD*EbOS!RH%BcUn%f#MKilZz~8 z?Vxo6U2yvt(c+0Gbko1&`)@!R|6UzL4jA_ZP`P792wA!I<~Rtf*%w_nNVe2qMsINd z>ULSnE%c=-$N1qzvT&lr#;kv>20NUOb*b`fBcQkKWLUD_Hz<$?H~0|of+WB7*cvfq zsocFTg@Dv?R6hJuRx$yWrmzEv-Ll({B9MKyaW)L}9s3iv#G3f z^<^ROpc}|M+i8QFBi}G zcDD1|6Y>|?9RFQ$<5iNNPQzzE!L$oIoGVlo59UqeZSshYK0D1+&1{_mZ=vSdpSuV| zk(1y_hYqzl0OM*P9QFrk{qYBR~vD_MebXFp810|9~ZxWaDN5|C6))&Z}=;+y0QwBI%|iD2qfu0 z$VyWzWWD}L>a8`NZu5B)N9(Z%>Pfv`f=UOb?cq;Y?$ba+yBQP=zU$_--jO>AbVM6q zU7zXd1I@nE>wLzd%cpXz)EF};5_N)NLUi0BP?}qna8+cpx^x5MgvQE%oO&u<`t%bF z;(bM|1FH@>&K!q|szDO3_4`J7h~VvTbD=zThRBBW7H(f3szXd`dvXH-(eNz3P}Q8= zN`(cV#&2*7Ba)Orxp5yKhvmPEp(0`p&Z?rYuO>CpT*8&#cp%Wch@IH9@4|pV;fo^f zBz%IL*VKdf(dn-yx`4dMrFKn}C_7D(4<8*-@#-{)Q~jJw7m@FDZ$3LP`0oN8GWUI7 zgSbkm<)bk0`*XA!&^_y46#OIjgDBUyrh8G!1&dzEpU2zX%w%%6Wj3%3{{ZqIzwlul zF-eopW8pP?L!#72ae7`jsYZsT^3hSOr<1mCF1zzFj7XowH7b{OVRi2aU~k+vuKW9t z`(RLjG4(2WhqqgD|3IN6t*beKizmrCO`DJrZe~V$-lNz+?$Kr?`Kyj@ljVfJTzgfi z>b7kdaAj5bIM_H{FLnJ{F`6$G>|h4X^j9Tl)QtCXIEUg4jSN^x5{h}CtKx9sAQ7IpvQknMf2S#t3P#Qd709ZpPAz!cKXZL!@dLpt zurpf@3O@e^z@T9wEJ5rX)hPj3%{z=D2q)#T*{=hmt`!`yz(;wq~UbQ)Q)Bc zkCYXB3Q{2B^(%~k>OAeZB3G)jwzo`P6bxC(Eq&Msixt3g zu%Gb3CKS{UJF~A7zl`dT03M1rfy_Q*W5WmILgRW&_B5{DrbJ(g(-OD%{cA{))hkx) z@o|5;`PHa_di=mJ`EUBu)GQErINCIYj`PGUVUsSem)E=<9h-UWxi>;FlFESQ1THG;bX0kN#p&aW!jbh?;Z5@5NBjN? zQ)FT627bq#o0}Z=Hsnwac~jkf(Z0NwPcH(3vag|eiNHSd-ES5SXvD=i0?oUaV?mH$ za8}l*#^NRF47GKU$ws4DnI*jO6|A1Q=9mVv{Xg^0#~Tr9ORcU%kL-IjE}P2bG55X) zQTiCO3Afp8kr|mcoY>U0xJGOlla{jmBRxw(qKBTRQpu!QPQ`0>ncJh(;rkSQVN zBTxWDjac%V-xdU@0{T|W!tW`!8=U>bJ4c=etmOUjQ8G(!EVY#pnAJ z^!CW}aMh`NF^{|rGF>CHWfoB-@QR+8w>$|xcw@}hVCE6l#5gqy$qU}Z5|!mYF{iTofmgu{&N46L|8-Ib)aS9 zvR=Er$u_IMi?MCDz5_Q(Op2=iD)B^cv^Mm8*W}EzP$Cmk!_xw>p3R-cKjGl009NR7 zce)7c?ms(0K;zp6H->6BoNt+(k^Xk~sUg_j49_!(^TgR0ef?mX0%FSXm zJW4~Ots_aP-lbaS#*rYJ{qF8|dR`Sv*f;_5)P?*jTkx(x&57O))7!z3B8W!NkD9}$ zSMi7}Z|v9OBlw}10SL|V6d4VpTKl+z_d0HF!VjXK=r11?ZQi_m^ro*h)3-h|P6Mfo z^z@bL=TSe2yC|KzIq;W869z(q^;M&w3e|Ms7ZpM?mlo#o3KW@3E)K&?UF#zQJ2!>1 zBS=%jRv}s-v2KT)GrNF=s{+m#&f!9Q0N5b} zu-$q?>A#z9Cx&h%`<1g z3-59whv=d5k(3DC6`wStxb0k5l~!Td(NP#r1|@k@t#eCb1gb>>GV z=-f`T$8)(Voue0wl!&d&o-*tb#r8{XTEg;SUi;{s@5t|cbZI`c22zr6>(*YB>tgN` zRpTsS7N;PIkmjB5sDI8xLgc>wcwzc4%imI3{z13A`xceRSig7Tr(Y!xw`mfR_JS0V z=}sYI9XO(U#SDgE?TGdk;w|p_ ziU=CUqSX`Z+u_f%Lr+;nyyS#y{aS=|VK#kb-x?;tGAK9haYx=wrQ6#{Q|_upMo^D? zZRc=&+xu1+qH0sgwRQl>*~O(+OLq8Q6!B0ARRffA5O`Mp@fXqOFXjl5s^g|o&%*cz z=shM0O`v6%l|%^BN3FIqtP=>+8*KR{cLTCZEEqou>Ui@2O2NDl$P)ClQw5DTBxhPz zbEfvc_z(enK=Mh$+wwLC;yF*H{>1y$sWf!~#QtzY>TqF7p+ZX-`y1n{IMF^D1*IjR)ciy5zP1c|*B||*x|5CRq`X;T(hGi1bG^yqb zqb&D^|GoIJJK!a$^-r^>6Lo8wW3rsS*Indpw?ASM++jnp6Tn{0W}Wl}6HNJBOp6 zio8AoI07YvjtWX;z4{rBDKDz zBpyTW_b0HX;?O;kkxrLP*<}Ia+o00zjKlmq`9e_q>y=zH>#x}P5}=bX9D(f#vo6Rm z3M$lke*5Xmn{bL>20u|JK}M4=a3Tr`qsgju!L{xak~0ucwL)il{f}>(>U$z9QjMk4 zh#EyXgAGB{;JP%EIkmnZcd5n<`u;hg3`T9GjmD~#)gAOXE=-P~doPkRbQ|USiAuS$ z2h%4#?E6FF6EE-lexVu;k0vb1G=bsX*Nk?^G!5sw4G9O1a@0XDHHEBX(axgLEMWXM z;(hPpeP_ArmN2Cd1T5)q31XRsEp#adMIVyg*tPkM@RMh1t2U8*igjWfgnBk8yNsc5 zhooW5Z?Aya`Zt~DC1@JVOXR}PlgJTVqKE!{w$Et1GmRe49%DS@q1YqYVg9Ke2nM33 zAh}@k1^Jtf4IfV7ZS5PcU*`6I!6c*2)_{w<7PbNHw~akI!yIpA#X8H_@YS@j*sU0> zxug6|`>I`e$`nN1R$!9+{_0Hc^VZ*`UTKP($ogVtx9q|(rsVIe6ke+NC5K$Sb(6F* zAGNLWVdKvJ2}0^qj1bO=jOfsiT48=z^Mb@+JP3lV3nj9uFEAPYem-* z4sUOL!;1T8c9pUH4ocShnCCZ&<$?M|aO3cBZ&FaLWAJf#Yw>y}yZ9NI$rlc`yWk>P z(|5h(V&`W!XblZ**Nm={Sr0Zl44WiE^UFvJ^6T3{8BnaxnohSs6XZjCWFP?f+*kBL z+H|!U!FV|$moiqj1IeJsGfx-%C4|2^ucj za*~}k&4BQVdHnhmI8@2%{Eg6yt~*{TW;oN^e*y91s#@AWHgPc%XL=2qGP(Lja6Uhz ziN6;1lhYqrI%jxyvD36^ZJK{$yxmu9@Z9^Xm(a!h<}4xP?B2R+BetB^liOhd=rhU< z%&lh23qRY9-Itaa$eM)Bdw~Yp=_Unir>dGFp+WLNHHb$tKZz)IPV3Q3VJBbEo*M!q z?x)gr)9gSUL3%VQF{OX~OeYXKkUSEPKXceyLDU27=(iJA9tA`_?FFFq#IqdmtWK9O zTg8jh0Kdaj+f(IgN=t_b^YiHfAm+L|FDD&0uTT7zD{1xnA>mcToM!f{N3Xb>oT28b z-^oHPGm7>>=A{;iZf!{N7|TF^Z;C!+0X?I#(N#BDAVL zcrGx_akXn`Myo}0hlgw8B6gpdu>pc729<1H2%`-zhS~?^>25;!AF4aSTSByXd%kxc~+D*D? z$qoRkvb!Y;H3iKqB3GhvGLzVV3b|(ANq|r8X|e?Om+!;N_;j4=3B;cLaWpZ1(Qq$Y z!58IqTDP7QuU%Y$crg!na&yK`di5c`8lB_AKD`?P0})8pU<9hg@vC>T9!ce+YC6zW zqS%~Y6Dbh|;LlIbnER)JxDMH+@ds6>gBQ+^1`h<1Xl;I7XD~YnbV#McqpE*VL~@}X zL@|345$R#Qgvp$}baA>8G${t#)tf}@#Ij;XUmVey9-pPE^1eTm>}4yU|3zwnSAV=q zECbj6nv2IxJQL<~SoB=W*22xE(6j_G)Mx6F9M9O9eRZ^uC||gMT+9!twAV|5TxaR@0M-3^+S6d8eDdlFrzBiqOU$+UuNlt64LeeF;2b4bkNwbgZSv zr}ErGCOcE1>Y9eRcv=5i;Ku1uC(uo|tuBBe#y`*Aq;s>YE*-Ar@lhsc=?jm?dg-GY zB(%k9-k;vi)Pi@8D;~;*W=y!z4DP81yV|#u!(W^Z)=Yk)EmhzQ%Qu>Lg+&5R>}hW- zdp}feyV9tqt;}sE$*W=6fFy*1IY=_bsCseqi+CQ|mQBs3cA1MJWPlR{-V$`VlQk(R z(w>fo4hL*6Fn>5dwVk7}VTWpUbxS3ZNpcM`_c_i)tr!^x%&7}My39N@ zyjJKDJ`NkMqtzT%!RB41hdV%Ou1Y)b;F1PcCty}^!|E`u> zjN+isdI$}PssZ%-2AFw&JeJz|i}4eqnWG6CpNXB|13w+c@BGStxgq4n1 zlewAfO!I0WCkr2C7)^U6U=S5nJ^ltTxXH1WgZ0%S@%A}~YS9&3I5(D~7eiTc+xq5~ zS>aCPiHb*zi^Di19qM zSBlavVC}awAie_1l!DIwmvRT`$lhkA9@SB!vN_3>jD{0GzY(mxK49TRc28#jQ88jL z^-$3HK!j#~XdUelj5^%(Do`Dslh)YwXl)`6odn3vn(v%yvDeadBsrXGR;Jshatl;>v@1NonR`G5camZV!ga=b&y0{H6+@~t zU@pY$jKCbzNY_B<{nrb-%BEq!3vghG5TLcK2MVlN&0eBW;X#q)pcQJmScS@UF69Qu z9>94QT%Tn_L1}^0(eMRV77O}ymFgbiwdC>#>eh?ih<+(F*_;H**NAtYhQHZxE$3dp z{Xl@3{^<2*Wy2K(KAubs{W=S%BS^1Bh;G|OQB9J*X~KuWD)1q!lJN znq?JBP}_S5`kq~5Icjv)WuH13L(o3k>UGRA8BWgw53NeP&Wx}cQBS!@Q@{Cupcizcw`-QygsFefDfD`cBX9l*{KOydM&e17>ZN{>_)eJ20Pogxh+LqWwF8>dR+%x{_4XN13x_sSqq}Ryv7d_mk_C8hZj-BstW@o*HAiEUF z3lwEMP2t`}**@}bXU~kB8HdiVTj!n=NiO|)wL9P=&l6#C8-m`c zt94sqrUKi%{IDeKGVq}oF4-PZFr5OED;mR`JJ5oG7fafZtN7cd=zg99I)P&=9$UmkG-g!CO#?BL?(@L{$0f8>RKnVm4*mgMtH zh+5z2{bx#!4dpwa#$a$(N!N5c09iHw-fLa(Vag|%rj5>Yq6R88&hc-WGFDYbIt9B z!&);aLi%)x?zCF0DwoH&_vh;8PC;Rs$u| zh_Sjzea0L1o;&4H^G_Fr$r_qRl7=^7?sVk3Fm57hu!*#a<8>z+3%4uyE<#m z!3FjEMHUIT=|d5BlqL851XqO?!A|DEvyBn+a?glbnK$N<#?Bt7RpJgS+^&POl1LQ5 zyrjW!m!W#=n<^A#kArOL#)O`cyc^RL_L>^DbUi3*o%>`_`!^hSEu6zc~tsG%QfeiKAI*m_)dy+0dv>F5(Z1Rr1`h$ zo@cBaHaupTWk04g9<#X7Cgbrl@0#i;>5qdRZUZa3ABzH9pR7mF%$-IX^_JlG04W@1 zlBpTJ0T+jFspZ?;j*<`vAu8{hW-B)QoWooa{p81Uu~m7kuMq&aT5BBUQu6Sn|Nq3d z8Ub>*_`~IMdV*1<3@rlDO^XwxUp!c`dwOTn7o9(M6dH1{qfrs=6*-6{4CU{{e}dHk zc5L$7yHV4_`UF7nA9%94AAOio(%YwWJGf%97H(+$N~~R_udJ!^{snAN|4>nzLY7lL z{BRdh0axi16bidGKFpm*t{=xWB5h&+=T9o6_U*DcTiVvs&q51Q{}Dz!1+JE3xL?QgF^)e$hQdL6|}XKl7lmmH^fhp8vP_nRMM z;|&64r0n%yS@D;^3&(fO42@THT=RghvSda89yd=;eE|n^OF97o2+?n=-ZgZ#Yb9Y( zBE8lHhYee;jgLv;Z!-R9NB^6M{k5yMi5q*mz6P#ET6HOjRJS0akn7Li$jb+krAI)< z#XPeCTvGWr0xRm|QyAU$sA=`GtKFg#%MqztiuYD^>AN$O>0XiDcT8dBGTMao#&)E6 zPzHA4^6{dwv8rPIiw$UnOUyn=0)U&s(B19&oPtFlb^aL)_(giLJ0bCGn!f#hICImN zx9ad>ct9iqM}1}YYUHkGR5LnK5v~87{b_r>Iz2HAVOGOiZ;dhJKXZZ}Tnf_6gGC(H z+0R;NXAV|)AM(|9%@t&O*4ApFWUl>XxkeG#>sh2`?wIWFChg)K&`v78OU7I+*>3o| zrTFFkOrSVqyo!TsA%GLKZLlnKjqBh|_gE;i+yTi!B;cyHw3d zzmj&4v`w5la*{NYj^;%=`spAkl|_?fX%TUn((+w0*j}jZ#9=hMdnoNmf4I6s&y6ZF z$i^+KM0AxLyocCwom3t?Y#@`yyvu0|4DYA*s)v@c)F~W=IRoHh!eZuj`-~9{?|@X^ z+XocuzI~M!=4qbMN(iw@hB-B@CXuY&8=T!kq@obWKsl&LBVpXCX`L@>CVDfs8HdH| z8cd@{IO+~iP8n#+?Kw<~+IS}++RTF&q14Pm0Uw}-4cF_v=v)|MD0;V1Y6wect#I$N z5qJCmA7b&8wZsoUIpoCST{>P%U2A$4I1E3Yn2wgp?kM}TM0Z1Cgr^E_8SMqo*m>j9 zmB`r+VA>PMEvq<&i?`PU4q^JuTU+L|;4&WcoUiVntl4jliAmCNzBvYBPr^1k7B*KT z2L(9Q9#DG8qs=HH#&|zrm_{#Fsg36Y&;Qn6ab|G_*m0-IZEe~c3N{if3u z7~MFk;x|joRJpk`+7c;0QAbRu|DV^ftl^gZCNwx6fdCA1#y|EuJML42upgyqng$Tq z8hxjB2QDzhN7@xohC-4wqbgF(`;M(STJ&C(M zdduw`?!eh~IS6;OI8iRWn$4D#W5QMG-ZetSi>bw?VJ0vZvRbZ9`uhZl3T~G0YjL00ZrjJ6G%Qi?ej$HQFf?Z}T|$*#1DUn;626WJ%XNTW+oABiIk$Ad`*uQN zdkDP>*hdbH$AkG5n292eb6FOzseWg(wx9i$DpE2fZDf)2YL#q~`GaiBeHz2+FV1#_ zniLwr+3IWCD^mN%z=d z#G(p_7+n|{*0L|^w(u~mo7uD_G~2J`rvWq@DKKgk-Q*^7xS}*WQjmYnQY+>6zVy_( zYJuIyjffqU0H-IOp2CxnIP0G{E__o$hykfoq+-z#hNa$6-)xjGjjcBv&_$oe7GM66uwAGz z^pr5+t$7{Y6ptYs6zS0#_odF!J>uiPS&6O%+b7Cx{F=F+7Nb~fvfkn3ck24?aI-s) znw%PZrY*sU*d8m+zvQr!luE|*XMgqRLHX5HCmeQL>sFTA!*|LPgVwgSE~r{%%GW8Q9k$DUQ?2Ed zVbn#ceu@!!ySLCcE|bWYRf#1hcA8WPRaLO*Z)84Ca#<69WErI{c5N>TUS?eT2O$Ki zbs&k*f|1MKI$;hrx@s8OP4hpP_r47>ed&vM{`-7iHZ7INkG+*A3u&*{b({8t#PME= z#O5U$IVcrR_OPhs#zC_x>&0O)CeqF@hzOHn&D}*s{Kvo*PrSM(Ohf!#$e97{*}CC{ z1Itk7YN4I$%=w;$8QD@%em$-yEzCb2vPD%o!;FiZ3DL>ZPkfx7uydU9e&d}POUzuD#oj`|gR*tg?Q z4$$NtX0I_pEn_wzVXF<3?lm}Ab7L%k0s??+6RxnhUHFE?hI_dVu-czpGiN8ZE|v{{ z@uHBVZbwy5c25S@lYL-3YQHLv5H8$^Hl4VUf#A9G!7LpIq%N>`&YJ=DYQ%0O#%Q1O zys3PvT{=OcYI9Y1+qHk9tS?VJfa3F540<7+?JGFhu;Pr1`V~K-@dZ3~x@UQjDx9@T zFFIvVW}6mq`WhcxwGLvhi9I7#ca}n-@}zB4poQe?9I#7v7%aB$?}MLY4r_rYehPqY z6qP^{Z(&%ubB^63@UQJ7)8$bADlq~NDC(iAG028lkr`*$GR0%B2&Cm4oqi zkP7dC7{HD#ebw^e61M`BFwoN#``fWhMb(ft7XliwhkN;^*uMUvrLARo6Q{vTG=N zkaL=u|KcozfvCwk1A;iH%Zy6p-QU>Yn5`^M{FgKH59%7zF2q~o$|0Yb=F={AA*S1h zv)P=4aeGvTybB%h*KD@!4o^?j%UMB*M0{KcxVVN#prn0~lhIv}Alvl05v?>vHyj8^_lXJIOhrhxt|;3VoU~ zo!tT~9+g-o{Uwy&1|OYL5%Que_1$dSYl0n?jK88-puXy!*B|9O=qjsugvU}_#Bd^N zjKiXbs@-RS3y%S$>#h8`mfhlu7 zM@D*>d-02|PeB}W_B(ew#iF+GC@)btve{52Ke!#TSZt_OoiY;`%x%AA9kZXTK_00r%t#0P@rbXP_t<0@tp@^`}0Xz)+mDekz=>$Q#aR9UIF1X?y)=} zfWoWMhz-fd3C<6oHn}g4kQF7ZlB+XTV&wLSPzlYw`i9&}v$n zsdN(x050`hzK1xhZ$w11+nqFXCqnI)kLxT8bnF`f!muf>G_RA~U_(<#lG{?Kf}XvP zG3iwkm7+SG^qvo2ac*F-MD>MTvGyJ!+X3i8A4>LmpM!BD&jzYs*&pf6q|f?Hw)#t6 zToU$O)2`NEKbTaOF5D3-;Vqz+RoCz2MAm*ZhG_~DWi_lY9cXtD4Dt_vDAOY^Tiph_M4Z{Z-661-X-!6mxGIo8@iz8Uyx@%_eCLe~9mA&`@EUF9V+Ie;peP<0e*3%(#DhIy zGgb?ejk&OB|73Ok^c2dH`e(mqQ=n6%IgtOD?5N?qB#((`E;cLodUUBc>9cJEvO!5xykUBq_ zhV1PtN{TQGHnp1Fx1$;;uT99T#AxwYVpKiQrG0VSEu)G6J9JplD1|bW= z^bX~zi6>xf6YHGg2o9AWf%`)>&M~!p-)ZileTjc+VwGBJljE3ct59EVA!kI)(|UZ` zZg)iE`?M3J&@}wvseK`^5hL!?=f*m@8?3in)YbE?dB2%v2fKvBLBR`G^p>Tzw14DL zR3iX5L1 zf@4V*5@tmRmSFY1b!UGxRhKNBhzQ$(JNXnretus%X{Nkzi(Xs$KwijI7A&<8AOq=w z1Q&4$PJRuEA;Ahntp6NpISICeYMFG5fBnhRt*VnZEU~;l)s}!2P3UV0zFnA1x-|nc zyo=I2iVQz*y*`8JPdRq$SvZ~R-#PUKXlxs*8@DxGi+h2i~ z#s7hQ(*j019fqcxm4sPuGb_b5)gco%WmcNBRo0{>HP0B^OV9}OXxGJp-|D@o77G4- zr*M8P5W?BZB2Y!f%wj6LURHA`em`n_iNsIoq$}j9LdwcKbJ31F*kSJMt0r zBw*ic|0{`F?7nRIWm7O?>J?ca3Y0I);pd0JJIOj6oXK<;NuVD`zOdM6gdzD7k-`m! z9%z6{4K9`n32Hg{^G>~J(gpVF3;GL?9YE~?{MZM;kk>p;5ty=s%( zvZu8g1kFsx&$J&YNEq3e`&Bc3Sp<3(btl=;glDMsc_WA+Awq#6gFw~h%a*n;MO%y= zV~!+d>B<#jMiX1X`1vXiNM6RQ3*As5y!|C+hERH_UDZuz$b*&q%BzG9AXCRQxQ$Qy zt>l~NH_G0e#(Nb9X|3K$x# z3PwOI-n7z!NK-1y@{rW$qj}?#2OG5LmdiCGpwW%=LIM}8Nl|la0&P|(z{osKkGF2E zlUem0wKWaNzum^2+=`|QqyJE5&?8lJ4eT$WBdx4s_z{=q&ck_Pe`Y_64#jz5e6Io+ zM28yC74HH-t&qkR`p0XLIveA6CTt#w)tVt*7gfOvNV+(YOvqFy@wXB>?p)NE z;0q}wu1d+bat|vBN9x{<-agslzRW@3ozx^H@C7t=?4Z0XA&96{{|f8^Lo*QPz{p`j zV90(F<$^SE(X?lH^X<^^Pe)+0M`hU0RDHl)Gp>KYpa{HM-?qE1dv+AH9f;&~b!(m3 zv4YMguy|OuMUlXyTP7%J8TH*w;`tuhhY$C*n1T7vFc?m6x*zHpoJ8{j>`ZJBs7L%W zg(ov#huz>gjxnW!6o-nesDoNsVVT`wIe<}#LJUNEL1oA^AhXR??@eGa-P$!tVKv5? zbi~L!x2CX{mX1@*?ZF3n?`>lYl?+u^QefWZUEWkt_U#$U*iU0#N7Q!ry*?buSx`ncyamRdf>IpbN@>I_F z*Bx&shYoC;#L-iOKWkdt?mIuRp=9)cG;;^-K!)U3qgy7@Qz-~j*<9y6LQ28Dpci0s zIWB230^4b_pySa(_?mS`h7&>TRV;ZKs4yyI!OBswpE=XNs)%6J%3?M z&P0`rlT%Z!&H9*bqBPOXWdQ<5fvh$_ge7n0rh&+*lyuUJb8%q4dMZHk2<(ZH7=-JU zOSDd4e582?jmMQ*NPI&K0lpBn=u?V@@Y!WX5am<-tU`OTD3c=32oH?w$bC&`2V31& zC!(Qah2)tWdilG(o%`cL0>HC<>`5g*LEpFNVKs_zsf)X=PmbIu=I=o=5b+@|)l5Gg8MBkaIoLWo>&m?nQTegv z&hfq7*R!im_rSc2{O7UkYmLvRR+j>-jdvzbgF_|Es&o#OURAncNHNBjp$hE|Na)WL zsB>cN2YT3xOhHhvQ}RJ`5CH5WDGCbCtT`{*953Tz$`L9hI1>X?XTf;qinht!w`(f0 z5A69y8j^d@cSfW_2haBuUHS(3;1)UW<<01TKn=Ox zu%YTd=YPgnybg^UTW|&4d}vRRSYQCA%QE2Yrq^Z2Wt&nLRPCr*UqzO_{&~BV*Iv;| zu0r&`7AxE|xkHh)+)sEytebKWFk9KWfvQo1V_#PdS$CJPk!<%U;elHS#s|IeB&oLo0-v%+3lC}E4dE*_j$d}$8 zlPrLRy(>w`%YXmkO@#eWz@S@{*msN{sa*-*UeH~EXuc^0w&C-7u^!j0=>KR}UTpsRI(&qA#>s6r8mmvbAV z&*_%ShnUVZ#Y-42`Wu`#hep4f%Rk>#_^K<+a|suXf5jx*8%;4TdN>j=S<+zPP7n3l zLgm!CiSYhe^)A#VV~`vR)b~tjNeyccOcf(H$~#M!_GCfNw+BMPv}p(<_6)AYSyz21 zhp4-PTex!-=U#7}Q~6dF;_4vS z&6DdOx}xAUc`=-n!psdc;-hi8@!d+Zv_2q=ZGoO^~$hIruu1;~X8p@4snMnB>kh$hPcC9)y)T2dp> zO*t8&X#V%8qw|q>br?RP2rOW8^Wi$`L4H0CD(HgD8J6+}0?Th2o7b9sS`JB4l-yUH zTo>i5aVUCqU3(41a&6rYy+(ZoneCV|HG(8MRe*j8uDZnEysE1B<&;oATN&S`mS5Ii zx0fh)nI>S!*Sd;z-7i$$0n{(g2vIv919Xvi;*j68CdY_5RsU)XEG=}A=t=?XR07x= zW8+U*7U%ucF0WgbkN}ghd*^?Kfjf5fRM+7N_V59`)G@&P3zj#$RO$44olq?x5?nft z6hBL72$6a87Ei`f3q1i?kqk2jq=d?X9j$ct4P}|dDAgRK=o-jyrV7H%yz zr25nv=aPxNy9FEmB#Vff`aakywnc%+hhBcYuxDCfn7l@eskjKCu=mgzc2rW&dtyA{ ztI$I6cqOr|IJ)C>a4GL%rRL*LniK}F0F>7I|CJrBvj(!D7 zq|LYpQB9M&?0G=Umiovky#DytU=Y!IKuh^CP*-$itsAd``OPeJ`yeO zmEOIu;0arCJ-55%uwS`?Jo>Hdm5h%Rx^`~0H00|Az%>zaqG;k~60ey$wB9fvAULfS z08Sf>EvWKz)Xog66uI}Tdns#ETxo^L+z<$*@mrDQ0B03xYD)NMZWM)sBa1Nq?VPK) zVwd+UrS^}Q6i-hxRR3iUO2_%{8T^Q< zO~9&}`ayUHZd{=8o2YP+M1&z_9sfyu9V?q&^h{UYn@o?j*+v`YMqiQ8#TwuOx;(5s z+6|gRJ_gqtkJ%Vzbo*PxOYltcda5TDC576*RYa1|Vt&C;fwae%KtvI&EmdM?Agb8X zokwYEiJZFc^UbxXMZA!4RU&{Fl!prpyqHYorGW36|MroG&w_0MtsYDxBR znxHAJq;ta`6RBhc`DnfR8H#Y7ozi{L+SN-rvP77@`f_#W%~F=nQpI)@Yue()lB>j7&s{-sOD9r~Wu1(%|Ss za;U17A?6NgwvIXCND-qf9v4?^Ih(eJEjtPxk0L!*4!1e0La;8U&MCTFbwben>#Y2BoI^8e z4hf)Vft5ZW&J@Z$gSA8_CoX`bI&`O0J)-c-Raz3VRQUS~7kcue_ z*M6>nQQaRYlx$0A#j54TG%YKpH~yA&03(*4ebFO}?jH5_BH+c(Q8ohPS#VBc7q_Br zj$KWfW+bh8(QKkjy%QR4Wi9)Xs=~>Z1VQYKZNGLVTz=kg%KSxvJxz)tBt-R{0AdcI z`IwT$nxyD-K!Pqd70nn5P>n01%|A|gk{(3x#fLCnD$*#f8Tzn7s#vu(M_*iKIsd9L4d@4ffSLdmbu?DOv$hMJhx%y9>U0@EOX@yRa+va7l zt%^l@bV72F{<*|MVLL?CFbHRzgn+4T)b^}n2GS*1ZpgJ`%vjclP;@J@ob0HwI($(S zOU(f2%S$J8w+=pjR0pun0p1vV7Zsa1GbRqKKo19fMlo0iCp5cwdx zaVeabkQMO7RKtZ_KmUL)7+fI5jfrcbH|w+vL-rt}j0)Q8G~Sr|NXCSL`u$(|1khLf zbALid=agOq{pdGBOgFy`z(j639>}P{A8W@=w9`)bnK&?M;HvKwbd^JUtV7Vr=?*gC zC_j{U7W;(=q$c@!p|UL$KFrv&otC;=79s?N{TS)un6d#qK+CC8`r-{67XA|r*WHy1 zf26h%afCEY?5N7Lx|J>gWy=}^0&tc4*ZCh!4RiB-GLha>0oKua^dTXsImezKrU^gC zhbAXt_ume$J#{H{yVj?sm$!K zF?C%CU0$l;olgn;4^tXRa1-<>Zh_|((io9pU}{xwf6C&xKMP-q(cpA$1he~@Y5$`Y z8H9Q`hjq>uPKp;)$qjfOyDgAo3S3siu#GO&FDk$t~^#%XNEFTN179IztDOypO$sbmm z)HkERSh?D52>#t{C_f?!%}ofsh5K8k3hiaJoBy7fRN|kSN%5EDPAqG8#t^O z@&vgY|5kE3|M_*7{^c1%e-1H0NT{_tX8 zit`@U;HIPr11Hh+@5a-J!>i@@wXL{*iVWn(rZ>E($v28td42b_H-+cq6SiF?Ip=c$ zwWa6$EUlj2XTyoqCe6H!h77g_J0`V1=V*gDVh#~B=TE27|h zn|&XbvJSiHde~3?^}bPgR~#@>fVm|}o*l+FHGQ|W95?13yOWHBYL+H#!&aQpJM5M>ztck#hPl2vi%YG$YavI+_rkPuV6%ejY!ad|* zK4cZ)`p^M}HH2h0uI&)|o*kkk?!ReZ%dA-A>WW<(o3sUmN(v$yp|N+}id9=Le5hi7 zI@0ipl%iPvWIv=u!RRxnWUIp*tB?vTsEGHpMb4%k85`}o3OoIVvHkXs&;`J~AO5mn zjH+S9DrqZCe*BUt1v?Wi4=3VfitCp}WA9yqri&DAqaiWw2`lEm+YZW219F0uya_IN zyzi|D$Ys9Oj7VlMO&RrlWgRb0tV-UhoC6$y3uG~B_?vGLS?Ck@{cVGM6$=E8>nocyyp1!Wv+ zLh|;Qz?hSIRCTYcAreljTF$Zq zUH`^j=ksg+gzo_u-&fr?2VJ{M8r}2e_wU#ggJd6*%{0)HF&)IH7cBayKs=f2?{WiF zGa9bP5gdhZVvV0O3am995<&zOE? z^A@>+e9$T!7Yq))tkG3>Gi^3)GEqmCgy}kMLI66g;U6W~NxS=mN!h$J+JA3f*MA#8 zd@!L2z#6Da&x?Z5C;#@`v;*4j$BO0VU-uG3%!(MtHX`yyi+eA!bOo%{_Di5Tkiq%v zss-ix&%PywNBjEzVZGPg>bgJLrbM3uN$D6>U07hy?rWhM3O!j~o;fOa^XO9`MGq85 z^Of#~*lF{v(g5^po}Lsh{XKo6ggp9tg()!)2AOxF9>A^VnvU2s6hI7}zDs{IPdQ%oGYSMOyFvx1* ziicrUn%PLEW$tpFrt*>iHTmu5ln2Xn3y&nDC0KE*H+Uj^)viKWh*#x}PjNK@ISvSs z09z$>3x(Q#2#+_^HY9klll4dIF?r{gs*WVPF1A|Yq-3`Ec5lN za+~QFz8~zjG8x6W;xJ#uczl+WYn2Z#CE>ynFGteq?#7)~C}ad983*JVgqEO)2~ipE zjQkFF&hSpRP1R*8dD8g~D%`>C#e*4ZiIkL2uu>TwiZcqwj}J5O?9LjastHbHfgsoa zz-I;~!2E2pxOf#vOC4cnXPAq;dtev(jJ47sgx|Ox&wMHUEGHXS!JnqR#h~Qt9 z2u-S9V$~rY=l34U^+ZtJA$9<&9kS&twU23cdrcmD&G z7y3VXyIYnk)v*&YFW@{=O^JE*Q6E*8$O1*MHVnL&{5b5AR9tu0Ts#k{eqq$KB{HV{yI}eKUxXB=W>b%+m(e+u ze2%7xf6eKq!NY=J5%;e|?!6a4CIqMjFO1950!iYSi#jB{L91T>LvFzM&{cPBIA>`z z1qlf24K|PpO)=2FHSgH>L(C*5o}#-14q&*E&iYMxwObe?e})6s(Xd78k}gKy#yzGB zgmo^{4imU`YmG^*vJrwJv64AZD7%8y3o!ub8>ixM*2rE&?w6HDNhz77a@5UFGNTB2 zUh>x1R%)-=Yvqh!!*`(mGB9OYod%`Mw9w&9{?FB)S!gB9V>X!Z-=^sWdwE)EwxPJ1yk8*<0#OM zAu|M&j|^`9R2Dp_WM8$vJ>xf#L(MiOYf-Ssa#nPy*cETH@t=;=QbpFRj{)#DPIET( z`S&iYIKr2ZItddO)Xv7ExZ%)sf1N_Njv-+|Anu}gPUh2K9d`Rlp6@nv9EtngIx4^d z-Wc0vsh}?U;NoRsCit7R#9AKE;Jcq1L-ayP6)-pfj&0=J0}J$S@13Mpx+m~cM^QxZ z0^)Q`Li-tp9=p#s_U>2yt``J&#~)1u1*yYuSGb3dQn1dT{5uf-PjvnUnKU^YOHDhR zl5+r+t~U)peIOMZ_-a9VfzB3>Lt0mz*yjC(3Aw;D|03b*k$|XmI*(O(He=Sng)0>@ zoTCEEDyeNW)n$IdGQc7qfBL6HZ>AJj=~_7luAyTB~B3j3E`0i){<#z^rmILsvC9S+T#&w1zueriI4jRhx z{W&-HkAI;EPF_dh%MG~tBd@TibQM5Tknj3tKp@HgYK#^!WB1`@3yQY!N@q5TD)cM| zueW;hY64Z@7!;{0=}$G}MEaUTE!BFPY6)Pzz~6Eg$j_i$Hu$5$!=d7mP!O;dM64F5 z1A!wT@4_F9-?ro(sKf%Lu-VxLsntD@qv{@!*+QCME}f2T6rLR_<+{f8btWa~Hw3|t zSG7R&H?I#@J#4oD$2j9HXXZ;2! zaD=W9#k7MYL2*Qat5}$c7z7JkPF$wEOsch7sxit$`D7CpGjdX#9pqo`bC2{irq|Hk#g>ZAMVG8I8+TAHIf7G zBGG+)-&R%xV|L_L?Nil&L?3?E*eO|YG`V1vty<;lu1iJ)H^NSPCHxGy_E-VnPId{5 z9@)JXCaA7xdz6tDb>&=mJ#>WTTy_#PdCmDyxHLcpLlNL8NWI*_x6AT`4wN5zmi}tR z&#lDHi0_@+B-X`oXgF$*D?ya6nS%i4DLV9r84Bp!wS~34Qjn zp70BANAS$5CFulz?+P@PWSK>02ar4s1LOJ0{G<7>p0(HBno8E%{BU*C7}xU5IRyq3 zUcUG7e9m0LeaBgY!j)OL(MCZ-mNIv$#7A{Q&OmR}3wU+>;T(a~K*+$m!vL0ovD zW&z#HZng+3;>dj(;99w?Z$QAV)N@XAQ~i6Qb-nTNwBF+itSPY!EL?v+~}*-69YQLvpV`S_6@D|Q>#Re&NQGVuq5JbdV9pGw+p62`CUt2iGt zv)d=2nOSpm;MXVw(*!pLVJu@#j-VnbTEo9P7k`i%@&AGuu!G0RMnoqc*WVxS${(hp z^dw(i&gH_R_a||9FP7$M{2@E6tmQ{B{BJ|}6`-Xw9RjD=JM<6g)oaRw20(z9xid!} zs-2`W3;gK~#11J5vm*(ZKbXu@%hqXN3%TTlzC>BlcKq~zpTZ?@%d#pTmNw+qgh69( z;*1grVUZ&0&4plc|Wu2IZl6-81zVchd5{89Yb4`M*LCNLm|S;k8t z+_Gg9-0d^Xr=3~Z!;pN3*W`2l@d}r=1avJA4cLd4WRDAiv5b3iw&3wk((ka-K%Nde z6bfS+jqM~BRI-5$7hg&JOGHc_aWEKR$%quXhgZZ35QkIV|;A-}o ze$g`roF~;G{o+X(VKDpzi6W^y%Kwzl7rIaKt&b7hfy5`4nwMtp(_7pnXv-NJH4VMR z+`}V)D#Zn<-jivWzgZR*dKJko)_pzXOZfz>&wuYZJulmA>S*h)K&PMv8J#;)85$!f zuA2Z*&B|(<&H>@yuvnbQc5q>k8bq||2vHlF@)57hHU7{d_iZxR2oIA$*Db~>->R92 z|AE^$2BPkPu_dS&j?M<-@pytJ1k51Mb24>Ts)T!^ZVFHB>qT)qm=#hQ5*mFq{TS*k z65!mW$s?40B?1A6;#L}HT+i>oo?*q?M2`9Did(gQ(>pPm+`amc=3ucQtJu-b9F5}x z?knE@F|s8gp}nu!j6DmXO_SQnoN^zXjXwJXL6C#mxVdm~C!_LK8$FQMvRt2s($a*b zH%e)4bk`#dB(oo(i`++5RsZrD z+4N6O-L&bi&AFiPqJ7NfWqIp`MuNu#>&OfPyFZtJUbvpk1g z(n;U-t$kprRvi;cQha|)z`3&;nVe_d$4;Oz@yL!6%| zsG1h0#1PA=IUk*+H3nG(_M43ATZ+nh89$vBeDgoR@x>^>EdV;1AM{Fk(%eriP2qyVmcNiY3tOG9#g0m5f7FewODXmo4<7cB1 zux<_!;Ni|Ggh(sp)A2xHnvvONT^Y#%SG+|*@PEvuPz9p433bJlwug2AC=0h4b@<6p z=>CTazK{DAiWF=XKU9swSGC|Jzm|A+D1K?PnWR>adp)LY5ml~z!~Y0qfaT)udR*Q= zt`&9vXsc(8p;>bJCz;SjQCIzVzSAmP@M$GfIX?FzVk)@nf1o70=?|M4{mQPls6$wt z=_Q22@jpI$zF*=?Bsys8*AB^;62y~}$_Y)Fz$ANo2&%LQ)pSxUH8h1t}DXPIC@m2*>ZT-I3A*1&6-D9 zw8$uAC{3H>0g=)cBqEFaEpcd>+Zv$=<;Z|7+cJnC*r2+QXT6F@X^ z(QPq4Fb74~@f62aEb4M|kWLw#coxgKl6(Wt{Z+@Y2Ai*5I@Irg>+nEd;0xm&v2;%a$iNt z)`W_n^^^{_+ZH}(WepV19du~rIu_yxxo$gr<^x7`;eYHM*bRIZF$RuRT}aF%!VTh^2s zuldU(o*ETxju0pwuj*7=SOD>-N7=ig+_3u^FnVlIQ4JlFrsvK~cA z-uqD7W@Vf3GC`}EqE!uGJjYUFO8h;7cQ;@I!dmF$cy7(G9UnMIH4m>$v25p5X~&-#5UxO1c(oZ7{rWp_6sm6k*ED%J^I-mqS8l+l+onql$3$!Hr2 zlM~T)zWfHkBc_7tDrrrC+vqstKE}#B|Cs{KhXL=`@IyBprYSi^NDyYrOXtx-wg}$b z-%9*Sf`9sA`81PR8|Qs`ws=m*o^hYe(uLQqc|^t*c=HogwOL}^-=o5VT9erRTldWU zmLL{|BPUZMC@o~Um}SNZJ?@Z&I^sC(GgoUmb}kCYP=%Wf5dUpCfA$X&l{S%};3oI@`?ak**O6u9SIQlT|)ucZ%$7_!87&i#x zNgpMCoL|rv$J8|=abbNpyJCP{KfA1LRbA8?B%xO6Jp|al6n*Qug0oPW z`)B@f+puhLmX9)G%0CwdCux#Rm~!U(O^L0LGx+mEn`o`cH-vJw#xGs>lpc${3bVN9 zU-K%i>%u0mftOIYLOf zT-5Z2<;EceCCLYsIE>!BxW5=PH-RLsTs0iB;&yuaUw;H{;=vt%pz}C2JIaITJf&HV z|5T_xWHJ<|iR<3(jqP-^0i)8E|F`UI@B~v-V}x&3jN9I7gYf_Im;A7xh`v#HH=q%f zP^KsMaT8@dp~~S=#w$PxM<3;SV6<^7JB%oj^JyB|rta+8I1(BUq}i=Lanu$e*hwEy zZ<+=pshQBR@kLdnWF#u%Kg{tv%H>?zRP0OM=uIGq_|Wg#^m&7$8b+ysgR2(t`f|4- ztxs?$+&2jT>cOuJ{)P5)<`ae zybrnba`N8$gcSyY)9m>vVLInZaI5iUmwb}|j2}!|K(edSbm=y|%4Yc?>U_aDr_H_- zG<0T_q;L4_{*25C9m5XHYp6g4(-1Y)oE$1|BR#UM2qaFziZ;|a6zsG=bNEBOFajFF zE&Cr5s=K5nbaN-?RL|7F1hRkxAXfAFL>|4Pg_Pq*YWuTNRHWc99Geozif-}o8!`G0|8XhT-ZX58+<(x#M&QmgS7f!oy+5tL?aRv!2POF-j=l4| za!#+?ef4TmgMo9@XpB{_2qH6G@(FlcjpujxjAZ5cO`Vp0cg#l>Z-NcWul?TQxpsKyO%oVO^564+@ z8RP=o0mKKx{wG?@3wxivRL~BmU`kztOkww%6Xq)`@oUvV&qeK+ckPc2*aNv)i%blJ zrdOG0*8J!5w3<7<2r8p_P?KU_+ocPX9#R56w|L0BIZ)j#;S@i1c8Bubd0Df#x3z-DxLeEqw)ux@kZ}^UQ-iDqlG!6jq8O|fnQfR2hs}!@;ndV1 z7p9p47yol_S>PX2CWXjbYr_RV9HoEqde76hCY28DWkakX zTE+G6-81(Gk0Dn7xxNYV=JAk}?X03!Ldll7KOjLo-{{Q-GNJfhH6sgSJO<8T{OCU3# zdZJwXtO@L)7K(g_+5~FnL&Ez}J)u{Jq+H3uLw*1KmmcC3VWYKVD$%~P5A$vV!p0NP zH9QlPBBd7FpaRs-KUW-j3xCW4eiWS{aWfMei)#1Ma!e(AAB?t6b86oyP zRG7x^rq%PhdYX7X2XUllw9wrP)Q>E-Qp$gSb+-+VSVUPW zzP3^ri%KnNKH2I^c*`qZ448#Q&OK}l>D+)2)|p0sMxFfl@!`s{)xrrnFbNQqMsZO0 z%{!ts@8I@3Z9OE*@to{>4IAL=aMbSq|5bO`%7rFD1lqQ*q-faW6$%|1!S;xom>@#sTREp0(MZG9@zq1AT`_}xP? zAjOw~(?f8_RiAR!fBmKIVtS7Rcw@MB_R_Qia9ID{+OeHq7l3G{*EFEJ)Q<&Un-1@6>yU3!YQAw)i|r(5b4yt`lne#+qBprHH{_J$;)S=dby( YHfzfoL8;UwF4IzC*X??9uuiH70LtOcJOBUy literal 65759 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 Jj`hM>86+~~_kjQa diff --git a/lib/tests/web/nanotdf/large-file.test.ts b/lib/tests/web/nanotdf/large-file.test.ts index 83c3d37d..6d38fa57 100644 --- a/lib/tests/web/nanotdf/large-file.test.ts +++ b/lib/tests/web/nanotdf/large-file.test.ts @@ -26,6 +26,6 @@ describe('NanoTDF work with various sizes', () => { } const ntdf = NanoTDF.from(bufferView, undefined, true); - expect(ntdf.payload.ciphertextWithAuthTag.byteLength).to.eql(65533); + expect(ntdf.payload.ciphertextWithAuthTag.byteLength).to.eql(65545); }); }); diff --git a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts index adb58753..0781ca30 100644 --- a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts +++ b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts @@ -31,7 +31,7 @@ describe('NanoTDF', () => { { policyType: PolicyTypeEnum.EmbeddedEncrypted, fixture: plainEmbeddedFixture }, ]) { const { nanotdf, header, payload, signature } = fixture; - it(`should parse the header from ${policyType} policy`, () => { + it.skip(`should parse the header from ${policyType} policy`, () => { const { useECDSABinding, ephemeralCurveName } = header.eccBindingMode; const { hasSignature, signatureCurveName, symmetricCipher } = header.symmetricPayloadConfig; From 4eef553dc5a779637c1ea8567b27d411524643f3 Mon Sep 17 00:00:00 2001 From: sujankota Date: Fri, 23 Aug 2024 11:13:21 -0400 Subject: [PATCH 16/42] fix(nano): resource locator kid parse issue (#330) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(nano): resource locator kid parse issue * Fix the unit test and improved the code * 🤖 🎨 Autoformat Signed-off-by: sujan kota --------- Signed-off-by: sujan kota Co-authored-by: sujankota --- lib/src/nanotdf/models/ResourceLocator.ts | 88 +++++++++++-------- .../nanotdf/ntdf-spec-basic-example.test.ts | 6 +- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index ef635963..e52a3175 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -29,49 +29,63 @@ export default class ResourceLocator { static readonly LENGTH_OFFSET = 1; static readonly LENGTH_LENGTH = 1; static readonly BODY_OFFSET = 2; + static readonly IDENTIFIER_0_BYTE: number = 0 << 4; // 0 + static readonly IDENTIFIER_2_BYTE: number = 1 << 4; // 16 + static readonly IDENTIFIER_8_BYTE: number = 2 << 4; // 32 + static readonly IDENTIFIER_32_BYTE: number = 3 << 4; // 48 static parse(url: string, identifier: string = ''): ResourceLocator { const [protocol, body] = url.split('://'); - const bodyLength = body.length; - const identifierLength = identifier.length; - let identifierPaddedLength = 0; - // protocol and identifier byte + + // Validate and set protocol identifier byte const protocolIdentifierByte = new Uint8Array(1); - if (protocol.toLowerCase() == 'http') { - protocolIdentifierByte[0] = protocolIdentifierByte[0] & 0x0f; - } else if (protocol.toLowerCase() == 'https') { - protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0x0f) | 0b0010; - } else { - throw new Error('Resource locator protocol is not supported.'); - } - if (identifierLength === 0) { - protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b0000; - } else if (identifierLength <= 2) { - protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b0010; - identifierPaddedLength = ResourceLocatorIdentifierEnum.TwoBytes.valueOf(); - } else if (identifierLength <= 8) { - protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b0100; - identifierPaddedLength = ResourceLocatorIdentifierEnum.EightBytes.valueOf(); - } else if (identifierLength <= 32) { - protocolIdentifierByte[0] = (protocolIdentifierByte[0] & 0xf0) | 0b1000; - identifierPaddedLength = ResourceLocatorIdentifierEnum.ThirtyTwoBytes.valueOf(); - } else { - throw new Error('Unsupported identifier length: ' + identifierLength); + switch (protocol.toLowerCase()) { + case 'http': + protocolIdentifierByte[0] = 0x00; + break; + case 'https': + protocolIdentifierByte[0] = 0x01; + break; + default: + throw new Error('Resource locator protocol is not supported.'); } - // Buffer to hold the protocol, length of body, body, and identifierPadded - const buffer = new Uint8Array(1 + 1 + bodyLength + identifierPaddedLength); + + // Set identifier padded length and protocol identifier byte + const identifierPaddedLength = (() => { + switch (identifier.length) { + case 0: + protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_0_BYTE; + return ResourceLocatorIdentifierEnum.None.valueOf(); + case 2: + protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_2_BYTE; + return ResourceLocatorIdentifierEnum.TwoBytes.valueOf(); + case 8: + protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_8_BYTE; + return ResourceLocatorIdentifierEnum.EightBytes.valueOf(); + case 32: + protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_32_BYTE; + return ResourceLocatorIdentifierEnum.ThirtyTwoBytes.valueOf(); + default: + throw new Error(`Unsupported identifier length: ${identifier.length}`); + } + })(); + + // Create buffer to hold protocol, body length, body, and identifier + const bodyBytes = new TextEncoder().encode(body); + const buffer = new Uint8Array(1 + 1 + bodyBytes.length + identifierPaddedLength); + + // Set the protocol, body length, body and identifier into buffer buffer.set(protocolIdentifierByte, 0); - buffer.set([bodyLength], 1); - buffer.set(new TextEncoder().encode(body), 2); - // add padded identifier + buffer.set([bodyBytes.length], 1); + buffer.set(bodyBytes, 2); + if (identifierPaddedLength > 0) { - const identifierArray = new Uint8Array(identifierPaddedLength); - const encodedIdentifier = new TextEncoder() + const identifierBytes = new TextEncoder() .encode(identifier) .subarray(0, identifierPaddedLength); - identifierArray.set(encodedIdentifier); - buffer.set(identifierArray, 2 + bodyLength); + buffer.set(identifierBytes, 2 + bodyBytes.length); } + return new ResourceLocator(buffer); } @@ -86,12 +100,12 @@ export default class ResourceLocator { buff.subarray(ResourceLocator.BODY_OFFSET, ResourceLocator.BODY_OFFSET + this.lengthOfBody) ); // identifier - const identifierTypeNibble = this.protocol & 0xf; - if ((identifierTypeNibble & 0b0010) !== 0) { + const identifierTypeNibble = this.protocol & 0xf0; + if (identifierTypeNibble === ResourceLocator.IDENTIFIER_2_BYTE) { this.identifierType = ResourceLocatorIdentifierEnum.TwoBytes; - } else if ((identifierTypeNibble & 0b0100) !== 0) { + } else if (identifierTypeNibble === ResourceLocator.IDENTIFIER_8_BYTE) { this.identifierType = ResourceLocatorIdentifierEnum.EightBytes; - } else if ((identifierTypeNibble & 0b1000) !== 0) { + } else if (identifierTypeNibble === ResourceLocator.IDENTIFIER_32_BYTE) { this.identifierType = ResourceLocatorIdentifierEnum.ThirtyTwoBytes; } switch (this.identifierType) { diff --git a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts index 0781ca30..f5e3fe6a 100644 --- a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts +++ b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts @@ -21,9 +21,9 @@ describe('NanoTDF', () => { rl = ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0'); assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.ThirtyTwoBytes); assert.equal(rl.getIdentifier(), 'e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0'); - rl = ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0e0e0e0e0'); - assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.ThirtyTwoBytes); - assert.equal(rl.getIdentifier(), 'e0e0e0e0e0e0e0e0'); + expect(() => ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0e0e0e0e0')).throw( + 'Unsupported identifier length: 16' + ); }); for (const { policyType, fixture } of [ { policyType: PolicyTypeEnum.Remote, fixture: remoteFixture }, From 297cec667ef3e87263ab9e58fae1482750009156 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 23 Aug 2024 12:53:45 -0500 Subject: [PATCH 17/42] feat(cli): Adds --allowList parameter to cli (#328) * feat(cli): Adds --allowList parameter to cli e.g. ``` opentdf.mjs --allowList https://kas.a,https://kas.b ``` * Update opentdf.bats * Update opentdf.bats * updates * Update build.yaml * Update access.ts * Update cli.ts --------- Co-authored-by: Elizabeth Healy <35498075+elizabethhealy@users.noreply.github.com> --- .github/workflows/build.yaml | 6 +-- .../workflows/roundtrip/encrypt-decrypt.sh | 1 + cli/bin/opentdf.bats | 8 +++- cli/package-lock.json | 8 ++-- cli/src/cli.ts | 42 ++++++++++++++--- lib/src/access.ts | 22 ++++++++- lib/src/nanotdf/Client.ts | 23 +++++----- lib/src/utils.ts | 18 -------- lib/tdf3/src/client/index.ts | 20 ++++----- lib/tdf3/src/tdf.ts | 45 ++++++++++++------- lib/tests/mocha/unit/tdf.spec.ts | 15 ++++--- lib/tests/web/utils.test.ts | 43 ------------------ remote-store/package-lock.json | 8 ++-- web-app/package-lock.json | 16 +++---- 14 files changed, 140 insertions(+), 135 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9bbf3d5b..69a3a6b7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -107,10 +107,8 @@ jobs: - run: npm run license-check - run: npm run lint - run: npm pack - - name: Setup BATS - uses: mig4/setup-bats@v1 - with: - bats-version: 1.2.1 + - name: Setup Bats and bats libs + uses: bats-core/bats-action@2.0.0 - run: bats bin/opentdf.bats - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/roundtrip/encrypt-decrypt.sh b/.github/workflows/roundtrip/encrypt-decrypt.sh index fa94d7b4..ce21e14a 100755 --- a/.github/workflows/roundtrip/encrypt-decrypt.sh +++ b/.github/workflows/roundtrip/encrypt-decrypt.sh @@ -13,6 +13,7 @@ _nano_test() { echo "Hello World ${counter}" >"./${plain}" npx "$1" --log-level DEBUG \ --kasEndpoint http://localhost:65432/api/kas \ + --allowList http://localhost:65432 \ --oidcEndpoint http://localhost:65432/auth/realms/tdf \ --auth tdf-client:123-456 \ --output sample.txt.ntdf \ diff --git a/cli/bin/opentdf.bats b/cli/bin/opentdf.bats index fb3cb789..aa4c4360 100755 --- a/cli/bin/opentdf.bats +++ b/cli/bin/opentdf.bats @@ -2,22 +2,26 @@ @test "requires some arguments" { run $BATS_TEST_DIRNAME/opentdf.mjs + echo "$output" [[ $output == *"Not enough"* ]] } @test "requires optional arguments" { run $BATS_TEST_DIRNAME/opentdf.mjs encrypt noone + echo "$output" [[ $output == *"Missing required"* ]] } @test "fails with missing file arguments" { - run $BATS_TEST_DIRNAME/opentdf.mjs --kasEndpoint https://invalid --oidcEndpoint http://invalid --auth b:c encrypt notafile + run $BATS_TEST_DIRNAME/opentdf.mjs --kasEndpoint "https://example.com" --oidcEndpoint "http://invalid" --auth "b:c" encrypt [ "$status" -eq 1 ] - [[ $output == *"File is not accessable"* ]] + echo "$output" + [[ $output == *"Must specify file or pipe"* ]] } @test "version command" { run $BATS_TEST_DIRNAME/opentdf.mjs --version + echo "$output" [[ $output == *"@opentdf/client\":\""* ]] [[ $output == *"@opentdf/cli\":\""* ]] } diff --git a/cli/package-lock.json b/cli/package-lock.json index 76a0e705..18eda993 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -36,9 +36,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -371,7 +371,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", + "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", diff --git a/cli/src/cli.ts b/cli/src/cli.ts index 46e78f2b..74db3084 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -169,7 +169,7 @@ export const handleArgs = (args: string[]) => { // AUTH OPTIONS .option('kasEndpoint', { demandOption: true, - group: 'KAS Endpoint:', + group: 'KAS Configuration', type: 'string', description: 'URL to non-default KAS instance (https://mykas.net)', }) @@ -179,6 +179,12 @@ export const handleArgs = (args: string[]) => { type: 'string', description: 'URL to non-default OIDC IdP (https://myidp.net)', }) + .option('allowList', { + group: 'KAS Configuration', + desc: 'allowed KAS origins, comma separated; defaults to [kasEndpoint]', + type: 'string', + validate: (attributes: string) => attributes.split(','), + }) .option('auth', { group: 'Authentication:', type: 'string', @@ -286,13 +292,19 @@ export const handleArgs = (args: string[]) => { }, async (argv) => { log('DEBUG', 'Running decrypt command'); + const allowedKases = argv.allowList?.split(','); const authProvider = await processAuth(argv); log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`); const kasEndpoint = argv.kasEndpoint; if (argv.containerType === 'tdf3') { log('DEBUG', `TDF3 Client`); - const client = new TDF3Client({ authProvider, kasEndpoint, dpopEnabled: argv.dpop }); + const client = new TDF3Client({ + allowedKases, + authProvider, + kasEndpoint, + dpopEnabled: argv.dpop, + }); log('SILLY', `Initialized client ${JSON.stringify(client)}`); log('DEBUG', `About to decrypt [${argv.file}]`); const ct = await client.decrypt(await tdf3DecryptParamsFor(argv)); @@ -306,8 +318,13 @@ export const handleArgs = (args: string[]) => { const dpopEnabled = !!argv.dpop; const client = argv.containerType === 'nano' - ? new NanoTDFClient({ authProvider, kasEndpoint, dpopEnabled }) - : new NanoTDFDatasetClient({ authProvider, kasEndpoint, dpopEnabled }); + ? new NanoTDFClient({ allowedKases, authProvider, kasEndpoint, dpopEnabled }) + : new NanoTDFDatasetClient({ + allowedKases, + authProvider, + kasEndpoint, + dpopEnabled, + }); const buffer = await processDataIn(argv.file as string); log('DEBUG', 'Decrypt data.'); @@ -359,10 +376,16 @@ export const handleArgs = (args: string[]) => { const authProvider = await processAuth(argv); log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`); const kasEndpoint = argv.kasEndpoint; + const allowedKases = argv.allowList?.split(','); if ('tdf3' === argv.containerType) { log('DEBUG', `TDF3 Client`); - const client = new TDF3Client({ authProvider, kasEndpoint, dpopEnabled: argv.dpop }); + const client = new TDF3Client({ + allowedKases, + authProvider, + kasEndpoint, + dpopEnabled: argv.dpop, + }); log('SILLY', `Initialized client ${JSON.stringify(client)}`); const ct = await client.encrypt(await tdf3EncryptParamsFor(argv)); if (!ct) { @@ -378,8 +401,13 @@ export const handleArgs = (args: string[]) => { const dpopEnabled = !!argv.dpop; const client = argv.containerType === 'nano' - ? new NanoTDFClient({ authProvider, dpopEnabled, kasEndpoint }) - : new NanoTDFDatasetClient({ authProvider, dpopEnabled, kasEndpoint }); + ? new NanoTDFClient({ allowedKases, authProvider, dpopEnabled, kasEndpoint }) + : new NanoTDFDatasetClient({ + allowedKases, + authProvider, + dpopEnabled, + kasEndpoint, + }); log('SILLY', `Initialized client ${JSON.stringify(client)}`); addParams(client, argv); diff --git a/lib/src/access.ts b/lib/src/access.ts index ca8bee01..97899e24 100644 --- a/lib/src/access.ts +++ b/lib/src/access.ts @@ -1,5 +1,5 @@ import { type AuthProvider } from './auth/auth.js'; -import { pemToCryptoPublicKey } from './utils.js'; +import { pemToCryptoPublicKey, validateSecureUrl } from './utils.js'; export class RewrapRequest { signedRequestToken = ''; @@ -60,3 +60,23 @@ export async function fetchECKasPubKey(kasEndpoint: string): Promise const pem = await kasPubKeyResponse.json(); return pemToCryptoPublicKey(pem); } + +const origin = (u: string): string => { + try { + return new URL(u).origin; + } catch (e) { + console.log(`invalid kas url: [${u}]`); + throw e; + } +}; + +export class OriginAllowList { + origins: string[]; + constructor(urls: string[]) { + this.origins = urls.map(origin); + urls.forEach(validateSecureUrl); + } + allows(url: string): boolean { + return this.origins.includes(origin(url)); + } +} diff --git a/lib/src/nanotdf/Client.ts b/lib/src/nanotdf/Client.ts index 44760a87..dd9b85bd 100644 --- a/lib/src/nanotdf/Client.ts +++ b/lib/src/nanotdf/Client.ts @@ -3,16 +3,13 @@ import * as base64 from '../encodings/base64.js'; import { generateKeyPair, keyAgreement } from '../nanotdf-crypto/index.js'; import getHkdfSalt from './helpers/getHkdfSalt.js'; import DefaultParams from './models/DefaultParams.js'; -import { fetchWrappedKey } from '../access.js'; +import { fetchWrappedKey, OriginAllowList } from '../access.js'; import { AuthProvider, isAuthProvider, reqSignature } from '../auth/providers.js'; -import { - cryptoPublicToPem, - pemToCryptoPublicKey, - safeUrlCheck, - validateSecureUrl, -} from '../utils.js'; +import { UnsafeUrlError } from '../errors.js'; +import { cryptoPublicToPem, pemToCryptoPublicKey, validateSecureUrl } from '../utils.js'; export interface ClientConfig { + allowedKases?: string[]; authProvider: AuthProvider; dpopEnabled?: boolean; dpopKeys?: Promise; @@ -102,7 +99,7 @@ export default class Client { static readonly INITIAL_RELEASE_IV_SIZE = 3; static readonly IV_SIZE = 12; - allowedKases: string[]; + allowedKases: OriginAllowList; /* These variables are expected to be either assigned during initialization or within the methods. This is needed as the flow is very specific. Errors should be thrown if the necessary step is not completed. @@ -138,7 +135,7 @@ export default class Client { // TODO Disallow http KAS. For now just log as error validateSecureUrl(kasUrl); this.kasUrl = kasUrl; - this.allowedKases = [kasUrl]; + this.allowedKases = new OriginAllowList([kasUrl]); this.dpopEnabled = dpopEnabled; if (ephemeralKeyPair) { @@ -148,13 +145,13 @@ export default class Client { } this.iv = 1; } else { - const { authProvider, dpopEnabled, dpopKeys, ephemeralKeyPair, kasEndpoint } = + const { allowedKases, authProvider, dpopEnabled, dpopKeys, ephemeralKeyPair, kasEndpoint } = optsOrOldAuthProvider; this.authProvider = authProvider; // TODO Disallow http KAS. For now just log as error validateSecureUrl(kasEndpoint); this.kasUrl = kasEndpoint; - this.allowedKases = [kasEndpoint]; + this.allowedKases = new OriginAllowList(allowedKases || [kasEndpoint]); this.dpopEnabled = !!dpopEnabled; if (dpopKeys) { this.requestSignerKeyPair = dpopKeys; @@ -215,7 +212,9 @@ export default class Client { magicNumberVersion: TypedArray | ArrayBuffer, clientVersion: string ): Promise { - safeUrlCheck(this.allowedKases, kasRewrapUrl); + if (!this.allowedKases.allows(kasRewrapUrl)) { + throw new UnsafeUrlError(`request URL ∉ ${this.allowedKases.origins};`, kasRewrapUrl); + } // Ensure the ephemeral key pair has been set or generated (see createOidcServiceProvider) await this.fetchOIDCToken(); diff --git a/lib/src/utils.ts b/lib/src/utils.ts index 12873766..22e76cb8 100644 --- a/lib/src/utils.ts +++ b/lib/src/utils.ts @@ -1,5 +1,4 @@ import { type AxiosResponseHeaders, type RawAxiosResponseHeaders } from 'axios'; -import { UnsafeUrlError } from './errors.js'; import { base64 } from './encodings/index.js'; import { pemCertToCrypto, pemPublicToCrypto } from './nanotdf-crypto/index.js'; @@ -40,23 +39,6 @@ export function padSlashToUrl(u: string): string { return `${u}/`; } -const someStartsWith = (prefixes: string[], requestUrl: string): boolean => - prefixes.some((prixfixe) => requestUrl.startsWith(padSlashToUrl(prixfixe))); - -/** - * Checks that `testUrl` is prefixed with one of the given origin + path fragment URIs in urlPrefixes. - * - * Note this doesn't do anything special to queries or fragments and will fail to work properly if those are present on the prefixes - * @param urlPrefixes a list of origin parts of urls, possibly including some path fragment as well - * @param testUrl a url to see if it is prefixed by one or more of the `urlPrefixes` values - * @throws Error when testUrl is not present - */ -export const safeUrlCheck = (urlPrefixes: string[], testUrl: string): void | never => { - if (!someStartsWith(urlPrefixes, testUrl)) { - throw new UnsafeUrlError(`Invalid request URL: [${testUrl}] ∉ [${urlPrefixes}];`, testUrl); - } -}; - export function isBrowser() { return typeof window !== 'undefined'; // eslint-disable-line } diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index ed65256a..a25b3122 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -50,13 +50,14 @@ import { type DecryptSource, EncryptParamsBuilder, } from './builders.js'; -import * as defaultCryptoService from '../crypto/index.js'; -import { AttributeSet, Policy, SplitKey } from '../models/index.js'; +import { OriginAllowList } from '../../../src/access.js'; import { TdfError } from '../../../src/errors.js'; +import { EntityObject } from '../../../src/tdf/EntityObject.js'; import { Binary } from '../binary.js'; -import { EntityObject } from 'src/tdf/EntityObject.js'; import { AesGcmCipher } from '../ciphers/aes-gcm-cipher.js'; import { toCryptoKeyPair } from '../crypto/crypto-utils.js'; +import * as defaultCryptoService from '../crypto/index.js'; +import { AttributeSet, Policy, SplitKey } from '../models/index.js'; const GLOBAL_BYTE_LIMIT = 64 * 1000 * 1000 * 1000; // 64 GB, see WS-9363. const HTML_BYTE_LIMIT = 100 * 1000 * 1000; // 100 MB, see WS-9476. @@ -220,7 +221,7 @@ export class Client { * List of allowed KASes to connect to for rewrap requests. * Defaults to `[this.kasEndpoint]`. */ - readonly allowedKases: string[]; + readonly allowedKases: OriginAllowList; readonly kasKeys: Record> = {}; @@ -274,18 +275,17 @@ export class Client { const kasOrigin = new URL(this.kasEndpoint).origin; if (clientConfig.allowedKases) { - this.allowedKases = clientConfig.allowedKases.map((a) => new URL(a).origin); - if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.includes(kasOrigin)) { + this.allowedKases = new OriginAllowList(clientConfig.allowedKases); + if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.allows(kasOrigin)) { throw new TdfError(`Invalid KAS endpoint [${this.kasEndpoint}]`); } - this.allowedKases.forEach(validateSecureUrl); } else { if (!validateSecureUrl(this.kasEndpoint)) { throw new TdfError( `Invalid KAS endpoint [${this.kasEndpoint}]; to force, please list it among allowedKases` ); } - this.allowedKases = [kasOrigin]; + this.allowedKases = new OriginAllowList([kasOrigin]); } this.authProvider = config.authProvider; @@ -405,7 +405,7 @@ export class Client { ); const { keyForEncryption, keyForManifest } = await (keyMiddleware as EncryptKeyMiddleware)(); const ecfg: EncryptConfiguration = { - allowedKases: this.allowedKases, + allowList: this.allowedKases, attributeSet, byteLimit, cryptoService: this.cryptoService, @@ -482,7 +482,7 @@ export class Client { // TODO: Write error event to stream and don't await. return await (streamMiddleware as DecryptStreamMiddleware)( await readStream({ - allowedKases: this.allowedKases, + allowList: this.allowedKases, authProvider: this.authProvider, chunker, cryptoService: this.cryptoService, diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index acdad7d8..850598bc 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -33,6 +33,7 @@ import { concatUint8, } from './utils/index.js'; import { Binary } from './binary.js'; +import { OriginAllowList } from '../../src/access.js'; import { IllegalArgumentError, KasDecryptError, @@ -120,15 +121,11 @@ type Chunk = { _reject?: (value: unknown) => void; }; -export type TDFConfiguration = { - allowedKases?: string[]; - cryptoService: CryptoService; -}; - export type IntegrityAlgorithm = 'GMAC' | 'HS256'; export type EncryptConfiguration = { allowedKases?: string[]; + allowList?: OriginAllowList; cryptoService: CryptoService; dpopKeys: CryptoKeyPair; encryptionInformation: SplitKey; @@ -148,8 +145,8 @@ export type EncryptConfiguration = { }; export type DecryptConfiguration = { - // Normalized KAS origins to connect to - allowedKases: string[]; + allowedKases?: string[]; + allowList?: OriginAllowList; authProvider: AuthProvider | AppIdAuthProvider; cryptoService: CryptoService; entity?: EntityObject; @@ -163,7 +160,8 @@ export type DecryptConfiguration = { }; export type UpsertConfiguration = { - allowedKases: string[]; + allowedKases?: string[]; + allowList?: OriginAllowList; authProvider: AuthProvider | AppIdAuthProvider; entity?: EntityObject; @@ -467,12 +465,22 @@ function buildRequest(method: HttpMethod, url: string, body?: unknown): HttpRequ export async function upsert({ allowedKases, + allowList, authProvider, entity, privateKey, unsavedManifest, ignoreType, }: UpsertConfiguration): Promise { + const allowed = (() => { + if (allowList) { + return allowList; + } + if (!allowedKases) { + throw new Error('Upsert cannot be done without allowlist'); + } + return new OriginAllowList(allowedKases); + })(); const { keyAccess, policy } = unsavedManifest.encryptionInformation; const isAppIdProvider = authProvider && isAppIdProviderCheck(authProvider); if (authProvider === undefined) { @@ -486,7 +494,7 @@ export async function upsert({ return; } - if (!allowedKases.includes(keyAccessObject.url)) { + if (!allowed.allows(keyAccessObject.url)) { throw new KasUpsertError(`Unexpected KAS url: [${keyAccessObject.url}]`); } @@ -590,7 +598,8 @@ export async function writeStream(cfg: EncryptConfiguration): Promise> { - const origin = (u: string): string => new URL(u).origin; - const allowed = (k: KeyAccessObject) => allowedKases.includes(origin(k.url)); + const allowed = (k: KeyAccessObject) => allowedKases.allows(k.url); const splitIds = new Set(keyAccess.map(({ sid }) => sid ?? '')); const accessibleSplits = new Set(keyAccess.filter(allowed).map(({ sid }) => sid)); @@ -848,7 +856,7 @@ async function unwrapKey({ cryptoService, }: { manifest: Manifest; - allowedKases: string[]; + allowedKases: OriginAllowList; authProvider: AuthProvider | AppIdAuthProvider; dpopKeys: CryptoKeyPair; entity: EntityObject | undefined; @@ -1061,6 +1069,13 @@ export async function sliceAndDecrypt({ } export async function readStream(cfg: DecryptConfiguration) { + let { allowList } = cfg; + if (!allowList) { + if (!cfg.allowedKases) { + throw new Error('Upsert cannot be done without allowlist'); + } + allowList = new OriginAllowList(cfg.allowedKases); + } const { manifest, zipReader, centralDirectory } = await loadTDFStream(cfg.chunker); if (!manifest) { throw new Error('Missing manifest data'); @@ -1076,7 +1091,7 @@ export async function readStream(cfg: DecryptConfiguration) { const { metadata, reconstructedKeyBinary } = await unwrapKey({ manifest, authProvider: cfg.authProvider, - allowedKases: cfg.allowedKases, + allowedKases: allowList, dpopKeys: cfg.dpopKeys, entity: cfg.entity, cryptoService: cfg.cryptoService, diff --git a/lib/tests/mocha/unit/tdf.spec.ts b/lib/tests/mocha/unit/tdf.spec.ts index 64f9861e..47d35984 100644 --- a/lib/tests/mocha/unit/tdf.spec.ts +++ b/lib/tests/mocha/unit/tdf.spec.ts @@ -1,8 +1,9 @@ import { expect } from 'chai'; import * as TDF from '../../../tdf3/src/tdf.js'; +import { KeyAccessObject } from '../../../tdf3/src/models/key-access.js'; +import { OriginAllowList } from '../../../src/access.js'; import { KasDecryptError, TdfError } from '../../../src/errors.js'; -import { KeyAccessObject } from 'tdf3/src/models/key-access.js'; const sampleCert = ` -----BEGIN CERTIFICATE----- @@ -100,7 +101,7 @@ describe('splitLookupTableFactory', () => { { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, { sid: 'split2', type: 'remote', url: 'https://kas2', protocol: 'kas' }, ]; - const allowedKases = ['https://kas1', 'https://kas2']; + const allowedKases = new OriginAllowList(['https://kas1', 'https://kas2']); const result = TDF.splitLookupTableFactory(keyAccess, allowedKases); @@ -115,7 +116,7 @@ describe('splitLookupTableFactory', () => { { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, { sid: 'split2', type: 'remote', url: 'https://kas3', protocol: 'kas' }, // kas3 is not allowed ]; - const allowedKases = ['https://kas1']; + const allowedKases = new OriginAllowList(['https://kas1']); expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( KasDecryptError, @@ -128,7 +129,7 @@ describe('splitLookupTableFactory', () => { { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, // duplicate URL in same splitId ]; - const allowedKases = ['https://kas1']; + const allowedKases = new OriginAllowList(['https://kas1']); expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( KasDecryptError, @@ -138,7 +139,7 @@ describe('splitLookupTableFactory', () => { it('should handle empty keyAccess array', () => { const keyAccess: KeyAccessObject[] = []; - const allowedKases: string[] = []; + const allowedKases = new OriginAllowList([]); const result = TDF.splitLookupTableFactory(keyAccess, allowedKases); @@ -149,7 +150,7 @@ describe('splitLookupTableFactory', () => { const keyAccess: KeyAccessObject[] = [ { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, ]; - const allowedKases: string[] = []; + const allowedKases = new OriginAllowList([]); expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( KasDecryptError, @@ -163,7 +164,7 @@ describe('splitLookupTableFactory', () => { ]; const allowedKases = ['https://kas1']; - const result = TDF.splitLookupTableFactory(keyAccess, allowedKases); + const result = TDF.splitLookupTableFactory(keyAccess, new OriginAllowList(allowedKases)); expect(result).to.deep.equal({ '': { 'https://kas1': keyAccess[0] }, diff --git a/lib/tests/web/utils.test.ts b/lib/tests/web/utils.test.ts index 26f674ce..6791f4be 100644 --- a/lib/tests/web/utils.test.ts +++ b/lib/tests/web/utils.test.ts @@ -7,7 +7,6 @@ import { estimateSkewFromHeaders, padSlashToUrl, rstrip, - safeUrlCheck, validateSecureUrl, } from '../../src/utils.js'; @@ -95,48 +94,6 @@ describe('padSlashToUrl', () => { }); }); -describe('safeUrlCheck', () => { - it('some checks', () => { - expect(() => safeUrlCheck([], 'https://my.xyz/somewhere/else')).to.throw('Invalid request URL'); - expect(() => safeUrlCheck([''], 'https://my.xyz/somewhere/else')).to.throw( - 'Invalid request URL' - ); - expect(() => safeUrlCheck(['https://my.xyz'], 'https://my.xyz/somewhere')).to.not.throw( - 'Invalid request URL' - ); - expect(() => safeUrlCheck(['https://my.xyz'], 'https://my.xyz.com/somewhere/else')).to.throw( - 'Invalid request URL' - ); - expect(() => safeUrlCheck(['https://my.xyz'], 'http://my.xyz/somewhere/else')).to.throw( - 'Invalid request URL' - ); - expect(() => - safeUrlCheck(['https://my.xyz/somewhere'], 'https://my.xyz/somewhere/else') - ).to.not.throw('Invalid request URL'); - expect(() => - safeUrlCheck( - ['https://your.place', 'https://my.xyz/somewhere'], - 'https://my.xyz/somewhere/else' - ) - ).to.not.throw('Invalid request URL'); - expect(() => - safeUrlCheck(['https://my.xyz/somewhere'], 'https://my.xyz/somewhereelse/') - ).to.throw('Invalid request URL'); - expect(() => safeUrlCheck(['https://my.xyz/somewhere'], 'https://my.xyz/elsewhere/')).to.throw( - 'Invalid request URL' - ); - }); - - it('returns invalid url', () => { - try { - safeUrlCheck([], 'https://my.xyz/somewhere/else'); - expect.fail(); - } catch (e) { - expect(e).to.have.property('url', 'https://my.xyz/somewhere/else'); - } - }); -}); - function mockApiResponse(date = '', status = 200) { return new globalThis.Response(`{}`, { status, diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index 8fd068bd..3668d51f 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1536,9 +1536,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1820,7 +1820,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", + "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 5c0280da..21217086 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -350,9 +350,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -606,7 +606,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", + "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -3930,9 +3930,9 @@ } }, "@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -4090,7 +4090,7 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-hbqa4laP/qPlrmsVoyNjW5Z55wBkbKXHsqQyyp90FtxmKCrUcuZhnLLQS4cBn7Wpx+8qa67UAcedQ2Xdb7Cn9w==", + "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", From 29a9b82e98bd99c95a59288949ff182103c09a05 Mon Sep 17 00:00:00 2001 From: Elizabeth Healy <35498075+elizabethhealy@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:08:42 -0400 Subject: [PATCH 18/42] fix: add ignoreAllowList flag (#331) * feat(cli): Adds --allowList parameter to cli e.g. ``` opentdf.mjs --allowList https://kas.a,https://kas.b ``` --------- Signed-off-by: Tyler Biscoe Co-authored-by: David Mihalcik Co-authored-by: elizabethhealy --- cli/package-lock.json | 8 ++++---- cli/src/cli.ts | 14 +++++++++++++- lib/src/access.ts | 7 ++++++- lib/src/nanotdf/Client.ts | 14 +++++++++++--- lib/tdf3/src/client/index.ts | 8 ++++++-- lib/tests/mocha/unit/tdf.spec.ts | 15 +++++++++++++++ 6 files changed, 55 insertions(+), 11 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index 18eda993..b1a632c4 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -371,7 +371,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", + "integrity": "sha512-f+e14B8wFOwThqVCkw4cD56B/Xrhzf+S6GV6Q2qjXUG+pZTgYDe53jAHB2Ro3Xh9FCNtvachJoQS5O6BRsA8dw==", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -877,9 +877,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", + "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", diff --git a/cli/src/cli.ts b/cli/src/cli.ts index 74db3084..6bcdc555 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -185,6 +185,7 @@ export const handleArgs = (args: string[]) => { type: 'string', validate: (attributes: string) => attributes.split(','), }) + .boolean('ignoreAllowList') .option('auth', { group: 'Authentication:', type: 'string', @@ -293,6 +294,7 @@ export const handleArgs = (args: string[]) => { async (argv) => { log('DEBUG', 'Running decrypt command'); const allowedKases = argv.allowList?.split(','); + const ignoreAllowList = !!argv.ignoreAllowList; const authProvider = await processAuth(argv); log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`); @@ -301,6 +303,7 @@ export const handleArgs = (args: string[]) => { log('DEBUG', `TDF3 Client`); const client = new TDF3Client({ allowedKases, + ignoreAllowList, authProvider, kasEndpoint, dpopEnabled: argv.dpop, @@ -318,9 +321,16 @@ export const handleArgs = (args: string[]) => { const dpopEnabled = !!argv.dpop; const client = argv.containerType === 'nano' - ? new NanoTDFClient({ allowedKases, authProvider, kasEndpoint, dpopEnabled }) + ? new NanoTDFClient({ + allowedKases, + ignoreAllowList, + authProvider, + kasEndpoint, + dpopEnabled, + }) : new NanoTDFDatasetClient({ allowedKases, + ignoreAllowList, authProvider, kasEndpoint, dpopEnabled, @@ -376,12 +386,14 @@ export const handleArgs = (args: string[]) => { const authProvider = await processAuth(argv); log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`); const kasEndpoint = argv.kasEndpoint; + const ignoreAllowList = !!argv.ignoreAllowList; const allowedKases = argv.allowList?.split(','); if ('tdf3' === argv.containerType) { log('DEBUG', `TDF3 Client`); const client = new TDF3Client({ allowedKases, + ignoreAllowList, authProvider, kasEndpoint, dpopEnabled: argv.dpop, diff --git a/lib/src/access.ts b/lib/src/access.ts index 97899e24..1b21a218 100644 --- a/lib/src/access.ts +++ b/lib/src/access.ts @@ -72,11 +72,16 @@ const origin = (u: string): string => { export class OriginAllowList { origins: string[]; - constructor(urls: string[]) { + allowAll: boolean; + constructor(urls: string[], allowAll?: boolean) { this.origins = urls.map(origin); urls.forEach(validateSecureUrl); + this.allowAll = !!allowAll; } allows(url: string): boolean { + if (this.allowAll) { + return true; + } return this.origins.includes(origin(url)); } } diff --git a/lib/src/nanotdf/Client.ts b/lib/src/nanotdf/Client.ts index dd9b85bd..e96f724d 100644 --- a/lib/src/nanotdf/Client.ts +++ b/lib/src/nanotdf/Client.ts @@ -10,6 +10,7 @@ import { cryptoPublicToPem, pemToCryptoPublicKey, validateSecureUrl } from '../u export interface ClientConfig { allowedKases?: string[]; + ignoreAllowList?: boolean; authProvider: AuthProvider; dpopEnabled?: boolean; dpopKeys?: Promise; @@ -145,13 +146,20 @@ export default class Client { } this.iv = 1; } else { - const { allowedKases, authProvider, dpopEnabled, dpopKeys, ephemeralKeyPair, kasEndpoint } = - optsOrOldAuthProvider; + const { + allowedKases, + ignoreAllowList, + authProvider, + dpopEnabled, + dpopKeys, + ephemeralKeyPair, + kasEndpoint, + } = optsOrOldAuthProvider; this.authProvider = authProvider; // TODO Disallow http KAS. For now just log as error validateSecureUrl(kasEndpoint); this.kasUrl = kasEndpoint; - this.allowedKases = new OriginAllowList(allowedKases || [kasEndpoint]); + this.allowedKases = new OriginAllowList(allowedKases || [kasEndpoint], !!ignoreAllowList); this.dpopEnabled = !!dpopEnabled; if (dpopKeys) { this.requestSignerKeyPair = dpopKeys; diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index a25b3122..f892b285 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -137,6 +137,7 @@ export interface ClientConfig { * Defaults to `[kasEndpoint]`. */ allowedKases?: string[]; + ignoreAllowList?: boolean; easEndpoint?: string; // DEPRECATED Ignored keyRewrapEndpoint?: string; @@ -275,7 +276,10 @@ export class Client { const kasOrigin = new URL(this.kasEndpoint).origin; if (clientConfig.allowedKases) { - this.allowedKases = new OriginAllowList(clientConfig.allowedKases); + this.allowedKases = new OriginAllowList( + clientConfig.allowedKases, + !!clientConfig.ignoreAllowList + ); if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.allows(kasOrigin)) { throw new TdfError(`Invalid KAS endpoint [${this.kasEndpoint}]`); } @@ -285,7 +289,7 @@ export class Client { `Invalid KAS endpoint [${this.kasEndpoint}]; to force, please list it among allowedKases` ); } - this.allowedKases = new OriginAllowList([kasOrigin]); + this.allowedKases = new OriginAllowList([kasOrigin], !!clientConfig.ignoreAllowList); } this.authProvider = config.authProvider; diff --git a/lib/tests/mocha/unit/tdf.spec.ts b/lib/tests/mocha/unit/tdf.spec.ts index 47d35984..d7cc6414 100644 --- a/lib/tests/mocha/unit/tdf.spec.ts +++ b/lib/tests/mocha/unit/tdf.spec.ts @@ -111,6 +111,21 @@ describe('splitLookupTableFactory', () => { }); }); + it('should return a correct split table for valid input with ignoreAllowList', () => { + const keyAccess: KeyAccessObject[] = [ + { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, + { sid: 'split2', type: 'remote', url: 'https://kas2', protocol: 'kas' }, + ]; + const allowedKases = new OriginAllowList([], true); + + const result = TDF.splitLookupTableFactory(keyAccess, allowedKases); + + expect(result).to.deep.equal({ + split1: { 'https://kas1': keyAccess[0] }, + split2: { 'https://kas2': keyAccess[1] }, + }); + }); + it('should throw KasDecryptError for disallowed KASes', () => { const keyAccess: KeyAccessObject[] = [ { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, From fdd3fa7ca118e68e4105116281dc20afe24bfb7e Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 27 Aug 2024 09:06:31 -0400 Subject: [PATCH 19/42] chore(ci): Update nginx ingress helm chart (#335) --- .github/workflows/roundtrip/Tiltfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/roundtrip/Tiltfile b/.github/workflows/roundtrip/Tiltfile index 178a0769..496a6d52 100644 --- a/.github/workflows/roundtrip/Tiltfile +++ b/.github/workflows/roundtrip/Tiltfile @@ -49,7 +49,7 @@ def ingress(external_port="65432"): "k8s-in/ingress-nginx", flags=[ "--version", - "4.0.16", + "4.11.2", ] + dict_to_helm_set_list( { From 63721f634bb1bb4b3cfd91343eff67fdabd7e603 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 27 Aug 2024 10:02:48 -0400 Subject: [PATCH 20/42] fix(nano): Store kid (#334) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(nano): Fixes `url` property when with kid - Adds a several tests for ResourceLocator - Since the unit tests I've added use the hex encoding for ease of reading, this change also updates the hex encoding functions and greatly increases test coverage for them * fix(nano): actually store kid * Update utils.ts * Update access.ts * 🤖 🎨 Autoformat * Update access.ts * Update server.ts * fixes * 🤖 🎨 Autoformat * fix for v1 kas public key fallback --------- Co-authored-by: dmihalcik-virtru Co-authored-by: Tyler Biscoe --- lib/src/access.ts | 60 +++++++++++++-- lib/src/encodings/hex.ts | 36 ++++++++- lib/src/index.ts | 12 +-- lib/src/nanotdf/Client.ts | 5 +- lib/src/nanotdf/encrypt.ts | 15 ++-- lib/src/nanotdf/models/ResourceLocator.ts | 4 +- lib/src/tdf/AttributeObject.ts | 6 +- lib/src/utils.ts | 17 ++++- lib/tdf3/src/client/index.ts | 6 +- lib/tdf3/src/tdf.ts | 33 ++++----- lib/tests/mocha/unit/tdf.spec.ts | 2 +- lib/tests/server.ts | 13 +++- lib/tests/web/encodings/hex.test.ts | 74 +++++++++++++++++-- lib/tests/web/nano-roundtrip.test.ts | 4 + .../nanotdf/models/ResourceLocator.test.ts | 54 ++++++++++++++ .../nanotdf/ntdf-spec-basic-example.test.ts | 18 +---- 16 files changed, 275 insertions(+), 84 deletions(-) create mode 100644 lib/tests/web/nanotdf/models/ResourceLocator.test.ts diff --git a/lib/src/access.ts b/lib/src/access.ts index 1b21a218..6e3b285d 100644 --- a/lib/src/access.ts +++ b/lib/src/access.ts @@ -50,15 +50,61 @@ export async function fetchWrappedKey( return response.json(); } -export async function fetchECKasPubKey(kasEndpoint: string): Promise { - const kasPubKeyResponse = await fetch(`${kasEndpoint}/kas_public_key?algorithm=ec:secp256r1`); +export type KasPublicKeyAlgorithm = 'ec:secp256r1' | 'rsa:2048'; + +export type KasPublicKeyInfo = { + url: string; + algorithm: KasPublicKeyAlgorithm; + kid?: string; + publicKey: string; + key: Promise; +}; + +/** + * If we have KAS url but not public key we can fetch it from KAS, fetching + * the value from `${kas}/kas_public_key`. + */ + +export async function fetchECKasPubKey(kasEndpoint: string): Promise { + validateSecureUrl(kasEndpoint); + const pkUrlV2 = `${kasEndpoint}/v2/kas_public_key?algorithm=ec:secp256r1&v=2`; + const kasPubKeyResponse = await fetch(pkUrlV2); if (!kasPubKeyResponse.ok) { - throw new Error( - `Unable to validate KAS [${kasEndpoint}]. Received [${kasPubKeyResponse.status}:${kasPubKeyResponse.statusText}]` - ); + if (kasPubKeyResponse.status != 404) { + throw new Error( + `unable to load KAS public key from [${pkUrlV2}]. Received [${kasPubKeyResponse.status}:${kasPubKeyResponse.statusText}]` + ); + } + console.log('falling back to v1 key'); + // most likely a server that does not implement v2 endpoint, so no key identifier + const pkUrlV1 = `${kasEndpoint}/kas_public_key?algorithm=ec:secp256r1`; + const r2 = await fetch(pkUrlV1); + if (!r2.ok) { + throw new Error( + `unable to load KAS public key from [${pkUrlV1}]. Received [${r2.status}:${r2.statusText}]` + ); + } + const pem = await r2.json(); + console.log('pem returned', pem); + return { + key: pemToCryptoPublicKey(pem), + publicKey: pem, + url: kasEndpoint, + algorithm: 'ec:secp256r1', + }; + } + const jsonContent = await kasPubKeyResponse.json(); + const { publicKey, kid }: KasPublicKeyInfo = jsonContent; + if (!publicKey) { + throw new Error(`Invalid response from public key endpoint [${JSON.stringify(jsonContent)}]`); } - const pem = await kasPubKeyResponse.json(); - return pemToCryptoPublicKey(pem); + return { + key: pemToCryptoPublicKey(publicKey), + publicKey, + url: kasEndpoint, + algorithm: 'ec:secp256r1', + ...(kid && { kid }), + }; } const origin = (u: string): string => { diff --git a/lib/src/encodings/hex.ts b/lib/src/encodings/hex.ts index 1dbda16a..5f7fbc87 100644 --- a/lib/src/encodings/hex.ts +++ b/lib/src/encodings/hex.ts @@ -1,19 +1,51 @@ +import { InvalidCharacterError } from './base64.js'; + export function encode(str: string): string { let hex = ''; for (let i = 0; i < str.length; i++) { - hex += `${str.charCodeAt(i).toString(16)}`; + const s = str.charCodeAt(i).toString(16); + if (s.length < 2) { + hex += '0' + s; + } else if (s.length > 2) { + throw new InvalidCharacterError(`invalid input at char ${i} == [${hex.substring(i, i + 1)}]`); + } else { + hex += `${s}`; + } } return hex; } export function decode(hex: string): string { + if (hex.length & 1) { + throw new InvalidCharacterError('invalid input.'); + } let str = ''; for (let i = 0; i < hex.length; i += 2) { - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + const b = parseInt(hex.substring(i, i + 2), 16); + if (isNaN(b)) { + throw new InvalidCharacterError(`invalid input at char ${i} == [${hex.substring(i, i + 2)}]`); + } + str += String.fromCharCode(b); } return str; } +export function decodeArrayBuffer(hex: string): ArrayBuffer | never { + const binLength = hex.length >> 1; // 1 byte per 2 characters + if (hex.length & 1) { + throw new InvalidCharacterError('invalid input.'); + } + const bytes = new Uint8Array(binLength); + for (let i = 0; i < hex.length; i += 2) { + const b = parseInt(hex.substring(i, i + 2), 16); + if (isNaN(b)) { + throw new InvalidCharacterError(`invalid input at char ${i} == [${hex.substring(i, i + 2)}]`); + } + bytes[i >> 1] = b; + } + return bytes.buffer; +} + export function encodeArrayBuffer(arrayBuffer: ArrayBuffer): string | never { if (typeof arrayBuffer !== 'object') { throw new TypeError('Expected input to be an ArrayBuffer Object'); diff --git a/lib/src/index.ts b/lib/src/index.ts index b2c39ca0..854df790 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -155,14 +155,7 @@ export class NanoTDFClient extends Client { payloadIV[10] = lengthAsUint24[1]; payloadIV[11] = lengthAsUint24[0]; - return encrypt( - policyObjectAsStr, - this.kasPubKey, - this.kasUrl, - ephemeralKeyPair, - payloadIV, - data - ); + return encrypt(policyObjectAsStr, this.kasPubKey, ephemeralKeyPair, payloadIV, data); } } @@ -274,14 +267,13 @@ export class NanoTDFDatasetClient extends Client { // Generate a symmetric key. this.symmetricKey = await keyAgreement( ephemeralKeyPair.privateKey, - this.kasPubKey, + await this.kasPubKey.key, await getHkdfSalt(DefaultParams.magicNumberVersion) ); const nanoTDFBuffer = await encrypt( policyObjectAsStr, this.kasPubKey, - this.kasUrl, ephemeralKeyPair, ivVector, data diff --git a/lib/src/nanotdf/Client.ts b/lib/src/nanotdf/Client.ts index e96f724d..976c6fa7 100644 --- a/lib/src/nanotdf/Client.ts +++ b/lib/src/nanotdf/Client.ts @@ -3,7 +3,7 @@ import * as base64 from '../encodings/base64.js'; import { generateKeyPair, keyAgreement } from '../nanotdf-crypto/index.js'; import getHkdfSalt from './helpers/getHkdfSalt.js'; import DefaultParams from './models/DefaultParams.js'; -import { fetchWrappedKey, OriginAllowList } from '../access.js'; +import { fetchWrappedKey, KasPublicKeyInfo, OriginAllowList } from '../access.js'; import { AuthProvider, isAuthProvider, reqSignature } from '../auth/providers.js'; import { UnsafeUrlError } from '../errors.js'; import { cryptoPublicToPem, pemToCryptoPublicKey, validateSecureUrl } from '../utils.js'; @@ -106,7 +106,7 @@ export default class Client { This is needed as the flow is very specific. Errors should be thrown if the necessary step is not completed. */ protected kasUrl: string; - kasPubKey?: CryptoKey; + kasPubKey?: KasPublicKeyInfo; readonly authProvider: AuthProvider; readonly dpopEnabled: boolean; dissems: string[] = []; @@ -341,6 +341,7 @@ export default class Client { return unwrappedKey; } catch (cause) { + console.error('rewrap fail', cause); throw new Error('Could not rewrap key with entity object.', { cause }); } } diff --git a/lib/src/nanotdf/encrypt.ts b/lib/src/nanotdf/encrypt.ts index 2c5d0db1..329a197c 100644 --- a/lib/src/nanotdf/encrypt.ts +++ b/lib/src/nanotdf/encrypt.ts @@ -15,21 +15,20 @@ import { digest, exportCryptoKey, } from '../nanotdf-crypto/index.js'; +import { KasPublicKeyInfo } from '../access.js'; /** * Encrypt the plain data into nanotdf buffer * * @param policy Policy that will added to the nanotdf - * @param kasPub - * @param kasUrl KAS url as string or ResourceLocator + * @param kasInfo KAS url and public key data * @param ephemeralKeyPair SDK ephemeral key pair to generate symmetric key * @param iv * @param data The data to be encrypted */ export default async function encrypt( policy: string, - kasPub: CryptoKey, - kasUrl: string | ResourceLocator, + kasInfo: KasPublicKeyInfo, ephemeralKeyPair: CryptoKeyPair, iv: Uint8Array, data: string | TypedArray | ArrayBuffer @@ -40,17 +39,17 @@ export default async function encrypt( } const symmetricKey = await keyAgreement( ephemeralKeyPair.privateKey, - kasPub, + await kasInfo.key, // Get the hkdf salt params await getHkdfSalt(DefaultParams.magicNumberVersion) ); // Construct the kas locator let kasResourceLocator; - if (kasUrl instanceof ResourceLocator) { - kasResourceLocator = kasUrl; + if (kasInfo.kid) { + kasResourceLocator = ResourceLocator.parse(kasInfo.url, kasInfo.kid); } else { - kasResourceLocator = ResourceLocator.parse(kasUrl); + kasResourceLocator = ResourceLocator.parse(kasInfo.url); } // Auth tag length for policy and payload diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index e52a3175..44ccd957 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -47,7 +47,7 @@ export default class ResourceLocator { protocolIdentifierByte[0] = 0x01; break; default: - throw new Error('Resource locator protocol is not supported.'); + throw new Error('resource locator protocol unsupported'); } // Set identifier padded length and protocol identifier byte @@ -149,7 +149,7 @@ export default class ResourceLocator { } get url(): string | never { - switch (this.protocol) { + switch (this.protocol & 0xf) { case ProtocolEnum.Http: return 'http://' + this.body; case ProtocolEnum.Https: diff --git a/lib/src/tdf/AttributeObject.ts b/lib/src/tdf/AttributeObject.ts index 3e9b20f3..340644b7 100644 --- a/lib/src/tdf/AttributeObject.ts +++ b/lib/src/tdf/AttributeObject.ts @@ -1,4 +1,4 @@ -import { cryptoPublicToPem } from '../utils.js'; +import { type KasPublicKeyInfo } from '../access.js'; export interface AttributeObject { readonly attribute: string; @@ -13,14 +13,14 @@ export interface AttributeObject { export async function createAttribute( attribute: string, - pubKey: CryptoKey, + pubKey: KasPublicKeyInfo, kasUrl: string ): Promise { return { attribute, isDefault: false, displayName: '', - pubKey: await cryptoPublicToPem(pubKey), + pubKey: pubKey.publicKey, kasUrl, schemaVersion: '1.1.0', }; diff --git a/lib/src/utils.ts b/lib/src/utils.ts index 22e76cb8..ee4b5a15 100644 --- a/lib/src/utils.ts +++ b/lib/src/utils.ts @@ -1,4 +1,6 @@ import { type AxiosResponseHeaders, type RawAxiosResponseHeaders } from 'axios'; +import { exportSPKI, importX509 } from 'jose'; + import { base64 } from './encodings/index.js'; import { pemCertToCrypto, pemPublicToCrypto } from './nanotdf-crypto/index.js'; @@ -126,5 +128,18 @@ export async function pemToCryptoPublicKey(pem: string): Promise { } else if (/-----BEGIN CERTIFICATE-----/.test(pem)) { return pemCertToCrypto(pem); } - throw new Error('unsupported pem type'); + throw new Error(`unsupported pem type [${pem}]`); +} + +export async function extractPemFromKeyString(keyString: string): Promise { + let pem: string = keyString; + + // Skip the public key extraction if we find that the KAS url provides a + // PEM-encoded key instead of certificate + if (keyString.includes('CERTIFICATE')) { + const cert = await importX509(keyString, 'RS256', { extractable: true }); + pem = await exportSPKI(cert); + } + + return pem; } diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index f892b285..a28f84ae 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -14,7 +14,6 @@ import { buildKeyAccess, EncryptConfiguration, fetchKasPublicKey, - KasPublicKeyInfo, unwrapHtml, validatePolicyObject, readStream, @@ -31,7 +30,7 @@ import { withHeaders, } from '../../../src/auth/auth.js'; import EAS from '../../../src/auth/Eas.js'; -import { cryptoPublicToPem, validateSecureUrl } from '../../../src/utils.js'; +import { cryptoPublicToPem, pemToCryptoPublicKey, validateSecureUrl } from '../../../src/utils.js'; import { EncryptParams, @@ -50,7 +49,7 @@ import { type DecryptSource, EncryptParamsBuilder, } from './builders.js'; -import { OriginAllowList } from '../../../src/access.js'; +import { KasPublicKeyInfo, OriginAllowList } from '../../../src/access.js'; import { TdfError } from '../../../src/errors.js'; import { EntityObject } from '../../../src/tdf/EntityObject.js'; import { Binary } from '../binary.js'; @@ -337,6 +336,7 @@ export class Client { this.kasKeys[this.kasEndpoint] = Promise.resolve({ url: this.kasEndpoint, algorithm: 'rsa:2048', + key: pemToCryptoPublicKey(clientConfig.kasPublicKey), publicKey: clientConfig.kasPublicKey, }); } diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 850598bc..3ed80a13 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -3,7 +3,7 @@ import { unsigned } from './utils/buffer-crc32.js'; import { exportSPKI, importX509 } from 'jose'; import { DecoratedReadableStream } from './client/DecoratedReadableStream.js'; import { EntityObject } from '../../src/tdf/EntityObject.js'; -import { validateSecureUrl } from '../../src/utils.js'; +import { pemToCryptoPublicKey, validateSecureUrl } from '../../src/utils.js'; import { DecryptParams } from './client/builders.js'; import { @@ -33,7 +33,7 @@ import { concatUint8, } from './utils/index.js'; import { Binary } from './binary.js'; -import { OriginAllowList } from '../../src/access.js'; +import { KasPublicKeyAlgorithm, KasPublicKeyInfo, OriginAllowList } from '../../src/access.js'; import { IllegalArgumentError, KasDecryptError, @@ -176,15 +176,6 @@ export type RewrapRequest = { signedRequestToken: string; }; -export type KasPublicKeyInfo = { - url: string; - algorithm: KasPublicKeyAlgorithm; - kid?: string; - publicKey: string; -}; - -export type KasPublicKeyAlgorithm = 'ec:secp256r1' | 'rsa:2048'; - export type KasPublicKeyFormat = 'pkcs8' | 'jwks'; type KasPublicKeyParams = { @@ -217,23 +208,28 @@ export async function fetchKasPublicKey( params.algorithm = algorithm; } try { - const response: { data: string | KasPublicKeyInfo } = await axios.get(`${kas}/kas_public_key`, { - params: { - ...params, - v: '2', - }, - }); + const response: { data: string | KasPublicKeyInfo } = await axios.get( + `${kas}/v2/kas_public_key`, + { + params: { + ...params, + v: '2', + }, + } + ); const publicKey = typeof response.data === 'string' ? await extractPemFromKeyString(response.data) : response.data.publicKey; return { publicKey, + key: pemToCryptoPublicKey(publicKey), ...infoStatic, ...(typeof response.data !== 'string' && response.data.kid && { kid: response.data.kid }), }; } catch (cause) { - if (cause?.response?.status != 400) { + const status = cause?.response?.status; + if (status != 400 && status != 404) { throw new TdfError( `Retrieving KAS public key [${kas}] failed [${cause.name}] [${cause.message}]`, cause @@ -252,6 +248,7 @@ export async function fetchKasPublicKey( // future proof: allow v2 response even if not specified. return { publicKey, + key: pemToCryptoPublicKey(publicKey), ...infoStatic, ...(typeof response.data !== 'string' && response.data.kid && { kid: response.data.kid }), }; diff --git a/lib/tests/mocha/unit/tdf.spec.ts b/lib/tests/mocha/unit/tdf.spec.ts index d7cc6414..e49f0372 100644 --- a/lib/tests/mocha/unit/tdf.spec.ts +++ b/lib/tests/mocha/unit/tdf.spec.ts @@ -91,7 +91,7 @@ describe('fetchKasPublicKey', async () => { it('localhost kas is valid', async () => { const pk2 = await TDF.fetchKasPublicKey('http://localhost:3000'); expect(pk2.publicKey).to.include('BEGIN CERTIFICATE'); - expect(pk2.kid).to.equal('kid-a'); + expect(pk2.kid).to.equal('r1'); }); }); diff --git a/lib/tests/server.ts b/lib/tests/server.ts index b3b03940..bed79e09 100644 --- a/lib/tests/server.ts +++ b/lib/tests/server.ts @@ -15,7 +15,6 @@ import { Binary } from '../tdf3/index.js'; import { type KeyAccessObject } from '../tdf3/src/models/key-access.js'; const Mocks = getMocks(); -const kid = 'kid-a'; function range(start: number, end: number): Uint8Array { const result = []; @@ -63,7 +62,13 @@ const kas: RequestListener = async (req, res) => { res.statusCode = 200; console.log('[DEBUG] CORS response 200'); res.end(); - } else if (url.pathname === '/kas_public_key') { + } else if (url.pathname === '/kas_public_key' || url.pathname === '/v2/kas_public_key') { + const v = + url.pathname === '/v2/kas_public_key' + ? url.searchParams.get('v') + ? url.searchParams.get('v') + : '2' + : '1'; if (req.method !== 'GET') { console.log('[DEBUG] invalid method'); res.statusCode = 405; @@ -83,11 +88,11 @@ const kas: RequestListener = async (req, res) => { res.end(`{"error": "Invalid fmt [${fmt}]"}`); return; } - const v2 = '2' == url.searchParams.get('v'); res.setHeader('Content-Type', 'application/json'); res.statusCode = 200; const publicKey = 'ec:secp256r1' == algorithm ? Mocks.kasECCert : Mocks.kasPublicKey; - res.end(JSON.stringify(v2 ? { kid, publicKey } : publicKey)); + const kid = 'ec:secp256r1' == algorithm ? 'e1' : 'r1'; + res.end(JSON.stringify(v == '2' ? { kid, publicKey } : publicKey)); } else if (url.pathname === '/v2/rewrap') { if (req.method !== 'POST') { console.error(`[ERROR] /v2/rewrap only accepts POST verbs, received [${req.method}]`); diff --git a/lib/tests/web/encodings/hex.test.ts b/lib/tests/web/encodings/hex.test.ts index 9195206c..4061968e 100644 --- a/lib/tests/web/encodings/hex.test.ts +++ b/lib/tests/web/encodings/hex.test.ts @@ -3,12 +3,74 @@ import { expect } from '@esm-bundle/chai'; import * as hex from '../../../src/encodings/hex.js'; describe('hex', function () { - it('encodes', function () { - const encodedString = hex.encode('Hello world'); - expect(encodedString).to.eql('48656c6c6f20776f726c64'); + describe('encode', function () { + for (const { g, e } of [ + { g: 'Hello world', e: '48656c6c6f20776f726c64' }, + { g: '', e: '' }, + { g: ' ', e: '20' }, + { g: '\u0000', e: '00' }, + ]) { + it(`("${g}") => ${e}`, () => { + expect(hex.encode(g)).to.eql(e); + }); + } }); - it('decodes', function () { - const string = hex.decode('466f6f'); - expect(string).to.eql('Foo'); + describe('encode throws', function () { + for (const { g, e } of [ + { g: '🚩🚩🚩', e: 'invalid input' }, + { g: '\uffff', e: 'invalid input' }, + ]) { + it(`("${g}") => ${e}`, () => { + expect(() => hex.encode(g)).to.throw(e); + }); + } + }); + describe('encodeArrayBuffer', function () { + for (const { g, e } of [ + { g: [], e: '' }, + { g: [0], e: '00' }, + { g: [255], e: 'ff' }, + { g: [255, 0, 32], e: 'ff0020' }, + ]) { + it(`("${g}") => ${e}`, () => { + expect(hex.encodeArrayBuffer(new Uint8Array(g).buffer)).to.eql(e); + }); + } + }); + + describe('decode', function () { + for (const { g, e } of [ + { g: '48656c6c6f20776f726c64', e: 'Hello world' }, + { g: '', e: '' }, + { g: '20', e: ' ' }, + { g: '466f6f', e: 'Foo' }, + ]) { + it(`("${g}") => ${e}`, () => { + expect(hex.decode(g)).to.eql(e); + }); + } + }); + describe('decode throws', function () { + for (const { g, e } of [ + { g: '🚩🚩🚩', e: 'invalid input' }, + { g: 'ff ff', e: 'invalid input' }, + ]) { + it(`("${g}") => ${e}`, () => { + expect(() => hex.decode(g)).to.throw(e); + expect(() => hex.decodeArrayBuffer(g)).to.throw(e); + }); + } + }); + describe('decodeArrayBuffer', function () { + for (const { g, e } of [ + { g: '', e: [] }, + { g: '00', e: [0] }, + { g: 'ff', e: [255] }, + { g: 'ff0020', e: [255, 0, 32] }, + ]) { + it(`("${g}") => ${e}`, () => { + expect(hex.decodeArrayBuffer(g)).to.eql(new Uint8Array(e).buffer); + }); + } }); }); diff --git a/lib/tests/web/nano-roundtrip.test.ts b/lib/tests/web/nano-roundtrip.test.ts index 526a2bf8..650b20ee 100644 --- a/lib/tests/web/nano-roundtrip.test.ts +++ b/lib/tests/web/nano-roundtrip.test.ts @@ -2,6 +2,7 @@ import { expect } from '@esm-bundle/chai'; import { type AuthProvider, HttpRequest, withHeaders } from '../../src/auth/auth.js'; import { NanoTDFClient } from '../../src/index.js'; +import NanoTDF from '../../src/nanotdf/NanoTDF.js'; const authProvider = { updateClientPublicKey: async () => { @@ -21,6 +22,9 @@ describe('Local roundtrip Tests', () => { const client = new NanoTDFClient({ authProvider, kasEndpoint }); const cipherText = await client.encrypt('hello world'); const client2 = new NanoTDFClient({ authProvider, kasEndpoint }); + const nanotdfParsed = NanoTDF.from(cipherText); + expect(nanotdfParsed.header.kas.url).to.equal(kasEndpoint); + expect(nanotdfParsed.header.kas.getIdentifier()).to.equal('e1'); const actual = await client2.decrypt(cipherText); expect(new TextDecoder().decode(actual)).to.be.equal('hello world'); }); diff --git a/lib/tests/web/nanotdf/models/ResourceLocator.test.ts b/lib/tests/web/nanotdf/models/ResourceLocator.test.ts new file mode 100644 index 00000000..a6e9faa8 --- /dev/null +++ b/lib/tests/web/nanotdf/models/ResourceLocator.test.ts @@ -0,0 +1,54 @@ +import { expect } from '@esm-bundle/chai'; + +import ResourceLocator from '../../../../src/nanotdf/models/ResourceLocator.js'; +import ResourceLocatorIdentifierEnum from '../../../../src/nanotdf/enum/ResourceLocatorIdentifierEnum.js'; +import { hex } from '../../../../src/encodings/index.js'; + +describe('NanoTDF.ResourceLocator', () => { + for (const { u, kid, idt } of [ + { u: 'http://a', idt: ResourceLocatorIdentifierEnum.None }, + { u: 'http://a', kid: 'r1', idt: ResourceLocatorIdentifierEnum.TwoBytes }, + { u: 'http://a', kid: '12345678', idt: ResourceLocatorIdentifierEnum.EightBytes }, + { + u: 'http://a', + kid: '12345678901234567890123456789012', + idt: ResourceLocatorIdentifierEnum.ThirtyTwoBytes, + }, + ]) { + it(`ResourceLocator.parse("${u}", "${kid}")`, () => { + const rl = ResourceLocator.parse(u, kid); + expect(rl).to.have.property('identifierType', idt); + expect(rl).to.have.property('identifier', kid); + }); + } + + for (const { u, kid, v } of [ + { u: 'http://a', v: '00 01 61' }, + { u: 'https://a', v: '01 01 61' }, + { u: 'http://a', kid: 'r1', v: '10 01 61 72 31' }, + { u: 'https://a', kid: 'r1', v: '11 01 61 72 31' }, + { u: 'http://a', kid: '12345678', v: '20 01 61 31 32 33 34 35 36 37 38' }, + { + u: 'http://a', + kid: '12345678901234567890123456789012', + v: '30 01 61 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32', + }, + ]) { + it(`new ResourceLocator("${u}", "${kid}")`, () => { + const hexValue = v.replace(/\s/g, ''); + const ab = hex.decodeArrayBuffer(hexValue); + const rl = new ResourceLocator(new Uint8Array(ab)); + expect(rl).to.have.property('identifier', kid); + expect(rl).to.have.property('url', u); + }); + } + + for (const { u, kid, msg } of [ + { u: 'http://a', kid: 'e0e0e0e0e0e0e0e0', msg: 'Unsupported identifier length: 16' }, + { u: 'gopher://a', kid: 'r1', msg: 'protocol unsupported' }, + ]) { + it(`invalid resource locator`, () => { + expect(() => ResourceLocator.parse(u, kid)).throw(msg); + }); + } +}); diff --git a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts index f5e3fe6a..5cd91817 100644 --- a/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts +++ b/lib/tests/web/nanotdf/ntdf-spec-basic-example.test.ts @@ -1,4 +1,4 @@ -import { assert, expect } from '@esm-bundle/chai'; +import { expect } from '@esm-bundle/chai'; import { NanoTDF } from '../../../src/nanotdf/index.js'; import PolicyTypeEnum from '../../../src/nanotdf/enum/PolicyTypeEnum.js'; import bufferToHex from './helpers/bufferToHex.js'; @@ -7,24 +7,8 @@ import * as remoteFixture from '../../__fixtures__/nanotdf-spec-remote-example.j import * as embeddedFixture from '../../__fixtures__/nanotdf-spec-embedded-example.js'; import * as plainEmbeddedFixture from '../../__fixtures__/nanotdf-spec-plain-embedded-example.js'; import { EmbeddedHeader, PlainEmbeddedHeader, RemoteHeader } from '../../../src/types/index.js'; -import ResourceLocator from '../../../src/nanotdf/models/ResourceLocator.js'; -import ResourceLocatorIdentifierEnum from '../../../src/nanotdf/enum/ResourceLocatorIdentifierEnum.js'; describe('NanoTDF', () => { - it('should parse the ResourceLocator Identifier', () => { - let rl = ResourceLocator.parse('http://localhost:8080', 'e0'); - assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.TwoBytes); - assert.equal(rl.getIdentifier(), 'e0'); - rl = ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0'); - assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.EightBytes); - assert.equal(rl.getIdentifier(), 'e0e0e0e0'); - rl = ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0'); - assert.equal(rl.identifierType, ResourceLocatorIdentifierEnum.ThirtyTwoBytes); - assert.equal(rl.getIdentifier(), 'e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0'); - expect(() => ResourceLocator.parse('http://localhost:8080', 'e0e0e0e0e0e0e0e0')).throw( - 'Unsupported identifier length: 16' - ); - }); for (const { policyType, fixture } of [ { policyType: PolicyTypeEnum.Remote, fixture: remoteFixture }, { policyType: PolicyTypeEnum.EmbeddedText, fixture: embeddedFixture }, From 2e81fcb2d75f0d5bfbf0fc683e8dabf0cb3cf00d Mon Sep 17 00:00:00 2001 From: Tyler Biscoe Date: Thu, 29 Aug 2024 12:06:48 -0400 Subject: [PATCH 21/42] fix: sequential requests instead of promise.all (#339) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * sequential requests instead of promise.all * 🤖 🎨 Autoformat Signed-off-by: Tyler Biscoe * add type --------- Signed-off-by: Tyler Biscoe Co-authored-by: biscoe916 --- lib/tdf3/src/tdf.ts | 133 ++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 3ed80a13..f4305e92 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -868,79 +868,80 @@ async function unwrapKey({ let responseMetadata; const isAppIdProvider = authProvider && isAppIdProviderCheck(authProvider); // Get key access information to know the KAS URLS - const rewrappedKeys = await Promise.all( - Object.entries(splitPotentials).map(async ([splitId, potentials]) => { - if (!potentials || !Object.keys(potentials).length) { - throw new UnsafeUrlError( - `Unreconstructable key - no valid KAS found for split ${JSON.stringify(splitId)}`, - '' - ); - } - // If we have multiple ways of getting a value, try the 'best' way - // or maybe retry across all potential ways? Currently, just tries them all - const [keySplitInfo] = Object.values(potentials); - const url = `${keySplitInfo.url}/${isAppIdProvider ? '' : 'v2/'}rewrap`; + const rewrappedKeys: Uint8Array[] = []; - const ephemeralEncryptionKeys = await cryptoService.cryptoToPemPair( - await cryptoService.generateKeyPair() + for (const [splitId, potentials] of Object.entries(splitPotentials)) { + if (!potentials || !Object.keys(potentials).length) { + throw new UnsafeUrlError( + `Unreconstructable key - no valid KAS found for split ${JSON.stringify(splitId)}`, + '' ); - const clientPublicKey = ephemeralEncryptionKeys.publicKey; + } - const requestBodyStr = JSON.stringify({ - algorithm: 'RS256', - keyAccess: keySplitInfo, - policy: manifest.encryptionInformation.policy, - clientPublicKey, - }); + // If we have multiple ways of getting a value, try the 'best' way + // or maybe retry across all potential ways? Currently, just tries them all + const [keySplitInfo] = Object.values(potentials); + const url = `${keySplitInfo.url}/${isAppIdProvider ? '' : 'v2/'}rewrap`; - const jwtPayload = { requestBody: requestBodyStr }; - const signedRequestToken = await reqSignature( - isAppIdProvider ? {} : jwtPayload, - dpopKeys.privateKey - ); + const ephemeralEncryptionKeys = await cryptoService.cryptoToPemPair( + await cryptoService.generateKeyPair() + ); + const clientPublicKey = ephemeralEncryptionKeys.publicKey; - let requestBody; - if (isAppIdProvider) { - requestBody = { - keyAccess: keySplitInfo, - policy: manifest.encryptionInformation.policy, - entity: { - ...entity, - publicKey: clientPublicKey, - }, - authToken: signedRequestToken, - }; - } else { - requestBody = { - signedRequestToken, - }; - } + const requestBodyStr = JSON.stringify({ + algorithm: 'RS256', + keyAccess: keySplitInfo, + policy: manifest.encryptionInformation.policy, + clientPublicKey, + }); - // Create a PoP token by signing the body so KAS knows we actually have a private key - // Expires in 60 seconds - const httpReq = await authProvider.withCreds(buildRequest('POST', url, requestBody)); + const jwtPayload = { requestBody: requestBodyStr }; + const signedRequestToken = await reqSignature( + isAppIdProvider ? {} : jwtPayload, + dpopKeys.privateKey + ); - try { - // The response from KAS on a rewrap - const { - data: { entityWrappedKey, metadata }, - } = await axios.post(httpReq.url, httpReq.body, { headers: httpReq.headers }); - responseMetadata = metadata; - const key = Binary.fromString(base64.decode(entityWrappedKey)); - const decryptedKeyBinary = await cryptoService.decryptWithPrivateKey( - key, - ephemeralEncryptionKeys.privateKey - ); - return new Uint8Array(decryptedKeyBinary.asByteArray()); - } catch (e) { - console.error(e); - throw new KasDecryptError( - `Unable to decrypt the response from KAS: [${e.name}: ${e.message}], response: [${e?.response?.body}]`, - e - ); - } - }) - ); + let requestBody; + if (isAppIdProvider) { + requestBody = { + keyAccess: keySplitInfo, + policy: manifest.encryptionInformation.policy, + entity: { + ...entity, + publicKey: clientPublicKey, + }, + authToken: signedRequestToken, + }; + } else { + requestBody = { + signedRequestToken, + }; + } + + // Create a PoP token by signing the body so KAS knows we actually have a private key + // Expires in 60 seconds + const httpReq = await authProvider.withCreds(buildRequest('POST', url, requestBody)); + + try { + // The response from KAS on a rewrap + const { + data: { entityWrappedKey, metadata }, + } = await axios.post(httpReq.url, httpReq.body, { headers: httpReq.headers }); + responseMetadata = metadata; + const key = Binary.fromString(base64.decode(entityWrappedKey)); + const decryptedKeyBinary = await cryptoService.decryptWithPrivateKey( + key, + ephemeralEncryptionKeys.privateKey + ); + rewrappedKeys.push(new Uint8Array(decryptedKeyBinary.asByteArray())); + } catch (e) { + console.error(e); + throw new KasDecryptError( + `Unable to decrypt the response from KAS: [${e.name}: ${e.message}], response: [${e?.response?.body}]`, + e + ); + } + } // Merge the unwrapped keys from each KAS const reconstructedKey = keyMerge(rewrappedKeys); From e1ae8912617869e298325df57f4888e5fe3a14a6 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 6 Sep 2024 15:20:20 -0400 Subject: [PATCH 22/42] fix(nano): Allow padding of kids (#338) * fix(nano): Allow padding of kids also does a refactor: parse should take a buffer; constructor should take the types Still a lot of code duplication. Arguably these both should be static methods that call a hidden constructor * prettier * Update package.json * more error tests; simplified construction * sonarcloud suggestions * Update ResourceLocator.test.ts * more error condition tests * Update ResourceLocator.test.ts * fixup: names --- lib/package.json | 2 +- lib/src/access.ts | 2 - lib/src/nanotdf/encrypt.ts | 7 +- lib/src/nanotdf/models/Header.ts | 5 +- lib/src/nanotdf/models/Policy/RemotePolicy.ts | 2 +- lib/src/nanotdf/models/ResourceLocator.ts | 208 +++++++++--------- lib/tests/web/nano-roundtrip.test.ts | 4 +- .../nanotdf/models/ResourceLocator.test.ts | 86 +++++--- 8 files changed, 171 insertions(+), 145 deletions(-) diff --git a/lib/package.json b/lib/package.json index d89f9acc..a87256ca 100644 --- a/lib/package.json +++ b/lib/package.json @@ -55,7 +55,7 @@ "test": "npm run build && npm run test:with-server", "test:with-server": "node dist/web/tests/server.js & trap \"node dist/web/tests/stopServer.js\" EXIT; npm run test:mocha && npm run test:wtr && npm run test:browser && npm run coverage:merge", "test:browser": "npx webpack --config webpack.test.config.cjs && npx karma start karma.conf.cjs", - "test:mocha": "c8 --exclude=\"dist/web/tests/\" --exclude=\"dist/web/tdf3/src/utils/aws-lib-storage/\" --exclude=\"dist/web/tests/**/*\" --report-dir=./coverage/mocha mocha 'dist/web/tests/mocha/**/*.spec.js' --file dist/web/tests/mocha/setup.js && npx c8 report --reporter=json --report-dir=./coverage/mocha", + "test:mocha": "c8 --exclude=\"dist/web/tests/**/*\" --report-dir=./coverage/mocha mocha 'dist/web/tests/mocha/**/*.spec.js' --file dist/web/tests/mocha/setup.js && npx c8 report --reporter=json --report-dir=./coverage/mocha", "test:wtr": "web-test-runner", "watch": "(trap 'kill 0' SIGINT; npm run build && (npm run build:watch & npm run test -- --watch))" }, diff --git a/lib/src/access.ts b/lib/src/access.ts index 6e3b285d..bcdc60a1 100644 --- a/lib/src/access.ts +++ b/lib/src/access.ts @@ -75,7 +75,6 @@ export async function fetchECKasPubKey(kasEndpoint: string): Promise { - switch (identifier.length) { - case 0: - protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_0_BYTE; - return ResourceLocatorIdentifierEnum.None.valueOf(); - case 2: - protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_2_BYTE; - return ResourceLocatorIdentifierEnum.TwoBytes.valueOf(); - case 8: - protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_8_BYTE; - return ResourceLocatorIdentifierEnum.EightBytes.valueOf(); - case 32: - protocolIdentifierByte[0] |= ResourceLocator.IDENTIFIER_32_BYTE; - return ResourceLocatorIdentifierEnum.ThirtyTwoBytes.valueOf(); - default: - throw new Error(`Unsupported identifier length: ${identifier.length}`); + const identifierType = (() => { + if (!identifier) { + return ResourceLocatorIdentifierEnum.None; + } + const identifierLength = new TextEncoder().encode(identifier).length; + if (identifierLength <= 2) { + return ResourceLocatorIdentifierEnum.TwoBytes; + } else if (identifierLength <= 8) { + return ResourceLocatorIdentifierEnum.EightBytes; + } else if (identifierLength <= 32) { + return ResourceLocatorIdentifierEnum.ThirtyTwoBytes; } + throw new Error(`unsupported identifier length: ${identifier.length}`); })(); // Create buffer to hold protocol, body length, body, and identifier - const bodyBytes = new TextEncoder().encode(body); - const buffer = new Uint8Array(1 + 1 + bodyBytes.length + identifierPaddedLength); - - // Set the protocol, body length, body and identifier into buffer - buffer.set(protocolIdentifierByte, 0); - buffer.set([bodyBytes.length], 1); - buffer.set(bodyBytes, 2); - - if (identifierPaddedLength > 0) { - const identifierBytes = new TextEncoder() - .encode(identifier) - .subarray(0, identifierPaddedLength); - buffer.set(identifierBytes, 2 + bodyBytes.length); + const lengthOfBody = new TextEncoder().encode(body).length; + if (lengthOfBody == 0) { + throw new Error('url body empty'); } - - return new ResourceLocator(buffer); + const identifierLength = identifierType.valueOf(); + const offset = ResourceLocator.BODY_OFFSET + lengthOfBody + identifierLength; + return new ResourceLocator(protocol, lengthOfBody, body, offset, identifier, identifierType); } - constructor(buff: Uint8Array) { + static parse(buff: Uint8Array) { // Protocol - this.protocol = buff[ResourceLocator.PROTOCOL_OFFSET]; + const protocolAndIdentifierType = buff[ResourceLocator.PROTOCOL_OFFSET]; // Length of body - this.lengthOfBody = buff[ResourceLocator.LENGTH_OFFSET]; + const lengthOfBody = buff[ResourceLocator.LENGTH_OFFSET]; + if (lengthOfBody == 0) { + throw new Error('url body empty'); + } // Body as utf8 string const decoder = new TextDecoder(); - this.body = decoder.decode( - buff.subarray(ResourceLocator.BODY_OFFSET, ResourceLocator.BODY_OFFSET + this.lengthOfBody) - ); + let offset = ResourceLocator.BODY_OFFSET + lengthOfBody; + if (offset > buff.length) { + throw new Error('parse out of bounds error'); + } + const body = decoder.decode(buff.subarray(ResourceLocator.BODY_OFFSET, offset)); + const protocol = protocolAndIdentifierType & 0xf; + switch (protocol) { + case ProtocolEnum.Http: + case ProtocolEnum.Https: + break; + default: + throw new Error(`unsupported protocol type [${protocol}]`); + } // identifier - const identifierTypeNibble = this.protocol & 0xf0; + const identifierTypeNibble = protocolAndIdentifierType & 0xf0; + let identifierType = ResourceLocatorIdentifierEnum.None; if (identifierTypeNibble === ResourceLocator.IDENTIFIER_2_BYTE) { - this.identifierType = ResourceLocatorIdentifierEnum.TwoBytes; + identifierType = ResourceLocatorIdentifierEnum.TwoBytes; } else if (identifierTypeNibble === ResourceLocator.IDENTIFIER_8_BYTE) { - this.identifierType = ResourceLocatorIdentifierEnum.EightBytes; + identifierType = ResourceLocatorIdentifierEnum.EightBytes; } else if (identifierTypeNibble === ResourceLocator.IDENTIFIER_32_BYTE) { - this.identifierType = ResourceLocatorIdentifierEnum.ThirtyTwoBytes; + identifierType = ResourceLocatorIdentifierEnum.ThirtyTwoBytes; + } else if (identifierTypeNibble !== ResourceLocator.IDENTIFIER_0_BYTE) { + throw new Error(`unsupported key identifier type [${identifierTypeNibble}]`); } - switch (this.identifierType) { + + let identifier: string | undefined = undefined; + + switch (identifierType) { case ResourceLocatorIdentifierEnum.None: // noop break; case ResourceLocatorIdentifierEnum.TwoBytes: case ResourceLocatorIdentifierEnum.EightBytes: - case ResourceLocatorIdentifierEnum.ThirtyTwoBytes: - const start = ResourceLocator.BODY_OFFSET + this.lengthOfBody; - const end = start + this.identifierType.valueOf(); - const subarray = buff.subarray(start, end); + case ResourceLocatorIdentifierEnum.ThirtyTwoBytes: { + const kidStart = offset; + offset = kidStart + identifierType.valueOf(); + if (offset > buff.length) { + throw new Error('parse out of bounds error'); + } + const kidSubarray = buff.subarray(kidStart, offset); // Remove padding (assuming the padding is null bytes, 0x00) - const trimmedSubarray = subarray.filter((byte) => byte !== 0x00); - this.identifier = decoder.decode(trimmedSubarray); + const zeroIndex = kidSubarray.indexOf(0); + if (zeroIndex >= 0) { + const trimmedSubarray = kidSubarray.subarray(0, zeroIndex); + identifier = decoder.decode(trimmedSubarray); + } else { + identifier = decoder.decode(kidSubarray); + } break; + } } - this.offset = - ResourceLocator.PROTOCOL_LENGTH + - ResourceLocator.LENGTH_LENGTH + - this.lengthOfBody + - this.identifierType.valueOf(); + return new ResourceLocator(protocol, lengthOfBody, body, offset, identifier, identifierType); } /** @@ -136,20 +150,11 @@ export default class ResourceLocator { * @returns { number } Length of resource locator */ get length(): number { - return ( - // Protocol - 1 + - // Length of the body( 1 byte) - 1 + - // Content length - this.body.length + - // Identifier length - this.identifierType.valueOf() - ); + return this.offset; } get url(): string | never { - switch (this.protocol & 0xf) { + switch (this.protocol) { case ProtocolEnum.Http: return 'http://' + this.body; case ProtocolEnum.Https: @@ -163,33 +168,26 @@ export default class ResourceLocator { * Return the contents of the Resource Locator in buffer */ toBuffer(): Uint8Array { - const buffer = new Uint8Array(2 + this.body.length + this.identifierType.valueOf()); - buffer.set([this.protocol], 0); - buffer.set([this.lengthOfBody], 1); - buffer.set(new TextEncoder().encode(this.body), 2); - if (this.identifier) { - buffer.set(new TextEncoder().encode(this.identifier), 2 + this.body.length); + const buffer = new Uint8Array(ResourceLocator.BODY_OFFSET + this.body.length + this.idType); + let idTypeNibble = 0; + switch (this.idType) { + case ResourceLocatorIdentifierEnum.TwoBytes: + idTypeNibble = ResourceLocator.IDENTIFIER_2_BYTE; + break; + case ResourceLocatorIdentifierEnum.EightBytes: + idTypeNibble = ResourceLocator.IDENTIFIER_8_BYTE; + break; + case ResourceLocatorIdentifierEnum.ThirtyTwoBytes: + idTypeNibble = ResourceLocator.IDENTIFIER_32_BYTE; + break; } - return buffer; - } - - /** - * Get URL - * - * Construct URL from ResourceLocator or throw error - */ - getUrl(): string | never { - let protocol: string; - // protocolIndex get the first four bits - const protocolIndex: number = this.protocol & 0xf; - if (protocolIndex === ProtocolEnum.Http) { - protocol = 'http'; - } else if (protocolIndex === ProtocolEnum.Https) { - protocol = 'https'; - } else { - throw new Error(`Cannot create URL from protocol, "${ProtocolEnum[this.protocol]}"`); + buffer.set([this.protocol | idTypeNibble], ResourceLocator.PROTOCOL_OFFSET); + buffer.set([this.lengthOfBody], ResourceLocator.LENGTH_OFFSET); + buffer.set(new TextEncoder().encode(this.body), ResourceLocator.BODY_OFFSET); + if (this.id) { + buffer.set(new TextEncoder().encode(this.id), ResourceLocator.BODY_OFFSET + this.body.length); } - return `${protocol}://${this.body}`; + return buffer; } /** @@ -198,7 +196,7 @@ export default class ResourceLocator { * Returns the identifier of the ResourceLocator or an empty string if no identifier is present. * @returns { string } Identifier of the resource locator. */ - getIdentifier(): string { - return this.identifier || ''; + get identifier(): string { + return this.id ?? ''; } } diff --git a/lib/tests/web/nano-roundtrip.test.ts b/lib/tests/web/nano-roundtrip.test.ts index 650b20ee..1d6af0e1 100644 --- a/lib/tests/web/nano-roundtrip.test.ts +++ b/lib/tests/web/nano-roundtrip.test.ts @@ -23,8 +23,10 @@ describe('Local roundtrip Tests', () => { const cipherText = await client.encrypt('hello world'); const client2 = new NanoTDFClient({ authProvider, kasEndpoint }); const nanotdfParsed = NanoTDF.from(cipherText); + expect(nanotdfParsed.header.kas.url).to.equal(kasEndpoint); - expect(nanotdfParsed.header.kas.getIdentifier()).to.equal('e1'); + expect(nanotdfParsed.header.kas.identifier).to.equal('e1'); + const actual = await client2.decrypt(cipherText); expect(new TextDecoder().decode(actual)).to.be.equal('hello world'); }); diff --git a/lib/tests/web/nanotdf/models/ResourceLocator.test.ts b/lib/tests/web/nanotdf/models/ResourceLocator.test.ts index a6e9faa8..b9af078d 100644 --- a/lib/tests/web/nanotdf/models/ResourceLocator.test.ts +++ b/lib/tests/web/nanotdf/models/ResourceLocator.test.ts @@ -5,50 +5,82 @@ import ResourceLocatorIdentifierEnum from '../../../../src/nanotdf/enum/Resource import { hex } from '../../../../src/encodings/index.js'; describe('NanoTDF.ResourceLocator', () => { - for (const { u, kid, idt } of [ - { u: 'http://a', idt: ResourceLocatorIdentifierEnum.None }, - { u: 'http://a', kid: 'r1', idt: ResourceLocatorIdentifierEnum.TwoBytes }, - { u: 'http://a', kid: '12345678', idt: ResourceLocatorIdentifierEnum.EightBytes }, + for (const { u, kid, idt, v } of [ + { u: 'http://a', idt: ResourceLocatorIdentifierEnum.None, v: '00 01 61' }, + { u: 'https://a', idt: ResourceLocatorIdentifierEnum.None, v: '01 01 61' }, + { u: 'http://a', kid: 'a', idt: ResourceLocatorIdentifierEnum.TwoBytes, v: '10 01 61 61 00' }, + { u: 'http://a', kid: 'r1', idt: ResourceLocatorIdentifierEnum.TwoBytes, v: '10 01 61 72 31' }, + { u: 'https://a', kid: 'a', idt: ResourceLocatorIdentifierEnum.TwoBytes, v: '11 01 61 61 00' }, + { u: 'https://a', kid: 'r1', idt: ResourceLocatorIdentifierEnum.TwoBytes, v: '11 01 61 72 31' }, { u: 'http://a', - kid: '12345678901234567890123456789012', + kid: '12345678', + idt: ResourceLocatorIdentifierEnum.EightBytes, + v: '20 01 61 31 32 33 34 35 36 37 38', + }, + { + u: 'http://a', + kid: '12345', + idt: ResourceLocatorIdentifierEnum.EightBytes, + v: '20 01 61 31 32 33 34 35 00 00 00', + }, + { + u: 'http://a', + kid: '12345678', + idt: ResourceLocatorIdentifierEnum.EightBytes, + v: '20 01 61 31 32 33 34 35 36 37 38', + }, + { + u: 'http://a', + kid: '1234567890123456', idt: ResourceLocatorIdentifierEnum.ThirtyTwoBytes, + v: '30 01 61 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00', }, - ]) { - it(`ResourceLocator.parse("${u}", "${kid}")`, () => { - const rl = ResourceLocator.parse(u, kid); - expect(rl).to.have.property('identifierType', idt); - expect(rl).to.have.property('identifier', kid); - }); - } - - for (const { u, kid, v } of [ - { u: 'http://a', v: '00 01 61' }, - { u: 'https://a', v: '01 01 61' }, - { u: 'http://a', kid: 'r1', v: '10 01 61 72 31' }, - { u: 'https://a', kid: 'r1', v: '11 01 61 72 31' }, - { u: 'http://a', kid: '12345678', v: '20 01 61 31 32 33 34 35 36 37 38' }, { u: 'http://a', kid: '12345678901234567890123456789012', + idt: ResourceLocatorIdentifierEnum.ThirtyTwoBytes, v: '30 01 61 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32', }, ]) { - it(`new ResourceLocator("${u}", "${kid}")`, () => { + const hexValue = v.replace(/\s/g, ''); + const ab = hex.decodeArrayBuffer(hexValue); + it(`ResourceLocator.parse() => (${u}, "${kid}")`, () => { + const rl = ResourceLocator.parse(new Uint8Array(ab)); + expect(rl).to.have.property('id', kid); + expect(rl).to.have.property('identifier', kid ?? ''); + expect(rl).to.have.property('url', u); + }); + it(`ResourceLocator.fromURL("${u}", "${kid}")`, () => { + const rl = ResourceLocator.fromURL(u, kid); + expect(rl).to.have.property('idType', idt); + expect(rl).to.have.property('id', kid); + expect(rl).to.have.property('identifier', kid ?? ''); + expect(hex.encodeArrayBuffer(rl.toBuffer())).to.eql(hexValue); + }); + } + + for (const { v, msg } of [ + { v: '03 01 61', msg: 'protocol' }, + { v: 'a1 01 61', msg: 'identifier' }, + { v: '00 00', msg: 'body' }, + { v: '10 ff 61 61 ', msg: 'bounds' }, + { v: '10 01 61 61 ', msg: 'bounds' }, + ]) { + it(`ResourceLocator.parse() throws ${msg}`, () => { const hexValue = v.replace(/\s/g, ''); const ab = hex.decodeArrayBuffer(hexValue); - const rl = new ResourceLocator(new Uint8Array(ab)); - expect(rl).to.have.property('identifier', kid); - expect(rl).to.have.property('url', u); + expect(() => ResourceLocator.parse(new Uint8Array(ab))).to.throw(msg); }); } for (const { u, kid, msg } of [ - { u: 'http://a', kid: 'e0e0e0e0e0e0e0e0', msg: 'Unsupported identifier length: 16' }, - { u: 'gopher://a', kid: 'r1', msg: 'protocol unsupported' }, + { u: 'gopher://a', kid: 'r1', msg: 'unsupported' }, + { u: 'https://', kid: 'r1', msg: 'empty' }, + { u: 'https://a', kid: '1234567890123456789012345678901234567890', msg: 'identifier length' }, ]) { - it(`invalid resource locator`, () => { - expect(() => ResourceLocator.parse(u, kid)).throw(msg); + it(`invalid resource locator param throws ${msg}`, () => { + expect(() => ResourceLocator.fromURL(u, kid)).throw(msg); }); } }); From 031bbb7154a638c3b0c55ea58369af3182414f94 Mon Sep 17 00:00:00 2001 From: sujankota Date: Tue, 17 Sep 2024 11:37:19 -0400 Subject: [PATCH 23/42] fix(nano): ecdsa policy binding support for encrypt (#346) --- lib/src/index.ts | 34 ++++-- lib/src/nanotdf-crypto/ecdsaSignature.ts | 108 +++++++++++++++++++ lib/src/nanotdf/encrypt.ts | 108 ++++++++++++++----- lib/src/nanotdf/models/DefaultParams.ts | 1 - lib/tests/mocha/unit/ecdsa-signature.spec.ts | 77 +++++++++++++ lib/tests/web/nano-roundtrip.test.ts | 23 ++-- 6 files changed, 310 insertions(+), 41 deletions(-) create mode 100644 lib/src/nanotdf-crypto/ecdsaSignature.ts create mode 100644 lib/tests/mocha/unit/ecdsa-signature.spec.ts diff --git a/lib/src/index.ts b/lib/src/index.ts index 854df790..a04fc6be 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -13,6 +13,16 @@ import { TypedArray, createAttribute, Policy } from './tdf/index.js'; import { fetchECKasPubKey } from './access.js'; import { ClientConfig } from './nanotdf/Client.js'; +// Define the EncryptOptions type +export type EncryptOptions = { + ecdsaBinding: boolean; +}; + +// Define default options +const defaultOptions: EncryptOptions = { + ecdsaBinding: false, +}; + /** * NanoTDF SDK Client * @@ -104,13 +114,17 @@ export class NanoTDFClient extends Client { } /** - * Encrypt data + * Encrypts the given data using the NanoTDF encryption scheme. * - * Pass a string, TypedArray, or ArrayBuffer data and get a promise which resolves ciphertext - * - * @param data to decrypt + * @param {string | TypedArray | ArrayBuffer} data - The data to be encrypted. + * @param {EncryptOptions} [options=defaultOptions] - The encryption options (currently unused). + * @returns {Promise} A promise that resolves to the encrypted data as an ArrayBuffer. + * @throws {Error} If the initialization vector is not a number. */ - async encrypt(data: string | TypedArray | ArrayBuffer): Promise { + async encrypt( + data: string | TypedArray | ArrayBuffer, + options?: EncryptOptions + ): Promise { // For encrypt always generate the client ephemeralKeyPair const ephemeralKeyPair = await this.ephemeralKeyPair; const initializationVector = this.iv; @@ -155,7 +169,15 @@ export class NanoTDFClient extends Client { payloadIV[10] = lengthAsUint24[1]; payloadIV[11] = lengthAsUint24[0]; - return encrypt(policyObjectAsStr, this.kasPubKey, ephemeralKeyPair, payloadIV, data); + const mergedOptions: EncryptOptions = { ...defaultOptions, ...options }; + return encrypt( + policyObjectAsStr, + this.kasPubKey, + ephemeralKeyPair, + payloadIV, + data, + mergedOptions.ecdsaBinding + ); } } diff --git a/lib/src/nanotdf-crypto/ecdsaSignature.ts b/lib/src/nanotdf-crypto/ecdsaSignature.ts new file mode 100644 index 00000000..9e1d8d49 --- /dev/null +++ b/lib/src/nanotdf-crypto/ecdsaSignature.ts @@ -0,0 +1,108 @@ +import { AlgorithmName } from './../nanotdf-crypto/enums.js'; + +/** + * Computes an ECDSA signature for the given data using the provided private key. + * + * This function uses the Web Crypto API to generate a digital signature + * for the input data using the ECDSA algorithm with SHA-256 as the hash function. + * + * @param {CryptoKey} privateKey - The ECDSA private key used for signing. + * @param {Uint8Array} data - The data to be signed. + * @returns {Promise} - A promise that resolves to the generated signature. + */ +export async function computeECDSASig( + privateKey: CryptoKey, + data: Uint8Array +): Promise { + const signature = await crypto.subtle.sign( + { + name: AlgorithmName.ECDSA, + hash: { name: 'SHA-256' }, + }, + privateKey, + data + ); + return signature; +} + +/** + * Verifies an ECDSA signature using the provided public key and data. + * + * This function uses the Web Crypto API to verify the digital signature + * for the input data using the ECDSA algorithm with SHA-256 as the hash function. + * + * @param {CryptoKey} publicKey - The ECDSA public key used for verification. + * @param {Uint8Array} signature - The signature to be verified. + * @param {Uint8Array} data - The data that was signed. + * @returns {Promise} - A promise that resolves to a boolean indicating whether the signature is valid. + */ +export async function verifyECDSASignature( + publicKey: CryptoKey, + signature: Uint8Array, + data: Uint8Array +): Promise { + const isValid = await crypto.subtle.verify( + { + name: AlgorithmName.ECDSA, + hash: { name: 'SHA-256' }, + }, + publicKey, + signature, + data + ); + return isValid; +} + +/** + * Extracts the r and s values from a given ECDSA signature. + * + * @param {Uint8Array} signatureBytes - The raw ECDSA signature bytes. + * @returns {{ r: Uint8Array; s: Uint8Array }} An object containing the r and s values as Uint8Arrays. + * @throws {Error} If the validation of the signature fails. + */ +export function extractRSValuesFromSignature(signatureBytes: Uint8Array): { + r: Uint8Array; + s: Uint8Array; +} { + // Split the raw signature into r and s values + const halfLength = Math.floor(signatureBytes.length / 2); + const rValue = signatureBytes.slice(0, halfLength); + const sValue = signatureBytes.slice(halfLength); + + // Correct validation + if (!concatAndCompareUint8Arrays(rValue, sValue, signatureBytes)) { + throw new Error('Invalid ECDSA signature'); + } + + return { + r: rValue, + s: sValue, + }; +} + +function concatAndCompareUint8Arrays( + arr1: Uint8Array, + arr2: Uint8Array, + arr3: Uint8Array +): boolean { + // Create a new Uint8Array with the combined length of arr1 and arr2 + const concatenated = new Uint8Array(arr1.length + arr2.length); + + // Copy arr1 and arr2 into the new array + concatenated.set(arr1, 0); + concatenated.set(arr2, arr1.length); + + // Check if the lengths are the same + if (concatenated.length !== arr3.length) { + return false; + } + + // Compare each element + for (let i = 0; i < concatenated.length; i++) { + if (concatenated[i] !== arr3[i]) { + return false; + } + } + + return true; +} diff --git a/lib/src/nanotdf/encrypt.ts b/lib/src/nanotdf/encrypt.ts index 54218049..5f7d3f02 100644 --- a/lib/src/nanotdf/encrypt.ts +++ b/lib/src/nanotdf/encrypt.ts @@ -6,8 +6,9 @@ import EmbeddedPolicy from './models/Policy/EmbeddedPolicy.js'; import Payload from './models/Payload.js'; import getHkdfSalt from './helpers/getHkdfSalt.js'; import { getBitLength as authTagLengthForCipher } from './models/Ciphers.js'; -import { lengthOfBinding } from './helpers/calculateByCipher.js'; import { TypedArray } from '../tdf/index.js'; +import { GMAC_BINDING_LEN } from './constants.js'; +import { AlgorithmName, KeyFormat, KeyUsageType } from './../nanotdf-crypto/enums.js'; import { encrypt as cryptoEncrypt, @@ -16,6 +17,7 @@ import { exportCryptoKey, } from '../nanotdf-crypto/index.js'; import { KasPublicKeyInfo } from '../access.js'; +import { computeECDSASig, extractRSValuesFromSignature } from '../nanotdf-crypto/ecdsaSignature.js'; /** * Encrypt the plain data into nanotdf buffer @@ -25,13 +27,15 @@ import { KasPublicKeyInfo } from '../access.js'; * @param ephemeralKeyPair SDK ephemeral key pair to generate symmetric key * @param iv * @param data The data to be encrypted + * @param ecdsaBinding Flag to enable ECDSA binding */ export default async function encrypt( policy: string, kasInfo: KasPublicKeyInfo, ephemeralKeyPair: CryptoKeyPair, iv: Uint8Array, - data: string | TypedArray | ArrayBuffer + data: string | TypedArray | ArrayBuffer, + ecdsaBinding: boolean = DefaultParams.ecdsaBinding ): Promise { // Generate a symmetric key. if (!ephemeralKeyPair.privateKey) { @@ -60,33 +64,34 @@ export default async function encrypt( authTagLengthInBytes * 8 ); - // Enable - once ecdsaBinding is true - // if (!DefaultParams.ecdsaBinding) { - // throw new Error("ECDSA binding should enable by default."); - // } - - // // Calculate the policy binding. - // const policyBinding = await calculateSignature(this.ephemeralKeyPair.privateKey, new Uint8Array(encryptedPolicy)); - // console.log("Length of the policyBinding " + policyBinding.byteLength); - - // // Create embedded policy - // const embeddedPolicy = new EmbeddedPolicy(DefaultParams.policyType, - // new Uint8Array(policyBinding), - // new Uint8Array(encryptedPolicy) - // ); + let policyBinding: Uint8Array; // Calculate the policy binding. - const lengthOfPolicyBinding = lengthOfBinding( - DefaultParams.ecdsaBinding, - DefaultParams.ephemeralCurveName - ); - - const policyBinding = await digest('SHA-256', new Uint8Array(encryptedPolicy)); + if (ecdsaBinding) { + const curveName = await getCurveNameFromPrivateKey(ephemeralKeyPair.privateKey); + const ecdsaPrivateKey = await convertECDHToECDSA(ephemeralKeyPair.privateKey, curveName); + const ecdsaSignature = await computeECDSASig(ecdsaPrivateKey, new Uint8Array(encryptedPolicy)); + const { r, s } = extractRSValuesFromSignature(new Uint8Array(ecdsaSignature)); + + const rLength = r.length; + const sLength = s.length; + + policyBinding = new Uint8Array(1 + rLength + 1 + sLength); + + // Set the lengths and values of r and s in policyBinding + policyBinding[0] = rLength; + policyBinding.set(r, 1); + policyBinding[1 + rLength] = sLength; + policyBinding.set(s, 1 + rLength + 1); + } else { + const signature = await digest('SHA-256', new Uint8Array(encryptedPolicy)); + policyBinding = new Uint8Array(signature.slice(-GMAC_BINDING_LEN)); + } // Create embedded policy const embeddedPolicy = new EmbeddedPolicy( DefaultParams.policyType, - new Uint8Array(policyBinding.slice(-lengthOfPolicyBinding)), + policyBinding, new Uint8Array(encryptedPolicy) ); @@ -99,7 +104,7 @@ export default async function encrypt( const header = new Header( DefaultParams.magicNumberVersion, kasResourceLocator, - DefaultParams.ecdsaBinding, + ecdsaBinding, DefaultParams.signatureCurveName, DefaultParams.signature, DefaultParams.signatureCurveName, @@ -134,3 +139,58 @@ export default async function encrypt( const nanoTDF = new NanoTDF(header, payload); return nanoTDF.toBuffer(); } + +/** + * Retrieves the curve name from a given ECDH private key. + * + * This function exports the provided ECDH private key in JWK format and extracts + * the curve name from the 'crv' property of the JWK. + * + * @param {CryptoKey} privateKey - The ECDH private key from which to retrieve the curve name. + * @returns {Promise} - A promise that resolves to the curve name. + * + * @throws {Error} - Throws an error if the curve name is undefined. + * + */ +async function getCurveNameFromPrivateKey(privateKey: CryptoKey): Promise { + // Export the private key + const keyData = await crypto.subtle.exportKey('jwk', privateKey); + + // The curve name is stored in the 'crv' property of the JWK + if (!keyData.crv) { + throw new Error('Curve name is undefined'); + } + + return keyData.crv; +} + +/** + * Converts an ECDH private key to an ECDSA private key. + * + * This function exports the given ECDH private key in PKCS#8 format and then + * imports it as an ECDSA private key using the specified curve name. + * + * @param {CryptoKey} key - The ECDH private key to be converted. + * @param {string} curveName - The name of the elliptic curve to be used for the ECDSA key. + * @returns {Promise} - A promise that resolves to the converted ECDSA private key. + * + * @throws {Error} - Throws an error if the key export or import fails. + */ +async function convertECDHToECDSA(key: CryptoKey, curveName: string): Promise { + // Export the ECDH private key + const ecdhPrivateKey = await crypto.subtle.exportKey('pkcs8', key); + + // Import the ECDH private key as an ECDSA private key + const ecdsaPrivateKey = await crypto.subtle.importKey( + KeyFormat.Pkcs8, + ecdhPrivateKey, + { + name: AlgorithmName.ECDSA, + namedCurve: curveName, + }, + true, + [KeyUsageType.Sign] + ); + + return ecdsaPrivateKey; +} diff --git a/lib/src/nanotdf/models/DefaultParams.ts b/lib/src/nanotdf/models/DefaultParams.ts index 76799d5d..a04915e0 100644 --- a/lib/src/nanotdf/models/DefaultParams.ts +++ b/lib/src/nanotdf/models/DefaultParams.ts @@ -10,7 +10,6 @@ const enc = new TextEncoder(); * @link https://github.com/virtru/tdf3-cpp/blob/develop/tdf3-src/lib/src/nanotdf_builder_impl.h */ const DefaultParams = { - // Enabling ECDSA is not currently supported. Conflict with reusing key for `verify/sign` and `encrypt/decrypt` ecdsaBinding: false, ephemeralCurveName: CurveNameEnum.SECP256R1, magicNumberVersion: enc.encode('L1L'), diff --git a/lib/tests/mocha/unit/ecdsa-signature.spec.ts b/lib/tests/mocha/unit/ecdsa-signature.spec.ts new file mode 100644 index 00000000..c7ff88ac --- /dev/null +++ b/lib/tests/mocha/unit/ecdsa-signature.spec.ts @@ -0,0 +1,77 @@ +import { expect } from 'chai'; +import { + computeECDSASig, + verifyECDSASignature, + extractRSValuesFromSignature, +} from '../../../src/nanotdf-crypto/ecdsaSignature.js'; + +describe('ECDSA Signature Functions', () => { + let privateKey: CryptoKey; + let publicKey: CryptoKey; + let data: Uint8Array; + let signature: ArrayBuffer; + let invalidSignature: Uint8Array; + + before(async () => { + // Generate ECDSA key pair for testing + const keyPair = await crypto.subtle.generateKey( + { + name: 'ECDSA', + namedCurve: 'P-256', + }, + true, + ['sign', 'verify'] + ); + privateKey = keyPair.privateKey; + publicKey = keyPair.publicKey; + + // Mock data + data = new Uint8Array(['v', 'i', 'r', 't', 'r'].map((c) => c.charCodeAt(0))); + signature = await computeECDSASig(privateKey, data); + invalidSignature = new Uint8Array([0, 1, 2, 3, 4, 5]); + }); + + describe('computeECDSASig', () => { + it('should compute a valid ECDSA signature', async () => { + const result = await computeECDSASig(privateKey, data); + expect(result).to.be.instanceOf(ArrayBuffer); + }); + + it('should throw an error with invalid private key', async () => { + try { + await computeECDSASig(null as any, data); + } catch (error) { + expect(error).to.exist; + } + }); + }); + + describe('verifyECDSASignature', () => { + it('should verify a valid ECDSA signature', async () => { + const isValid = await verifyECDSASignature(publicKey, new Uint8Array(signature), data); + expect(isValid).to.be.true; + }); + + it('should not verify an invalid ECDSA signature', async () => { + const isValid = await verifyECDSASignature(publicKey, invalidSignature, data); + expect(isValid).to.be.false; + }); + }); + + describe('extractRSValuesFromSignature', () => { + it('should extract R and S values from a valid ASN.1 DER formatted signature', () => { + const signatureArray = new Uint8Array(signature); + const { r, s } = extractRSValuesFromSignature(signatureArray); + expect(r).to.be.instanceOf(Uint8Array); + expect(s).to.be.instanceOf(Uint8Array); + }); + + it('should throw an error with invalid formatted signature', () => { + try { + extractRSValuesFromSignature(invalidSignature); + } catch (error) { + expect(error).to.exist; + } + }); + }); +}); diff --git a/lib/tests/web/nano-roundtrip.test.ts b/lib/tests/web/nano-roundtrip.test.ts index 1d6af0e1..e0a55e3f 100644 --- a/lib/tests/web/nano-roundtrip.test.ts +++ b/lib/tests/web/nano-roundtrip.test.ts @@ -18,16 +18,19 @@ const authProvider = { const kasEndpoint = 'http://localhost:3000'; describe('Local roundtrip Tests', () => { - it('roundtrip string', async () => { - const client = new NanoTDFClient({ authProvider, kasEndpoint }); - const cipherText = await client.encrypt('hello world'); - const client2 = new NanoTDFClient({ authProvider, kasEndpoint }); - const nanotdfParsed = NanoTDF.from(cipherText); + for (const ecdsaBinding of [false, true]) { + const bindingName = ecdsaBinding ? 'ecdsa' : 'gmac'; + it(`roundtrip string (${bindingName} policy binding)`, async () => { + const client = new NanoTDFClient({ authProvider, kasEndpoint }); + const cipherText = await client.encrypt('hello world', { ecdsaBinding }); + const client2 = new NanoTDFClient({ authProvider, kasEndpoint }); + const nanotdfParsed = NanoTDF.from(cipherText); - expect(nanotdfParsed.header.kas.url).to.equal(kasEndpoint); - expect(nanotdfParsed.header.kas.identifier).to.equal('e1'); + expect(nanotdfParsed.header.kas.url).to.equal(kasEndpoint); + expect(nanotdfParsed.header.kas.identifier).to.equal('e1'); - const actual = await client2.decrypt(cipherText); - expect(new TextDecoder().decode(actual)).to.be.equal('hello world'); - }); + const actual = await client2.decrypt(cipherText); + expect(new TextDecoder().decode(actual)).to.be.equal('hello world'); + }); + } }); From 4e54c0d6d9cd6b6d1c05296cf954431970509367 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 17 Sep 2024 16:03:06 -0400 Subject: [PATCH 24/42] feat(cli): Adds `--policyBinding ecdsa` option (#352) Only effective with `-t nano`, this enables the ECDSA binding type to verify the policy is attached to the key is as expected. --- cli/package-lock.json | 60 +++++++++++++++++++--------- cli/src/cli.ts | 61 +++++++++++++++------------- lib/src/index.ts | 11 ++++- remote-store/package-lock.json | 34 +++++++++++----- web-app/package-lock.json | 73 ++++++++++++++++++++++------------ 5 files changed, 156 insertions(+), 83 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index b1a632c4..3f6e319c 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -36,9 +36,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -371,7 +372,8 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-f+e14B8wFOwThqVCkw4cD56B/Xrhzf+S6GV6Q2qjXUG+pZTgYDe53jAHB2Ro3Xh9FCNtvachJoQS5O6BRsA8dw==", + "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", + "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -874,12 +876,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", - "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -890,6 +894,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -918,7 +923,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -957,7 +963,8 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", + "license": "Apache-2.0" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -983,6 +990,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -992,6 +1000,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } @@ -1135,6 +1144,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1219,6 +1229,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1260,6 +1271,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1474,7 +1486,8 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -1602,15 +1615,16 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1640,6 +1654,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1845,7 +1860,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.1", @@ -1982,6 +1998,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -2029,6 +2046,7 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2225,6 +2243,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2233,6 +2252,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -2638,7 +2658,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", @@ -2749,7 +2770,8 @@ "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==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", @@ -3033,7 +3055,8 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ] + ], + "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", @@ -3272,6 +3295,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } diff --git a/cli/src/cli.ts b/cli/src/cli.ts index 6bcdc555..28a61e8e 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -31,7 +31,9 @@ type LoggedAuthProvider = AuthProvider & { requestLog: HttpRequest[]; }; -const containerTypes = ['tdf3', 'nano', 'dataset'] as const; +const bindingTypes = ['ecdsa', 'gmac']; + +const containerTypes = ['tdf3', 'nano', 'dataset', 'ztdf']; const parseJwt = (jwt: string, field = 1) => { return JSON.parse(Buffer.from(jwt.split('.')[field], 'base64').toString()); @@ -219,35 +221,13 @@ export const handleArgs = (args: string[]) => { }) .implies('exchangeToken', 'clientId') - .option('containerType', { - group: 'TDF Settings', - alias: 't', - choices: containerTypes, - description: 'Container format', - default: 'nano', - }) - - .option('userId', { - group: 'TDF Settings', - type: 'string', - description: 'Owner email address', - }) - // Examples .example('$0 --auth ClientID123:Cli3nt$ecret', '# OIDC client credentials') .example('$0 --clientId ClientID123 --clientSecret Cli3nt$ecret', '# OIDC client credentials') - // POLICY + // Policy, encryption, and container options .options({ - usersWithAccess: { - alias: 'users-with-access', - group: 'Encrypt Options', - desc: 'Add users to the policy', - type: 'string', - default: '', - validate: (users: string) => users.split(','), - }, attributes: { group: 'Encrypt Options', desc: 'Data attributes for the policy', @@ -255,12 +235,38 @@ export const handleArgs = (args: string[]) => { default: '', validate: (attributes: string) => attributes.split(','), }, + containerType: { + group: 'Encrypt Options', + alias: 't', + choices: containerTypes, + description: 'Container format', + default: 'nano', + }, + policyBinding: { + group: 'Encrypt Options', + choices: bindingTypes, + description: 'Policy Binding Type (nano only)', + default: 'gmac', + }, mimeType: { group: 'Encrypt Options', desc: 'Mime type for the plain text file (only supported for ztdf)', type: 'string', default: '', }, + userId: { + group: 'Encrypt Options', + type: 'string', + description: 'Owner email address', + }, + usersWithAccess: { + alias: 'users-with-access', + group: 'Encrypt Options', + desc: 'Add users to the policy', + type: 'string', + default: '', + validate: (users: string) => users.split(','), + }, }) // COMMANDS @@ -299,7 +305,7 @@ export const handleArgs = (args: string[]) => { log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`); const kasEndpoint = argv.kasEndpoint; - if (argv.containerType === 'tdf3') { + if (argv.containerType === 'tdf3' || argv.containerType == 'ztdf') { log('DEBUG', `TDF3 Client`); const client = new TDF3Client({ allowedKases, @@ -389,7 +395,7 @@ export const handleArgs = (args: string[]) => { const ignoreAllowList = !!argv.ignoreAllowList; const allowedKases = argv.allowList?.split(','); - if ('tdf3' === argv.containerType) { + if ('tdf3' === argv.containerType || 'ztdf' === argv.containerType) { log('DEBUG', `TDF3 Client`); const client = new TDF3Client({ allowedKases, @@ -411,6 +417,7 @@ export const handleArgs = (args: string[]) => { } } else { const dpopEnabled = !!argv.dpop; + const ecdsaBinding = argv.policyBinding.toLowerCase() == 'ecdsa'; const client = argv.containerType === 'nano' ? new NanoTDFClient({ allowedKases, authProvider, dpopEnabled, kasEndpoint }) @@ -425,7 +432,7 @@ export const handleArgs = (args: string[]) => { addParams(client, argv); const buffer = await processDataIn(argv.file as string); - const cyphertext = await client.encrypt(buffer); + const cyphertext = await client.encrypt(buffer, { ecdsaBinding }); log('DEBUG', `Handle cyphertext output ${JSON.stringify(cyphertext)}`); if (argv.output) { diff --git a/lib/src/index.ts b/lib/src/index.ts index a04fc6be..03cdd32d 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -221,6 +221,7 @@ export class NanoTDFDatasetClient extends Client { private unwrappedKey?: CryptoKey; private symmetricKey?: CryptoKey; private cachedHeader?: Header; + private ecdsaBinding: boolean; /** * Create new NanoTDF Dataset Client @@ -256,9 +257,14 @@ export class NanoTDFDatasetClient extends Client { * * @param data to decrypt */ - async encrypt(data: string | TypedArray | ArrayBuffer): Promise { + async encrypt( + data: string | TypedArray | ArrayBuffer, + options?: EncryptOptions + ): Promise { // Intial encrypt if (this.keyIterationCount == 0) { + const mergedOptions: EncryptOptions = { ...defaultOptions, ...options }; + this.ecdsaBinding = mergedOptions.ecdsaBinding; // For encrypt always generate the client ephemeralKeyPair const ephemeralKeyPair = await this.ephemeralKeyPair; @@ -298,7 +304,8 @@ export class NanoTDFDatasetClient extends Client { this.kasPubKey, ephemeralKeyPair, ivVector, - data + data, + this.ecdsaBinding ); // Cache the header and increment the key iteration diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index 3668d51f..a6c1f533 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1536,9 +1536,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1820,7 +1821,8 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", + "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", + "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -3300,6 +3302,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -3328,7 +3331,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -3369,7 +3373,8 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", + "license": "Apache-2.0" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -3395,6 +3400,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -3404,6 +3410,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } @@ -3637,6 +3644,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -3864,7 +3872,8 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -4241,7 +4250,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.2.4", @@ -4378,6 +4388,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -4425,6 +4436,7 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -5184,7 +5196,8 @@ "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==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", @@ -5428,7 +5441,8 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ] + ], + "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 21217086..72bc9050 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -350,9 +350,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -606,7 +607,8 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", + "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", + "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -1184,12 +1186,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1200,6 +1204,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -1253,7 +1258,8 @@ "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", + "license": "Apache-2.0" }, "node_modules/browserslist": { "version": "4.21.10", @@ -1312,6 +1318,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } @@ -1413,6 +1420,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1492,6 +1500,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1539,6 +1548,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1841,7 +1851,8 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -1976,15 +1987,16 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1998,6 +2010,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -2251,6 +2264,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -2267,6 +2281,7 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2470,6 +2485,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2478,6 +2494,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -2909,7 +2926,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.0", @@ -3021,7 +3039,8 @@ "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==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.1", @@ -3262,7 +3281,8 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ] + ], + "license": "MIT" }, "node_modules/strip-ansi": { "version": "6.0.1", @@ -3490,6 +3510,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -3930,9 +3951,9 @@ } }, "@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -4090,7 +4111,7 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-AYYYJYSNJgUXNHJTK8pH+W74udFhwn1Co5/utjdfZZUFBjl2cGn+knfJe/Blrgj0S2VseOUs1nvwPiZYnAS/8w==", + "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -4438,9 +4459,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "requires": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -4924,9 +4945,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" }, "form-data": { "version": "4.0.0", From ced163d9fe4ea2309c4e36662f988fb62c5aaef2 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Thu, 19 Sep 2024 08:27:52 -0400 Subject: [PATCH 25/42] chore(docs): Adds documentation on some recent changes (#348) Co-authored-by: Paul Flynn <43211074+pflynn-virtru@users.noreply.github.com> --- lib/src/access.ts | 16 +++++++++++++++- lib/src/nanotdf/models/ResourceLocator.ts | 9 +++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/src/access.ts b/lib/src/access.ts index bcdc60a1..aa0def5f 100644 --- a/lib/src/access.ts +++ b/lib/src/access.ts @@ -52,11 +52,26 @@ export async function fetchWrappedKey( export type KasPublicKeyAlgorithm = 'ec:secp256r1' | 'rsa:2048'; +/** + * Information about one of a KAS's published public keys. + * A KAS may publish multiple keys with a given algorithm type. + */ export type KasPublicKeyInfo = { + /** The locator to the given KAS associated with this key */ url: string; + + /** The encryption algorithm the key is to be used with. */ algorithm: KasPublicKeyAlgorithm; + + /** If present, an identifier which is tied to this specific key. */ kid?: string; + + /** The key value, encoded within a PEM envelope */ publicKey: string; + + /** A subtle crypto version of the key. + * This can be used for wrapping key data for key access objects (with RSA) + * or to derive key data (with EC keys). */ key: Promise; }; @@ -64,7 +79,6 @@ export type KasPublicKeyInfo = { * If we have KAS url but not public key we can fetch it from KAS, fetching * the value from `${kas}/kas_public_key`. */ - export async function fetchECKasPubKey(kasEndpoint: string): Promise { validateSecureUrl(kasEndpoint); const pkUrlV2 = `${kasEndpoint}/v2/kas_public_key?algorithm=ec:secp256r1&v=2`; diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index 23517062..eea61fbc 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -36,6 +36,15 @@ export default class ResourceLocator { readonly idType: ResourceLocatorIdentifierEnum = ResourceLocatorIdentifierEnum.None ) {} + /** + * Construct a new URL or URL + identifier pair, for use with NanoTDF envelopes. + * @param url The URL to encrypt; `http` and `https` schemes are supported + * @param identifier An optional identifier. + * For KAS URLs, this is usually a public key identifier (kid). Limit 32 characters + * @returns a value representing the URL and identifier, if present. + * This method throws an Error if the URL is invalid or of the wrong schema, + * or if the identifier is an unsupported value. + */ static fromURL(url: string, identifier?: string): ResourceLocator { const [protocolStr, body] = url.split('://'); From 6eb70c1fdfc4e18308dbb898594fa773e1f2c7a8 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Thu, 19 Sep 2024 09:49:48 -0400 Subject: [PATCH 26/42] feat(lib): offline abac KAO configuration (#349) --- lib/src/policy/attributes.ts | 103 +++++++++ lib/src/policy/granter.ts | 180 +++++++++++++++ lib/tdf3/src/client/builders.ts | 2 + lib/tdf3/src/client/index.ts | 67 +++++- lib/tests/mocha/encrypt-decrypt.spec.ts | 8 +- lib/tests/mocha/unit/attribute-set.spec.ts | 2 +- lib/tests/mocks/index.ts | 150 ++---------- lib/tests/mocks/pems.ts | 133 +++++++++++ lib/tests/server.ts | 2 +- lib/tests/web/policy/granter.test.ts | 80 +++++++ lib/tests/web/policy/mock-attrs.ts | 254 +++++++++++++++++++++ 11 files changed, 836 insertions(+), 145 deletions(-) create mode 100644 lib/src/policy/attributes.ts create mode 100644 lib/src/policy/granter.ts create mode 100644 lib/tests/mocks/pems.ts create mode 100644 lib/tests/web/policy/granter.test.ts create mode 100644 lib/tests/web/policy/mock-attrs.ts diff --git a/lib/src/policy/attributes.ts b/lib/src/policy/attributes.ts new file mode 100644 index 00000000..f8cfe784 --- /dev/null +++ b/lib/src/policy/attributes.ts @@ -0,0 +1,103 @@ +export type Metadata = { + /** + * created_at set by server (entity who created will recorded in an audit event) + * Format: date-time + */ + createdAt?: string; + + /** + * updated_at set by server (entity who updated will recorded in an audit event) + * Format: date-time + */ + updatedAt?: string; + + /** optional short description */ + labels?: Record; +}; + +export type KasPublicKeyAlgorithm = + | 'KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED' + | 'KAS_PUBLIC_KEY_ALG_ENUM_RSA_2048' + | 'KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1'; + +export type KasPublicKey = { + /** x509 ASN.1 content in PEM envelope, usually */ + pem: string; + /** A unique string identifier for this key */ + kid: string; + /** + * @description A known algorithm type with any additional parameters encoded. + * To start, these may be `rsa:2048` for encrypting ZTDF files and + * `ec:secp256r1` for nanoTDF, but more formats may be added as needed. + */ + alg: KasPublicKeyAlgorithm; +}; + +export type KasPublicKeySet = { + keys: KasPublicKey[]; +}; + +export type PublicKey = { + /** kas public key url - optional since can also be retrieved via public key */ + remote?: string; + /** public key; PEM of RSA public key; prefer `cached` */ + local?: string; + /** public key with additional information. Current preferred version */ + cached?: KasPublicKeySet; +}; + +export type KeyAccessServer = { + id?: string; + /** Address of a KAS instance */ + uri: string; + publicKey?: PublicKey; + metadata?: Metadata; +}; + +export type Namespace = { + /** uuid */ + id?: string; + /** used to partition Attribute Definitions, support by namespace AuthN and enable federation */ + name?: string; + fqn: string; + /** active by default until explicitly deactivated */ + active?: boolean; + metadata?: Metadata; + grants?: KeyAccessServer[]; +}; + +export type AttributeRuleType = + | 'ATTRIBUTE_RULE_TYPE_ENUM_UNSPECIFIED' + | 'ATTRIBUTE_RULE_TYPE_ENUM_ALL_OF' + | 'ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF' + | 'ATTRIBUTE_RULE_TYPE_ENUM_HIERARCHY'; + +export type Attribute = { + /** UUID */ + id?: string; + namespace?: Namespace; + /** attribute name */ + name?: string; + /** attribute rule enum */ + rule?: AttributeRuleType; + values?: Value[]; + grants?: KeyAccessServer[]; + fqn: string; + /** active by default until explicitly deactivated */ + active?: boolean; + /** Common metadata */ + metadata?: Metadata; +}; + +export type Value = { + id?: string; + attribute?: Attribute; + value?: string; + /** list of key access servers */ + grants?: KeyAccessServer[]; + fqn: string; + /** active by default until explicitly deactivated */ + active?: boolean; + /** Common metadata */ + metadata?: Metadata; +}; diff --git a/lib/src/policy/granter.ts b/lib/src/policy/granter.ts new file mode 100644 index 00000000..9173d8c8 --- /dev/null +++ b/lib/src/policy/granter.ts @@ -0,0 +1,180 @@ +import { Attribute, AttributeRuleType, KeyAccessServer, Value } from './attributes.js'; + +export type KeySplitStep = { + kas: KeyAccessServer; + sid?: string; +}; + +type AttributeClause = { + def: Attribute; + values: string[]; +}; + +type AndClause = { + op: 'allOf'; + kases: string[]; +}; + +type HeirarchyClause = { + op: 'hierarchy'; + kases: string[]; +}; + +type OrClause = { + op: 'anyOf'; + kases: string[]; +}; + +type BooleanClause = AndClause | OrClause | HeirarchyClause; + +type BooleanOperator = BooleanClause['op']; + +type ComplexBooleanClause = { + op: BooleanOperator; + children: BooleanClause[]; +}; + +export function booleanOperatorFor(rule?: AttributeRuleType): BooleanOperator { + if (!rule) { + return 'allOf'; + } + switch (rule) { + case 'ATTRIBUTE_RULE_TYPE_ENUM_UNSPECIFIED': + case 'ATTRIBUTE_RULE_TYPE_ENUM_ALL_OF': + return 'allOf'; + case 'ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF': + return 'anyOf'; + case 'ATTRIBUTE_RULE_TYPE_ENUM_HIERARCHY': + return 'hierarchy'; + } +} + +export function plan(dataAttrs: Value[]): KeySplitStep[] { + // KASes by value + const grants: Record> = {}; + // KAS detail by KAS url + const kasInfo: Record = {}; + // Attribute definitions in use + const prefixes: Set = new Set(); + // Values grouped by normalized attribute prefix + const allClauses: Record = {}; + // Values by normalized FQN + const allValues: Record = {}; + + const addGrants = (val: string, gs?: KeyAccessServer[]): boolean => { + if (!gs?.length) { + if (!(val in grants)) { + grants[val] = new Set(); + } + return false; + } + for (const g of gs) { + if (val in grants) { + grants[val].add(g.uri); + } else { + grants[val] = new Set([g.uri]); + } + kasInfo[g.uri] = g; + } + return true; + }; + + for (const v of dataAttrs) { + const { attribute, fqn } = v; + if (!attribute) { + throw new Error(`attribute not defined for [${fqn}]`); + } + const valFqn = fqn.toLowerCase(); + const attrFqn = attribute.fqn.toLowerCase(); + if (!prefixes.has(attrFqn)) { + prefixes.add(attrFqn); + allClauses[attrFqn] = { + def: attribute, + values: [], + }; + } + allClauses[attrFqn].values.push(valFqn); + allValues[valFqn] = v; + if (!addGrants(valFqn, v.grants)) { + if (!addGrants(valFqn, attribute.grants)) { + addGrants(valFqn, attribute.namespace?.grants); + } + } + } + const kcs: ComplexBooleanClause[] = []; + for (const attrClause of Object.values(allClauses)) { + const ccv: BooleanClause[] = []; + for (const term of attrClause.values) { + const grantsForTerm = Array.from(grants[term] || []); + if (grantsForTerm?.length) { + ccv.push({ + op: 'anyOf', + kases: grantsForTerm, + }); + } + } + const op = booleanOperatorFor(attrClause.def.rule); + kcs.push({ + op, + children: ccv, + }); + } + return simplify(kcs, kasInfo); +} + +function simplify( + clauses: ComplexBooleanClause[], + kasInfo: Record +): KeySplitStep[] { + const conjunction: Record = {}; + function keyFor(kases: string[]): string { + const k = Array.from(new Set([kases])).sort(); + return k.join('|'); + } + for (const { op, children } of clauses) { + if (!children) { + continue; + } + if (op === 'anyOf') { + const anyKids = []; + for (const bc of children) { + if (bc.op != 'anyOf') { + throw new Error('inversion'); + } + if (!bc.kases?.length) { + continue; + } + anyKids.push(...bc.kases); + } + if (!anyKids?.length) { + continue; + } + const k = keyFor(anyKids); + conjunction[k] = anyKids; + } else { + for (const bc of children) { + if (bc.op != 'anyOf') { + throw new Error('inversion'); + } + if (!bc.kases?.length) { + continue; + } + const k = keyFor(bc.kases); + conjunction[k] = bc.kases; + } + } + } + const t: KeySplitStep[] = []; + let i = 0; + for (const k of Object.keys(conjunction).sort()) { + if (!conjunction[k]) { + continue; + } + i += 1; + const sid = '' + i; + for (const kas of conjunction[k]) { + t.push({ sid, kas: kasInfo[kas] }); + } + } + return t; +} diff --git a/lib/tdf3/src/client/builders.ts b/lib/tdf3/src/client/builders.ts index 6efb899d..ee055f4f 100644 --- a/lib/tdf3/src/client/builders.ts +++ b/lib/tdf3/src/client/builders.ts @@ -8,6 +8,7 @@ import { PemKeyPair } from '../crypto/declarations.js'; import { EntityObject } from '../../../src/tdf/EntityObject.js'; import { DecoratedReadableStream } from './DecoratedReadableStream.js'; import { type Chunker } from '../utils/chunkers.js'; +import { Value } from '../../../src/policy/attributes.js'; export const DEFAULT_SEGMENT_SIZE: number = 1024 * 1024; export type Scope = { @@ -15,6 +16,7 @@ export type Scope = { policyId?: string; policyObject?: Policy; attributes?: (string | AttributeObject)[]; + attributeValues?: Value[]; }; export type EncryptKeyMiddleware = (...args: unknown[]) => Promise<{ diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index a28f84ae..a8994d0f 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -56,7 +56,9 @@ import { Binary } from '../binary.js'; import { AesGcmCipher } from '../ciphers/aes-gcm-cipher.js'; import { toCryptoKeyPair } from '../crypto/crypto-utils.js'; import * as defaultCryptoService from '../crypto/index.js'; -import { AttributeSet, Policy, SplitKey } from '../models/index.js'; +import { type AttributeObject, AttributeSet, type Policy, SplitKey } from '../models/index.js'; +import { plan } from '../../../src/policy/granter.js'; +import { type Value } from '../../../src/policy/attributes.js'; const GLOBAL_BYTE_LIMIT = 64 * 1000 * 1000 * 1000; // 64 GB, see WS-9363. const HTML_BYTE_LIMIT = 100 * 1000 * 1000; // 100 MB, see WS-9476. @@ -198,12 +200,22 @@ function asPolicy(scope: Scope): Policy { return scope.policyObject; } const policyId = scope.policyId ?? v4(); + let dataAttributes: AttributeObject[]; + if (scope.attributeValues) { + dataAttributes = scope.attributeValues + .filter(({ fqn }) => !!fqn) + .map(({ fqn }): AttributeObject => { + return { attribute: fqn! }; + }); + } else { + dataAttributes = (scope.attributes ?? []).map((attribute) => + typeof attribute === 'string' ? { attribute } : attribute + ); + } return { uuid: policyId, body: { - dataAttributes: (scope.attributes ?? []).map((attribute) => - typeof attribute === 'string' ? { attribute } : attribute - ), + dataAttributes, dissem: scope.dissem ?? [], }, }; @@ -346,7 +358,7 @@ export class Client { * Encrypt plaintext into TDF ciphertext. One of the core operations of the Virtru SDK. * * @param scope dissem and attributes for constructing the policy - * @param source nodeJS source object of unencrypted data + * @param source source object of unencrypted data * @param [asHtml] If we should wrap the TDF data in a self-opening HTML wrapper. Defaults to false * @param [metadata] Additional non-secret data to store with the TDF * @param [opts] Test only @@ -376,6 +388,49 @@ export class Client { const policyObject = asPolicy(scope); validatePolicyObject(policyObject); + if (!splitPlan && scope.attributeValues?.length) { + const avs: Value[] = scope.attributeValues; + const fqns: string[] = scope.attributes + ? scope.attributes.map((attribute) => + typeof attribute === 'string' ? attribute : attribute.attribute + ) + : []; + + if (!scope.attributes?.length) { + scope.attributes = avs.map(({ fqn }) => fqn); + } + if ( + avs.length != scope.attributes?.length || + !avs.map(({ fqn }) => fqn).every((a) => fqns.indexOf(a) >= 0) + ) { + throw new Error( + `Attribute mismatch between [${fqns}] and explicit values ${JSON.stringify( + avs.map(({ fqn }) => fqn) + )}` + ); + } + const detailedPlan = plan(avs); + splitPlan = detailedPlan.map((kat) => { + const { kas, sid } = kat; + if (kas?.publicKey?.cached?.keys && !(kas.uri in this.kasKeys)) { + const keys = kas.publicKey.cached.keys.filter( + ({ alg }) => alg == 'KAS_PUBLIC_KEY_ALG_ENUM_RSA_2048' + ); + if (keys?.length) { + const key = keys[0]; + this.kasKeys[kas.uri] = Promise.resolve({ + key: pemToCryptoPublicKey(key.pem), + publicKey: key.pem, + url: kas.uri, + algorithm: 'rsa:2048', + kid: key.kid, + }); + } + } + return { kas: kas.uri, sid }; + }); + } + // TODO: Refactor underlying builder to remove some of this unnecessary config. const byteLimit = asHtml ? HTML_BYTE_LIMIT : GLOBAL_BYTE_LIMIT; @@ -389,7 +444,7 @@ export class Client { attributeSet = s; } - const splits: SplitStep[] = splitPlan || [{ kas: this.kasEndpoint }]; + const splits: SplitStep[] = splitPlan?.length ? splitPlan : [{ kas: this.kasEndpoint }]; encryptionInformation.keyAccess = await Promise.all( splits.map(async ({ kas, sid }) => { if (!(kas in this.kasKeys)) { diff --git a/lib/tests/mocha/encrypt-decrypt.spec.ts b/lib/tests/mocha/encrypt-decrypt.spec.ts index 229726b8..81ceaf4d 100644 --- a/lib/tests/mocha/encrypt-decrypt.spec.ts +++ b/lib/tests/mocha/encrypt-decrypt.spec.ts @@ -1,12 +1,13 @@ // Simplest HTTP server that supports RANGE headers AFAIK. import { assert } from 'chai'; -import getMocks from '../mocks/index.js'; +import { getMocks } from '../mocks/index.js'; import { HttpRequest } from '../../src/auth/auth.js'; import { WebCryptoService } from '../../tdf3/index.js'; import { Client } from '../../tdf3/src/index.js'; import { SplitKey } from '../../tdf3/src/models/encryption-information.js'; import { AesGcmCipher } from '../../tdf3/src/ciphers/aes-gcm-cipher.js'; +import { Scope } from '../../tdf3/src/client/builders.js'; const Mocks = getMocks(); const authProvider = { @@ -42,7 +43,10 @@ describe('encrypt decrypt test', async function () { }); const eo = await Mocks.getEntityObject(); - const scope = Mocks.getScope(); + const scope: Scope = { + dissem: ['user@domain.com'], + attributes: [], + }; const encryptedStream = await client.encrypt({ eo, diff --git a/lib/tests/mocha/unit/attribute-set.spec.ts b/lib/tests/mocha/unit/attribute-set.spec.ts index 87084b49..a2aff4ae 100644 --- a/lib/tests/mocha/unit/attribute-set.spec.ts +++ b/lib/tests/mocha/unit/attribute-set.spec.ts @@ -1,7 +1,7 @@ import { assert } from 'chai'; import { AttributeSet } from '../../../tdf3/src/models/index.js'; -import getMocks from '../../mocks/index.js'; +import { getMocks } from '../../mocks/index.js'; const Mocks = getMocks(); diff --git a/lib/tests/mocks/index.ts b/lib/tests/mocks/index.ts index e88061bd..9e0c2ab8 100644 --- a/lib/tests/mocks/index.ts +++ b/lib/tests/mocks/index.ts @@ -4,6 +4,18 @@ import { v4 } from 'uuid'; import { AttributeObject } from '../../src/tdf/AttributeObject.js'; import { toCryptoKeyPair } from '../../tdf3/src/crypto/crypto-utils.js'; import { AttributeSet } from '../../tdf3/src/models/attribute-set.js'; +import { + entityECPrivateKey, + entityECPublicKey, + entityPrivateKey, + entityPublicKey, + extraECPrivateKey, + extraECPublicKey, + kasECCert, + kasECPrivateKey, + kasPrivateKey, + kasPublicKey, +} from './pems.js'; type CreateAttributePayload = { attribute: string; @@ -41,143 +53,11 @@ function getKasUrl() { return 'http://local.virtru.com:4000'; // Sensitive } -const kasPublicKey = `-----BEGIN CERTIFICATE----- -MIIDsTCCApmgAwIBAgIJAONESzw+N+3SMA0GCSqGSIb3DQEBDAUAMHUxCzAJBgNV -BAYTAlVTMQswCQYDVQQIDAJEQzETMBEGA1UEBwwKV2FzaGluZ3RvbjEPMA0GA1UE -CgwGVmlydHJ1MREwDwYDVQQDDAhhY2NvdW50czEgMB4GCSqGSIb3DQEJARYRZGV2 -b3BzQHZpcnRydS5jb20wIBcNMTgxMDE4MTY1MjIxWhgPMzAxODAyMTgxNjUyMjFa -MHUxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJEQzETMBEGA1UEBwwKV2FzaGluZ3Rv -bjEPMA0GA1UECgwGVmlydHJ1MREwDwYDVQQDDAhhY2NvdW50czEgMB4GCSqGSIb3 -DQEJARYRZGV2b3BzQHZpcnRydS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQC3GdLoh0BHjsu9doR2D3+MekHB9VR/cmqV7v6R7xEWZJkuymrJzPy8 -reKSLK7yDhUEZNA9jslVReMpQHaR0/ND0fevJZ0yoo8IXGSIYv+prX6wZbqp4Ykc -ahWMx5nFzpCDSJfd2ZBnCvnsz4x95eX8jme9qNYcELFDEkeLFCushNLXdg8NKrWh -/Ew8VEZGf4hmtb30J11Uj5P2cv6zgATpa6xqjpg8hUarQYTyQi01DTKZ9iR8Kw/x -AH+ocXtbJdy046bMb9uMpeJ/LlMpELSN5pqamVJis/NkWJOVRdwD//p7WQdz9T4T -GzvvrO8KUQoORYERf0EtwBtufv5SDpNhAgMBAAGjQjBAMB0GA1UdDgQWBBTVPQ3Y -oYYXHWbZfK2sonPrOE7nszAfBgNVHSMEGDAWgBTVPQ3YoYYXHWbZfK2sonPrOE7n -szANBgkqhkiG9w0BAQwFAAOCAQEAT2ZjAJPQSf0tME0vbAqHzB8iIhR5KniGgJMJ -mRrXbTl2HBH6WnRwfgY1Ok1X224ph4uBGaAUGs8ONBKli0673jE+IgVob7TCu2yV -gHaKcybDegK4esVNRdsDmOWT+eTxGYAzejdIgdFo6R7Xvs87RbqwM4Cko4xoWGVF -ghWsBqUmyg/rZoggL5H1V166hvoLPKU7SrCInZ8Wd6x4rsNDaxNiC9El102pKXu4 -wCiqJZ0XwklGkH9X0Z5x0txc68tqmSlE/z4i/96oxMp0C2thWfy90ub85f5FrB9m -tN5S0umLPkMUJ6zBIxh1RQK1ZYjfuKij+EEimbqtte9rYyQr3Q== ------END CERTIFICATE-----`; - -const entityPrivateKey = `-----BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDLXwR+Lr7e9IQu -lsrnyAID28nFm2hEdHrTjKLvTuHqfNOxNI1SDmY3O3+dazBbOWghYKADsQ82knL2 -VifiHVnouHESB/TAVxq7HT8LX10LpZE93onoQjvPvvqC2hJX+EA1QEZKNpJgI58B -VgTxJnYXNvp8SHFpXP7V0RWFPV0GzNt6zH9qJwIn/u8KaXAR5QfCOyLyb0LM9M9y -MSNuseLvBhSP/Ju+kzf1mDBFGBn9cZdmx0vGJsmKXHWhLmBj0iilxShaLt3ejsm4 -x0ExnSPGRWCvaGJQeptt9ETNnFnX8SjBd/3AmJebf/l4IABr7aRNw6u5xlfM07gn -fwKgXP/DAgMBAAECggEADInMpJzsLqHDnn20f8rAeQ1taK32pTXLNsy2ZOunmQXe -JVA4oET7/06/ROzNW+pzpY8n/mJFrlckGFTie5nUp7jrW7G64LreDog0kVZtTaEF -DdvxA61Fs76yAixAskS/bKkMTFoF90Bq9rGfd2CoKjE9CzmKKHVPzs3ntkG8wQT3 -C1ClT8Ce4Y+aNjLd+i47xIxNenHKfezZOriteKxVWna23fl3ISXr7e1LDI75qhcY -l3NY+EtwHKm2tGW5ukGUsNqkFRIW+kulclb+xpaL/hRKf+FiE4h/0B5MLN8eVXNf -8z2A31cbXRTqzcDYLRuz1ykHfBX6ZG/6eL3t+VqCEQKBgQD44o5kdM8mIcxcruI7 -TT5tE/cUr4CQnus6NEbMj8WpfGG17GBVVIy/6cXh8+UhiFHbWAJb1wXejs9vUZZw -6hE7uWcOuwoY5F7hl9idWryrIUut+7a8YASYTDMrI77p7Sjin5NQvRppyH1io1Yi -fl9+8MJ5FQYVTI3OnqI3v/hBEwKBgQDRL19MEVH9h4NmXh7wRkz0iXM5dM9mpI9C -daUjv/wH2dlI5SpZkqqgOZ2X2qdgrZdwX33q2z1nSRzbWMjvcfDkJvwexZ995XYH -ffI2Yd1sydUCLJ796vnGphJOpvasKqqIjnYDWXi/uhepw7xYJkTPzmy1P/MzjcbS -JDEsHSfMkQKBgF9rTLhK6FhwQM+P5QBjXvmm2+W8W4gWxYxtGm+290tBepyq4UwV -vFifodQ9E63Fe8yic1UOnRt0mSbOmuTzeGPzcwV8xCRC+fV3p/68GPVrMH6lsKuM -DHbvT/bMH5fD6xbnoy0jMws3aIr2oEFdPfOHDqgpXUmxLfT3cK37FYytAoGAU1/n -QsFQhZViiQWQnUHX4Et8cnUdSRLjyqBrTqFxiYuJsCUuyP7NJQlxx5mtxrnJt09I -N7hkc+tPJhnwFIe8dKMZMAaieCJh9cB8LrK492hGjxRL1na2UTfV6iVgAeULjVwC -q3kYyIoabl6GjjfKi20CJQe1HmIu0Yj9VFDWkRECgYAe0j6P2Kkb/BBdVArme1PK -at1tabfCj99bPEIJgMN0ASU5WU34PVPx4TPiYO40t/ckprslBJAqS4uDwhltiw7q -oFbMAKcie6QXgQkuVPwVjVw6tyJz4mWO8k+XU+9eC+lDq0KHMvXDDabtjYVBQR8g -V5v5HTYXvWh5SG1ZrFLLmw== ------END PRIVATE KEY-----`; - -const entityPublicKey = `-----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy18Efi6+3vSELpbK58gC -A9vJxZtoRHR604yi707h6nzTsTSNUg5mNzt/nWswWzloIWCgA7EPNpJy9lYn4h1Z -6LhxEgf0wFcaux0/C19dC6WRPd6J6EI7z776gtoSV/hANUBGSjaSYCOfAVYE8SZ2 -Fzb6fEhxaVz+1dEVhT1dBszbesx/aicCJ/7vCmlwEeUHwjsi8m9CzPTPcjEjbrHi -7wYUj/ybvpM39ZgwRRgZ/XGXZsdLxibJilx1oS5gY9IopcUoWi7d3o7JuMdBMZ0j -xkVgr2hiUHqbbfREzZxZ1/EowXf9wJiXm3/5eCAAa+2kTcOrucZXzNO4J38CoFz/ -wwIDAQAB ------END PUBLIC KEY-----`; - -const kasECCert = `-----BEGIN CERTIFICATE----- -MIIBcDCCARegAwIBAgIUDbM0tUXlfSEQWsZv63xh4hQIpz4wCgYIKoZIzj0EAwIw -DjEMMAoGA1UEAwwDa2FzMB4XDTI0MDUyMDE4MDgzMVoXDTI1MDUyMDE4MDgzMVow -DjEMMAoGA1UEAwwDa2FzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3MSgw8Dc -tWF3AVd3GQrsNRCn+hqdHuFJhwmvtikHO7pPAtSkvGUiMr1yOsb467aIR0Q3rHLJ -cwSqHR23gls4wqNTMFEwHQYDVR0OBBYEFNJPyqzmUK831ZUnEHnKwyR4LAfNMB8G -A1UdIwQYMBaAFNJPyqzmUK831ZUnEHnKwyR4LAfNMA8GA1UdEwEB/wQFMAMBAf8w -CgYIKoZIzj0EAwIDRwAwRAIgJ/5jiPffo2HinkD725lS3g1hO8NY6blqWuNWyZWF -blMCIBEd8go2XB5sbKZ+VSrfV5EuQsZzf/3SE4oC8jQSMMAc ------END CERTIFICATE-----`; - -const kasECPrivateKey = `-----BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0J2XuMk/ru/LY7XQ -wVe4nK42SFZAIV9e6A+cgJXYX9OhRANCAATcxKDDwNy1YXcBV3cZCuw1EKf6Gp0e -4UmHCa+2KQc7uk8C1KS8ZSIyvXI6xvjrtohHRDescslzBKodHbeCWzjC ------END PRIVATE KEY-----`; - -const entityECPublicKey = `-----BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/2aDZn2NqUdPwZGR\ -D6YnmBySTcC1QSi9XNSK4MtT5zmhRANCAAR37xrx2fCXv0teqQfdRM6cfm0Da6Wf -WbnkPacc6p5eITXg9D0fcCcRbf2AQi+KAsF5zttJ+NOdUgfGRGqmtKYT ------END PRIVATE KEY----- -`; - -const entityECPrivateKey = `-----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEd+8a8dnwl79LXqkH3UTOnH5tA2ul -n1m55D2nHOqeXiE14PQ9H3AnEW39gEIvigLBec7bSfjTnVIHxkRqprSmEw== ------END PUBLIC KEY----- -`; - -const extraECPublicKey = `-----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwajvY7i+B74K2vrVy4pbL7WOpBUn -vWr6IH25k6fEfN/7Xvg6Mqn5D05jsjHNCnNpZva+iXvrKx99mJa3hw25UQ== ------END PUBLIC KEY----- -`; - -const extraECPrivateKey = `-----BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgmiSE/NSqLnpjy1ZC -CxQ5FqxlK+nz90AmKetf1GOUgMmhRANCAATBqO9juL4Hvgra+tXLilsvtY6kFSe9 -avogfbmTp8R83/te+DoyqfkPTmOyMc0Kc2lm9r6Je+srH32YlreHDblR ------END PRIVATE KEY----- -`; - -export default function getMocks() { +export function getMocks() { return Object.create({ - // TODO: diff key then KAS - kasPrivateKey: `-----BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3GdLoh0BHjsu9 -doR2D3+MekHB9VR/cmqV7v6R7xEWZJkuymrJzPy8reKSLK7yDhUEZNA9jslVReMp -QHaR0/ND0fevJZ0yoo8IXGSIYv+prX6wZbqp4YkcahWMx5nFzpCDSJfd2ZBnCvns -z4x95eX8jme9qNYcELFDEkeLFCushNLXdg8NKrWh/Ew8VEZGf4hmtb30J11Uj5P2 -cv6zgATpa6xqjpg8hUarQYTyQi01DTKZ9iR8Kw/xAH+ocXtbJdy046bMb9uMpeJ/ -LlMpELSN5pqamVJis/NkWJOVRdwD//p7WQdz9T4TGzvvrO8KUQoORYERf0EtwBtu -fv5SDpNhAgMBAAECggEBAI7tk5t76ItzRktRNrlKA9DOpoIXVaxeziDX/NRB/96x -DHpf+9gnMaq/ObvNMYs1vuY9I+jJixQLh/VtoqDXCHAKeQO5ouohxvFJ3hgw302+ -ZsSfxIRTz8nkbYoFTV4BjwFMK3A8IuKsyMc4hHzKdyscppKANxKVXSn0HPDOAAGc -Ivdah2o68kef3eeMxwwxEjUCGbv98AsnXOcygb41ZOTFdWjnSZ9/aV2EVTmNs6lL -hU9uD2RTsz7ohbaM2abDeRNCDlQNQe7eQS8B6mItSPahg4eeYC1at2ZbYIcDchUj -Iqz4fMiuAInLNahua6wjN2P9v6wHFax/WXsxTHiHgyECgYEA4nsaTllXq/8ZtK1U -D7e9mqiipKPf/JcHBrG20kSwAgGtzXh0qeVl/KKfSGzTYUF91+q0/XjLvQeaVpDo -VQShe09mAjDPOnqgqV8dqsNRP49JlnkF3V83pBrmMjXDAzA552RwkwZmNQegU19V -jtIsEQQheFe5ZrrzBsc4wd4BFu0CgYEAzvdHLAlki2E9lDqRcwMsJNE4AWS8u+ZR -4G8VLo+fr6qHmv+HYM9vjPvnoS8yiorywLQaBCSDmxPvY9Wy7ErSZ799LLgSpx1e -Z/KFr9VFYZQ+Y0Dm9OPOHPCzOqjNJwdKNsIaRuKAL+NCJQZ1MyZJC3VsThf8gnfm -cQvnK3ryy8UCgYEAhlRLkwLsvCgvP/m6LSRnAg9ZgFtuY6vUUAUiEW8KEfaa9o6m -a4qTRhfSb6uUaE/m6yTbuqdl+DVFNmj2VE7N1IyQTWZT0zSejDbNKtZ0H0XGeMhJ -UTbDksMdm9RFWWPGRFdPafTWtEdUsX6PCYng9yrDC1TEs4jY0kFhiaM6dDUCgYB6 -X19nvE4E04QzhsXFeVS6mDJDMKsfdrlmuIePtkA2/9+aWAhVx5EvjSqR9XQu0qVi -J5tSY7ylDw52uz5F1J+/1EtRC62LviO51n4RT0rsvVh+Gzv0BFY0amWvA2v57aeF -5RLgYsBkkDzl44GcssBx1AYrzqbxBa/tm5od7V5t+QKBgQCdR+BwAsIHF2KzRQhW -BK7+TM6jTOpG5CmxyHhalOdGc56l67NPw10FIZx7zGihAzYbyRv4IBUj2R3nTASb -7uDr0bAL0hHapZgRGzQPG0WX3ifFcfJ+LZoRklm/jHMxYGC/XrCtCfL3ROBL8rcF -3JkIg040ZMZ8wNzpy8zgA7D3KA== ------END PRIVATE KEY-----`, + kasPrivateKey, kasPublicKey, + // TODO: diff key then KAS aaPrivateKey: `-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3GdLoh0BHjsu9 doR2D3+MekHB9VR/cmqV7v6R7xEWZJkuymrJzPy8reKSLK7yDhUEZNA9jslVReMp diff --git a/lib/tests/mocks/pems.ts b/lib/tests/mocks/pems.ts new file mode 100644 index 00000000..70478e7d --- /dev/null +++ b/lib/tests/mocks/pems.ts @@ -0,0 +1,133 @@ +export const kasPublicKey = `-----BEGIN CERTIFICATE----- +MIIDsTCCApmgAwIBAgIJAONESzw+N+3SMA0GCSqGSIb3DQEBDAUAMHUxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJEQzETMBEGA1UEBwwKV2FzaGluZ3RvbjEPMA0GA1UE +CgwGVmlydHJ1MREwDwYDVQQDDAhhY2NvdW50czEgMB4GCSqGSIb3DQEJARYRZGV2 +b3BzQHZpcnRydS5jb20wIBcNMTgxMDE4MTY1MjIxWhgPMzAxODAyMTgxNjUyMjFa +MHUxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJEQzETMBEGA1UEBwwKV2FzaGluZ3Rv +bjEPMA0GA1UECgwGVmlydHJ1MREwDwYDVQQDDAhhY2NvdW50czEgMB4GCSqGSIb3 +DQEJARYRZGV2b3BzQHZpcnRydS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC3GdLoh0BHjsu9doR2D3+MekHB9VR/cmqV7v6R7xEWZJkuymrJzPy8 +reKSLK7yDhUEZNA9jslVReMpQHaR0/ND0fevJZ0yoo8IXGSIYv+prX6wZbqp4Ykc +ahWMx5nFzpCDSJfd2ZBnCvnsz4x95eX8jme9qNYcELFDEkeLFCushNLXdg8NKrWh +/Ew8VEZGf4hmtb30J11Uj5P2cv6zgATpa6xqjpg8hUarQYTyQi01DTKZ9iR8Kw/x +AH+ocXtbJdy046bMb9uMpeJ/LlMpELSN5pqamVJis/NkWJOVRdwD//p7WQdz9T4T +GzvvrO8KUQoORYERf0EtwBtufv5SDpNhAgMBAAGjQjBAMB0GA1UdDgQWBBTVPQ3Y +oYYXHWbZfK2sonPrOE7nszAfBgNVHSMEGDAWgBTVPQ3YoYYXHWbZfK2sonPrOE7n +szANBgkqhkiG9w0BAQwFAAOCAQEAT2ZjAJPQSf0tME0vbAqHzB8iIhR5KniGgJMJ +mRrXbTl2HBH6WnRwfgY1Ok1X224ph4uBGaAUGs8ONBKli0673jE+IgVob7TCu2yV +gHaKcybDegK4esVNRdsDmOWT+eTxGYAzejdIgdFo6R7Xvs87RbqwM4Cko4xoWGVF +ghWsBqUmyg/rZoggL5H1V166hvoLPKU7SrCInZ8Wd6x4rsNDaxNiC9El102pKXu4 +wCiqJZ0XwklGkH9X0Z5x0txc68tqmSlE/z4i/96oxMp0C2thWfy90ub85f5FrB9m +tN5S0umLPkMUJ6zBIxh1RQK1ZYjfuKij+EEimbqtte9rYyQr3Q== +-----END CERTIFICATE-----`; + +export const kasPrivateKey = `-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3GdLoh0BHjsu9 +doR2D3+MekHB9VR/cmqV7v6R7xEWZJkuymrJzPy8reKSLK7yDhUEZNA9jslVReMp +QHaR0/ND0fevJZ0yoo8IXGSIYv+prX6wZbqp4YkcahWMx5nFzpCDSJfd2ZBnCvns +z4x95eX8jme9qNYcELFDEkeLFCushNLXdg8NKrWh/Ew8VEZGf4hmtb30J11Uj5P2 +cv6zgATpa6xqjpg8hUarQYTyQi01DTKZ9iR8Kw/xAH+ocXtbJdy046bMb9uMpeJ/ +LlMpELSN5pqamVJis/NkWJOVRdwD//p7WQdz9T4TGzvvrO8KUQoORYERf0EtwBtu +fv5SDpNhAgMBAAECggEBAI7tk5t76ItzRktRNrlKA9DOpoIXVaxeziDX/NRB/96x +DHpf+9gnMaq/ObvNMYs1vuY9I+jJixQLh/VtoqDXCHAKeQO5ouohxvFJ3hgw302+ +ZsSfxIRTz8nkbYoFTV4BjwFMK3A8IuKsyMc4hHzKdyscppKANxKVXSn0HPDOAAGc +Ivdah2o68kef3eeMxwwxEjUCGbv98AsnXOcygb41ZOTFdWjnSZ9/aV2EVTmNs6lL +hU9uD2RTsz7ohbaM2abDeRNCDlQNQe7eQS8B6mItSPahg4eeYC1at2ZbYIcDchUj +Iqz4fMiuAInLNahua6wjN2P9v6wHFax/WXsxTHiHgyECgYEA4nsaTllXq/8ZtK1U +D7e9mqiipKPf/JcHBrG20kSwAgGtzXh0qeVl/KKfSGzTYUF91+q0/XjLvQeaVpDo +VQShe09mAjDPOnqgqV8dqsNRP49JlnkF3V83pBrmMjXDAzA552RwkwZmNQegU19V +jtIsEQQheFe5ZrrzBsc4wd4BFu0CgYEAzvdHLAlki2E9lDqRcwMsJNE4AWS8u+ZR +4G8VLo+fr6qHmv+HYM9vjPvnoS8yiorywLQaBCSDmxPvY9Wy7ErSZ799LLgSpx1e +Z/KFr9VFYZQ+Y0Dm9OPOHPCzOqjNJwdKNsIaRuKAL+NCJQZ1MyZJC3VsThf8gnfm +cQvnK3ryy8UCgYEAhlRLkwLsvCgvP/m6LSRnAg9ZgFtuY6vUUAUiEW8KEfaa9o6m +a4qTRhfSb6uUaE/m6yTbuqdl+DVFNmj2VE7N1IyQTWZT0zSejDbNKtZ0H0XGeMhJ +UTbDksMdm9RFWWPGRFdPafTWtEdUsX6PCYng9yrDC1TEs4jY0kFhiaM6dDUCgYB6 +X19nvE4E04QzhsXFeVS6mDJDMKsfdrlmuIePtkA2/9+aWAhVx5EvjSqR9XQu0qVi +J5tSY7ylDw52uz5F1J+/1EtRC62LviO51n4RT0rsvVh+Gzv0BFY0amWvA2v57aeF +5RLgYsBkkDzl44GcssBx1AYrzqbxBa/tm5od7V5t+QKBgQCdR+BwAsIHF2KzRQhW +BK7+TM6jTOpG5CmxyHhalOdGc56l67NPw10FIZx7zGihAzYbyRv4IBUj2R3nTASb +7uDr0bAL0hHapZgRGzQPG0WX3ifFcfJ+LZoRklm/jHMxYGC/XrCtCfL3ROBL8rcF +3JkIg040ZMZ8wNzpy8zgA7D3KA== +-----END PRIVATE KEY-----`; + +export const entityPrivateKey = `-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDLXwR+Lr7e9IQu +lsrnyAID28nFm2hEdHrTjKLvTuHqfNOxNI1SDmY3O3+dazBbOWghYKADsQ82knL2 +VifiHVnouHESB/TAVxq7HT8LX10LpZE93onoQjvPvvqC2hJX+EA1QEZKNpJgI58B +VgTxJnYXNvp8SHFpXP7V0RWFPV0GzNt6zH9qJwIn/u8KaXAR5QfCOyLyb0LM9M9y +MSNuseLvBhSP/Ju+kzf1mDBFGBn9cZdmx0vGJsmKXHWhLmBj0iilxShaLt3ejsm4 +x0ExnSPGRWCvaGJQeptt9ETNnFnX8SjBd/3AmJebf/l4IABr7aRNw6u5xlfM07gn +fwKgXP/DAgMBAAECggEADInMpJzsLqHDnn20f8rAeQ1taK32pTXLNsy2ZOunmQXe +JVA4oET7/06/ROzNW+pzpY8n/mJFrlckGFTie5nUp7jrW7G64LreDog0kVZtTaEF +DdvxA61Fs76yAixAskS/bKkMTFoF90Bq9rGfd2CoKjE9CzmKKHVPzs3ntkG8wQT3 +C1ClT8Ce4Y+aNjLd+i47xIxNenHKfezZOriteKxVWna23fl3ISXr7e1LDI75qhcY +l3NY+EtwHKm2tGW5ukGUsNqkFRIW+kulclb+xpaL/hRKf+FiE4h/0B5MLN8eVXNf +8z2A31cbXRTqzcDYLRuz1ykHfBX6ZG/6eL3t+VqCEQKBgQD44o5kdM8mIcxcruI7 +TT5tE/cUr4CQnus6NEbMj8WpfGG17GBVVIy/6cXh8+UhiFHbWAJb1wXejs9vUZZw +6hE7uWcOuwoY5F7hl9idWryrIUut+7a8YASYTDMrI77p7Sjin5NQvRppyH1io1Yi +fl9+8MJ5FQYVTI3OnqI3v/hBEwKBgQDRL19MEVH9h4NmXh7wRkz0iXM5dM9mpI9C +daUjv/wH2dlI5SpZkqqgOZ2X2qdgrZdwX33q2z1nSRzbWMjvcfDkJvwexZ995XYH +ffI2Yd1sydUCLJ796vnGphJOpvasKqqIjnYDWXi/uhepw7xYJkTPzmy1P/MzjcbS +JDEsHSfMkQKBgF9rTLhK6FhwQM+P5QBjXvmm2+W8W4gWxYxtGm+290tBepyq4UwV +vFifodQ9E63Fe8yic1UOnRt0mSbOmuTzeGPzcwV8xCRC+fV3p/68GPVrMH6lsKuM +DHbvT/bMH5fD6xbnoy0jMws3aIr2oEFdPfOHDqgpXUmxLfT3cK37FYytAoGAU1/n +QsFQhZViiQWQnUHX4Et8cnUdSRLjyqBrTqFxiYuJsCUuyP7NJQlxx5mtxrnJt09I +N7hkc+tPJhnwFIe8dKMZMAaieCJh9cB8LrK492hGjxRL1na2UTfV6iVgAeULjVwC +q3kYyIoabl6GjjfKi20CJQe1HmIu0Yj9VFDWkRECgYAe0j6P2Kkb/BBdVArme1PK +at1tabfCj99bPEIJgMN0ASU5WU34PVPx4TPiYO40t/ckprslBJAqS4uDwhltiw7q +oFbMAKcie6QXgQkuVPwVjVw6tyJz4mWO8k+XU+9eC+lDq0KHMvXDDabtjYVBQR8g +V5v5HTYXvWh5SG1ZrFLLmw== +-----END PRIVATE KEY-----`; + +export const entityPublicKey = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy18Efi6+3vSELpbK58gC +A9vJxZtoRHR604yi707h6nzTsTSNUg5mNzt/nWswWzloIWCgA7EPNpJy9lYn4h1Z +6LhxEgf0wFcaux0/C19dC6WRPd6J6EI7z776gtoSV/hANUBGSjaSYCOfAVYE8SZ2 +Fzb6fEhxaVz+1dEVhT1dBszbesx/aicCJ/7vCmlwEeUHwjsi8m9CzPTPcjEjbrHi +7wYUj/ybvpM39ZgwRRgZ/XGXZsdLxibJilx1oS5gY9IopcUoWi7d3o7JuMdBMZ0j +xkVgr2hiUHqbbfREzZxZ1/EowXf9wJiXm3/5eCAAa+2kTcOrucZXzNO4J38CoFz/ +wwIDAQAB +-----END PUBLIC KEY-----`; + +export const kasECCert = `-----BEGIN CERTIFICATE----- +MIIBcDCCARegAwIBAgIUDbM0tUXlfSEQWsZv63xh4hQIpz4wCgYIKoZIzj0EAwIw +DjEMMAoGA1UEAwwDa2FzMB4XDTI0MDUyMDE4MDgzMVoXDTI1MDUyMDE4MDgzMVow +DjEMMAoGA1UEAwwDa2FzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3MSgw8Dc +tWF3AVd3GQrsNRCn+hqdHuFJhwmvtikHO7pPAtSkvGUiMr1yOsb467aIR0Q3rHLJ +cwSqHR23gls4wqNTMFEwHQYDVR0OBBYEFNJPyqzmUK831ZUnEHnKwyR4LAfNMB8G +A1UdIwQYMBaAFNJPyqzmUK831ZUnEHnKwyR4LAfNMA8GA1UdEwEB/wQFMAMBAf8w +CgYIKoZIzj0EAwIDRwAwRAIgJ/5jiPffo2HinkD725lS3g1hO8NY6blqWuNWyZWF +blMCIBEd8go2XB5sbKZ+VSrfV5EuQsZzf/3SE4oC8jQSMMAc +-----END CERTIFICATE-----`; + +export const kasECPrivateKey = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0J2XuMk/ru/LY7XQ +wVe4nK42SFZAIV9e6A+cgJXYX9OhRANCAATcxKDDwNy1YXcBV3cZCuw1EKf6Gp0e +4UmHCa+2KQc7uk8C1KS8ZSIyvXI6xvjrtohHRDescslzBKodHbeCWzjC +-----END PRIVATE KEY-----`; + +export const entityECPublicKey = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/2aDZn2NqUdPwZGR\ +D6YnmBySTcC1QSi9XNSK4MtT5zmhRANCAAR37xrx2fCXv0teqQfdRM6cfm0Da6Wf +WbnkPacc6p5eITXg9D0fcCcRbf2AQi+KAsF5zttJ+NOdUgfGRGqmtKYT +-----END PRIVATE KEY----- +`; + +export const entityECPrivateKey = `-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEd+8a8dnwl79LXqkH3UTOnH5tA2ul +n1m55D2nHOqeXiE14PQ9H3AnEW39gEIvigLBec7bSfjTnVIHxkRqprSmEw== +-----END PUBLIC KEY----- +`; + +export const extraECPublicKey = `-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwajvY7i+B74K2vrVy4pbL7WOpBUn +vWr6IH25k6fEfN/7Xvg6Mqn5D05jsjHNCnNpZva+iXvrKx99mJa3hw25UQ== +-----END PUBLIC KEY----- +`; + +export const extraECPrivateKey = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgmiSE/NSqLnpjy1ZC +CxQ5FqxlK+nz90AmKetf1GOUgMmhRANCAATBqO9juL4Hvgra+tXLilsvtY6kFSe9 +avogfbmTp8R83/te+DoyqfkPTmOyMc0Kc2lm9r6Je+srH32YlreHDblR +-----END PRIVATE KEY----- +`; diff --git a/lib/tests/server.ts b/lib/tests/server.ts index bed79e09..2a10b707 100644 --- a/lib/tests/server.ts +++ b/lib/tests/server.ts @@ -5,7 +5,7 @@ import { IncomingMessage, RequestListener, createServer } from 'node:http'; import { base64 } from '../src/encodings/index.js'; import { decryptWithPrivateKey, encryptWithPublicKey } from '../tdf3/src/crypto/index.js'; -import getMocks from './mocks/index.js'; +import { getMocks } from './mocks/index.js'; import { Header, getHkdfSalt } from '../src/nanotdf/index.js'; import { keyAgreement } from '../src/nanotdf-crypto/keyAgreement.js'; import generateRandomNumber from '../src/nanotdf-crypto/generateRandomNumber.js'; diff --git a/lib/tests/web/policy/granter.test.ts b/lib/tests/web/policy/granter.test.ts new file mode 100644 index 00000000..762fb5f6 --- /dev/null +++ b/lib/tests/web/policy/granter.test.ts @@ -0,0 +1,80 @@ +import { expect } from '@esm-bundle/chai'; +import { plan } from '../../../src/policy/granter.js'; +import * as matr from './mock-attrs.js'; + +describe('policy/granter', () => { + describe('constructs kao template', () => { + for (const { name, attrs, e } of [ + { name: 'one actual', attrs: [matr.valRelAus], e: [{ kas: matr.kasAu, sid: '1' }] }, + { + name: 'one actual with default', + attrs: [matr.valClassA, matr.valRelAus], + e: [{ kas: matr.kasAu, sid: '1' }], + }, + { name: 'one defaulted attr default', attrs: [matr.valClassA], e: [] }, + { name: 'empty policy', attrs: [], e: [] }, + { + name: 'shares', + attrs: [matr.valRelAus, matr.valRelCan, matr.valRelUsa], + e: [matr.kasAu, matr.kasCa, matr.kasUs].map((kas) => ({ kas, sid: '1' })), + }, + { + name: 'splits', + attrs: [matr.valN2KHCS, matr.valN2KSI], + e: [ + { kas: matr.kasUsHCS, sid: '1' }, + { kas: matr.kasUsSA, sid: '2' }, + ], + }, + { + name: 'simplifies two with a default', + attrs: [matr.valClassS, matr.valRelGbr, matr.valN2KINT], + e: [{ kas: matr.kasUk, sid: '1' }], + }, + { + name: 'compartments', + attrs: [matr.valClassS, matr.valRelGbr, matr.valRelUsa, matr.valN2KHCS, matr.valN2KSI], + e: [ + { kas: matr.kasUsHCS, sid: '1' }, + { kas: matr.kasUk, sid: '2' }, + { kas: matr.kasUs, sid: '2' }, + { kas: matr.kasUsSA, sid: '3' }, + ], + }, + ]) { + const expected = e.map(({ kas, sid }) => ({ kas: matr.kases[kas], sid })); + it(name, async () => { + const p = plan(matr.valuesFor(attrs)); + expect(p).to.deep.equal(expected); + }); + } + }); + + describe('grant overloading', () => { + for (const { name, e } of [ + { name: 'UUU', e: [] }, + { name: 'UUG', e: [{ kas: matr.evenMoreSpecificKas, sid: '1' }] }, + { name: 'UGU', e: [{ kas: matr.specifiedKas, sid: '1' }] }, + { name: 'UGG', e: [{ kas: matr.evenMoreSpecificKas, sid: '1' }] }, + { name: 'GUU', e: [{ kas: matr.lessSpecificKas, sid: '1' }] }, + { name: 'GUG', e: [{ kas: matr.evenMoreSpecificKas, sid: '1' }] }, + { name: 'GGU', e: [{ kas: matr.specifiedKas, sid: '1' }] }, + { name: 'GGG', e: [{ kas: matr.evenMoreSpecificKas, sid: '1' }] }, + { name: 'UUU+UUG', e: [{ kas: matr.evenMoreSpecificKas, sid: '1' }] }, + ]) { + const attrs = matr.valuesFor( + name.split('+').map((s) => { + const [n, a, v] = s; + const ns = n == 'G' ? matr.nsGranted : matr.nsUngranted; + const attr = `${ns}/attr/${a == 'G' ? '' : 'un'}granted`; + return `${attr}/value/${v == 'G' ? '' : 'un'}granted`; + }) + ); + const expected = e.map(({ kas, sid }) => ({ kas: matr.kases[kas], sid })); + it(name, async () => { + const p = plan(attrs); + expect(p).to.deep.equal(expected); + }); + } + }); +}); diff --git a/lib/tests/web/policy/mock-attrs.ts b/lib/tests/web/policy/mock-attrs.ts new file mode 100644 index 00000000..e679b6fd --- /dev/null +++ b/lib/tests/web/policy/mock-attrs.ts @@ -0,0 +1,254 @@ +import { Attribute, KeyAccessServer, Namespace, Value } from '../../../src/policy/attributes.js'; +import { kasECCert, kasPublicKey } from '../../mocks/pems.js'; + +export const kasAu = 'https://kas.au/'; +export const kasCa = 'https://kas.ca/'; +export const kasUk = 'https://kas.uk/'; +export const kasNz = 'https://kas.nz/'; +export const kasUs = 'https://kas.us/'; +export const kasUsHCS = 'https://hcs.kas.us/'; +export const kasUsSA = 'https://si.kas.us/'; +export const authority = 'https://virtru.com/'; +export const otherAuth = 'https://other.com/'; +export const specifiedKas = 'https://attr.kas.com/'; +export const evenMoreSpecificKas = 'https://value.kas.com/'; +export const lessSpecificKas = 'https://namespace.kas.com/'; + +export const nsStandard = 'https://standard.ns'; + +export const attrCLS = `${nsStandard}/attr/Classification`; +export const attrN2K = `${nsStandard}/attr/Need%20to%20Know`; +export const attrREL = `${nsStandard}/attr/Releasable%20To`; + +export const valClassA = `${attrCLS}/value/Allowed`; +export const valClassS = `${attrCLS}/value/Secret`; +export const valClassTS = `${attrCLS}/value/Top%20Secret`; + +export const valN2KHCS = `${attrN2K}/value/HCS`; +export const valN2KINT = `${attrN2K}/value/INT`; +export const valN2KSI = `${attrN2K}/value/SI`; + +export const valRelAus = `${attrREL}/value/AUS`; +export const valRelCan = `${attrREL}/value/CAN`; +export const valRelGbr = `${attrREL}/value/GBR`; +export const valRelNzl = `${attrREL}/value/NZL`; +export const valRelUsa = `${attrREL}/value/USA`; +export const valRelFvey = `${attrREL}/value/FVEY`; + +// For testing grant specificity +export const nsGranted = 'https://granted.ns'; +export const nsUngranted = 'https://ungranted.ns'; +export const attrGG = `${nsGranted}/attr/granted`; +export const attrGU = `${nsGranted}/attr/ungranted`; +export const attrUG = `${nsUngranted}/attr/granted`; +export const attrUU = `${nsUngranted}/attr/ungranted`; +export const valGGG = `${attrGG}/value/granted`; +export const valGGU = `${attrGG}/value/ungranted`; +export const valGUG = `${attrGU}/value/granted`; +export const valGUU = `${attrGU}/value/ungranted`; +export const valUGG = `${attrUG}/value/granted`; +export const valUGU = `${attrUG}/value/ungranted`; +export const valUUG = `${attrUU}/value/granted`; +export const valUUU = `${attrUU}/value/ungranted`; + +export const kases: Record = Object.fromEntries( + [ + kasAu, + kasCa, + kasUk, + kasNz, + kasUs, + kasUsHCS, + kasUsSA, + authority, + otherAuth, + specifiedKas, + evenMoreSpecificKas, + lessSpecificKas, + ].map((k) => [ + k, + { + uri: k, + publicKey: { + cached: { + keys: [ + { + pem: kasECCert, + kid: 'e1', + alg: 'KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1', + }, + { + pem: kasPublicKey, + kid: 'r1', + alg: 'KAS_PUBLIC_KEY_ALG_ENUM_RSA_2048', + }, + ], + }, + }, + }, + ]) +); + +export const namespaces: Record = {}; +for (const ns of [nsStandard, nsGranted, nsUngranted]) { + namespaces[ns] = { + fqn: ns, + name: ns.split('//')[1], + active: true, + }; + if (ns == nsGranted) { + namespaces[ns].grants = [kases[lessSpecificKas]]; + } +} + +export const attributes: Record = { + [attrCLS]: { + fqn: attrCLS, + namespace: namespaces[nsStandard], + active: true, + name: 'Classification', + rule: 'ATTRIBUTE_RULE_TYPE_ENUM_UNSPECIFIED', + }, + [attrN2K]: { + fqn: attrN2K, + namespace: namespaces[nsStandard], + active: true, + name: 'Need to Know', + rule: 'ATTRIBUTE_RULE_TYPE_ENUM_ALL_OF', + }, + [attrREL]: { + fqn: attrREL, + namespace: namespaces[nsStandard], + active: true, + name: 'Releasable To', + rule: 'ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF', + }, +}; +for (const fqn of [attrGG, attrGU, attrUG, attrUU]) { + const { groups } = fqn.match(/^(?https?:\/\/[\w./]+)\/attr\/(?\w+)$/) || {}; + if (!groups?.ns || !namespaces[groups.ns] || !groups.at) { + throw Error(`Invalid fqn [${fqn}]`); + } + attributes[fqn] = { + fqn, + namespace: namespaces[groups.ns], + active: true, + name: groups.at, + }; + if (groups.at == 'granted') { + attributes[fqn].grants = [kases[specifiedKas]]; + } +} + +export const values: Record = {}; +for (const fqn of [ + valClassA, + valClassS, + valClassTS, + valN2KHCS, + valN2KINT, + valN2KSI, + valRelAus, + valRelCan, + valRelGbr, + valRelNzl, + valRelUsa, + valRelFvey, + valGGG, + valGGU, + valGUG, + valGUU, + valUGG, + valUGU, + valUUG, + valUUU, +]) { + const m = fqn.match(/^(https?:\/\/[\w./-]+\/attr\/\S*)\/value\/(\S*)$/); + if (!m || m.length < 3) { + throw Error(`invalid attribute value fqn [${fqn}] m:[${m}]`); + } + const attribute = attributes[m[1]]; + if (!attribute) { + throw Error(`unknown attribute [${m[1]}] value fqn [${fqn}]`); + } + const value = decodeURIComponent(m[2]); + if (!value) { + throw Error(`invalid attribute value fqn [${fqn}]`); + } + if (!attribute.values) { + attribute.values = []; + } + let grants: string[] | undefined = undefined; + switch (m[1]) { + case attrCLS: + // defaults only + break; + case attrN2K: + switch (value) { + case 'INT': + grants = [kasUk]; + break; + case 'HCS': + grants = [kasUsHCS]; + break; + case 'SI': + grants = [kasUsSA]; + break; + } + break; + case attrREL: + switch (value) { + case 'FVEY': + grants = [kasAu, kasCa, kasNz, kasUk, kasUs]; + break; + case 'AUS': + grants = [kasAu]; + break; + case 'CAN': + grants = [kasCa]; + break; + case 'GBR': + grants = [kasUk]; + break; + case 'NZL': + grants = [kasNz]; + break; + case 'USA': + grants = [kasUs]; + break; + } + break; + case attrGG: + case attrGU: + case attrUG: + case attrUU: + { + if (value == 'granted') { + grants = [evenMoreSpecificKas]; + } + } + break; + } + + const val = { + attribute, + value, + fqn, + active: true, + ...(grants && { grants: grants.map((g) => kases[g]) }), + }; + attribute.values.push(val); + values[fqn] = val; +} + +export function valueFor(attr: string): Value { + if (!(attr in values)) { + throw new Error(`invalid FQN [${attr}]`); + } + console.log('value for', attr, 'is', values[attr]); + return values[attr]; +} + +export function valuesFor(attrs: string[]): Value[] { + return attrs.map(valueFor); +} From 48b24426c26ff56e0edb7d2e78eda34e844be135 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Thu, 19 Sep 2024 12:48:00 -0400 Subject: [PATCH 27/42] feat(lib): Load abac config from policy service (#351) New parameters for tdf/client allow looking up attribute definitions and KAS grants to autoconfigure with just attribute URLs. - New arguments to cli `encrypt` - `encrypt --autoconfigure` enables attribute lookup during encrypt and corresponding updates to the KAO - `--policyEndpoint` allows KAS and policy service to be hosted separately. if not set, it is inferred by removing `/kas` off of the end of the `--kasEndpoint` argument. - New cli command, `attrs`, which prints out the JSON hydrated version of the attributes from the policy service --- .github/workflows/roundtrip/package-lock.json | 3755 ++--------------- cli/package-lock.json | 2 +- cli/src/cli.ts | 122 +- lib/src/index.ts | 1 + lib/src/package-lock.json | 6 + lib/src/policy/api.ts | 62 + lib/src/policy/attributes.ts | 14 + lib/tdf3/package-lock.json | 6 + lib/tdf3/src/client/builders.ts | 11 + lib/tdf3/src/client/index.ts | 48 +- lib/tests/server.ts | 30 + remote-store/package-lock.json | 2 +- web-app/package-lock.json | 4 +- 13 files changed, 671 insertions(+), 3392 deletions(-) create mode 100644 lib/src/package-lock.json create mode 100644 lib/src/policy/api.ts create mode 100644 lib/tdf3/package-lock.json diff --git a/.github/workflows/roundtrip/package-lock.json b/.github/workflows/roundtrip/package-lock.json index 2f899aa0..f271315e 100644 --- a/.github/workflows/roundtrip/package-lock.json +++ b/.github/workflows/roundtrip/package-lock.json @@ -8,3412 +8,477 @@ "name": "client-web-roundtrip", "version": "0.0.1", "dependencies": { - "@opentdf/cli": "file:../../../cli/opentdf-cli-1.0.1.tgz" + "@opentdf/cli": "file:../../../cli/opentdf-cli-2.0.0.tgz" } }, - "node_modules/@aws-crypto/crc32": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", - "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", - "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/crc32/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/crc32c": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", - "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", - "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/crc32c/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/ie11-detection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", - "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", - "dependencies": { - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/sha1-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", - "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", - "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", - "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", - "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/sha256-js": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", - "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", - "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", - "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", - "dependencies": { - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/util": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", - "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-sdk/abort-controller": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.357.0.tgz", - "integrity": "sha512-nQYDJon87quPwt2JZJwUN2GFKJnvE5kWb6tZP4xb5biSGUKBqDQo06oYed7yokatCuCMouIXV462aN0fWODtOw==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/chunked-blob-reader": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.310.0.tgz", - "integrity": "sha512-CrJS3exo4mWaLnWxfCH+w88Ou0IcAZSIkk4QbmxiHl/5Dq705OLoxf4385MVyExpqpeVJYOYQ2WaD8i/pQZ2fg==", - "dependencies": { - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/client-s3": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.363.0.tgz", - "integrity": "sha512-LNnfg/t8wG5Fqj6l+PSV/t+IXDq9r3Kj9jEHn84513+p7bewXYSSreSpmLjG8OcKuMfHc9EJGNQ3DkMyFaLoWg==", - "dependencies": { - "@aws-crypto/sha1-browser": "3.0.0", - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.363.0", - "@aws-sdk/credential-provider-node": "3.363.0", - "@aws-sdk/hash-blob-browser": "3.357.0", - "@aws-sdk/hash-stream-node": "3.357.0", - "@aws-sdk/md5-js": "3.357.0", - "@aws-sdk/middleware-bucket-endpoint": "3.363.0", - "@aws-sdk/middleware-expect-continue": "3.363.0", - "@aws-sdk/middleware-flexible-checksums": "3.363.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-location-constraint": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-sdk-s3": "3.363.0", - "@aws-sdk/middleware-signing": "3.363.0", - "@aws-sdk/middleware-ssec": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/signature-v4-multi-region": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@aws-sdk/xml-builder": "3.310.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/eventstream-serde-browser": "^1.0.1", - "@smithy/eventstream-serde-config-resolver": "^1.0.1", - "@smithy/eventstream-serde-node": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.2", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/protocol-http": "^1.0.1", - "@smithy/smithy-client": "^1.0.3", - "@smithy/types": "^1.0.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.2", - "@smithy/util-stream": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "@smithy/util-waiter": "^1.0.1", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.363.0.tgz", - "integrity": "sha512-PZ+HfKSgS4hlMnJzG+Ev8/mgHd/b/ETlJWPSWjC/f2NwVoBQkBnqHjdyEx7QjF6nksJozcVh5Q+kkYLKc/QwBQ==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.2", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/protocol-http": "^1.0.1", - "@smithy/smithy-client": "^1.0.3", - "@smithy/types": "^1.0.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.2", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.363.0.tgz", - "integrity": "sha512-V3Ebiq/zNtDS/O92HUWGBa7MY59RYSsqWd+E0XrXv6VYTA00RlMTbNcseivNgp2UghOgB9a20Nkz6EqAeIN+RQ==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.2", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/protocol-http": "^1.0.1", - "@smithy/smithy-client": "^1.0.3", - "@smithy/types": "^1.0.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.2", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-sts": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.363.0.tgz", - "integrity": "sha512-0jj14WvBPJQ8xr72cL0mhlmQ90tF0O0wqXwSbtog6PsC8+KDE6Yf+WsxsumyI8E5O8u3eYijBL+KdqG07F/y/w==", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/credential-provider-node": "3.363.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-sdk-sts": "3.363.0", - "@aws-sdk/middleware-signing": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.1", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/smithy-client": "^1.0.2", - "@smithy/types": "^1.1.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.363.0.tgz", - "integrity": "sha512-VAQ3zITT2Q0acht0HezouYnMFKZ2vIOa20X4zQA3WI0HfaP4D6ga6KaenbDcb/4VFiqfqiRHfdyXHP0ThcDRMA==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.363.0.tgz", - "integrity": "sha512-ZYN+INoqyX5FVC3rqUxB6O8nOWkr0gHRRBm1suoOlmuFJ/WSlW/uUGthRBY5x1AQQnBF8cpdlxZzGHd41lFVNw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.363.0", - "@aws-sdk/credential-provider-process": "3.363.0", - "@aws-sdk/credential-provider-sso": "3.363.0", - "@aws-sdk/credential-provider-web-identity": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/credential-provider-imds": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.363.0.tgz", - "integrity": "sha512-C1qXFIN2yMxD6pGgug0vR1UhScOki6VqdzuBHzXZAGu7MOjvgHNdscEcb3CpWnITHaPL2ztkiw75T1sZ7oIgQg==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.363.0", - "@aws-sdk/credential-provider-ini": "3.363.0", - "@aws-sdk/credential-provider-process": "3.363.0", - "@aws-sdk/credential-provider-sso": "3.363.0", - "@aws-sdk/credential-provider-web-identity": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/credential-provider-imds": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.363.0.tgz", - "integrity": "sha512-fOKAINU7Rtj2T8pP13GdCt+u0Ml3gYynp8ki+1jMZIQ+Ju/MdDOqZpKMFKicMn3Z1ttUOgqr+grUdus6z8ceBQ==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.363.0.tgz", - "integrity": "sha512-5RUZ5oM0lwZSo3EehT0dXggOjgtxFogpT3cZvoLGtIwrPBvm8jOQPXQUlaqCj10ThF1sYltEyukz/ovtDwYGew==", - "dependencies": { - "@aws-sdk/client-sso": "3.363.0", - "@aws-sdk/token-providers": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.363.0.tgz", - "integrity": "sha512-Z6w7fjgy79pAax580wdixbStQw10xfyZ+hOYLcPudoYFKjoNx0NQBejg5SwBzCF/HQL23Ksm9kDfbXDX9fkPhA==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.357.0.tgz", - "integrity": "sha512-5sPloTO8y8fAnS/6/Sfp/aVoL9zuhzkLdWBORNzMazdynVNEzWKWCPZ27RQpgkaCDHiXjqUY4kfuFXAGkvFfDQ==", - "dependencies": { - "@aws-sdk/protocol-http": "3.357.0", - "@aws-sdk/querystring-builder": "3.357.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-base64": "3.310.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/hash-blob-browser": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.357.0.tgz", - "integrity": "sha512-RDd6UgrGHDmleTnXM9LRSSVa69euSAG2mlNhZMEDWk3OFseXVYqBDaqroVbQ01rM2UAe8MeBFchlV9OmxuVgvw==", - "dependencies": { - "@aws-sdk/chunked-blob-reader": "3.310.0", - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/hash-stream-node": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.357.0.tgz", - "integrity": "sha512-KZjN1VAw1KHNp+xKVOWBGS+MpaYQTjZFD5f+7QQqW4TfbAkFFwIAEYIHq5Q8Gw+jVh0h61OrV/LyW3J2PVzc+w==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/is-array-buffer": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz", - "integrity": "sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/md5-js": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.357.0.tgz", - "integrity": "sha512-to42sFAL7KgV/X9X40LLfEaNMHMGQL6/7mPMVCL/W2BZf3zw5OTl3lAaNyjXA+gO5Uo4lFEiQKAQVKNbr8b8Nw==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.363.0.tgz", - "integrity": "sha512-kR8+0X50zslpzRW29q4JbpPMadE1z39ZfGwPaBLKpoWvSGt4x+75FaoK71TH7urPPoFyD2Y+XKGA6YRYTUNHSQ==", + "node_modules/@babel/runtime": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "@smithy/util-config-provider": "^1.0.1", - "tslib": "^2.5.0" + "regenerator-runtime": "^0.14.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-sdk/middleware-endpoint": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.357.0.tgz", - "integrity": "sha512-ScJi0SL8X/Lyi0Fp5blg0QN/Z6PoRwV/ZJXd8dQkXSznkbSvJHfqPP0xk/w3GcQ1TKsu5YEPfeYy8ejcq+7Pgg==", + "node_modules/@opentdf/cli": { + "version": "2.0.0", + "resolved": "file:../../../cli/opentdf-cli-2.0.0.tgz", + "integrity": "sha512-VyP+j6+YeitjJz5xWpVsQbwjiqkPY5OfHLU/fn2I3rU0qlOARqZia47TuS7MLkPmQ/m6Myt1q79ysIXV9Dxlng==", "dependencies": { - "@aws-sdk/middleware-serde": "3.357.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/url-parser": "3.357.0", - "@aws-sdk/util-middleware": "3.357.0", - "tslib": "^2.5.0" + "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "yargs": "^17.7.2" }, - "engines": { - "node": ">=14.0.0" + "bin": { + "opentdf": "bin/opentdf.mjs" } }, - "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.363.0.tgz", - "integrity": "sha512-I88xneZp6jRwySmIl9uI7eZCcTsqRVnTDfUr1JiXt7zonqNNm80PVYMs6pwaw7t97ec1AQJcsONjuXZyCMnu5g==", + "node_modules/@opentdf/client": { + "version": "2.0.0", + "resolved": "file:../../../lib/opentdf-client-2.0.0.tgz", + "integrity": "sha512-hrF0E3JpYyYab0HOOQZ8VT+69SFgeRAxdS1f97s5Su2dBBX0IrGgpR0ZlKMbt9nlzCKChia1MIz7jsRTg+3sSg==", "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "axios": "^1.6.1", + "axios-retry": "^3.9.0", + "base64-js": "^1.5.1", + "browser-fs-access": "^0.34.1", + "buffer": "^6.0.3", + "buffer-crc32": "^0.2.13", + "dpop": "^1.2.0", + "eventemitter3": "^5.0.1", + "jose": "^4.14.4", + "streamsaver": "^2.0.6", + "uuid": "~9.0.0" } }, - "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.363.0.tgz", - "integrity": "sha512-FBYmrMRX01uNximNN0WLgpf97GN4xNTLaKsDlkjYRWKJ+J97ICkvLG0FcSu7+SNCpCdJJBeQ5tRVOPVpUu6nmA==", - "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@aws-crypto/crc32c": "3.0.0", - "@aws-sdk/types": "3.357.0", - "@smithy/is-array-buffer": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - }, + "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==", "engines": { - "node": ">=14.0.0" + "node": ">=8" } }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.363.0.tgz", - "integrity": "sha512-FobpclDCf5Y1ueyJDmb9MqguAdPssNMlnqWQpujhYVABq69KHu73fSCWSauFPUrw7YOpV8kG1uagDF0POSxHzA==", + "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==", "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.363.0.tgz", - "integrity": "sha512-piNzpNNI/fChSGOZxcq/2msN2qFUSEAbhqs91zbcpv8CEPekVLc4W9laXCG764BEMyfG97ZU8MtzwHeMhELhBA==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "node": ">=8" }, - "engines": { - "node": ">=14.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.363.0.tgz", - "integrity": "sha512-SSGgthScYnFGTOw8EzbkvquqweFmvn7uJihkpFekbtBNGC/jGOGO+8ziHjTQ8t/iI/YKubEwv+LMi0f77HKSEg==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.363.0.tgz", - "integrity": "sha512-MWD/57QgI/N7fG8rtzDTUdSqNpYohQfgj9XCFAoVeI/bU4usrkOrew43L4smJG4XrDxlNT8lSJlDtd64tuiUZA==", + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, - "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.363.0.tgz", - "integrity": "sha512-npC8vLCero+vULizrK0QPjNanWbgH4A/2Llc1nO8N005uvUe7co6WglILF2W3guZrFk/0uGEdX67OnLxUD97pw==", + "node_modules/axios-retry": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", + "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "@babel/runtime": "^7.15.4", + "is-retry-allowed": "^2.2.0" } }, - "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.363.0.tgz", - "integrity": "sha512-1yy2Ac50FO8BrODaw5bPWvVrRhaVLqXTFH6iHB+dJLPUkwtY5zLM3Mp+9Ilm7kME+r7oIB1wuO6ZB1Lf4ZszIw==", - "dependencies": { - "@aws-sdk/middleware-signing": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } + "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" + } + ] }, - "node_modules/@aws-sdk/middleware-serde": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.357.0.tgz", - "integrity": "sha512-bGI4kYuuEsFjlANbyJLyy4AovETnyf/SukgLOG7Qjbua+ZGuzvRhMsk21mBKKGrnsTO4PmtieJo6xClThGAN8g==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } + "node_modules/browser-fs-access": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" }, - "node_modules/@aws-sdk/middleware-signing": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.363.0.tgz", - "integrity": "sha512-/7qia715pt9JKYIPDGu22WmdZxD8cfF/5xB+1kmILg7ZtjO0pPuTaCNJ7xiIuFd7Dn7JXp5lop08anX/GOhNRQ==", + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/signature-v4": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-middleware": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.363.0.tgz", - "integrity": "sha512-pN+QN1rMShYpJnTJSCIYnNRhD0S8xSZsTn6ThgcO559Xiwz5LMHFOfOXUCEyxtbVW5kMHLUh3w101AMUKae99A==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "engines": { - "node": ">=14.0.0" + "node": "*" } }, - "node_modules/@aws-sdk/middleware-stack": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.357.0.tgz", - "integrity": "sha512-nNV+jfwGwmbOGZujAY/U8AW3EbVlxa9DJDLz3TPp/39o6Vu5KEzHJyDDNreo2k9V/TMvV+nOzHafufgPdagv7w==", + "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==", "dependencies": { - "tslib": "^2.5.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12" } }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.363.0.tgz", - "integrity": "sha512-ri8YaQvXP6odteVTMfxPqFR26Q0h9ejtqhUDv47P34FaKXedEM4nC6ix6o+5FEYj6l8syGyktftZ5O70NoEhug==", + "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==", "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=14.0.0" + "node": ">=7.0.0" } }, - "node_modules/@aws-sdk/node-http-handler": { - "version": "3.360.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.360.0.tgz", - "integrity": "sha512-oMsXdMmNwHpUbebETO44bq0N4SocEMGfPjYNUTRs8md7ita5fuFd2qFuvf+ZRt6iVcGWluIqmF8DidD+b7d+TA==", - "dependencies": { - "@aws-sdk/abort-controller": "3.357.0", - "@aws-sdk/protocol-http": "3.357.0", - "@aws-sdk/querystring-builder": "3.357.0", - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } + "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==" }, - "node_modules/@aws-sdk/protocol-http": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.357.0.tgz", - "integrity": "sha512-w1JHiI50VEea7duDeAspUiKJmmdIQblvRyjVMOqWA6FIQAyDVuEiPX7/MdQr0ScxhtRQxHbP0I4MFyl7ctRQvA==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/querystring-builder": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.357.0.tgz", - "integrity": "sha512-aQcicqB6Y2cNaXPPwunz612a01SMiQQPsdz632F/3Lzn0ua82BJKobHOtaiTUlmVJ5Q4/EAeNfwZgL7tTUNtDQ==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/querystring-parser": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.357.0.tgz", - "integrity": "sha512-Svvq+atRNP9s2VxiklcUNgCzmt3T5kfs7X2C+yjmxHvOQTPjLNaNGbfC/vhjOK7aoXw0h+lBac48r5ymx1PbQA==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.363.0.tgz", - "integrity": "sha512-iWamQSpaBKg88LKuiUq8xO/7iyxJ+ORkA3qDhAwUqyTJOg87ma47yFf4ycCKqINnflc3AIGLGzBHnkBc4cMF5g==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/signature-v4": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@aws-sdk/signature-v4-crt": "^3.118.0" - }, - "peerDependenciesMeta": { - "@aws-sdk/signature-v4-crt": { - "optional": true - } - } - }, - "node_modules/@aws-sdk/smithy-client": { - "version": "3.360.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.360.0.tgz", - "integrity": "sha512-R7wbT2SkgWNEAxMekOTNcPcvBszabW2+qHjrcelbbVJNjx/2yK+MbpZI4WRSncByQMeeoW+aSUP+JgsbpiOWfw==", - "dependencies": { - "@aws-sdk/middleware-stack": "3.357.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-stream": "3.360.0", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.363.0.tgz", - "integrity": "sha512-6+0aJ1zugNgsMmhTtW2LBWxOVSaXCUk2q3xyTchSXkNzallYaRiZMRkieW+pKNntnu0g5H1T0zyfCO0tbXwxEA==", - "dependencies": { - "@aws-sdk/client-sso-oidc": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/types": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.357.0.tgz", - "integrity": "sha512-/riCRaXg3p71BeWnShrai0y0QTdXcouPSM0Cn1olZbzTf7s71aLEewrc96qFrL70XhY4XvnxMpqQh+r43XIL3g==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/url-parser": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.357.0.tgz", - "integrity": "sha512-fAaU6cFsaAba01lCRsRJiYR/LfXvX2wudyEyutBVglE4dWSoSeu3QJNxImIzTBULfbiFhz59++NQ1JUVx88IVg==", - "dependencies": { - "@aws-sdk/querystring-parser": "3.357.0", - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz", - "integrity": "sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-base64": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz", - "integrity": "sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==", - "dependencies": { - "@aws-sdk/util-buffer-from": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-buffer-from": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz", - "integrity": "sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==", - "dependencies": { - "@aws-sdk/is-array-buffer": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.357.0.tgz", - "integrity": "sha512-XHKyS5JClT9su9hDif715jpZiWHQF9gKZXER8tW0gOizU3R9cyWc9EsJ2BRhFNhi7nt/JF/CLUEc5qDx3ETbUw==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-hex-encoding": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz", - "integrity": "sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", - "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-middleware": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.357.0.tgz", - "integrity": "sha512-pV1krjZs7BdahZBfsCJMatE8kcor7GFsBOWrQgQDm9T0We5b5xPpOO2vxAD0RytBpY8Ky2ELs/+qXMv7l5fWIA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-stream": { - "version": "3.360.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream/-/util-stream-3.360.0.tgz", - "integrity": "sha512-t3naBfNesXwLis29pzSfLx2ifCn2180GiPjRaIsQP14IiVCBOeT1xaU6Dpyk7WeR/jW4cu7wGl+kbeyfNF6QmQ==", - "dependencies": { - "@aws-sdk/fetch-http-handler": "3.357.0", - "@aws-sdk/node-http-handler": "3.360.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-buffer-from": "3.310.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-uri-escape": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz", - "integrity": "sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.363.0.tgz", - "integrity": "sha512-fk9ymBUIYbxiGm99Cn+kAAXmvMCWTf/cHAcB79oCXV4ELXdPa9lN5xQhZRFNxLUeXG4OAMEuCAUUuZEj8Fnc1Q==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.363.0.tgz", - "integrity": "sha512-Fli/dvgGA9hdnQUrYb1//wNSFlK2jAfdJcfNXA6SeBYzSeH5pVGYF4kXF0FCdnMA3Fef+Zn1zAP/hw9v8VJHWQ==", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@aws-sdk/util-utf8": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz", - "integrity": "sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==", - "dependencies": { - "@aws-sdk/util-buffer-from": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", - "dependencies": { - "tslib": "^2.3.1" - } - }, - "node_modules/@aws-sdk/xml-builder": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz", - "integrity": "sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@opentdf/cli": { - "version": "1.0.1", - "resolved": "file:../../../cli/opentdf-cli-1.0.1.tgz", - "integrity": "sha512-y4cHLNxThrz+yLbp8ByYQ6qMJkRLBTgt9ytLlYiZJSHwsiJX/bNlzWuMZ3aReVo+CFgCBDXKiy2B4/qAAaEsoQ==", - "license": "BSD-3-Clause-Clear", - "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-1.0.1.tgz", - "yargs": "^17.7.2" - }, - "bin": { - "opentdf": "bin/opentdf.mjs" - } - }, - "node_modules/@opentdf/client": { - "version": "1.0.1", - "resolved": "file:../../../lib/opentdf-client-1.0.1.tgz", - "integrity": "sha512-YzC2O2b8HcyotxQLRUEuivi1ItFZ0XL0tIPzRyF1RqagynI2tMDJmA3tfP7hcsq5/BPV5VQ/Ejr0cn8P1EDenQ==", - "license": "BSD-3-Clause-Clear", - "dependencies": { - "@aws-sdk/abort-controller": "^3.357.0", - "@aws-sdk/client-s3": "^3.363.0", - "@aws-sdk/middleware-endpoint": "^3.357.0", - "@aws-sdk/protocol-http": "^3.357.0", - "@aws-sdk/smithy-client": "^3.360.0", - "axios": "^1.4.0", - "axios-retry": "^3.5.1", - "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", - "buffer-crc32": "^0.2.13", - "dpop": "^1.2.0", - "eventemitter3": "^5.0.1", - "events": "^3.3.0", - "jose": "^4.14.4", - "jsonschema": "^1.4.1", - "streamsaver": "^2.0.6", - "uuid": "~9.0.0", - "web-streams-polyfill": "^3.2.1" - } - }, - "node_modules/@smithy/abort-controller": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-1.0.1.tgz", - "integrity": "sha512-An6irzp9NCji2JtJHhrEFlDbxLwHd6c6Y9fq3ZeomyUR8BIXlGXVTxsemUSZVVgOq3166iYbYs/CrPAmgRSFLw==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/config-resolver": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-1.0.1.tgz", - "integrity": "sha512-quj0xUiEVG/UHfY82EtthR/+S5/17p3IxXArC3NFSNqryMobWbG9oWgJy2s2cgUSVZLzxevjKKvxrilK7JEDaA==", - "dependencies": { - "@smithy/types": "^1.1.0", - "@smithy/util-config-provider": "^1.0.1", - "@smithy/util-middleware": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-1.0.1.tgz", - "integrity": "sha512-hkRJoxVCh4CEt1zYOBElE+G/MV6lyx3g68hSJpesM4pwMT/bzEVo5E5XzXY+6dVq8yszeatWKbFuqCCBQte8tg==", - "dependencies": { - "@smithy/node-config-provider": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/url-parser": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/eventstream-codec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-1.0.1.tgz", - "integrity": "sha512-cpcTXQEOEs2wEvIyxW/iTHJ2m0RVqoEOTjjWEXD6SY8Gcs3FCFP6E8MXadC098tdH5ctMIUXc8POXyMpxzGnjw==", - "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^1.1.0", - "@smithy/util-hex-encoding": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "node_modules/@smithy/eventstream-serde-browser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-1.0.1.tgz", - "integrity": "sha512-oc8vxe+AU2RzvXH/Ehh0TzM/Nsw3I3ywu7V3qaCzqdkBIntAwK9JGZqcSDsqTK0WxZKBRgFIEwopcuZ2slVnFQ==", - "dependencies": { - "@smithy/eventstream-serde-universal": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-1.0.1.tgz", - "integrity": "sha512-TJwaXima0djnNY819utO1j93qZHaheFH1bhHxBkMrImtEOuXY48Tjma/L2m8swkIq8dy8jFC9hrYOkD0eYHkFA==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-1.0.1.tgz", - "integrity": "sha512-JEj8w7IRs4l+kcwKxbv3pNuu8n7ORC4pMFrIOrM4rERzrRnI7vMNTRzvAPGYA53rqm/Y9tBA9dw4C+H6hLXcsA==", - "dependencies": { - "@smithy/eventstream-serde-universal": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-1.0.1.tgz", - "integrity": "sha512-c6m9DH7m6D2S93dof4wSxysaGSQdauO20TNcSePzrgHd4rkTnz5pqZ1a7Pt22q2SKf09SvTugq5cV2Sy4r8zHw==", - "dependencies": { - "@smithy/eventstream-codec": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-1.0.1.tgz", - "integrity": "sha512-/e2A8eOMk4FVZBQ0o6uF/ttLtFZcmsK5MIwDu1UE3crM4pCAIP19Ul8U9rdLlHhIu81X4AcJmSw55RDSpVRL/w==", - "dependencies": { - "@smithy/protocol-http": "^1.1.0", - "@smithy/querystring-builder": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-base64": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "node_modules/@smithy/hash-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-1.0.1.tgz", - "integrity": "sha512-eCz08BySBcOjVObjbRAS/XMKUGY4ujnuS+GoWeEpzpCSKDnO8/YQ0rStRt4C0llRmhApizYc1tK9DiJwfvXcBg==", - "dependencies": { - "@smithy/types": "^1.1.0", - "@smithy/util-buffer-from": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/invalid-dependency": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-1.0.1.tgz", - "integrity": "sha512-kib63GFlAzRn/wf8M0cRWrZA1cyOy5IvpTkLavCY782DPFMP0EaEeD6VrlNIOvD6ncf7uCJ68HqckhwK1qLT3g==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-1.0.1.tgz", - "integrity": "sha512-fHSTW70gANnzPYWNDcWkPXpp+QMbHhKozbQm/+Denkhp4gwSiPuAovWZRpJa9sXO+Q4dOnNzYN2max1vTCEroA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/middleware-content-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-1.0.1.tgz", - "integrity": "sha512-vWWigayk5i2cFp9xPX5vdzHyK+P0t/xZ3Ovp4Ss+c8JQ1Hlq2kpJZVWtTKsmdfND5rVo5lu0kD5wgAMUCcmuhw==", - "dependencies": { - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-1.0.2.tgz", - "integrity": "sha512-F3CyXgjtDI4quGFkDmVNytt6KMwlzzeMxtopk6Edue4uKdKcMC1vUmoRS5xTbFzKDDp4XwpnEV7FshPaL3eCPw==", - "dependencies": { - "@smithy/middleware-serde": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-middleware": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/middleware-retry": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-1.0.3.tgz", - "integrity": "sha512-ZRsjG8adtxQ456FULPqPFmWtrW44Fq8IgdQvQB+rC2RSho3OUzS+TiEIwb5Zs6rf2IoewITKtfdtsUZcxXO0ng==", - "dependencies": { - "@smithy/protocol-http": "^1.1.0", - "@smithy/service-error-classification": "^1.0.2", - "@smithy/types": "^1.1.0", - "@smithy/util-middleware": "^1.0.1", - "@smithy/util-retry": "^1.0.3", - "tslib": "^2.5.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/middleware-retry/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@smithy/middleware-serde": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-1.0.1.tgz", - "integrity": "sha512-bn5lWk8UUeXFCQfkrNErz5SbeNd+2hgYegHMLsOLPt4URDIsyREar6wMsdsR+8UCdgR5s8udG3Zalgc7puizIQ==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/middleware-stack": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-1.0.1.tgz", - "integrity": "sha512-T6+gsAO1JYamOJqmORCrByDeQ/NB+ggjHb33UDOgdX4xIjXz/FB/3UqHgQu6PL1cSFrK+i4oteDIwqARDs/Szw==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/node-config-provider": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-1.0.1.tgz", - "integrity": "sha512-FRxifH/J2SgOaVLihIqBFuGhiHR/NfzbZYp5nYO7BGgT/gc/f9nAuuRJcEy/hwO3aI6ThyG5apH4tGec6A2sCw==", - "dependencies": { - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-1.0.2.tgz", - "integrity": "sha512-PzPrGRSt3kNuruLCeR4ffJp57ZLVnIukMXVL3Ppr65ZoxiE+HBsOVAa/Z/T+4HzjCM6RaXnnmB8YKfsDjlb0iA==", - "dependencies": { - "@smithy/abort-controller": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/querystring-builder": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/property-provider": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-1.0.1.tgz", - "integrity": "sha512-3EG/61Ls1MrgEaafpltXBJHSqFPqmTzEX7QKO7lOEHuYGmGYzZ08t1SsTgd1vM74z0IihoZyGPynZ7WmXKvTeg==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.1.0.tgz", - "integrity": "sha512-H5y/kZOqfJSqRkwtcAoVbqONmhdXwSgYNJ1Glk5Ry8qlhVVy5qUzD9EklaCH8/XLnoCsLO/F/Giee8MIvaBRkg==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/querystring-builder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-1.0.1.tgz", - "integrity": "sha512-J5Tzkw1PMtu01h6wl+tlN5vsyROmS6/z5lEfNlLo/L4ELHeVkQ4Q0PEIjDddPLfjVLCm8biQTESE5GCMixSRNQ==", - "dependencies": { - "@smithy/types": "^1.1.0", - "@smithy/util-uri-escape": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/querystring-parser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-1.0.1.tgz", - "integrity": "sha512-zauxdMc3cwxoLitI5DZqH7xN6Fk0mwRxrUMAETbav2j6Se2U0UGak/55rZcDg2yGzOURaLYi5iOm1gHr98P+Bw==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/service-error-classification": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-1.0.2.tgz", - "integrity": "sha512-Q5CCuzYL5FGo6Rr/O+lZxXHm2hrRgbmMn8MgyjqZUWZg20COg20DuNtIbho2iht6CoB7jOpmpBqhWizLlzUZgg==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-1.0.1.tgz", - "integrity": "sha512-EztziuIPoNronENGqh+MWVKJErA4rJpaPzJCPukzBeEoG2USka0/q4B5Mr/1zszOnrb49fPNh4u3u5LfiH7QzA==", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-1.0.1.tgz", - "integrity": "sha512-2D69je14ou1vBTnAQeysSK4QVMm0j3WHS3MDg/DnHnFFcXRCzVl/xAARO7POD8+fpi4tMFPs8Z4hzo1Zw40L0Q==", - "dependencies": { - "@smithy/eventstream-codec": "^1.0.1", - "@smithy/is-array-buffer": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-hex-encoding": "^1.0.1", - "@smithy/util-middleware": "^1.0.1", - "@smithy/util-uri-escape": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-1.0.3.tgz", - "integrity": "sha512-Wh1mNP/1yUZK0uYkgCQ6NMxpBT3Fmc45TMdUfOlH1xD2zGYL7U4yDHFOhEZdi/suyjaelFobXB2p9pPIw6LjRQ==", - "dependencies": { - "@smithy/middleware-stack": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-stream": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.1.0.tgz", - "integrity": "sha512-KzmvisMmuwD2jZXuC9e65JrgsZM97y5NpDU7g347oB+Q+xQLU6hQZ5zFNNbEfwwOJHoOvEVTna+dk1h/lW7alw==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/url-parser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-1.0.1.tgz", - "integrity": "sha512-33vWEtE6HzmwjEcEb4I58XMLRAchwPS93YhfDyXAXr1jwDCzfXmMayQwwpyW847rpWj0XJimxqia8q0z+k/ybw==", - "dependencies": { - "@smithy/querystring-parser": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@smithy/util-base64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-1.0.1.tgz", - "integrity": "sha512-rJcpRi/yUi6TyCEkjdTH86/ExBuKlfctEXhG9/4gMJ3/cnPcHJJnr0mQ9evSEO+3DbpT/Nxq90bcTBdTIAmCig==", - "dependencies": { - "@smithy/util-buffer-from": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-body-length-browser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-1.0.1.tgz", - "integrity": "sha512-Pdp744fmF7E1NWoSb7256Anhm8eYoCubvosdMwXzOnHuPRVbDa15pKUz2027K3+jrfGpXo1r+MnDerajME1Osw==", - "dependencies": { - "tslib": "^2.5.0" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-1.0.1.tgz", - "integrity": "sha512-4PIHjDFwG07SNensAiVq/CJmubEVuwclWSYOTNtzBNTvxOeGLznvygkGYgPzS3erByT8C4S9JvnLYgtrsVV3nQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-buffer-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-1.0.1.tgz", - "integrity": "sha512-363N7Wq0ceUgE5lLe6kaR6GlJs2/m4r9V6bRMfIszb6P1FZbbRRM2FQYUWWPFSsRymm9mJL18b3fjiVsIvhDGg==", - "dependencies": { - "@smithy/is-array-buffer": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-config-provider": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-1.0.1.tgz", - "integrity": "sha512-4Qy38Oy5/q43MpTwCLV1P+7NeaOp4W2etQDxMjgEeRlOyGGNlgttn0syi4g2rVSukFVqQ6FbeRs5xbnFmS6kaQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-1.0.1.tgz", - "integrity": "sha512-/9ObwNch4Z/NJYfkO4AvqBWku60Ju+c2Ck32toPOLmWe/V6eI9FLn8C1abri+GxDRCkLIqvkaWU1lgZ3nWZIIw==", - "dependencies": { - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-1.0.1.tgz", - "integrity": "sha512-XQM3KvqRLgv7bwAzVkXTITkOmcOINoG9icJiGT8FA0zV35lY5UvyIsg5kHw01xigQS8ufa/33AwG3ZoXip+V5g==", - "dependencies": { - "@smithy/config-resolver": "^1.0.1", - "@smithy/credential-provider-imds": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-hex-encoding": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-1.0.1.tgz", - "integrity": "sha512-FPTtMz/t02/rbfq5Pdll/TWUYP+GVFLCQNr+DgifrLzVRU0g8rdRjyFpDh8nPTdkDDusTTo9P1bepAYj68s0eA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-middleware": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-1.0.1.tgz", - "integrity": "sha512-u9akN3Zmbr0vZH4F+2iehG7cFg+3fvDfnvS/hhsXH4UHuhqiQ+ADefibnLzPoz1pooY7rvwaQ/TVHyJmZHdLdQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-retry": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-1.0.3.tgz", - "integrity": "sha512-gYQnZDD8I2XJFspVwUISyukjPWVikTzKR0IdG8hCWYPTpeULFl1o6yzXlT5SL63TBkuEYl0R1/93cdNtMiNnoA==", - "dependencies": { - "@smithy/service-error-classification": "^1.0.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@smithy/util-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-1.0.1.tgz", - "integrity": "sha512-4aBCIz35aZAnt2Rbq341KrnUzGhWv2/Zu8HouJqYLvSWCzlrvsNCGlXP4e70Kjzcw8hSuuCNtdUICwQ5qUWLxg==", - "dependencies": { - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/types": "^1.1.0", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-buffer-from": "^1.0.1", - "@smithy/util-hex-encoding": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-uri-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-1.0.1.tgz", - "integrity": "sha512-IJUrRnXKEIc+PKnU1XzTsIENVR+60jUDPBP3iWX/EvuuT3Xfob47x1FGUe2c3yMXNuU6ax8VDk27hL5LKNoehQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-utf8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-1.0.1.tgz", - "integrity": "sha512-iX6XHpjh4DFEUIBSKp2tjy3pYnLQMsJ62zYi1BVAC0kobE6p8AVpiZnxsU3ZkgQatAsUaEspFHUZ7CL7oSqaPQ==", - "dependencies": { - "@smithy/util-buffer-from": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-waiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-1.0.1.tgz", - "integrity": "sha512-dsn8O0s3pFIgxFzySLe1dv0w4tEQizEP6UqbgZ4r/Kar4n8pSdrPi6DJg8BzXwkwEIZpMtV4/nhSeGZ7HksDXA==", - "dependencies": { - "@smithy/abort-controller": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axios-retry": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.5.1.tgz", - "integrity": "sha512-mQRJ4IyAUnYig14BQ4MnnNHHuH1cNH7NW4JxEUD6mNJwK6pwOY66wKLCwZ6Y0o3POpfStalqRC+J4+Hnn6Om7w==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "is-retry-allowed": "^2.2.0" - } - }, - "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" - } - ] - }, - "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, - "node_modules/browser-fs-access": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "engines": { - "node": "*" - } - }, - "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==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "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==" - }, - "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==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dpop": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.2.0.tgz", - "integrity": "sha512-TWdzNSSYWVAT7UKGE+MJZBinSiVQGcElMaAV4xgOgPJtWcNfSefkHfc7RCYY0H5CZvnNo180xxkVSeYAtaFaBQ==", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "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==" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-xml-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", - "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", - "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/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==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "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==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "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" - } - ] - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-retry-allowed": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", - "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jose": { - "version": "4.14.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", - "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "engines": { - "node": "*" - } - }, - "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==", - "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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/streamsaver": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/streamsaver/-/streamsaver-2.0.6.tgz", - "integrity": "sha512-LK4e7TfCV8HzuM0PKXuVUfKyCB1FtT9L0EGxsFk5Up8njj0bXK8pJM9+Wq2Nya7/jslmCQwRK39LFm55h7NBTw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - } - ] - }, - "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==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, - "node_modules/tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" - }, - "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "engines": { - "node": ">= 8" - } - }, - "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==", - "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/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "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" - }, - "engines": { - "node": ">=12" - } - }, - "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==", - "engines": { - "node": ">=12" - } - } - }, - "dependencies": { - "@aws-crypto/crc32": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", - "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", - "requires": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/crc32c": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", - "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", - "requires": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/ie11-detection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", - "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", - "requires": { - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/sha1-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", - "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", - "requires": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/sha256-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", - "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", - "requires": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/sha256-js": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/sha256-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", - "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", - "requires": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/supports-web-crypto": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", - "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", - "requires": { - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/util": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", - "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-sdk/abort-controller": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.357.0.tgz", - "integrity": "sha512-nQYDJon87quPwt2JZJwUN2GFKJnvE5kWb6tZP4xb5biSGUKBqDQo06oYed7yokatCuCMouIXV462aN0fWODtOw==", - "requires": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/chunked-blob-reader": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.310.0.tgz", - "integrity": "sha512-CrJS3exo4mWaLnWxfCH+w88Ou0IcAZSIkk4QbmxiHl/5Dq705OLoxf4385MVyExpqpeVJYOYQ2WaD8i/pQZ2fg==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/client-s3": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.363.0.tgz", - "integrity": "sha512-LNnfg/t8wG5Fqj6l+PSV/t+IXDq9r3Kj9jEHn84513+p7bewXYSSreSpmLjG8OcKuMfHc9EJGNQ3DkMyFaLoWg==", - "requires": { - "@aws-crypto/sha1-browser": "3.0.0", - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.363.0", - "@aws-sdk/credential-provider-node": "3.363.0", - "@aws-sdk/hash-blob-browser": "3.357.0", - "@aws-sdk/hash-stream-node": "3.357.0", - "@aws-sdk/md5-js": "3.357.0", - "@aws-sdk/middleware-bucket-endpoint": "3.363.0", - "@aws-sdk/middleware-expect-continue": "3.363.0", - "@aws-sdk/middleware-flexible-checksums": "3.363.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-location-constraint": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-sdk-s3": "3.363.0", - "@aws-sdk/middleware-signing": "3.363.0", - "@aws-sdk/middleware-ssec": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/signature-v4-multi-region": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@aws-sdk/xml-builder": "3.310.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/eventstream-serde-browser": "^1.0.1", - "@smithy/eventstream-serde-config-resolver": "^1.0.1", - "@smithy/eventstream-serde-node": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.2", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/protocol-http": "^1.0.1", - "@smithy/smithy-client": "^1.0.3", - "@smithy/types": "^1.0.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.2", - "@smithy/util-stream": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "@smithy/util-waiter": "^1.0.1", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/client-sso": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.363.0.tgz", - "integrity": "sha512-PZ+HfKSgS4hlMnJzG+Ev8/mgHd/b/ETlJWPSWjC/f2NwVoBQkBnqHjdyEx7QjF6nksJozcVh5Q+kkYLKc/QwBQ==", - "requires": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.2", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/protocol-http": "^1.0.1", - "@smithy/smithy-client": "^1.0.3", - "@smithy/types": "^1.0.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.2", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/client-sso-oidc": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.363.0.tgz", - "integrity": "sha512-V3Ebiq/zNtDS/O92HUWGBa7MY59RYSsqWd+E0XrXv6VYTA00RlMTbNcseivNgp2UghOgB9a20Nkz6EqAeIN+RQ==", - "requires": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.2", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/protocol-http": "^1.0.1", - "@smithy/smithy-client": "^1.0.3", - "@smithy/types": "^1.0.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.2", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/client-sts": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.363.0.tgz", - "integrity": "sha512-0jj14WvBPJQ8xr72cL0mhlmQ90tF0O0wqXwSbtog6PsC8+KDE6Yf+WsxsumyI8E5O8u3eYijBL+KdqG07F/y/w==", - "requires": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/credential-provider-node": "3.363.0", - "@aws-sdk/middleware-host-header": "3.363.0", - "@aws-sdk/middleware-logger": "3.363.0", - "@aws-sdk/middleware-recursion-detection": "3.363.0", - "@aws-sdk/middleware-sdk-sts": "3.363.0", - "@aws-sdk/middleware-signing": "3.363.0", - "@aws-sdk/middleware-user-agent": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.363.0", - "@aws-sdk/util-user-agent-node": "3.363.0", - "@smithy/config-resolver": "^1.0.1", - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/hash-node": "^1.0.1", - "@smithy/invalid-dependency": "^1.0.1", - "@smithy/middleware-content-length": "^1.0.1", - "@smithy/middleware-endpoint": "^1.0.1", - "@smithy/middleware-retry": "^1.0.1", - "@smithy/middleware-serde": "^1.0.1", - "@smithy/middleware-stack": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/node-http-handler": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/smithy-client": "^1.0.2", - "@smithy/types": "^1.1.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-body-length-browser": "^1.0.1", - "@smithy/util-body-length-node": "^1.0.1", - "@smithy/util-defaults-mode-browser": "^1.0.1", - "@smithy/util-defaults-mode-node": "^1.0.1", - "@smithy/util-retry": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/credential-provider-env": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.363.0.tgz", - "integrity": "sha512-VAQ3zITT2Q0acht0HezouYnMFKZ2vIOa20X4zQA3WI0HfaP4D6ga6KaenbDcb/4VFiqfqiRHfdyXHP0ThcDRMA==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/credential-provider-ini": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.363.0.tgz", - "integrity": "sha512-ZYN+INoqyX5FVC3rqUxB6O8nOWkr0gHRRBm1suoOlmuFJ/WSlW/uUGthRBY5x1AQQnBF8cpdlxZzGHd41lFVNw==", - "requires": { - "@aws-sdk/credential-provider-env": "3.363.0", - "@aws-sdk/credential-provider-process": "3.363.0", - "@aws-sdk/credential-provider-sso": "3.363.0", - "@aws-sdk/credential-provider-web-identity": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/credential-provider-imds": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/credential-provider-node": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.363.0.tgz", - "integrity": "sha512-C1qXFIN2yMxD6pGgug0vR1UhScOki6VqdzuBHzXZAGu7MOjvgHNdscEcb3CpWnITHaPL2ztkiw75T1sZ7oIgQg==", - "requires": { - "@aws-sdk/credential-provider-env": "3.363.0", - "@aws-sdk/credential-provider-ini": "3.363.0", - "@aws-sdk/credential-provider-process": "3.363.0", - "@aws-sdk/credential-provider-sso": "3.363.0", - "@aws-sdk/credential-provider-web-identity": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/credential-provider-imds": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/credential-provider-process": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.363.0.tgz", - "integrity": "sha512-fOKAINU7Rtj2T8pP13GdCt+u0Ml3gYynp8ki+1jMZIQ+Ju/MdDOqZpKMFKicMn3Z1ttUOgqr+grUdus6z8ceBQ==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/credential-provider-sso": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.363.0.tgz", - "integrity": "sha512-5RUZ5oM0lwZSo3EehT0dXggOjgtxFogpT3cZvoLGtIwrPBvm8jOQPXQUlaqCj10ThF1sYltEyukz/ovtDwYGew==", - "requires": { - "@aws-sdk/client-sso": "3.363.0", - "@aws-sdk/token-providers": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/credential-provider-web-identity": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.363.0.tgz", - "integrity": "sha512-Z6w7fjgy79pAax580wdixbStQw10xfyZ+hOYLcPudoYFKjoNx0NQBejg5SwBzCF/HQL23Ksm9kDfbXDX9fkPhA==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/fetch-http-handler": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.357.0.tgz", - "integrity": "sha512-5sPloTO8y8fAnS/6/Sfp/aVoL9zuhzkLdWBORNzMazdynVNEzWKWCPZ27RQpgkaCDHiXjqUY4kfuFXAGkvFfDQ==", - "requires": { - "@aws-sdk/protocol-http": "3.357.0", - "@aws-sdk/querystring-builder": "3.357.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-base64": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/hash-blob-browser": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.357.0.tgz", - "integrity": "sha512-RDd6UgrGHDmleTnXM9LRSSVa69euSAG2mlNhZMEDWk3OFseXVYqBDaqroVbQ01rM2UAe8MeBFchlV9OmxuVgvw==", - "requires": { - "@aws-sdk/chunked-blob-reader": "3.310.0", - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/hash-stream-node": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.357.0.tgz", - "integrity": "sha512-KZjN1VAw1KHNp+xKVOWBGS+MpaYQTjZFD5f+7QQqW4TfbAkFFwIAEYIHq5Q8Gw+jVh0h61OrV/LyW3J2PVzc+w==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/is-array-buffer": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz", - "integrity": "sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/md5-js": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.357.0.tgz", - "integrity": "sha512-to42sFAL7KgV/X9X40LLfEaNMHMGQL6/7mPMVCL/W2BZf3zw5OTl3lAaNyjXA+gO5Uo4lFEiQKAQVKNbr8b8Nw==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-bucket-endpoint": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.363.0.tgz", - "integrity": "sha512-kR8+0X50zslpzRW29q4JbpPMadE1z39ZfGwPaBLKpoWvSGt4x+75FaoK71TH7urPPoFyD2Y+XKGA6YRYTUNHSQ==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "@smithy/util-config-provider": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-endpoint": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.357.0.tgz", - "integrity": "sha512-ScJi0SL8X/Lyi0Fp5blg0QN/Z6PoRwV/ZJXd8dQkXSznkbSvJHfqPP0xk/w3GcQ1TKsu5YEPfeYy8ejcq+7Pgg==", - "requires": { - "@aws-sdk/middleware-serde": "3.357.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/url-parser": "3.357.0", - "@aws-sdk/util-middleware": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-expect-continue": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.363.0.tgz", - "integrity": "sha512-I88xneZp6jRwySmIl9uI7eZCcTsqRVnTDfUr1JiXt7zonqNNm80PVYMs6pwaw7t97ec1AQJcsONjuXZyCMnu5g==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-flexible-checksums": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.363.0.tgz", - "integrity": "sha512-FBYmrMRX01uNximNN0WLgpf97GN4xNTLaKsDlkjYRWKJ+J97ICkvLG0FcSu7+SNCpCdJJBeQ5tRVOPVpUu6nmA==", - "requires": { - "@aws-crypto/crc32": "3.0.0", - "@aws-crypto/crc32c": "3.0.0", - "@aws-sdk/types": "3.357.0", - "@smithy/is-array-buffer": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-host-header": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.363.0.tgz", - "integrity": "sha512-FobpclDCf5Y1ueyJDmb9MqguAdPssNMlnqWQpujhYVABq69KHu73fSCWSauFPUrw7YOpV8kG1uagDF0POSxHzA==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-location-constraint": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.363.0.tgz", - "integrity": "sha512-piNzpNNI/fChSGOZxcq/2msN2qFUSEAbhqs91zbcpv8CEPekVLc4W9laXCG764BEMyfG97ZU8MtzwHeMhELhBA==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-logger": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.363.0.tgz", - "integrity": "sha512-SSGgthScYnFGTOw8EzbkvquqweFmvn7uJihkpFekbtBNGC/jGOGO+8ziHjTQ8t/iI/YKubEwv+LMi0f77HKSEg==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-recursion-detection": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.363.0.tgz", - "integrity": "sha512-MWD/57QgI/N7fG8rtzDTUdSqNpYohQfgj9XCFAoVeI/bU4usrkOrew43L4smJG4XrDxlNT8lSJlDtd64tuiUZA==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-sdk-s3": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.363.0.tgz", - "integrity": "sha512-npC8vLCero+vULizrK0QPjNanWbgH4A/2Llc1nO8N005uvUe7co6WglILF2W3guZrFk/0uGEdX67OnLxUD97pw==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-sdk-sts": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.363.0.tgz", - "integrity": "sha512-1yy2Ac50FO8BrODaw5bPWvVrRhaVLqXTFH6iHB+dJLPUkwtY5zLM3Mp+9Ilm7kME+r7oIB1wuO6ZB1Lf4ZszIw==", - "requires": { - "@aws-sdk/middleware-signing": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-serde": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.357.0.tgz", - "integrity": "sha512-bGI4kYuuEsFjlANbyJLyy4AovETnyf/SukgLOG7Qjbua+ZGuzvRhMsk21mBKKGrnsTO4PmtieJo6xClThGAN8g==", - "requires": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-signing": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.363.0.tgz", - "integrity": "sha512-/7qia715pt9JKYIPDGu22WmdZxD8cfF/5xB+1kmILg7ZtjO0pPuTaCNJ7xiIuFd7Dn7JXp5lop08anX/GOhNRQ==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/signature-v4": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-middleware": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-ssec": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.363.0.tgz", - "integrity": "sha512-pN+QN1rMShYpJnTJSCIYnNRhD0S8xSZsTn6ThgcO559Xiwz5LMHFOfOXUCEyxtbVW5kMHLUh3w101AMUKae99A==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-stack": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.357.0.tgz", - "integrity": "sha512-nNV+jfwGwmbOGZujAY/U8AW3EbVlxa9DJDLz3TPp/39o6Vu5KEzHJyDDNreo2k9V/TMvV+nOzHafufgPdagv7w==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/middleware-user-agent": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.363.0.tgz", - "integrity": "sha512-ri8YaQvXP6odteVTMfxPqFR26Q0h9ejtqhUDv47P34FaKXedEM4nC6ix6o+5FEYj6l8syGyktftZ5O70NoEhug==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/node-http-handler": { - "version": "3.360.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.360.0.tgz", - "integrity": "sha512-oMsXdMmNwHpUbebETO44bq0N4SocEMGfPjYNUTRs8md7ita5fuFd2qFuvf+ZRt6iVcGWluIqmF8DidD+b7d+TA==", - "requires": { - "@aws-sdk/abort-controller": "3.357.0", - "@aws-sdk/protocol-http": "3.357.0", - "@aws-sdk/querystring-builder": "3.357.0", - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/protocol-http": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.357.0.tgz", - "integrity": "sha512-w1JHiI50VEea7duDeAspUiKJmmdIQblvRyjVMOqWA6FIQAyDVuEiPX7/MdQr0ScxhtRQxHbP0I4MFyl7ctRQvA==", - "requires": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/querystring-builder": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.357.0.tgz", - "integrity": "sha512-aQcicqB6Y2cNaXPPwunz612a01SMiQQPsdz632F/3Lzn0ua82BJKobHOtaiTUlmVJ5Q4/EAeNfwZgL7tTUNtDQ==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/querystring-parser": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.357.0.tgz", - "integrity": "sha512-Svvq+atRNP9s2VxiklcUNgCzmt3T5kfs7X2C+yjmxHvOQTPjLNaNGbfC/vhjOK7aoXw0h+lBac48r5ymx1PbQA==", - "requires": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/signature-v4-multi-region": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.363.0.tgz", - "integrity": "sha512-iWamQSpaBKg88LKuiUq8xO/7iyxJ+ORkA3qDhAwUqyTJOg87ma47yFf4ycCKqINnflc3AIGLGzBHnkBc4cMF5g==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/signature-v4": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/smithy-client": { - "version": "3.360.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.360.0.tgz", - "integrity": "sha512-R7wbT2SkgWNEAxMekOTNcPcvBszabW2+qHjrcelbbVJNjx/2yK+MbpZI4WRSncByQMeeoW+aSUP+JgsbpiOWfw==", - "requires": { - "@aws-sdk/middleware-stack": "3.357.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-stream": "3.360.0", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/token-providers": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.363.0.tgz", - "integrity": "sha512-6+0aJ1zugNgsMmhTtW2LBWxOVSaXCUk2q3xyTchSXkNzallYaRiZMRkieW+pKNntnu0g5H1T0zyfCO0tbXwxEA==", - "requires": { - "@aws-sdk/client-sso-oidc": "3.363.0", - "@aws-sdk/types": "3.357.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/types": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.357.0.tgz", - "integrity": "sha512-/riCRaXg3p71BeWnShrai0y0QTdXcouPSM0Cn1olZbzTf7s71aLEewrc96qFrL70XhY4XvnxMpqQh+r43XIL3g==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/url-parser": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.357.0.tgz", - "integrity": "sha512-fAaU6cFsaAba01lCRsRJiYR/LfXvX2wudyEyutBVglE4dWSoSeu3QJNxImIzTBULfbiFhz59++NQ1JUVx88IVg==", - "requires": { - "@aws-sdk/querystring-parser": "3.357.0", - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-arn-parser": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz", - "integrity": "sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-base64": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz", - "integrity": "sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==", - "requires": { - "@aws-sdk/util-buffer-from": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-buffer-from": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz", - "integrity": "sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==", - "requires": { - "@aws-sdk/is-array-buffer": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-endpoints": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.357.0.tgz", - "integrity": "sha512-XHKyS5JClT9su9hDif715jpZiWHQF9gKZXER8tW0gOizU3R9cyWc9EsJ2BRhFNhi7nt/JF/CLUEc5qDx3ETbUw==", - "requires": { - "@aws-sdk/types": "3.357.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-hex-encoding": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz", - "integrity": "sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-locate-window": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", - "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-middleware": { - "version": "3.357.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.357.0.tgz", - "integrity": "sha512-pV1krjZs7BdahZBfsCJMatE8kcor7GFsBOWrQgQDm9T0We5b5xPpOO2vxAD0RytBpY8Ky2ELs/+qXMv7l5fWIA==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-stream": { - "version": "3.360.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream/-/util-stream-3.360.0.tgz", - "integrity": "sha512-t3naBfNesXwLis29pzSfLx2ifCn2180GiPjRaIsQP14IiVCBOeT1xaU6Dpyk7WeR/jW4cu7wGl+kbeyfNF6QmQ==", - "requires": { - "@aws-sdk/fetch-http-handler": "3.357.0", - "@aws-sdk/node-http-handler": "3.360.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-buffer-from": "3.310.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-uri-escape": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz", - "integrity": "sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-user-agent-browser": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.363.0.tgz", - "integrity": "sha512-fk9ymBUIYbxiGm99Cn+kAAXmvMCWTf/cHAcB79oCXV4ELXdPa9lN5xQhZRFNxLUeXG4OAMEuCAUUuZEj8Fnc1Q==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/types": "^1.1.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-user-agent-node": { - "version": "3.363.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.363.0.tgz", - "integrity": "sha512-Fli/dvgGA9hdnQUrYb1//wNSFlK2jAfdJcfNXA6SeBYzSeH5pVGYF4kXF0FCdnMA3Fef+Zn1zAP/hw9v8VJHWQ==", - "requires": { - "@aws-sdk/types": "3.357.0", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-utf8": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz", - "integrity": "sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==", - "requires": { - "@aws-sdk/util-buffer-from": "3.310.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", - "requires": { - "tslib": "^2.3.1" - } - }, - "@aws-sdk/xml-builder": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz", - "integrity": "sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", - "requires": { - "regenerator-runtime": "^0.13.11" - } - }, - "@opentdf/cli": { - "version": "file:../../../cli/opentdf-cli-1.0.1.tgz", - "integrity": "sha512-y4cHLNxThrz+yLbp8ByYQ6qMJkRLBTgt9ytLlYiZJSHwsiJX/bNlzWuMZ3aReVo+CFgCBDXKiy2B4/qAAaEsoQ==", - "requires": { - "@opentdf/client": "file:../lib/opentdf-client-1.0.1.tgz", - "yargs": "^17.7.2" - } - }, - "@opentdf/client": { - "version": "file:../lib/opentdf-client-1.0.1.tgz", - "integrity": "sha512-YzC2O2b8HcyotxQLRUEuivi1ItFZ0XL0tIPzRyF1RqagynI2tMDJmA3tfP7hcsq5/BPV5VQ/Ejr0cn8P1EDenQ==", - "requires": { - "@aws-sdk/abort-controller": "^3.357.0", - "@aws-sdk/client-s3": "^3.363.0", - "@aws-sdk/middleware-endpoint": "^3.357.0", - "@aws-sdk/protocol-http": "^3.357.0", - "@aws-sdk/smithy-client": "^3.360.0", - "axios": "^1.4.0", - "axios-retry": "^3.5.1", - "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", - "buffer-crc32": "^0.2.13", - "dpop": "^1.2.0", - "eventemitter3": "^5.0.1", - "events": "^3.3.0", - "jose": "^4.14.4", - "jsonschema": "^1.4.1", - "streamsaver": "^2.0.6", - "uuid": "~9.0.0", - "web-streams-polyfill": "^3.2.1" - } - }, - "@smithy/abort-controller": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-1.0.1.tgz", - "integrity": "sha512-An6irzp9NCji2JtJHhrEFlDbxLwHd6c6Y9fq3ZeomyUR8BIXlGXVTxsemUSZVVgOq3166iYbYs/CrPAmgRSFLw==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@smithy/config-resolver": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-1.0.1.tgz", - "integrity": "sha512-quj0xUiEVG/UHfY82EtthR/+S5/17p3IxXArC3NFSNqryMobWbG9oWgJy2s2cgUSVZLzxevjKKvxrilK7JEDaA==", - "requires": { - "@smithy/types": "^1.1.0", - "@smithy/util-config-provider": "^1.0.1", - "@smithy/util-middleware": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@smithy/credential-provider-imds": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-1.0.1.tgz", - "integrity": "sha512-hkRJoxVCh4CEt1zYOBElE+G/MV6lyx3g68hSJpesM4pwMT/bzEVo5E5XzXY+6dVq8yszeatWKbFuqCCBQte8tg==", - "requires": { - "@smithy/node-config-provider": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/url-parser": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@smithy/eventstream-codec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-1.0.1.tgz", - "integrity": "sha512-cpcTXQEOEs2wEvIyxW/iTHJ2m0RVqoEOTjjWEXD6SY8Gcs3FCFP6E8MXadC098tdH5ctMIUXc8POXyMpxzGnjw==", - "requires": { - "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^1.1.0", - "@smithy/util-hex-encoding": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@smithy/eventstream-serde-browser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-1.0.1.tgz", - "integrity": "sha512-oc8vxe+AU2RzvXH/Ehh0TzM/Nsw3I3ywu7V3qaCzqdkBIntAwK9JGZqcSDsqTK0WxZKBRgFIEwopcuZ2slVnFQ==", - "requires": { - "@smithy/eventstream-serde-universal": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@smithy/eventstream-serde-config-resolver": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-1.0.1.tgz", - "integrity": "sha512-TJwaXima0djnNY819utO1j93qZHaheFH1bhHxBkMrImtEOuXY48Tjma/L2m8swkIq8dy8jFC9hrYOkD0eYHkFA==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@smithy/eventstream-serde-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-1.0.1.tgz", - "integrity": "sha512-JEj8w7IRs4l+kcwKxbv3pNuu8n7ORC4pMFrIOrM4rERzrRnI7vMNTRzvAPGYA53rqm/Y9tBA9dw4C+H6hLXcsA==", - "requires": { - "@smithy/eventstream-serde-universal": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@smithy/eventstream-serde-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-1.0.1.tgz", - "integrity": "sha512-c6m9DH7m6D2S93dof4wSxysaGSQdauO20TNcSePzrgHd4rkTnz5pqZ1a7Pt22q2SKf09SvTugq5cV2Sy4r8zHw==", - "requires": { - "@smithy/eventstream-codec": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@smithy/fetch-http-handler": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-1.0.1.tgz", - "integrity": "sha512-/e2A8eOMk4FVZBQ0o6uF/ttLtFZcmsK5MIwDu1UE3crM4pCAIP19Ul8U9rdLlHhIu81X4AcJmSw55RDSpVRL/w==", - "requires": { - "@smithy/protocol-http": "^1.1.0", - "@smithy/querystring-builder": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-base64": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@smithy/hash-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-1.0.1.tgz", - "integrity": "sha512-eCz08BySBcOjVObjbRAS/XMKUGY4ujnuS+GoWeEpzpCSKDnO8/YQ0rStRt4C0llRmhApizYc1tK9DiJwfvXcBg==", - "requires": { - "@smithy/types": "^1.1.0", - "@smithy/util-buffer-from": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@smithy/invalid-dependency": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-1.0.1.tgz", - "integrity": "sha512-kib63GFlAzRn/wf8M0cRWrZA1cyOy5IvpTkLavCY782DPFMP0EaEeD6VrlNIOvD6ncf7uCJ68HqckhwK1qLT3g==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@smithy/is-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-1.0.1.tgz", - "integrity": "sha512-fHSTW70gANnzPYWNDcWkPXpp+QMbHhKozbQm/+Denkhp4gwSiPuAovWZRpJa9sXO+Q4dOnNzYN2max1vTCEroA==", - "requires": { - "tslib": "^2.5.0" - } - }, - "@smithy/middleware-content-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-1.0.1.tgz", - "integrity": "sha512-vWWigayk5i2cFp9xPX5vdzHyK+P0t/xZ3Ovp4Ss+c8JQ1Hlq2kpJZVWtTKsmdfND5rVo5lu0kD5wgAMUCcmuhw==", - "requires": { - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "@smithy/middleware-endpoint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-1.0.2.tgz", - "integrity": "sha512-F3CyXgjtDI4quGFkDmVNytt6KMwlzzeMxtopk6Edue4uKdKcMC1vUmoRS5xTbFzKDDp4XwpnEV7FshPaL3eCPw==", - "requires": { - "@smithy/middleware-serde": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/url-parser": "^1.0.1", - "@smithy/util-middleware": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "@smithy/middleware-retry": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-1.0.3.tgz", - "integrity": "sha512-ZRsjG8adtxQ456FULPqPFmWtrW44Fq8IgdQvQB+rC2RSho3OUzS+TiEIwb5Zs6rf2IoewITKtfdtsUZcxXO0ng==", - "requires": { - "@smithy/protocol-http": "^1.1.0", - "@smithy/service-error-classification": "^1.0.2", - "@smithy/types": "^1.1.0", - "@smithy/util-middleware": "^1.0.1", - "@smithy/util-retry": "^1.0.3", - "tslib": "^2.5.0", - "uuid": "^8.3.2" - }, + "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==", "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - } + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "@smithy/middleware-serde": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-1.0.1.tgz", - "integrity": "sha512-bn5lWk8UUeXFCQfkrNErz5SbeNd+2hgYegHMLsOLPt4URDIsyREar6wMsdsR+8UCdgR5s8udG3Zalgc7puizIQ==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" } }, - "@smithy/middleware-stack": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-1.0.1.tgz", - "integrity": "sha512-T6+gsAO1JYamOJqmORCrByDeQ/NB+ggjHb33UDOgdX4xIjXz/FB/3UqHgQu6PL1cSFrK+i4oteDIwqARDs/Szw==", - "requires": { - "tslib": "^2.5.0" + "node_modules/dpop": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", + "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "@smithy/node-config-provider": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-1.0.1.tgz", - "integrity": "sha512-FRxifH/J2SgOaVLihIqBFuGhiHR/NfzbZYp5nYO7BGgT/gc/f9nAuuRJcEy/hwO3aI6ThyG5apH4tGec6A2sCw==", - "requires": { - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } + "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==" }, - "@smithy/node-http-handler": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-1.0.2.tgz", - "integrity": "sha512-PzPrGRSt3kNuruLCeR4ffJp57ZLVnIukMXVL3Ppr65ZoxiE+HBsOVAa/Z/T+4HzjCM6RaXnnmB8YKfsDjlb0iA==", - "requires": { - "@smithy/abort-controller": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/querystring-builder": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" } }, - "@smithy/property-provider": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-1.0.1.tgz", - "integrity": "sha512-3EG/61Ls1MrgEaafpltXBJHSqFPqmTzEX7QKO7lOEHuYGmGYzZ08t1SsTgd1vM74z0IihoZyGPynZ7WmXKvTeg==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - } + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, - "@smithy/protocol-http": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.1.0.tgz", - "integrity": "sha512-H5y/kZOqfJSqRkwtcAoVbqONmhdXwSgYNJ1Glk5Ry8qlhVVy5qUzD9EklaCH8/XLnoCsLO/F/Giee8MIvaBRkg==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "@smithy/querystring-builder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-1.0.1.tgz", - "integrity": "sha512-J5Tzkw1PMtu01h6wl+tlN5vsyROmS6/z5lEfNlLo/L4ELHeVkQ4Q0PEIjDddPLfjVLCm8biQTESE5GCMixSRNQ==", - "requires": { - "@smithy/types": "^1.1.0", - "@smithy/util-uri-escape": "^1.0.1", - "tslib": "^2.5.0" + "node_modules/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==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, - "@smithy/querystring-parser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-1.0.1.tgz", - "integrity": "sha512-zauxdMc3cwxoLitI5DZqH7xN6Fk0mwRxrUMAETbav2j6Se2U0UGak/55rZcDg2yGzOURaLYi5iOm1gHr98P+Bw==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.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==", + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "@smithy/service-error-classification": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-1.0.2.tgz", - "integrity": "sha512-Q5CCuzYL5FGo6Rr/O+lZxXHm2hrRgbmMn8MgyjqZUWZg20COg20DuNtIbho2iht6CoB7jOpmpBqhWizLlzUZgg==" + "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" + } + ] }, - "@smithy/shared-ini-file-loader": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-1.0.1.tgz", - "integrity": "sha512-EztziuIPoNronENGqh+MWVKJErA4rJpaPzJCPukzBeEoG2USka0/q4B5Mr/1zszOnrb49fPNh4u3u5LfiH7QzA==", - "requires": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "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==", + "engines": { + "node": ">=8" } }, - "@smithy/signature-v4": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-1.0.1.tgz", - "integrity": "sha512-2D69je14ou1vBTnAQeysSK4QVMm0j3WHS3MDg/DnHnFFcXRCzVl/xAARO7POD8+fpi4tMFPs8Z4hzo1Zw40L0Q==", - "requires": { - "@smithy/eventstream-codec": "^1.0.1", - "@smithy/is-array-buffer": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-hex-encoding": "^1.0.1", - "@smithy/util-middleware": "^1.0.1", - "@smithy/util-uri-escape": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" + "node_modules/is-retry-allowed": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", + "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@smithy/smithy-client": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-1.0.3.tgz", - "integrity": "sha512-Wh1mNP/1yUZK0uYkgCQ6NMxpBT3Fmc45TMdUfOlH1xD2zGYL7U4yDHFOhEZdi/suyjaelFobXB2p9pPIw6LjRQ==", - "requires": { - "@smithy/middleware-stack": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-stream": "^1.0.1", - "tslib": "^2.5.0" + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "@smithy/types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.1.0.tgz", - "integrity": "sha512-KzmvisMmuwD2jZXuC9e65JrgsZM97y5NpDU7g347oB+Q+xQLU6hQZ5zFNNbEfwwOJHoOvEVTna+dk1h/lW7alw==", - "requires": { - "tslib": "^2.5.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==", + "engines": { + "node": ">= 0.6" } }, - "@smithy/url-parser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-1.0.1.tgz", - "integrity": "sha512-33vWEtE6HzmwjEcEb4I58XMLRAchwPS93YhfDyXAXr1jwDCzfXmMayQwwpyW847rpWj0XJimxqia8q0z+k/ybw==", - "requires": { - "@smithy/querystring-parser": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "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==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "@smithy/util-base64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-1.0.1.tgz", - "integrity": "sha512-rJcpRi/yUi6TyCEkjdTH86/ExBuKlfctEXhG9/4gMJ3/cnPcHJJnr0mQ9evSEO+3DbpT/Nxq90bcTBdTIAmCig==", - "requires": { - "@smithy/util-buffer-from": "^1.0.1", - "tslib": "^2.5.0" - } + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "@smithy/util-body-length-browser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-1.0.1.tgz", - "integrity": "sha512-Pdp744fmF7E1NWoSb7256Anhm8eYoCubvosdMwXzOnHuPRVbDa15pKUz2027K3+jrfGpXo1r+MnDerajME1Osw==", - "requires": { - "tslib": "^2.5.0" - } + "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==" }, - "@smithy/util-body-length-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-1.0.1.tgz", - "integrity": "sha512-4PIHjDFwG07SNensAiVq/CJmubEVuwclWSYOTNtzBNTvxOeGLznvygkGYgPzS3erByT8C4S9JvnLYgtrsVV3nQ==", - "requires": { - "tslib": "^2.5.0" + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" } }, - "@smithy/util-buffer-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-1.0.1.tgz", - "integrity": "sha512-363N7Wq0ceUgE5lLe6kaR6GlJs2/m4r9V6bRMfIszb6P1FZbbRRM2FQYUWWPFSsRymm9mJL18b3fjiVsIvhDGg==", - "requires": { - "@smithy/is-array-buffer": "^1.0.1", - "tslib": "^2.5.0" - } + "node_modules/streamsaver": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/streamsaver/-/streamsaver-2.0.6.tgz", + "integrity": "sha512-LK4e7TfCV8HzuM0PKXuVUfKyCB1FtT9L0EGxsFk5Up8njj0bXK8pJM9+Wq2Nya7/jslmCQwRK39LFm55h7NBTw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + } + ] }, - "@smithy/util-config-provider": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-1.0.1.tgz", - "integrity": "sha512-4Qy38Oy5/q43MpTwCLV1P+7NeaOp4W2etQDxMjgEeRlOyGGNlgttn0syi4g2rVSukFVqQ6FbeRs5xbnFmS6kaQ==", - "requires": { - "tslib": "^2.5.0" + "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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "@smithy/util-defaults-mode-browser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-1.0.1.tgz", - "integrity": "sha512-/9ObwNch4Z/NJYfkO4AvqBWku60Ju+c2Ck32toPOLmWe/V6eI9FLn8C1abri+GxDRCkLIqvkaWU1lgZ3nWZIIw==", - "requires": { - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" + "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==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "@smithy/util-defaults-mode-node": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-1.0.1.tgz", - "integrity": "sha512-XQM3KvqRLgv7bwAzVkXTITkOmcOINoG9icJiGT8FA0zV35lY5UvyIsg5kHw01xigQS8ufa/33AwG3ZoXip+V5g==", - "requires": { - "@smithy/config-resolver": "^1.0.1", - "@smithy/credential-provider-imds": "^1.0.1", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/property-provider": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" } }, - "@smithy/util-hex-encoding": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-1.0.1.tgz", - "integrity": "sha512-FPTtMz/t02/rbfq5Pdll/TWUYP+GVFLCQNr+DgifrLzVRU0g8rdRjyFpDh8nPTdkDDusTTo9P1bepAYj68s0eA==", - "requires": { - "tslib": "^2.5.0" + "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==", + "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" } }, - "@smithy/util-middleware": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-1.0.1.tgz", - "integrity": "sha512-u9akN3Zmbr0vZH4F+2iehG7cFg+3fvDfnvS/hhsXH4UHuhqiQ+ADefibnLzPoz1pooY7rvwaQ/TVHyJmZHdLdQ==", - "requires": { - "tslib": "^2.5.0" + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" } }, - "@smithy/util-retry": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-1.0.3.tgz", - "integrity": "sha512-gYQnZDD8I2XJFspVwUISyukjPWVikTzKR0IdG8hCWYPTpeULFl1o6yzXlT5SL63TBkuEYl0R1/93cdNtMiNnoA==", - "requires": { - "@smithy/service-error-classification": "^1.0.2", - "tslib": "^2.5.0" + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "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" + }, + "engines": { + "node": ">=12" } }, - "@smithy/util-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-1.0.1.tgz", - "integrity": "sha512-4aBCIz35aZAnt2Rbq341KrnUzGhWv2/Zu8HouJqYLvSWCzlrvsNCGlXP4e70Kjzcw8hSuuCNtdUICwQ5qUWLxg==", - "requires": { - "@smithy/fetch-http-handler": "^1.0.1", - "@smithy/node-http-handler": "^1.0.2", - "@smithy/types": "^1.1.0", - "@smithy/util-base64": "^1.0.1", - "@smithy/util-buffer-from": "^1.0.1", - "@smithy/util-hex-encoding": "^1.0.1", - "@smithy/util-utf8": "^1.0.1", - "tslib": "^2.5.0" + "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==", + "engines": { + "node": ">=12" } - }, - "@smithy/util-uri-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-1.0.1.tgz", - "integrity": "sha512-IJUrRnXKEIc+PKnU1XzTsIENVR+60jUDPBP3iWX/EvuuT3Xfob47x1FGUe2c3yMXNuU6ax8VDk27hL5LKNoehQ==", + } + }, + "dependencies": { + "@babel/runtime": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "requires": { - "tslib": "^2.5.0" + "regenerator-runtime": "^0.14.0" } }, - "@smithy/util-utf8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-1.0.1.tgz", - "integrity": "sha512-iX6XHpjh4DFEUIBSKp2tjy3pYnLQMsJ62zYi1BVAC0kobE6p8AVpiZnxsU3ZkgQatAsUaEspFHUZ7CL7oSqaPQ==", + "@opentdf/cli": { + "version": "file:../../../cli/opentdf-cli-2.0.0.tgz", + "integrity": "sha512-VyP+j6+YeitjJz5xWpVsQbwjiqkPY5OfHLU/fn2I3rU0qlOARqZia47TuS7MLkPmQ/m6Myt1q79ysIXV9Dxlng==", "requires": { - "@smithy/util-buffer-from": "^1.0.1", - "tslib": "^2.5.0" + "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "yargs": "^17.7.2" } }, - "@smithy/util-waiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-1.0.1.tgz", - "integrity": "sha512-dsn8O0s3pFIgxFzySLe1dv0w4tEQizEP6UqbgZ4r/Kar4n8pSdrPi6DJg8BzXwkwEIZpMtV4/nhSeGZ7HksDXA==", + "@opentdf/client": { + "version": "file:../lib/opentdf-client-2.0.0.tgz", + "integrity": "sha512-hrF0E3JpYyYab0HOOQZ8VT+69SFgeRAxdS1f97s5Su2dBBX0IrGgpR0ZlKMbt9nlzCKChia1MIz7jsRTg+3sSg==", "requires": { - "@smithy/abort-controller": "^1.0.1", - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "axios": "^1.6.1", + "axios-retry": "^3.9.0", + "base64-js": "^1.5.1", + "browser-fs-access": "^0.34.1", + "buffer": "^6.0.3", + "buffer-crc32": "^0.2.13", + "dpop": "^1.2.0", + "eventemitter3": "^5.0.1", + "jose": "^4.14.4", + "streamsaver": "^2.0.6", + "uuid": "~9.0.0" } }, "ansi-regex": { @@ -3435,19 +500,19 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "requires": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "axios-retry": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.5.1.tgz", - "integrity": "sha512-mQRJ4IyAUnYig14BQ4MnnNHHuH1cNH7NW4JxEUD6mNJwK6pwOY66wKLCwZ6Y0o3POpfStalqRC+J4+Hnn6Om7w==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", + "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", "requires": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -3458,11 +523,6 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, "browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", @@ -3519,9 +579,9 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "dpop": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.2.0.tgz", - "integrity": "sha512-TWdzNSSYWVAT7UKGE+MJZBinSiVQGcElMaAV4xgOgPJtWcNfSefkHfc7RCYY0H5CZvnNo180xxkVSeYAtaFaBQ==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", + "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==" }, "emoji-regex": { "version": "8.0.0", @@ -3538,23 +598,10 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "fast-xml-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", - "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", - "requires": { - "strnum": "^1.0.5" - } - }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" }, "form-data": { "version": "4.0.0", @@ -3587,14 +634,9 @@ "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==" }, "jose": { - "version": "4.14.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", - "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==" - }, - "jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==" + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==" }, "mime-db": { "version": "1.52.0", @@ -3615,9 +657,9 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "require-directory": { "version": "2.1.1", @@ -3647,25 +689,10 @@ "ansi-regex": "^5.0.1" } }, - "strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, - "tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" - }, "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" - }, - "web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, "wrap-ansi": { "version": "7.0.0", diff --git a/cli/package-lock.json b/cli/package-lock.json index 3f6e319c..c4dae6db 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -372,7 +372,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", + "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", diff --git a/cli/src/cli.ts b/cli/src/cli.ts index 28a61e8e..fd066c47 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -18,6 +18,7 @@ import { } from '@opentdf/client'; import { CLIError, Level, log } from './logger.js'; import { webcrypto } from 'crypto'; +import { attributeFQNsAsValues } from '@opentdf/client/nano'; type AuthToProcess = { auth?: string; @@ -91,6 +92,13 @@ async function processAuth({ }; } +const rstrip = (str: string, suffix = ' '): string => { + while (str && suffix && str.endsWith(suffix)) { + str = str.slice(0, -suffix.length); + } + return str; +}; + type AnyNanoClient = NanoTDFClient | NanoTDFDatasetClient; function addParams(client: AnyNanoClient, argv: Partial) { @@ -120,6 +128,9 @@ async function tdf3EncryptParamsFor(argv: Partial): Promise { // AUTH OPTIONS .option('kasEndpoint', { demandOption: true, - group: 'KAS Configuration', + group: 'Server Endpoints:', type: 'string', description: 'URL to non-default KAS instance (https://mykas.net)', }) .option('oidcEndpoint', { demandOption: true, - group: 'OIDC IdP Endpoint:', + group: 'Server Endpoints:', type: 'string', description: 'URL to non-default OIDC IdP (https://myidp.net)', }) + .option('policyEndpoint', { + group: 'Server Endpoints:', + type: 'string', + description: 'Attribute and key grant service endpoint', + }) .option('allowList', { - group: 'KAS Configuration', + group: 'Security:', desc: 'allowed KAS origins, comma separated; defaults to [kasEndpoint]', type: 'string', validate: (attributes: string) => attributes.split(','), }) - .boolean('ignoreAllowList') + .option('ignoreAllowList', { + group: 'Security:', + desc: 'disable KAS allowlist feature for decrypt', + type: 'boolean', + }) .option('auth', { - group: 'Authentication:', + group: 'OAuth and OIDC:', type: 'string', - description: 'Authentication string (:)', + description: 'Combined OAuth Client Credentials (:)', + }) + .option('dpop', { + group: 'Security:', + desc: 'Use DPoP for token binding', + type: 'boolean', }) - .boolean('dpop') .implies('auth', '--no-clientId') .implies('auth', '--no-clientSecret') .option('clientId', { - group: 'OIDC client credentials', + group: 'OAuth and OIDC:', alias: 'cid', type: 'string', - description: 'IdP-issued Client ID', + description: 'OAuth Client Credentials: IdP-issued Client ID', }) .implies('clientId', 'clientSecret') .option('clientSecret', { - group: 'OIDC client credentials', + group: 'OAuth and OIDC:', alias: 'cs', type: 'string', - description: 'IdP-issued Client Secret', + description: 'OAuth Client Credentials: IdP-issued Client Secret', }) .implies('clientSecret', 'clientId') .option('exchangeToken', { - group: 'Token from trusted external IdP to exchange for Virtru auth', + group: 'OAuth and OIDC:', alias: 'et', type: 'string', - description: 'Token issued by trusted external IdP', + description: 'OAuth Token Exchange: Token issued by trusted external IdP', }) .implies('exchangeToken', 'clientId') @@ -229,39 +253,45 @@ export const handleArgs = (args: string[]) => { // Policy, encryption, and container options .options({ attributes: { - group: 'Encrypt Options', + group: 'Encrypt Options:', desc: 'Data attributes for the policy', type: 'string', default: '', validate: (attributes: string) => attributes.split(','), }, + autoconfigure: { + group: 'Encrypt Options:', + desc: 'Enable automatic configuration from attributes using policy service', + type: 'boolean', + default: false, + }, containerType: { - group: 'Encrypt Options', + group: 'Encrypt Options:', alias: 't', choices: containerTypes, description: 'Container format', default: 'nano', }, policyBinding: { - group: 'Encrypt Options', + group: 'Encrypt Options:', choices: bindingTypes, description: 'Policy Binding Type (nano only)', default: 'gmac', }, mimeType: { - group: 'Encrypt Options', + group: 'Encrypt Options:', desc: 'Mime type for the plain text file (only supported for ztdf)', type: 'string', default: '', }, userId: { - group: 'Encrypt Options', + group: 'Encrypt Options:', type: 'string', description: 'Owner email address', }, usersWithAccess: { alias: 'users-with-access', - group: 'Encrypt Options', + group: 'Encrypt Options:', desc: 'Add users to the policy', type: 'string', default: '', @@ -272,12 +302,14 @@ export const handleArgs = (args: string[]) => { // COMMANDS .options({ logLevel: { + group: 'Verbosity:', alias: 'log-level', type: 'string', default: 'info', desc: 'Set logging level', }, silent: { + group: 'Verbosity:', type: 'boolean', default: false, desc: 'Disable logging', @@ -287,6 +319,39 @@ export const handleArgs = (args: string[]) => { type: 'string', description: 'output file', }) + + .command( + 'attrs', + 'Look up defintions of attributes', + (yargs) => { + yargs.strict(); + }, + async (argv) => { + log('DEBUG', 'attribute value lookup'); + const authProvider = await processAuth(argv); + const signingKey = await crypto.subtle.generateKey( + { + name: 'RSASSA-PKCS1-v1_5', + hash: 'SHA-256', + modulusLength: 2048, + publicExponent: new Uint8Array([0x01, 0x00, 0x01]), + }, + true, + ['sign', 'verify'] + ); + authProvider.updateClientPublicKey(signingKey); + log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`); + + const policyUrl: string = guessPolicyUrl(argv); + const defs = await attributeFQNsAsValues( + policyUrl, + authProvider, + ...(argv.attributes as string).split(',') + ); + console.log(JSON.stringify(defs, null, 2)); + } + ) + .command( 'decrypt [file]', 'Decrypt TDF to string', @@ -397,11 +462,13 @@ export const handleArgs = (args: string[]) => { if ('tdf3' === argv.containerType || 'ztdf' === argv.containerType) { log('DEBUG', `TDF3 Client`); + const policyEndpoint: string = guessPolicyUrl(argv); const client = new TDF3Client({ allowedKases, ignoreAllowList, authProvider, kasEndpoint, + policyEndpoint, dpopEnabled: argv.dpop, }); log('SILLY', `Initialized client ${JSON.stringify(client)}`); @@ -480,3 +547,20 @@ handleArgs(hideBin(process.argv)) .catch((err) => { console.error(err); }); + +function guessPolicyUrl({ + kasEndpoint, + policyEndpoint, +}: { + kasEndpoint: string; + policyEndpoint?: string; +}) { + let policyUrl: string; + if (policyEndpoint) { + policyUrl = rstrip(policyEndpoint, '/'); + } else { + const uNoSlash = rstrip(kasEndpoint, '/'); + policyUrl = uNoSlash.endsWith('/kas') ? uNoSlash.slice(0, -4) : uNoSlash; + } + return policyUrl; +} diff --git a/lib/src/index.ts b/lib/src/index.ts index 03cdd32d..0244d674 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -12,6 +12,7 @@ import { keyAgreement } from './nanotdf-crypto/index.js'; import { TypedArray, createAttribute, Policy } from './tdf/index.js'; import { fetchECKasPubKey } from './access.js'; import { ClientConfig } from './nanotdf/Client.js'; +export { attributeFQNsAsValues } from './policy/api.js'; // Define the EncryptOptions type export type EncryptOptions = { diff --git a/lib/src/package-lock.json b/lib/src/package-lock.json new file mode 100644 index 00000000..72e5c2e3 --- /dev/null +++ b/lib/src/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "src", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/lib/src/policy/api.ts b/lib/src/policy/api.ts new file mode 100644 index 00000000..8a575734 --- /dev/null +++ b/lib/src/policy/api.ts @@ -0,0 +1,62 @@ +import { AuthProvider } from '../auth/auth.js'; +import { rstrip } from '../utils.js'; +import { GetAttributeValuesByFqnsResponse, Value } from './attributes.js'; + +export async function attributeFQNsAsValues( + kasUrl: string, + authProvider: AuthProvider, + ...fqns: string[] +): Promise { + const avs = new URLSearchParams(); + for (const fqn of fqns) { + avs.append('fqns', fqn); + } + avs.append('withValue.withKeyAccessGrants', 'true'); + avs.append('withValue.withAttribute.withKeyAccessGrants', 'true'); + const uNoSlash = rstrip(kasUrl, '/'); + const uNoKas = uNoSlash.endsWith('/kas') ? uNoSlash.slice(0, -4) : uNoSlash; + const url = `${uNoKas}/attributes/*/fqn?${avs}`; + const req = await authProvider.withCreds({ + url, + headers: {}, + method: 'GET', + }); + let response: Response; + try { + response = await fetch(req.url, { + mode: 'cors', + credentials: 'same-origin', + headers: req.headers, + redirect: 'follow', + referrerPolicy: 'no-referrer', + }); + + if (!response.ok) { + throw new Error(`${req.method} ${req.url} => ${response.status} ${response.statusText}`); + } + } catch (e) { + console.error(`network error [${req.method} ${req.url}]`, e); + throw e; + } + + let resp: GetAttributeValuesByFqnsResponse; + try { + resp = (await response.json()) as GetAttributeValuesByFqnsResponse; + } catch (e) { + console.error(`response parse error [${req.method} ${req.url}]`, e); + throw e; + } + + const values: Value[] = []; + for (const [fqn, av] of Object.entries(resp.fqnAttributeValues)) { + if (!av.value) { + console.log(`Missing value definition for [${fqn}]; is this a valid attribute?`); + continue; + } + if (av.attribute && !av.value.attribute) { + av.value.attribute = av.attribute; + } + values.push(av.value); + } + return values; +} diff --git a/lib/src/policy/attributes.ts b/lib/src/policy/attributes.ts index f8cfe784..a6cf2e79 100644 --- a/lib/src/policy/attributes.ts +++ b/lib/src/policy/attributes.ts @@ -89,6 +89,10 @@ export type Attribute = { metadata?: Metadata; }; +// This is not currently needed by the client, but may be returned. +// Setting it to unknown to allow it to be ignored for now. +export type SubjectMapping = unknown; + export type Value = { id?: string; attribute?: Attribute; @@ -98,6 +102,16 @@ export type Value = { fqn: string; /** active by default until explicitly deactivated */ active?: boolean; + subjectMappings?: SubjectMapping[]; /** Common metadata */ metadata?: Metadata; }; + +export type AttributeAndValue = { + attribute: Attribute; + value: Value; +}; + +export type GetAttributeValuesByFqnsResponse = { + fqnAttributeValues: Record; +}; diff --git a/lib/tdf3/package-lock.json b/lib/tdf3/package-lock.json new file mode 100644 index 00000000..dfb5038b --- /dev/null +++ b/lib/tdf3/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "tdf3", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/lib/tdf3/src/client/builders.ts b/lib/tdf3/src/client/builders.ts index ee055f4f..dbdc17a2 100644 --- a/lib/tdf3/src/client/builders.ts +++ b/lib/tdf3/src/client/builders.ts @@ -36,6 +36,7 @@ export type SplitStep = { export type EncryptParams = { source: ReadableStream; opts?: { keypair: PemKeyPair }; + autoconfigure?: boolean; scope?: Scope; metadata?: Metadata; keypair?: CryptoKeyPair; @@ -133,6 +134,16 @@ class EncryptParamsBuilder { return this; } + /** + * If set, the encrypt method will use the KAS Grants from the + * policy service to configure the Key Access Object array, instead + * of the client object's default `kasEndpoint`. + */ + withAutoconfigure(enabled: boolean = true) { + this._params.autoconfigure = enabled; + return this; + } + /** * Specify the content to encrypt, in buffer form. * @param {Buffer} buf - a buffer to encrypt. diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index a8994d0f..1a6b1493 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -30,7 +30,12 @@ import { withHeaders, } from '../../../src/auth/auth.js'; import EAS from '../../../src/auth/Eas.js'; -import { cryptoPublicToPem, pemToCryptoPublicKey, validateSecureUrl } from '../../../src/utils.js'; +import { + cryptoPublicToPem, + pemToCryptoPublicKey, + rstrip, + validateSecureUrl, +} from '../../../src/utils.js'; import { EncryptParams, @@ -58,6 +63,7 @@ import { toCryptoKeyPair } from '../crypto/crypto-utils.js'; import * as defaultCryptoService from '../crypto/index.js'; import { type AttributeObject, AttributeSet, type Policy, SplitKey } from '../models/index.js'; import { plan } from '../../../src/policy/granter.js'; +import { attributeFQNsAsValues } from '../../../src/policy/api.js'; import { type Value } from '../../../src/policy/attributes.js'; const GLOBAL_BYTE_LIMIT = 64 * 1000 * 1000 * 1000; // 64 GB, see WS-9363. @@ -133,6 +139,11 @@ export interface ClientConfig { dpopEnabled?: boolean; dpopKeys?: Promise; kasEndpoint?: string; + /** + * Service to use to look up ABAC. Used during autoconfigure. Defaults to + * kasEndpoint without the trailing `/kas` path segment, if present. + */ + policyEndpoint?: string; /** * List of allowed KASes to connect to for rewrap requests. * Defaults to `[kasEndpoint]`. @@ -229,6 +240,12 @@ export class Client { */ readonly kasEndpoint: string; + /** + * Policy service endpoint, if present. + * Required for autoconfiguration with ABAC. + */ + readonly policyEndpoint: string; + /** * List of allowed KASes to connect to for rewrap requests. * Defaults to `[this.kasEndpoint]`. @@ -284,6 +301,12 @@ export class Client { } this.kasEndpoint = clientConfig.keyRewrapEndpoint.replace(/\/rewrap$/, ''); } + this.kasEndpoint = rstrip(this.kasEndpoint, '/'); + if (clientConfig.policyEndpoint) { + this.policyEndpoint = rstrip(clientConfig.policyEndpoint, '/'); + } else if (this.kasEndpoint.endsWith('/kas')) { + this.policyEndpoint = this.kasEndpoint.slice(0, -4); + } const kasOrigin = new URL(this.kasEndpoint).origin; if (clientConfig.allowedKases) { @@ -360,6 +383,7 @@ export class Client { * @param scope dissem and attributes for constructing the policy * @param source source object of unencrypted data * @param [asHtml] If we should wrap the TDF data in a self-opening HTML wrapper. Defaults to false + * @param [autoconfigure] If we should use scope.attributes to configure KAOs * @param [metadata] Additional non-secret data to store with the TDF * @param [opts] Test only * @param [mimeType] mime type of source. defaults to `unknown` @@ -372,6 +396,7 @@ export class Client { */ async encrypt({ scope = { attributes: [], dissem: [] }, + autoconfigure, source, asHtml = false, metadata, @@ -388,16 +413,29 @@ export class Client { const policyObject = asPolicy(scope); validatePolicyObject(policyObject); - if (!splitPlan && scope.attributeValues?.length) { - const avs: Value[] = scope.attributeValues; + if (!splitPlan && autoconfigure) { + let avs: Value[] = scope.attributeValues ?? []; const fqns: string[] = scope.attributes ? scope.attributes.map((attribute) => typeof attribute === 'string' ? attribute : attribute.attribute ) : []; - if (!scope.attributes?.length) { - scope.attributes = avs.map(({ fqn }) => fqn); + if (!avs.length && fqns.length) { + // Hydrate avs from policy endpoint givnen the fqns + if (!this.policyEndpoint) { + throw new Error('policyEndpoint not set in TDF3 Client constructor'); + } + avs = await attributeFQNsAsValues( + this.policyEndpoint, + this.authProvider as AuthProvider, + ...fqns + ); + } else if (scope.attributeValues) { + avs = scope.attributeValues; + if (!scope.attributes) { + scope.attributes = avs.map(({ fqn }) => fqn); + } } if ( avs.length != scope.attributes?.length || diff --git a/lib/tests/server.ts b/lib/tests/server.ts index 2a10b707..972cada3 100644 --- a/lib/tests/server.ts +++ b/lib/tests/server.ts @@ -13,6 +13,8 @@ import { pemPublicToCrypto } from '../src/nanotdf-crypto/pemPublicToCrypto.js'; import { removePemFormatting } from '../tdf3/src/crypto/crypto-utils.js'; import { Binary } from '../tdf3/index.js'; import { type KeyAccessObject } from '../tdf3/src/models/key-access.js'; +import { valueFor } from './web/policy/mock-attrs.js'; +import { AttributeAndValue } from '../src/policy/attributes.js'; const Mocks = getMocks(); @@ -241,6 +243,34 @@ const kas: RequestListener = async (req, res) => { res.setHeader('Content-Type', 'application/octet-stream'); res.end(Buffer.from(fullRange.buffer)); } + } else if (url.pathname === '/attributes/*/fqn') { + const fqnAttributeValues: Record = {}; + let skipped = 0; + for (const [k, v] of url.searchParams.entries()) { + if (k !== 'fqns') { + continue; + } + const value = valueFor(v); + if (!value) { + console.error(`unable to find definition for value [${v}]`); + skipped++; + continue; + } + const attribute = value.attribute; + if (!attribute) { + console.error(`unable to find definition for attribute [${v}]`); + skipped++; + continue; + } + fqnAttributeValues[v] = { attribute, value }; + } + if (skipped) { + res.statusCode = 404; + res.end('Not Found'); + return; + } + res.writeHead(200); + res.end(JSON.stringify({ fqnAttributeValues })); } else if (url.pathname === '/stop' && req.method === 'GET') { server.close(() => { console.log('Server gracefully terminated.'); diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index a6c1f533..62bb5163 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1821,7 +1821,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", + "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 72bc9050..33fe70e7 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -607,7 +607,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", + "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", @@ -4111,7 +4111,7 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-vzJwjNfEa0vM/g1jQZNj38022xuibdwSZgfor9e04yESkaPhkJY7t+bbS89fbtyhXl/XImIUHVgyMZcWEVhSsw==", + "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", From e775ba5b7d9fca7f91ce9a50650d4e69a03711bc Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 23 Sep 2024 13:01:18 -0400 Subject: [PATCH 28/42] fix(lib): Adds a 10 MiB cap to manifest size (#353) This should help prevent an avenue for DoSes --- lib/tdf3/src/utils/zip-reader.ts | 7 +++++++ lib/tests/mocha/unit/zip.spec.ts | 31 ++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/tdf3/src/utils/zip-reader.ts b/lib/tdf3/src/utils/zip-reader.ts index 585129ee..e76dff48 100644 --- a/lib/tdf3/src/utils/zip-reader.ts +++ b/lib/tdf3/src/utils/zip-reader.ts @@ -8,6 +8,8 @@ const CD_SIGNATURE = 0x02014b50; const CENTRAL_DIRECTORY_RECORD_FIXED_SIZE = 46; const LOCAL_FILE_HEADER_FIXED_SIZE = 30; const VERSION_NEEDED_TO_EXTRACT_ZIP64 = 45; +const manifestMaxSize = 1024 * 1024 * 10; // 10 MB + const cp437 = '\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ '; @@ -92,6 +94,11 @@ export class ZipReader { throw new Error('Unable to retrieve CD manifest'); } const byteStart = cdObj.relativeOffsetOfLocalHeader + cdObj.headerLength; + if (cdObj.uncompressedSize > manifestMaxSize) { + throw new Error( + `manifest file too large: ${(cdObj.uncompressedSize >> 10).toLocaleString()} KiB` + ); + } const byteEnd = byteStart + cdObj.uncompressedSize; const manifest = await this.getChunk(byteStart, byteEnd); diff --git a/lib/tests/mocha/unit/zip.spec.ts b/lib/tests/mocha/unit/zip.spec.ts index 4b384795..a5386a27 100644 --- a/lib/tests/mocha/unit/zip.spec.ts +++ b/lib/tests/mocha/unit/zip.spec.ts @@ -1,7 +1,12 @@ import { expect } from 'chai'; import { encodeArrayBuffer } from '../../../src/encodings/base64.js'; -import { parseCDBuffer, readUInt64LE } from '../../../tdf3/src/utils/zip-reader.js'; +import { + CentralDirectory, + parseCDBuffer, + readUInt64LE, + ZipReader, +} from '../../../tdf3/src/utils/zip-reader.js'; import { ZipWriter, dateToDosDateTime, writeUInt64LE } from '../../../tdf3/src/utils/zip-writer.js'; describe('zip utilities', () => { @@ -170,3 +175,27 @@ describe('zip utilities', () => { }); }); }); + +describe('reader', () => { + it('fails on bad manifest size', async () => { + const reader = new ZipReader(async () => new Uint8Array([])); + const fileName = '0.manifest.json'; + try { + expect( + await reader.getManifest( + [ + { + fileName, + relativeOffsetOfLocalHeader: 0, + headerLength: 1024, + uncompressedSize: 1024 * 1024 * 128, + } as CentralDirectory, + ], + fileName + ) + ).to.be.undefined; + } catch (e) { + expect(e.message).to.contain('too large'); + } + }); +}); From 10ff5c7b940a1287cb2dfbbaeee50ba58d0b85a7 Mon Sep 17 00:00:00 2001 From: sujankota Date: Mon, 30 Sep 2024 19:37:56 -0400 Subject: [PATCH 29/42] feat(sdk): Assertion support (#350) * feat(sdk): Assertion support --- lib/package-lock.json | 5 + lib/package.json | 1 + lib/tdf3/src/client/AssertionConfig.ts | 29 ++++++ lib/tdf3/src/client/builders.ts | 15 +++ lib/tdf3/src/client/index.ts | 5 + lib/tdf3/src/models/assertion.ts | 129 ++++++++++++++++++++++++ lib/tdf3/src/models/index.ts | 1 + lib/tdf3/src/models/manifest.ts | 2 + lib/tdf3/src/tdf.ts | 92 ++++++++++++++++- lib/tests/mocha/encrypt-decrypt.spec.ts | 83 ++++++++++++++- 10 files changed, 359 insertions(+), 3 deletions(-) create mode 100644 lib/tdf3/src/client/AssertionConfig.ts create mode 100644 lib/tdf3/src/models/assertion.ts diff --git a/lib/package-lock.json b/lib/package-lock.json index 7fd7f565..77aa7881 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -18,6 +18,7 @@ "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" }, @@ -6159,6 +6160,10 @@ "node": ">=4" } }, + "node_modules/json-canonicalize": { + "version": "1.0.6", + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "dev": true, diff --git a/lib/package.json b/lib/package.json index a87256ca..98c1ad67 100644 --- a/lib/package.json +++ b/lib/package.json @@ -69,6 +69,7 @@ "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" }, diff --git a/lib/tdf3/src/client/AssertionConfig.ts b/lib/tdf3/src/client/AssertionConfig.ts new file mode 100644 index 00000000..cd065aa8 --- /dev/null +++ b/lib/tdf3/src/client/AssertionConfig.ts @@ -0,0 +1,29 @@ +import { + AssertionKeyAlg, + AssertionType, + Scope, + AppliesToState, + Statement, +} from '../models/assertion.js'; + +export type AssertionKey = { + alg: AssertionKeyAlg; + key: any; // Replace AnyKey with the actual type of your key +}; + +// AssertionConfig is a shadow of Assertion with the addition of the signing key. +// It is used on creation of the assertion. +export type AssertionConfig = { + id: string; + type: AssertionType; + scope: Scope; + appliesToState: AppliesToState; + statement: Statement; + signingKey?: AssertionKey; +}; + +// AssertionVerificationKeys represents the verification keys for assertions. +export type AssertionVerificationKeys = { + DefaultKey?: AssertionKey; + Keys: Record; +}; diff --git a/lib/tdf3/src/client/builders.ts b/lib/tdf3/src/client/builders.ts index dbdc17a2..a5b87fcf 100644 --- a/lib/tdf3/src/client/builders.ts +++ b/lib/tdf3/src/client/builders.ts @@ -8,6 +8,7 @@ import { PemKeyPair } from '../crypto/declarations.js'; import { EntityObject } from '../../../src/tdf/EntityObject.js'; import { DecoratedReadableStream } from './DecoratedReadableStream.js'; import { type Chunker } from '../utils/chunkers.js'; +import { AssertionConfig, AssertionVerificationKeys } from './AssertionConfig.js'; import { Value } from '../../../src/policy/attributes.js'; export const DEFAULT_SEGMENT_SIZE: number = 1024 * 1024; @@ -50,6 +51,7 @@ export type EncryptParams = { keyMiddleware?: EncryptKeyMiddleware; splitPlan?: SplitStep[]; streamMiddleware?: EncryptStreamMiddleware; + assertionConfigs?: AssertionConfig[]; }; // 'Readonly': scope, metadata, offline, windowSize, asHtml @@ -77,6 +79,7 @@ class EncryptParamsBuilder { offline: false, windowSize: DEFAULT_SEGMENT_SIZE, asHtml: false, + assertionConfigs: [], } ) { this._params = { ...params }; @@ -485,6 +488,17 @@ class EncryptParamsBuilder { build(): Readonly { return this._deepCopy(this._params as EncryptParams); } + + /** + * Sets the assertion configurations for the encryption parameters. + * + * @param {AssertionConfig[]} assertionConfigs - An array of assertion configurations to be set. + * @returns {EncryptParamsBuilder} The current instance of the EncryptParamsBuilder for method chaining. + */ + withAssertions(assertionConfigs: AssertionConfig[]): EncryptParamsBuilder { + this._params.assertionConfigs = assertionConfigs; + return this; + } } export type DecryptKeyMiddleware = (key: Binary) => Promise; @@ -505,6 +519,7 @@ export type DecryptParams = { source: DecryptSource; keyMiddleware?: DecryptKeyMiddleware; streamMiddleware?: DecryptStreamMiddleware; + assertionVerificationKeys?: AssertionVerificationKeys; }; /** diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index 1a6b1493..c703a2fb 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -407,6 +407,7 @@ export class Client { keyMiddleware = defaultKeyMiddleware, streamMiddleware = async (stream: DecoratedReadableStream) => stream, splitPlan, + assertionConfigs = [], }: EncryptParams): Promise { const dpopKeys = await this.dpopKeys; @@ -519,6 +520,7 @@ export class Client { progressHandler: this.clientConfig.progressHandler, keyForEncryption, keyForManifest, + assertionConfigs, }; const stream = await (streamMiddleware as EncryptStreamMiddleware)(await writeStream(ecfg)); @@ -549,6 +551,7 @@ export class Client { * @param params streamMiddleware fucntion to process streamMiddleware * @param params.source A data stream object, one of remote, stream, buffer, etc. types. * @param params.eo Optional entity object (legacy AuthZ) + * @param params.assertionVerificationKeys Optional verification keys for assertions. * @return a {@link https://nodejs.org/api/stream.html#stream_class_stream_readable|Readable} stream containing the decrypted plaintext. * @see DecryptParamsBuilder */ @@ -557,6 +560,7 @@ export class Client { source, keyMiddleware = async (key: Binary) => key, streamMiddleware = async (stream: DecoratedReadableStream) => stream, + assertionVerificationKeys, }: DecryptParams): Promise { const dpopKeys = await this.dpopKeys; let entityObject; @@ -588,6 +592,7 @@ export class Client { fileStreamServiceWorker: this.clientConfig.fileStreamServiceWorker, keyMiddleware, progressHandler: this.clientConfig.progressHandler, + assertionVerificationKeys, }) ); } diff --git a/lib/tdf3/src/models/assertion.ts b/lib/tdf3/src/models/assertion.ts new file mode 100644 index 00000000..746bb615 --- /dev/null +++ b/lib/tdf3/src/models/assertion.ts @@ -0,0 +1,129 @@ +import { canonicalizeEx } from 'json-canonicalize'; +import { SignJWT, jwtVerify } from 'jose'; +import { AssertionKey } from './../client/AssertionConfig.js'; + +export type AssertionKeyAlg = 'RS256' | 'HS256'; +export type AssertionType = 'handling' | 'other'; +export type Scope = 'tdo' | 'payload'; +export type AppliesToState = 'encrypted' | 'unencrypted'; +export type BindingMethod = 'jws'; + +const kAssertionHash = 'assertionHash'; +const kAssertionSignature = 'assertionSig'; + +// Statement type +export type Statement = { + format: string; + schema: string; + value: string; +}; + +// Binding type +export type Binding = { + method: string; + signature: string; +}; + +// Assertion type +export type Assertion = { + id: string; + type: AssertionType; + scope: Scope; + appliesToState?: AppliesToState; + statement: Statement; + binding: Binding; + hash: () => Promise; + sign: (hash: string, sig: string, key: AssertionKey) => Promise; + verify: (key: AssertionKey) => Promise<[string, string]>; +}; + +/** + * Computes the SHA-256 hash of the assertion object, excluding the 'binding' and 'hash' properties. + * + * @returns {Promise} A promise that resolves to the hexadecimal string representation of the hash. + */ +export async function hash(this: Assertion): Promise { + const result = canonicalizeEx(this, { exclude: ['binding', 'hash', 'sign', 'verify'] }); + + const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(result)); + return Buffer.from(hash).toString('hex'); +} + +/** + * Signs the given hash and signature using the provided key and sets the binding method and signature. + * + * @param {string} hash - The hash to be signed. + * @param {string} sig - The signature to be signed. + * @param {AssertionKey} key - The key used for signing. + * @returns {Promise} A promise that resolves when the signing is complete. + */ +export async function sign( + this: Assertion, + assertionHash: string, + sig: string, + key: AssertionKey +): Promise { + const payload: any = {}; + payload[kAssertionHash] = assertionHash; + payload[kAssertionSignature] = sig; + + try { + const token = await new SignJWT(payload).setProtectedHeader({ alg: key.alg }).sign(key.key); + + this.binding.method = 'jws'; + this.binding.signature = token; + } catch (error) { + throw new Error(`Signing assertion failed: ${error.message}`); + } +} + +/** + * Verifies the signature of the assertion using the provided key. + * + * @param {AssertionKey} key - The key used for verification. + * @returns {Promise<[string, string]>} A promise that resolves to a tuple containing the assertion hash and signature. + * @throws {Error} If the verification fails. + */ +export async function verify(this: Assertion, key: AssertionKey): Promise<[string, string]> { + try { + const { payload } = await jwtVerify(this.binding.signature, key.key, { + algorithms: [key.alg], + }); + + return [payload[kAssertionHash] as string, payload[kAssertionSignature] as string]; + } catch (error) { + throw new Error(`Verifying assertion failed: ${error.message}`); + } +} + +/** + * Creates an Assertion object with the specified properties. + * + * @param {string} id - The unique identifier for the assertion. + * @param {AssertionType} type - The type of the assertion (e.g., 'handling', 'other'). + * @param {Scope} scope - The scope of the assertion (e.g., 'tdo', 'payload'). + * @param {Statement} statement - The statement associated with the assertion. + * @param {Binding} binding - The binding method and signature for the assertion. + * @param {AppliesToState} [appliesToState] - The state to which the assertion applies (optional). + * @returns {Assertion} The created Assertion object. + */ +export function CreateAssertion( + id: string, + type: AssertionType, + scope: Scope, + statement: Statement, + appliesToState?: AppliesToState, + binding?: Binding +): Assertion { + return { + id, + type, + scope, + appliesToState, + statement, + binding: { method: binding?.method ?? '', signature: binding?.signature ?? '' }, + hash, + sign, + verify, + }; +} diff --git a/lib/tdf3/src/models/index.ts b/lib/tdf3/src/models/index.ts index 5842d5e8..12ba37ef 100644 --- a/lib/tdf3/src/models/index.ts +++ b/lib/tdf3/src/models/index.ts @@ -5,3 +5,4 @@ export * from './manifest.js'; export * from './payload.js'; export * from './policy.js'; export * from './upsert-response.js'; +export * from './assertion.js'; diff --git a/lib/tdf3/src/models/manifest.ts b/lib/tdf3/src/models/manifest.ts index 40e20f6b..51e86f81 100644 --- a/lib/tdf3/src/models/manifest.ts +++ b/lib/tdf3/src/models/manifest.ts @@ -1,7 +1,9 @@ +import { type Assertion } from './assertion.js'; import { type Payload } from './payload.js'; import { type EncryptionInformation } from './encryption-information.js'; export type Manifest = { payload: Payload; encryptionInformation: EncryptionInformation; + assertions: Assertion[]; }; diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index f4305e92..2ef75776 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -5,6 +5,12 @@ import { DecoratedReadableStream } from './client/DecoratedReadableStream.js'; import { EntityObject } from '../../src/tdf/EntityObject.js'; import { pemToCryptoPublicKey, validateSecureUrl } from '../../src/utils.js'; import { DecryptParams } from './client/builders.js'; +import { + AssertionConfig, + AssertionKey, + AssertionVerificationKeys, +} from './client/AssertionConfig.js'; +import { Assertion, CreateAssertion } from './models/assertion.js'; import { AttributeSet, @@ -142,6 +148,7 @@ export type EncryptConfiguration = { progressHandler?: (bytesProcessed: number) => void; keyForEncryption: KeyInfo; keyForManifest: KeyInfo; + assertionConfigs?: AssertionConfig[]; }; export type DecryptConfiguration = { @@ -157,6 +164,7 @@ export type DecryptConfiguration = { keyMiddleware: KeyMiddleware; progressHandler?: (bytesProcessed: number) => void; fileStreamServiceWorker?: string; + assertionVerificationKeys?: AssertionVerificationKeys; }; export type UpsertConfiguration = { @@ -423,10 +431,13 @@ async function _generateManifest( throw new Error('Missing encryption information'); } + const assertions: Assertion[] = []; + return { payload, // generate the manifest first, then insert integrity information into it encryptionInformation: encryptionInformationStr, + assertions: assertions, }; } @@ -701,6 +712,40 @@ export async function writeStream(cfg: EncryptConfiguration): Promise 0) { + await Promise.all( + cfg.assertionConfigs.map(async (assertionConfig) => { + // Create assertion using the assertionConfig values + const assertion = CreateAssertion( + assertionConfig.id, + assertionConfig.type, + assertionConfig.scope, + assertionConfig.statement, + assertionConfig.appliesToState + ); + + const assertionHash = await assertion.hash(); + const combinedHash = aggregateHash + assertionHash; + const encodedHash = base64.encode(combinedHash); + + // Create assertion key using the signingKey from the config, or a default key + const assertionKey: AssertionKey = assertionConfig.signingKey ?? { + alg: 'HS256', + key: new Uint8Array(cfg.keyForEncryption.unwrappedKeyBinary.asArrayBuffer()), + }; + + // Sign the assertion + await assertion.sign(assertionHash, encodedHash, assertionKey); + + // Add signed assertion to the signedAssertions array + signedAssertions.push(assertion); + }) + ); + } + + manifest.assertions = signedAssertions; + // write the manifest const manifestBuffer = new TextEncoder().encode(JSON.stringify(manifest)); controller.enqueue(manifestBuffer); @@ -1099,10 +1144,11 @@ export async function readStream(cfg: DecryptConfiguration) { const encryptedSegmentSizeDefault = defaultSegmentSize || DEFAULT_SEGMENT_SIZE; // check the combined string of hashes + const aggregateHash = segments.map(({ hash }) => base64.decode(hash)).join(''); const integrityAlgorithm = rootSignature.alg; const payloadSigStr = await getSignature( keyForDecryption, - Binary.fromString(segments.map((segment) => base64.decode(segment.hash)).join('')), + Binary.fromString(aggregateHash), integrityAlgorithm, cfg.cryptoService ); @@ -1114,6 +1160,50 @@ export async function readStream(cfg: DecryptConfiguration) { throw new ManifestIntegrityError('Failed integrity check on root signature'); } + // // Validate assertions + const assertions = manifest.assertions || []; + for (const assertion of assertions) { + // Create a default assertion key + let assertionKey: AssertionKey = { + alg: 'HS256', + key: new Uint8Array(reconstructedKeyBinary.asArrayBuffer()), + }; + + if (cfg.assertionVerificationKeys) { + const foundKey = cfg.assertionVerificationKeys.Keys[assertion.id]; + if (foundKey) { + assertionKey = foundKey; + } + } + + // create assertion object from the assertion + const assertionObj = CreateAssertion( + assertion.id, + assertion.type, + assertion.scope, + assertion.statement, + assertion.appliesToState, + assertion.binding + ); + + const [assertionHash, assertionSig] = await assertionObj.verify(assertionKey); + + // Get the hash of the assertion + const hashOfAssertion = await assertionObj.hash(); + const combinedHash = aggregateHash + hashOfAssertion; + const encodedHash = base64.encode(combinedHash); + + // check if assertionHash is same as hashOfAssertion + if (hashOfAssertion !== assertionHash) { + throw new ManifestIntegrityError('Assertion hash mismatch'); + } + + // check if assertionSig is same as encodedHash + if (assertionSig !== encodedHash) { + throw new ManifestIntegrityError('Failed integrity check on assertion signature'); + } + } + let mapOfRequestsOffset = 0; const chunkMap = new Map( segments.map(({ hash, encryptedSegmentSize = encryptedSegmentSizeDefault }) => { diff --git a/lib/tests/mocha/encrypt-decrypt.spec.ts b/lib/tests/mocha/encrypt-decrypt.spec.ts index 81ceaf4d..532856e8 100644 --- a/lib/tests/mocha/encrypt-decrypt.spec.ts +++ b/lib/tests/mocha/encrypt-decrypt.spec.ts @@ -7,6 +7,10 @@ import { WebCryptoService } from '../../tdf3/index.js'; import { Client } from '../../tdf3/src/index.js'; import { SplitKey } from '../../tdf3/src/models/encryption-information.js'; import { AesGcmCipher } from '../../tdf3/src/ciphers/aes-gcm-cipher.js'; +import { + AssertionConfig, + AssertionVerificationKeys, +} from '../../tdf3/src/client/AssertionConfig.js'; import { Scope } from '../../tdf3/src/client/builders.js'; const Mocks = getMocks(); @@ -41,13 +45,28 @@ describe('encrypt decrypt test', async function () { clientId: 'id', authProvider, }); - + const keyPair = await crypto.subtle.generateKey( + { + name: 'RSASSA-PKCS1-v1_5', + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: { name: 'SHA-256' }, + }, + true, + ['sign', 'verify'] + ); + const publicKey = keyPair.publicKey; + console.log('publicKey', publicKey); const eo = await Mocks.getEntityObject(); const scope: Scope = { dissem: ['user@domain.com'], attributes: [], }; + // Generate a random HS256 key + const hs256Key = new Uint8Array(32); + crypto.getRandomValues(hs256Key); + const encryptedStream = await client.encrypt({ eo, metadata: Mocks.getMetadataObject(), @@ -60,18 +79,78 @@ describe('encrypt decrypt test', async function () { controller.close(); }, }), + assertionConfigs: [ + { + id: 'assertion1', + type: 'handling', + scope: 'tdo', + statement: { + format: 'json', + schema: 'https://example.com/schema', + value: '{"example": "value"}', + }, + appliesToState: 'encrypted', + signingKey: { + alg: 'HS256', + key: hs256Key, + }, + }, + { + id: 'assertion2', + type: 'handling', + scope: 'tdo', + statement: { + format: 'json', + schema: 'https://example.com/schema', + value: '{"example": "value"}', + }, + appliesToState: 'encrypted', + signingKey: { + alg: 'RS256', + key: keyPair.privateKey, + }, + }, + { + id: 'assertion3', + type: 'handling', + scope: 'tdo', + statement: { + format: 'json', + schema: 'https://example.com/schema', + value: '{"example": "value"}', + }, + appliesToState: 'encrypted', + }, + // Add more assertion configs as needed + ] as AssertionConfig[], }); + console.log('encryptedStream', encryptedStream); + + // Create AssertionVerificationKeys for verification + const assertionVerificationKeys: AssertionVerificationKeys = { + Keys: { + assertion1: { + alg: 'HS256', + key: hs256Key, + }, + assertion2: { + alg: 'RS256', + key: publicKey, + }, + }, + }; + const decryptStream = await client.decrypt({ eo, source: { type: 'stream', location: encryptedStream.stream, }, + assertionVerificationKeys, }); const { value: decryptedText } = await decryptStream.stream.getReader().read(); - assert.equal(new TextDecoder().decode(decryptedText), expectedVal); }); }); From fb0358c583f512b37c8e2067c1e697701596d3bf Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Wed, 9 Oct 2024 09:36:41 -0400 Subject: [PATCH 30/42] chore(docs): Improve readme samples (#359) - Uses newer 'options object' constructor parameter - Be more clear about what the auth providers are and how to select one, or write your own --- README.md | 87 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 51afafc8..b72205b2 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,81 @@ This project is focused on providing web client support for the OpenTDF platform This includes encrypting and decrypting TDF content, and some management tasks for ABAC. -## Usage +## Usage (NanoTDF) ```typescript - // currently we support only ESM import - import { AuthProviders, NanoTDFClient } from '@opentdf/client'; - - const oidcCredentials: RefreshTokenCredentials = { - clientId: keycloakClientId, - exchange: 'refresh', - refreshToken: refreshToken, - oidcOrigin: keycloakUrlWithRealm, - } - const authProvider = await AuthProviders.refreshAuthProvider(oidcCredentials); - const client = new NanoTDFClient(authProvider, access); - const cipherText = await client.encrypt(plainText); - const clearText = await client.decrypt(cipherText); +import { AuthProviders, NanoTDFClient } from '@opentdf/client'; + +// Configuration Options +const kasEndpoint = "http://localhost:65432/kas"; + +// Authentication options (vary by middleware) +const oidcOrigin = "http://localhost:65432/auth/realms/tdf"; +const clientId = "applicationNameFromIdP"; +const refreshToken = "refreshTokenValueFromIdP"; + +// AuthProviders are middlewares that add `Authorization` or other bearer tokens to requests. +// These include The `refresh` provider can be handed a refresh and optional access token. +const authProvider = await AuthProviders.refreshAuthProvider({ + clientId, + exchange: 'refresh', + refreshToken, + oidcOrigin, +}); + +const client = new NanoTDFClient({ + authProvider, + kasEndpoint, +}); +client.dataAttributes = ["http://opentdf.io/attr/class/value/secret"] +const cipherText = await client.encrypt(plainText); +const clearText = await client.decrypt(cipherText); ``` +### Authorization Middleware Options + +#### Client Credentials + +For long running server-side apps, a client id + secret is allowed with OAuth2. +This should not be used in a browser, but within a Deno or Node process. + +```typescript +import { AuthProviders } from '@opentdf/client'; + +// Authentication options (vary by middleware) +const oidcOrigin = "http://localhost:65432/auth/realms/tdf"; +const clientId = "username"; +const clientSecret = "IdP_GENERATED_SECRET"; + +const authProvider = await AuthProviders.clientSecretAuthProvider({ + clientId, + clientSecret, + oidcOrigin, + exchange: 'client', +}); +``` + +#### Given Credentials + +The `refreshAuthProvider` and `externalAuthProvder` allow the application developer to use existing tokens. + +```typescript +import { AuthProviders, NanoTDFClient } from '@opentdf/client'; + +const oidcCredentials: RefreshTokenCredentials = { + clientId: keycloakClientId, + exchange: 'refresh', + refreshToken: refreshToken, + oidcOrigin: keycloakUrlWithRealm, +} +``` + +#### Building your own provider + +A more complete example of using an OIDC compatible provider +with support for authorization code flow with PKCE and DPoP +is available in the [sample `web-app` folder](./web-app/src/session.ts) + ## Build and Test ```shell @@ -37,7 +94,7 @@ We develop using [nvm](https://github.com/nvm-sh/nvm#readme), which allows us to pin to the same version of `npm` easily. - Install [nvm](https://github.com/nvm-sh/nvm#readme) - - see https://github.com/nvm-sh/nvm#installing-and-updating + - see - `nvm use` will install `npm` and `node` [![Build](https://github.com/opentdf/client-web/actions/workflows/build.yaml/badge.svg)](https://github.com/opentdf/client-web/actions/workflows/build.yaml) From 386ec6f46093305e60513b6f82a575dbec4d36d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:10:24 -0400 Subject: [PATCH 31/42] chore(deps): bump cookie and socket.io in /lib (#360) Bumps [cookie](https://github.com/jshttp/cookie) and [socket.io](https://github.com/socketio/socket.io). These dependencies needed to be updated together. Updates `cookie` from 0.4.2 to 0.7.2 - [Release notes](https://github.com/jshttp/cookie/releases) - [Commits](https://github.com/jshttp/cookie/compare/v0.4.2...v0.7.2) Updates `socket.io` from 4.7.0 to 4.8.0 - [Release notes](https://github.com/socketio/socket.io/releases) - [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io/compare/4.7.0...socket.io@4.8.0) --- updated-dependencies: - dependency-name: cookie dependency-type: indirect - dependency-name: socket.io dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- lib/package-lock.json | 44 +++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/package-lock.json b/lib/package-lock.json index 77aa7881..ee635e59 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -1273,8 +1273,9 @@ }, "node_modules/@types/cookie": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true }, "node_modules/@types/cookies": { "version": "0.7.7", @@ -1288,9 +1289,10 @@ } }, "node_modules/@types/cors": { - "version": "2.8.13", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2539,8 +2541,9 @@ }, "node_modules/base64id": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "dev": true, - "license": "MIT", "engines": { "node": "^4.5.0 || >= 5.9" } @@ -3340,9 +3343,10 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.4.2", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3361,8 +3365,9 @@ }, "node_modules/cors": { "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, - "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -3750,18 +3755,17 @@ } }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, - "license": "MIT", "dependencies": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -3776,7 +3780,6 @@ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -3786,7 +3789,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -7527,8 +7529,9 @@ }, "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" } @@ -8934,20 +8937,21 @@ } }, "node_modules/socket.io": { - "version": "4.7.0", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "dev": true, - "license": "MIT", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.0", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/socket.io-adapter": { From 7fb29c5ef519720f7d2c9c8e488e6246743e8d1c Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 15 Oct 2024 11:54:56 -0400 Subject: [PATCH 32/42] feat(lib): Updated error types (#362) * feat(lib): Updated error types - Untyped `Error` objects indicate a likely bug in the library itself - The messages should be prefixed `internal: ` - Samples include bad resource management or missing values in fields that should be const. - `TdfError` should be the root for all errors an application might theoretically screen for to find out if something is wrong in their application that might be caused by TDF or this library. Includes a novel `code` field to allow tracking based on a unique(?) error code - `ConfigurationError` should be able to be fixed by updating the application code. - `InvalidFileError` indicates that a file is likely tampered with or corrupt, although for some errors this may also indicate something is wrong with the user KAS. There are several subtypes when there may be changes to the configuration or user settings that could potentially fix the issue. - `DecryptError` may indicate that the key is incorrect; this could be caused by using a remote or CKS key is out of date, indicating a failure on the server side, but at the moment we have not implemented this. - `IntegrityError` indicates that the segment or global hash is incorrect. This could indicate a file was generated with a deprecated library that uses a different hash calculation. - `UnsafeUrlError` indicates that one or more required Key Access Objects refers to a remote KAS that is not in the allowlist. You can manually check the URL and add it to the allowlist in the client constructor if is a supported KAS. - `NetworkError` indicates a network connectivity error (e.g. during rewrap or key lookup), or a 5xx error on a service - `UnauthenticatedError` indicates that the Bearer token or a required DPoP was not attached to a request. This is often fixable with a mix of IdP/OAuth configuration changes and changes to the application or by adding custom middleware or some combination of all these. - `PermissionDeniedError` indicates that a service (rewrap or public key) has denied access, either due to traditional login (bearer token insufficient scope is one possibility) or due to ABAC (client entity does not have sufficient attributes for policy) - `UnsupportedFeatureError` indicates that an enum in the file or a KAS requirement is not met, e.g. KAS uses an unsupported EC curve, or the TDF file embeds such a curve; could indicate the file was generated with a newer, experimental, or deprecated/removed feature. --- cli/package-lock.json | 21 +- lib/src/access.ts | 107 +++++-- .../auth/oidc-clientcredentials-provider.ts | 5 +- lib/src/auth/oidc-externaljwt-provider.ts | 5 +- lib/src/auth/oidc-refreshtoken-provider.ts | 5 +- lib/src/auth/oidc.ts | 30 +- lib/src/auth/providers.ts | 11 +- lib/src/errors.ts | 128 ++++---- lib/src/index.ts | 32 +- lib/src/nanotdf-crypto/ecdsaSignature.ts | 3 +- lib/src/nanotdf-crypto/keyAgreement.ts | 7 +- lib/src/nanotdf-crypto/pemPublicToCrypto.ts | 5 +- lib/src/nanotdf/Client.ts | 193 +++++++------ lib/src/nanotdf/NanoTDF.ts | 10 +- lib/src/nanotdf/encrypt.ts | 7 +- lib/src/nanotdf/helpers/calculateByCipher.ts | 20 -- lib/src/nanotdf/helpers/calculateByCurve.ts | 6 +- lib/src/nanotdf/models/Ciphers.ts | 4 +- lib/src/nanotdf/models/EcCurves.ts | 16 +- lib/src/nanotdf/models/Header.ts | 8 +- lib/src/nanotdf/models/Payload.ts | 12 +- .../nanotdf/models/Policy/AbstractPolicy.ts | 7 +- .../nanotdf/models/Policy/EmbeddedPolicy.ts | 3 +- .../nanotdf/models/Policy/PolicyFactory.ts | 4 +- lib/src/nanotdf/models/ResourceLocator.ts | 19 +- lib/src/nanotdf/models/Signature.ts | 3 +- lib/src/policy/api.ts | 15 +- lib/src/policy/granter.ts | 7 +- lib/src/utils.ts | 8 +- lib/tdf3/src/binary.ts | 3 +- .../src/client/DecoratedReadableStream.ts | 3 +- lib/tdf3/src/client/builders.ts | 12 +- lib/tdf3/src/client/index.ts | 21 +- lib/tdf3/src/client/validation.ts | 12 +- lib/tdf3/src/crypto/crypto-utils.ts | 18 +- lib/tdf3/src/crypto/index.ts | 11 +- lib/tdf3/src/models/assertion.ts | 15 +- lib/tdf3/src/models/encryption-information.ts | 10 +- lib/tdf3/src/models/policy.ts | 6 +- lib/tdf3/src/tdf.ts | 273 +++++++++++------- lib/tdf3/src/utils/chunkers.ts | 15 +- lib/tdf3/src/utils/index.ts | 3 +- lib/tdf3/src/utils/zip-reader.ts | 23 +- lib/tdf3/src/utils/zip-writer.ts | 2 +- lib/tests/mocha/unit/errors.spec.ts | 26 +- lib/tests/mocha/unit/tdf.spec.ts | 12 +- lib/tests/mocha/unit/zip.spec.ts | 2 +- .../nanotdf/models/ResourceLocator.test.ts | 2 +- remote-store/package-lock.json | 15 +- web-app/package-lock.json | 41 ++- 50 files changed, 677 insertions(+), 549 deletions(-) delete mode 100644 lib/src/nanotdf/helpers/calculateByCipher.ts diff --git a/cli/package-lock.json b/cli/package-lock.json index c4dae6db..9be5f34b 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -36,9 +36,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -372,7 +372,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", + "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", @@ -384,6 +384,7 @@ "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" } @@ -1651,9 +1652,9 @@ } }, "node_modules/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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -2069,6 +2070,12 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-canonicalize": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/json-canonicalize/-/json-canonicalize-1.0.6.tgz", + "integrity": "sha512-kP2iYpOS5SZHYhIaR1t9oG80d4uTY3jPoaBj+nimy3njtJk8+sRsVatN8pyJRDRtk9Su3+6XqA2U8k0dByJBUQ==", + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", diff --git a/lib/src/access.ts b/lib/src/access.ts index aa0def5f..3648839a 100644 --- a/lib/src/access.ts +++ b/lib/src/access.ts @@ -1,4 +1,11 @@ import { type AuthProvider } from './auth/auth.js'; +import { + InvalidFileError, + NetworkError, + PermissionDeniedError, + ServiceError, + UnauthenticatedError, +} from './errors.js'; import { pemToCryptoPublicKey, validateSecureUrl } from './utils.js'; export class RewrapRequest { @@ -32,22 +39,40 @@ export async function fetchWrappedKey( }, body: JSON.stringify(requestBody), }); - const response = await fetch(req.url, { - method: req.method, - mode: 'cors', // no-cors, *cors, same-origin - cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached - credentials: 'same-origin', // include, *same-origin, omit - headers: req.headers, - redirect: 'follow', // manual, *follow, error - referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url - body: req.body as BodyInit, - }); - if (!response.ok) { - throw new Error(`${req.method} ${req.url} => ${response.status} ${response.statusText}`); - } + try { + const response = await fetch(req.url, { + method: req.method, + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'same-origin', // include, *same-origin, omit + headers: req.headers, + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: req.body as BodyInit, + }); - return response.json(); + if (!response.ok) { + switch (response.status) { + case 400: + throw new InvalidFileError( + `400 for [${req.url}]: rewrap failure [${await response.text()}]` + ); + case 401: + throw new UnauthenticatedError(`401 for [${req.url}]`); + case 403: + throw new PermissionDeniedError(`403 for [${req.url}]`); + default: + throw new NetworkError( + `${req.method} ${req.url} => ${response.status} ${response.statusText}` + ); + } + } + + return response.json(); + } catch (e) { + throw new NetworkError(`unable to fetch wrapped key from [${url}]: ${e}`); + } } export type KasPublicKeyAlgorithm = 'ec:secp256r1' | 'rsa:2048'; @@ -75,6 +100,17 @@ export type KasPublicKeyInfo = { key: Promise; }; +async function noteInvalidPublicKey(url: string, r: Promise): Promise { + try { + return await r; + } catch (e) { + if (e instanceof TypeError) { + throw new ServiceError(`invalid public key from [${url}]`, e); + } + throw e; + } +} + /** * If we have KAS url but not public key we can fetch it from KAS, fetching * the value from `${kas}/kas_public_key`. @@ -82,36 +118,53 @@ export type KasPublicKeyInfo = { export async function fetchECKasPubKey(kasEndpoint: string): Promise { validateSecureUrl(kasEndpoint); const pkUrlV2 = `${kasEndpoint}/v2/kas_public_key?algorithm=ec:secp256r1&v=2`; - const kasPubKeyResponse = await fetch(pkUrlV2); - if (!kasPubKeyResponse.ok) { - if (kasPubKeyResponse.status != 404) { - throw new Error( - `unable to load KAS public key from [${pkUrlV2}]. Received [${kasPubKeyResponse.status}:${kasPubKeyResponse.statusText}]` - ); + const kasPubKeyResponseV2 = await fetch(pkUrlV2); + if (!kasPubKeyResponseV2.ok) { + switch (kasPubKeyResponseV2.status) { + case 404: + // v2 not implemented, perhaps a legacy server + break; + case 401: + throw new UnauthenticatedError(`401 for [${pkUrlV2}]`); + case 403: + throw new PermissionDeniedError(`403 for [${pkUrlV2}]`); + default: + throw new NetworkError( + `${pkUrlV2} => ${kasPubKeyResponseV2.status} ${kasPubKeyResponseV2.statusText}` + ); } // most likely a server that does not implement v2 endpoint, so no key identifier const pkUrlV1 = `${kasEndpoint}/kas_public_key?algorithm=ec:secp256r1`; const r2 = await fetch(pkUrlV1); if (!r2.ok) { - throw new Error( - `unable to load KAS public key from [${pkUrlV1}]. Received [${r2.status}:${r2.statusText}]` - ); + switch (r2.status) { + case 401: + throw new UnauthenticatedError(`401 for [${pkUrlV2}]`); + case 403: + throw new PermissionDeniedError(`403 for [${pkUrlV2}]`); + default: + throw new NetworkError( + `unable to load KAS public key from [${pkUrlV1}]. Received [${r2.status}:${r2.statusText}]` + ); + } } const pem = await r2.json(); return { - key: pemToCryptoPublicKey(pem), + key: noteInvalidPublicKey(pkUrlV1, pemToCryptoPublicKey(pem)), publicKey: pem, url: kasEndpoint, algorithm: 'ec:secp256r1', }; } - const jsonContent = await kasPubKeyResponse.json(); + const jsonContent = await kasPubKeyResponseV2.json(); const { publicKey, kid }: KasPublicKeyInfo = jsonContent; if (!publicKey) { - throw new Error(`Invalid response from public key endpoint [${JSON.stringify(jsonContent)}]`); + throw new NetworkError( + `invalid response from public key endpoint [${JSON.stringify(jsonContent)}]` + ); } return { - key: pemToCryptoPublicKey(publicKey), + key: noteInvalidPublicKey(pkUrlV2, pemToCryptoPublicKey(publicKey)), publicKey, url: kasEndpoint, algorithm: 'ec:secp256r1', diff --git a/lib/src/auth/oidc-clientcredentials-provider.ts b/lib/src/auth/oidc-clientcredentials-provider.ts index 93b47b63..843e34e8 100644 --- a/lib/src/auth/oidc-clientcredentials-provider.ts +++ b/lib/src/auth/oidc-clientcredentials-provider.ts @@ -1,3 +1,4 @@ +import { ConfigurationError } from '../errors.js'; import { AuthProvider, type HttpRequest } from './auth.js'; import { AccessToken, type ClientSecretCredentials } from './oidc.js'; @@ -10,9 +11,7 @@ export class OIDCClientCredentialsProvider implements AuthProvider { oidcOrigin, }: Partial & Omit) { if (!clientId || !clientSecret) { - throw new Error( - 'To use this nonbrowser-only provider you must supply clientId & clientSecret' - ); + throw new ConfigurationError('clientId & clientSecret required for client credentials flow'); } this.oidcAuth = new AccessToken({ diff --git a/lib/src/auth/oidc-externaljwt-provider.ts b/lib/src/auth/oidc-externaljwt-provider.ts index b115f0af..4006355a 100644 --- a/lib/src/auth/oidc-externaljwt-provider.ts +++ b/lib/src/auth/oidc-externaljwt-provider.ts @@ -1,3 +1,4 @@ +import { ConfigurationError } from '../errors.js'; import { type AuthProvider, type HttpRequest } from './auth.js'; import { AccessToken, type ExternalJwtCredentials } from './oidc.js'; @@ -11,9 +12,7 @@ export class OIDCExternalJwtProvider implements AuthProvider { oidcOrigin, }: Partial & Omit) { if (!clientId || !externalJwt) { - throw new Error( - 'To use this browser-only provider you must supply clientId/JWT from trusted external IdP' - ); + throw new ConfigurationError('external JWT exchange reequires client id and jwt'); } this.oidcAuth = new AccessToken({ diff --git a/lib/src/auth/oidc-refreshtoken-provider.ts b/lib/src/auth/oidc-refreshtoken-provider.ts index e3be9ce3..9c5da4cc 100644 --- a/lib/src/auth/oidc-refreshtoken-provider.ts +++ b/lib/src/auth/oidc-refreshtoken-provider.ts @@ -1,3 +1,4 @@ +import { ConfigurationError } from '../errors.js'; import { type AuthProvider, type HttpRequest } from './auth.js'; import { AccessToken, type RefreshTokenCredentials } from './oidc.js'; @@ -11,9 +12,7 @@ export class OIDCRefreshTokenProvider implements AuthProvider { oidcOrigin, }: Partial & Omit) { if (!clientId || !refreshToken) { - throw new Error( - 'To use this browser-only provider you must supply clientId/valid OIDC refresh token' - ); + throw new ConfigurationError('refresh token or client id missing'); } this.oidcAuth = new AccessToken({ diff --git a/lib/src/auth/oidc.ts b/lib/src/auth/oidc.ts index 970dc5a4..e261c458 100644 --- a/lib/src/auth/oidc.ts +++ b/lib/src/auth/oidc.ts @@ -1,7 +1,7 @@ import { default as dpopFn } from 'dpop'; import { HttpRequest, withHeaders } from './auth.js'; import { base64 } from '../encodings/index.js'; -import { IllegalArgumentError } from '../errors.js'; +import { ConfigurationError, TdfError } from '../errors.js'; import { cryptoPublicToPem, rstrip } from '../utils.js'; /** @@ -98,19 +98,23 @@ export class AccessToken { constructor(cfg: OIDCCredentials, request?: typeof fetch) { if (!cfg.clientId) { - throw new Error('A Keycloak client identifier is currently required for all auth mechanisms'); + throw new ConfigurationError( + 'A Keycloak client identifier is currently required for all auth mechanisms' + ); } if (cfg.exchange === 'client' && !cfg.clientSecret) { - throw new Error('When using client credentials, both clientId and clientSecret are required'); + throw new ConfigurationError( + 'When using client credentials, both clientId and clientSecret are required' + ); } if (cfg.exchange === 'refresh' && !cfg.refreshToken) { - throw new Error('When using refresh token, a refresh token must be provided'); + throw new ConfigurationError('When using refresh token, a refresh token must be provided'); } if (cfg.exchange === 'external' && !cfg.externalJwt) { - throw new Error('When using external JWT, the jwt must be provided'); + throw new ConfigurationError('When using external JWT, the jwt must be provided'); } if (!cfg.exchange) { - throw new Error('Invalid oidc configuration'); + throw new ConfigurationError('Invalid oidc configuration'); } this.config = cfg; this.request = request; @@ -137,7 +141,9 @@ export class AccessToken { }); if (!response.ok) { console.error(await response.text()); - throw new Error(`${response.status} ${response.statusText}`); + throw new TdfError( + `auth info fail: GET [${url}] => ${response.status} ${response.statusText}` + ); } return (await response.json()) as unknown; @@ -151,7 +157,7 @@ export class AccessToken { // add DPoP headers if configured if (this.config.dpopEnabled) { if (!this.signingKey) { - throw new IllegalArgumentError('No signature configured'); + throw new ConfigurationError('No signature configured'); } const clientPubKey = await cryptoPublicToPem(this.signingKey.publicKey); headers['X-VirtruPubKey'] = base64.encode(clientPubKey); @@ -195,7 +201,9 @@ export class AccessToken { const response = await this.doPost(url, body); if (!response.ok) { console.error(await response.text()); - throw new Error(`${response.status} ${response.statusText}`); + throw new TdfError( + `token/code exchange fail: POST [${url}] => ${response.status} ${response.statusText}` + ); } return response.json(); } @@ -255,7 +263,7 @@ export class AccessToken { async exchangeForRefreshToken(): Promise { const cfg = this.config; if (cfg.exchange != 'external' && cfg.exchange != 'refresh') { - throw new Error('No refresh token provided!'); + throw new ConfigurationError('no refresh token provided!'); } const tokenResponse = (this.data = await this.accessTokenLookup(this.config)); if (!tokenResponse.refresh_token) { @@ -278,7 +286,7 @@ export class AccessToken { async withCreds(httpReq: HttpRequest): Promise { if (!this.signingKey) { - throw new Error( + throw new ConfigurationError( 'Client public key was not set via `updateClientPublicKey` or passed in via constructor, cannot fetch OIDC token with valid Virtru claims' ); } diff --git a/lib/src/auth/providers.ts b/lib/src/auth/providers.ts index 956c1530..7c96c075 100644 --- a/lib/src/auth/providers.ts +++ b/lib/src/auth/providers.ts @@ -9,6 +9,7 @@ import { OIDCExternalJwtProvider } from './oidc-externaljwt-provider.js'; import { type AuthProvider } from './auth.js'; import { OIDCRefreshTokenProvider } from './oidc-refreshtoken-provider.js'; import { isBrowser } from '../utils.js'; +import { ConfigurationError } from '../errors.js'; /** * Creates an OIDC Client Credentials Provider for non-browser contexts. @@ -95,13 +96,13 @@ export const refreshAuthProvider = async ( */ export const clientAuthProvider = async (clientConfig: OIDCCredentials): Promise => { if (!clientConfig.clientId) { - throw new Error('Client ID must be provided to constructor'); + throw new ConfigurationError('Client ID must be provided to constructor'); } if (isBrowser()) { //If you're in a browser and passing client secrets, you're Doing It Wrong. // if (clientConfig.clientSecret) { - // throw new Error('Client credentials not supported in a browser context'); + // throw new ConfigurationError('Client credentials not supported in a browser context'); // } //Are we exchanging a refreshToken for a bearer token (normal AuthCode browser auth flow)? //If this is a browser context, we expect the caller to handle the initial @@ -118,15 +119,15 @@ export const clientAuthProvider = async (clientConfig: OIDCCredentials): Promise return clientSecretAuthProvider(clientConfig); } default: - throw new Error(`Unsupported client type`); + throw new ConfigurationError(`Unsupported client type`); } } //If you're NOT in a browser and are NOT passing client secrets, you're Doing It Wrong. //If this is not a browser context, we expect the caller to supply their client ID and client secret, so that // we can authenticate them directly with the OIDC endpoint. if (clientConfig.exchange !== 'client') { - throw new Error( - 'If using client credentials, must supply both client ID and client secret to constructor' + throw new ConfigurationError( + 'When using client credentials, must supply both client ID and client secret to constructor' ); } return clientSecretAuthProvider(clientConfig); diff --git a/lib/src/errors.ts b/lib/src/errors.ts index 6df81f15..76be014a 100644 --- a/lib/src/errors.ts +++ b/lib/src/errors.ts @@ -15,6 +15,10 @@ function scrubCause(error?: Error, d?: number): { cause?: Error } { return { cause }; } +/** + * Root class for all errors thrown by this library. + * This should not be thrown directly, but rather one of its subclasses. + */ export class TdfError extends Error { override name = 'TdfError'; @@ -27,91 +31,83 @@ export class TdfError extends Error { } } -export class UnsafeUrlError extends Error { - override name = 'UnsafeUrlError'; - readonly url: string; - - constructor(message: string, url: string) { - super(message); - Object.setPrototypeOf(this, new.target.prototype); - this.url = url; - } +/** + * Errors that indicate the client or method does not have valid options. + */ +export class ConfigurationError extends TdfError { + override name = 'ConfigurationError'; } -export class AttributeValidationError extends TdfError { +/** + * The assigned data attribute is not in the correct form. + */ +export class AttributeValidationError extends ConfigurationError { override name = 'AttributeValidationError'; + attribute: unknown; + constructor(message: string, attribute: unknown, cause?: Error) { + super(message, cause); + this.attribute = attribute; + } } -export class KasDecryptError extends TdfError { - override name = 'KasDecryptError'; -} - -export class KasUpsertError extends TdfError { - override name = 'KasUpsertError'; -} - -export class KeyAccessError extends TdfError { - override name = 'KeyAccessError'; -} - -export class KeySyncError extends TdfError { - override name = 'KeySyncError'; -} - -export class IllegalArgumentError extends Error {} - -export class IllegalEnvError extends Error {} - -export class InvalidCipherError extends TdfError { - override name = 'InvalidCipherError'; -} - -export class InvalidCurveNameError extends TdfError { - override name = 'InvalidCurveNameError'; -} +/** + * Errors that indicate the TDF object is corrupt, invalid, or fails validation or decrypt. + */ +export class InvalidFileError extends TdfError {} -export class InvalidDataTypeError extends TdfError { - override name = 'InvalidDataTypeError'; +/** + * Indicates a decrypt failure, either due to an incorrect key, corrupt ciphertext, or inappropriate key parameters. + */ +export class DecryptError extends InvalidFileError { + override name = 'DecryptError'; } -export class InvalidEphemeralKeyError extends TdfError { - override name = 'InvalidEphemeralKeyError'; +export class IntegrityError extends InvalidFileError { + override name = 'IntegrityError'; } -export class InvalidPayloadError extends TdfError { - override name = 'InvalidPayloadError'; -} +/** + * Thrown when a KAS URL found in one or more required key access objects are not in the list of known and allowed KASes in the client. + * This may indicate a malicious file - e.g. an attempt to DDoS a server by listing it as the KAS for many files, or to siphon credentials using a lookalike URL. + */ +export class UnsafeUrlError extends InvalidFileError { + override name = 'UnsafeUrlError'; + readonly url: string[]; -export class InvalidPolicyTypeError extends TdfError { - override name = 'InvalidPolicyTypeError'; + constructor(message: string, ...url: string[]) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + this.url = url; + } } -export class ManifestIntegrityError extends TdfError { - override name = 'ManifestIntegrityError'; +/** + * A network error (no response) from rewrap or other endpoint, Possibly fixed by retrying or adjusting your network settings; could indicate network failure. + */ +export class NetworkError extends TdfError { + override name = 'NetworkError'; } -export class PolicyIntegrityError extends TdfError { - override name = 'PolicyIntegrityError'; +/** + * The service reports an unexpected error on its behalf, or a subcomponent (5xx). + */ +export class ServiceError extends TdfError { + override name = 'ServiceError'; } -export class SignatureError extends TdfError { - override name = 'SignatureError'; +/** Authentication failure (401) */ +export class UnauthenticatedError extends TdfError { + override name = 'UnauthenticatedError'; } -export class TdfCorruptError extends TdfError { - reason: string; - - override name = 'TdfCorruptError'; - - constructor(message: string, err: Error, reason: string) { - super(message, err); - this.reason = reason; - } -} -export class TdfDecryptError extends TdfError { - override name = 'TdfDecryptError'; +/** Authorization failure (403) */ +export class PermissionDeniedError extends TdfError { + override name = 'PermissionDeniedError'; } -export class TdfPayloadExtractionError extends TdfError { - override name = 'TdfPayloadExtractionError'; +/** + * Version of file is unsupported, or file uses a feature that is not supported by this version of the library. + */ +export class UnsupportedFeatureError extends TdfError { + override name = 'UnsupportedFeatureError'; } diff --git a/lib/src/index.ts b/lib/src/index.ts index 0244d674..ae7b6674 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -12,6 +12,7 @@ import { keyAgreement } from './nanotdf-crypto/index.js'; import { TypedArray, createAttribute, Policy } from './tdf/index.js'; import { fetchECKasPubKey } from './access.js'; import { ClientConfig } from './nanotdf/Client.js'; +import { ConfigurationError } from './errors.js'; export { attributeFQNsAsValues } from './policy/api.js'; // Define the EncryptOptions type @@ -79,7 +80,7 @@ export class NanoTDFClient extends Client { ); if (!ukey) { - throw new Error('Key rewrap failure'); + throw new Error('internal: key rewrap failure'); } // Return decrypt promise return decrypt(ukey, nanotdf); @@ -108,7 +109,7 @@ export class NanoTDFClient extends Client { ); if (!key) { - throw new Error('Failed unwrap'); + throw new Error('internal: failed unwrap'); } // Return decrypt promise return decrypt(key, nanotdf); @@ -131,7 +132,9 @@ export class NanoTDFClient extends Client { const initializationVector = this.iv; if (typeof initializationVector !== 'number') { - throw new Error('NanoTDF clients are single use. Please generate a new client and keypair.'); + throw new ConfigurationError( + 'NanoTDF clients are single use. Please generate a new client and keypair.' + ); } delete this.iv; @@ -241,8 +244,8 @@ export class NanoTDFDatasetClient extends Client { opts.maxKeyIterations && opts.maxKeyIterations > NanoTDFDatasetClient.NTDF_MAX_KEY_ITERATIONS ) { - throw new Error( - `Key iteration exceeds max iterations(${NanoTDFDatasetClient.NTDF_MAX_KEY_ITERATIONS})` + throw new ConfigurationError( + `key iteration exceeds max iterations(${NanoTDFDatasetClient.NTDF_MAX_KEY_ITERATIONS})` ); } super(opts); @@ -323,11 +326,10 @@ export class NanoTDFDatasetClient extends Client { this.keyIterationCount += 1; if (!this.cachedHeader) { - throw new Error('NanoTDF dataset header should have been assgined'); + throw new ConfigurationError('invalid dataset client: empty nanoTDF header'); } - if (!this.symmetricKey) { - throw new Error('NanoTDF dataset payload key is not set'); + throw new ConfigurationError('invalid dataset client: empty dek'); } this.keyIterationCount += 1; @@ -361,7 +363,8 @@ export class NanoTDFDatasetClient extends Client { if (this.cachedEphemeralKey.toString() == nanotdf.header.ephemeralPublicKey.toString()) { const ukey = this.unwrappedKey; if (!ukey) { - throw new Error('Key rewrap failure'); + // These should have thrown already. + throw new Error('internal: key rewrap failure'); } // Return decrypt promise return decrypt(ukey, nanotdf); @@ -383,7 +386,8 @@ export class NanoTDFDatasetClient extends Client { version ); if (!ukey) { - throw new Error('Key rewrap failure'); + // These should have thrown already. + throw new Error('internal: key rewrap failure'); } this.cachedEphemeralKey = nanotdf.header.ephemeralPublicKey; @@ -396,11 +400,15 @@ export class NanoTDFDatasetClient extends Client { generateIV(): Uint8Array { const iv = this.iv; if (iv === undefined) { - throw new Error('Dataset full'); + // iv has passed the maximum iteration count for this dek + throw new ConfigurationError('dataset full'); } // assert iv ∈ ℤ ∩ (0, 2^24) if (!Number.isInteger(iv) || iv <= 0 || 0xff_ffff < iv) { - throw new Error('Invalid state'); + // Something has fiddled with the iv outside of the expected behavior + // could indicate a race condition, e.g. if two workers or handlers are + // processing the file at once, for example. + throw new Error('internal: invalid state'); } const lengthAsUint32 = new Uint32Array(1); diff --git a/lib/src/nanotdf-crypto/ecdsaSignature.ts b/lib/src/nanotdf-crypto/ecdsaSignature.ts index 9e1d8d49..8e66c380 100644 --- a/lib/src/nanotdf-crypto/ecdsaSignature.ts +++ b/lib/src/nanotdf-crypto/ecdsaSignature.ts @@ -1,3 +1,4 @@ +import { ConfigurationError } from '../errors.js'; import { AlgorithmName } from './../nanotdf-crypto/enums.js'; /** @@ -71,7 +72,7 @@ export function extractRSValuesFromSignature(signatureBytes: Uint8Array): { // Correct validation if (!concatAndCompareUint8Arrays(rValue, sValue, signatureBytes)) { - throw new Error('Invalid ECDSA signature'); + throw new ConfigurationError('invalid ECDSA signature'); } return { diff --git a/lib/src/nanotdf-crypto/keyAgreement.ts b/lib/src/nanotdf-crypto/keyAgreement.ts index 65a767e3..9b76590c 100644 --- a/lib/src/nanotdf-crypto/keyAgreement.ts +++ b/lib/src/nanotdf-crypto/keyAgreement.ts @@ -27,6 +27,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { ConfigurationError } from '../errors.js'; import { AlgorithmName, CipherType, HashType, KeyFormat, KeyType, KeyUsageType } from './enums.js'; const KEY_USAGE_DERIVE_KEY = 'deriveKey'; @@ -72,15 +73,15 @@ export async function keyAgreement( publicKey?.algorithm?.name !== AlgorithmName.ECDSA && publicKey?.algorithm?.name !== AlgorithmName.ECDH ) { - throw new Error('CryptoKey is expected to be of type ECDSA or ECDH'); + throw new ConfigurationError('CryptoKey is expected to be of type ECDSA or ECDH'); } if (privateKey.type !== KeyType.Private) { - throw new TypeError('Expected input of privateKey to be a CryptoKey of type private'); + throw new ConfigurationError('Expected input of privateKey to be a CryptoKey of type private'); } if (publicKey.type !== KeyType.Public) { - throw new TypeError('Expected input of publicKey to be a CryptoKey of type public'); + throw new ConfigurationError('Expected input of publicKey to be a CryptoKey of type public'); } const { diff --git a/lib/src/nanotdf-crypto/pemPublicToCrypto.ts b/lib/src/nanotdf-crypto/pemPublicToCrypto.ts index 3cfbde5f..3f121eae 100644 --- a/lib/src/nanotdf-crypto/pemPublicToCrypto.ts +++ b/lib/src/nanotdf-crypto/pemPublicToCrypto.ts @@ -31,6 +31,7 @@ import * as base64 from '../encodings/base64.js'; import { importX509 } from 'jose'; import { type KeyObject } from 'crypto'; import { encodeArrayBuffer as hexEncodeArrayBuffer } from '../encodings/hex.js'; +import { ConfigurationError, TdfError } from '../errors.js'; const RSA_OID = '06092a864886f70d010101'; const EC_OID = '06072a8648ce3d0201'; @@ -100,7 +101,7 @@ function guessCurveName(hex: string): CurveName { } else if (hex.includes(P521_OID)) { return P_512; } - throw new Error('Unsupported curve name or invalid key'); + throw new TdfError('Unsupported curve name or invalid key'); } /** @@ -209,7 +210,7 @@ export async function pemCertToCrypto( const keylike = await importX509(pem, jwsAlg, { extractable: options.isExtractable }); const { type } = keylike; if (type !== 'public') { - throw new Error('Unpublic'); + throw new ConfigurationError('unpublic'); } // FIXME Jose workaround for node clients. // jose returns a crypto key on node, but we expect a subtle-crypto key diff --git a/lib/src/nanotdf/Client.ts b/lib/src/nanotdf/Client.ts index 976c6fa7..85ded767 100644 --- a/lib/src/nanotdf/Client.ts +++ b/lib/src/nanotdf/Client.ts @@ -5,7 +5,7 @@ import getHkdfSalt from './helpers/getHkdfSalt.js'; import DefaultParams from './models/DefaultParams.js'; import { fetchWrappedKey, KasPublicKeyInfo, OriginAllowList } from '../access.js'; import { AuthProvider, isAuthProvider, reqSignature } from '../auth/providers.js'; -import { UnsafeUrlError } from '../errors.js'; +import { ConfigurationError, DecryptError, TdfError, UnsafeUrlError } from '../errors.js'; import { cryptoPublicToPem, pemToCryptoPublicKey, validateSecureUrl } from '../utils.js'; export interface ClientConfig { @@ -40,7 +40,7 @@ function toJWSAlg(c: CryptoKey): string { return 'ES256'; } } - throw new Error(`Unsupported key algorithm ${JSON.stringify(algorithm)}`); + throw new ConfigurationError(`unsupported key algorithm ${JSON.stringify(algorithm)}`); } async function generateEphemeralKeyPair(): Promise { @@ -131,7 +131,7 @@ export default class Client { if (isAuthProvider(optsOrOldAuthProvider)) { this.authProvider = optsOrOldAuthProvider; if (!kasUrl) { - throw new Error('please specify kasEndpoint'); + throw new ConfigurationError('please specify kasEndpoint'); } // TODO Disallow http KAS. For now just log as error validateSecureUrl(kasUrl); @@ -199,7 +199,7 @@ export default class Client { async fetchOIDCToken(): Promise { const signer = await this.requestSignerKeyPair; if (!signer) { - throw new Error('Unexpected state'); + throw new ConfigurationError('failed to find or generate signer session key'); } await this.authProvider.updateClientPublicKey(signer); @@ -231,118 +231,119 @@ export default class Client { // Ensure the ephemeral key pair has been set or generated (see fetchEntityObject) if (!ephemeralKeyPair?.privateKey) { - throw new Error('Ephemeral key has not been set or generated'); + throw new ConfigurationError('Ephemeral key has not been set or generated'); } if (!requestSignerKeyPair?.privateKey) { - throw new Error('Signer key has not been set or generated'); + throw new ConfigurationError('Signer key has not been set or generated'); } - try { - const requestBodyStr = JSON.stringify({ - algorithm: DefaultParams.defaultECAlgorithm, - // nano keyAccess minimum, header is used for nano - keyAccess: { - type: Client.KEY_ACCESS_REMOTE, - url: '', - protocol: Client.KAS_PROTOCOL, - header: base64.encodeArrayBuffer(nanoTdfHeader), - }, - clientPublicKey: await cryptoPublicToPem(ephemeralKeyPair.publicKey), - }); + const requestBodyStr = JSON.stringify({ + algorithm: DefaultParams.defaultECAlgorithm, + // nano keyAccess minimum, header is used for nano + keyAccess: { + type: Client.KEY_ACCESS_REMOTE, + url: '', + protocol: Client.KAS_PROTOCOL, + header: base64.encodeArrayBuffer(nanoTdfHeader), + }, + clientPublicKey: await cryptoPublicToPem(ephemeralKeyPair.publicKey), + }); - const jwtPayload = { requestBody: requestBodyStr }; - const requestBody = { - signedRequestToken: await reqSignature(jwtPayload, requestSignerKeyPair.privateKey, { - alg: toJWSAlg(requestSignerKeyPair.publicKey), - }), - }; + const jwtPayload = { requestBody: requestBodyStr }; + const requestBody = { + signedRequestToken: await reqSignature(jwtPayload, requestSignerKeyPair.privateKey, { + alg: toJWSAlg(requestSignerKeyPair.publicKey), + }), + }; - // Wrapped - const wrappedKey = await fetchWrappedKey( - kasRewrapUrl, - requestBody, - this.authProvider, - clientVersion - ); + // Wrapped + const wrappedKey = await fetchWrappedKey( + kasRewrapUrl, + requestBody, + this.authProvider, + clientVersion + ); - // Extract the iv and ciphertext - const entityWrappedKey = new Uint8Array( - base64.decodeArrayBuffer(wrappedKey.entityWrappedKey) - ); - const ivLength = - clientVersion == Client.SDK_INITIAL_RELEASE - ? Client.INITIAL_RELEASE_IV_SIZE - : Client.IV_SIZE; - const iv = entityWrappedKey.subarray(0, ivLength); - const encryptedSharedKey = entityWrappedKey.subarray(ivLength); + // Extract the iv and ciphertext + const entityWrappedKey = new Uint8Array(base64.decodeArrayBuffer(wrappedKey.entityWrappedKey)); + const ivLength = + clientVersion == Client.SDK_INITIAL_RELEASE ? Client.INITIAL_RELEASE_IV_SIZE : Client.IV_SIZE; + const iv = entityWrappedKey.subarray(0, ivLength); + const encryptedSharedKey = entityWrappedKey.subarray(ivLength); - let kasPublicKey; - try { - // Let us import public key as a cert or public key - kasPublicKey = await pemToCryptoPublicKey(wrappedKey.sessionPublicKey); - } catch (cause) { - throw new Error( - `PEM Public Key to crypto public key failed. Is PEM formatted correctly?\n Caused by: ${cause.message}`, - { cause } - ); - } + let kasPublicKey; + try { + // Let us import public key as a cert or public key + kasPublicKey = await pemToCryptoPublicKey(wrappedKey.sessionPublicKey); + } catch (cause) { + throw new ConfigurationError( + `internal: [${kasRewrapUrl}] PEM Public Key to crypto public key failed. Is PEM formatted correctly?`, + cause + ); + } - let hkdfSalt; - try { - // Get the hkdf salt params - hkdfSalt = await getHkdfSalt(magicNumberVersion); - } catch (e) { - throw new Error(`Salting hkdf failed\n Caused by: ${e.message}`); - } - const { privateKey } = await this.ephemeralKeyPair; + let hkdfSalt; + try { + // Get the hkdf salt params + hkdfSalt = await getHkdfSalt(magicNumberVersion); + } catch (e) { + throw new TdfError('salting hkdf failed', e); + } + const { privateKey } = await this.ephemeralKeyPair; - // Get the unwrapping key - const unwrappingKey = await keyAgreement( + // Get the unwrapping key + let unwrappingKey; + try { + unwrappingKey = await keyAgreement( // Ephemeral private key privateKey, kasPublicKey, hkdfSalt ); - - const authTagLength = 8 * (encryptedSharedKey.byteLength - 32); - let decryptedKey; - try { - // Decrypt the wrapped key - decryptedKey = await crypto.subtle.decrypt( - { name: 'AES-GCM', iv, tagLength: authTagLength }, - unwrappingKey, - encryptedSharedKey - ); - } catch (cause) { - throw new Error( - `Unable to decrypt key. Are you using the right KAS? Is the salt correct?`, - { cause } - ); + } catch (e) { + if (e.name == 'InvalidAccessError' || e.name == 'OperationError') { + throw new DecryptError('unable to solve key agreement', e); + } else if (e.name == 'NotSupported') { + throw new ConfigurationError('unable to unwrap key from kas', e); } + throw new TdfError('unable to reach agreement', e); + } - // UnwrappedKey - let unwrappedKey; - try { - unwrappedKey = await crypto.subtle.importKey( - 'raw', - decryptedKey, - 'AES-GCM', - // @security This allows the key to be used in `exportKey` and `wrapKey` - // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey - // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey - true, - // Want to use the key to encrypt and decrypt. Signing key will be used later. - ['encrypt', 'decrypt'] - ); - } catch (cause) { - throw new Error('Unable to import raw key.', { cause }); - } + const authTagLength = 8 * (encryptedSharedKey.byteLength - 32); + let decryptedKey; + try { + // Decrypt the wrapped key + decryptedKey = await crypto.subtle.decrypt( + { name: 'AES-GCM', iv, tagLength: authTagLength }, + unwrappingKey, + encryptedSharedKey + ); + } catch (cause) { + throw new DecryptError( + `unable to decrypt key. Are you using the right KAS? Is the salt correct?`, + cause + ); + } - return unwrappedKey; + // UnwrappedKey + let unwrappedKey; + try { + unwrappedKey = await crypto.subtle.importKey( + 'raw', + decryptedKey, + 'AES-GCM', + // @security This allows the key to be used in `exportKey` and `wrapKey` + // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey + // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey + true, + // Want to use the key to encrypt and decrypt. Signing key will be used later. + ['encrypt', 'decrypt'] + ); } catch (cause) { - console.error('rewrap fail', cause); - throw new Error('Could not rewrap key with entity object.', { cause }); + throw new DecryptError('Unable to import raw key.', cause); } + + return unwrappedKey; } } diff --git a/lib/src/nanotdf/NanoTDF.ts b/lib/src/nanotdf/NanoTDF.ts index ea90c5ef..4a926c7e 100644 --- a/lib/src/nanotdf/NanoTDF.ts +++ b/lib/src/nanotdf/NanoTDF.ts @@ -4,7 +4,7 @@ import Header from './models/Header.js'; import Payload from './models/Payload.js'; import Signature from './models/Signature.js'; import EncodingEnum from './enum/EncodingEnum.js'; -import { InvalidDataTypeError, SignatureError } from '../errors.js'; +import { ConfigurationError, InvalidFileError } from '../errors.js'; // Defaults when none set during encryption @@ -32,14 +32,14 @@ export default class NanoTDF { if (!encoding || encoding === EncodingEnum.Base64) { buffer = base64.decodeArrayBuffer(content); } else { - throw new InvalidDataTypeError(); + throw new ConfigurationError(`Unsupported encoding: ${encoding}`); } } // Handle Uint8Array types else if (ArrayBuffer.isView(content) || content instanceof ArrayBuffer) { buffer = content; } else { - throw new InvalidDataTypeError(); + throw new ConfigurationError(`unsupported content type`); } const dataView = new Uint8Array(buffer); @@ -66,10 +66,10 @@ export default class NanoTDF { // Singature checking if (!header.hasSignature && signature.length > 0) { - throw new SignatureError("Found signature when there shouldn't be one"); + throw new InvalidFileError("Found signature when there shouldn't be one"); } if (header.hasSignature && signature.length === 0) { - throw new SignatureError('Could not find signature'); + throw new InvalidFileError('Could not find signature'); } return new NanoTDF(header, payload, signature); diff --git a/lib/src/nanotdf/encrypt.ts b/lib/src/nanotdf/encrypt.ts index 5f7d3f02..6ad7901f 100644 --- a/lib/src/nanotdf/encrypt.ts +++ b/lib/src/nanotdf/encrypt.ts @@ -18,6 +18,7 @@ import { } from '../nanotdf-crypto/index.js'; import { KasPublicKeyInfo } from '../access.js'; import { computeECDSASig, extractRSValuesFromSignature } from '../nanotdf-crypto/ecdsaSignature.js'; +import { ConfigurationError } from '../errors.js'; /** * Encrypt the plain data into nanotdf buffer @@ -39,7 +40,7 @@ export default async function encrypt( ): Promise { // Generate a symmetric key. if (!ephemeralKeyPair.privateKey) { - throw new Error('incomplete ephemeral key'); + throw new ConfigurationError('incomplete ephemeral key'); } const symmetricKey = await keyAgreement( ephemeralKeyPair.privateKey, @@ -96,7 +97,7 @@ export default async function encrypt( ); if (!ephemeralKeyPair.publicKey) { - throw new Error('incomplete ephemeral key'); + throw new ConfigurationError('incomplete ephemeral key'); } // Create a header const pubKeyAsArrayBuffer = await exportCryptoKey(ephemeralKeyPair.publicKey); @@ -158,7 +159,7 @@ async function getCurveNameFromPrivateKey(privateKey: CryptoKey): Promise buffer.length) { - throw new Error('Invalid buffer size to copy tdf header'); + throw new InvalidFileError('invalid buffer size to copy tdf header'); } let offset = 0; @@ -316,7 +316,7 @@ export default class Header { try { return `${rstrip(this.kas.url, '/')}/v2/rewrap`; } catch (e) { - throw new Error(`Cannot construct KAS Rewrap URL: ${e.message}`); + throw new ConfigurationError(`cannot construct KAS Rewrap URL: ${e.message}`); } } } diff --git a/lib/src/nanotdf/models/Payload.ts b/lib/src/nanotdf/models/Payload.ts index 141824bb..37645a82 100644 --- a/lib/src/nanotdf/models/Payload.ts +++ b/lib/src/nanotdf/models/Payload.ts @@ -1,6 +1,6 @@ import Header from './Header.js'; import { getBitLength } from './Ciphers.js'; -import { InvalidPayloadError } from '../../errors.js'; +import { ConfigurationError, InvalidFileError } from '../../errors.js'; /** * Payload @@ -57,7 +57,7 @@ export default class Payload { const inRange = length >= this.MIN_LENGTH && length <= this.MAX_NANO_TDF_ENCRYPT_PAYLOAD_SIZE; if (!inRange) { - throw new InvalidPayloadError('Payload Length Out Of Range'); + throw new InvalidFileError('nanotdf parse failure: Payload Length Out Of Range'); } /** @@ -71,7 +71,7 @@ export default class Payload { offset += Payload.IV_LEN; if (iv.byteLength != 3) { - throw new InvalidPayloadError('Invalid Payload Length'); + throw new InvalidFileError('nanotdf parse failure: Invalid Payload Length'); } if (!legacyTDF) { @@ -93,7 +93,7 @@ export default class Payload { ); if (ciphertextWithAuthTag.byteLength + Payload.LENGTH_LEN !== length) { - throw new InvalidPayloadError('Invalid Payload Length'); + throw new InvalidFileError('nanotdf parse failure: Invalid Payload Length'); } /** @@ -169,12 +169,12 @@ export default class Payload { */ copyToBuffer(buffer: Uint8Array): void { if (this.length > buffer.length) { - throw new Error('Invalid buffer size to copy payload'); + throw new Error('internal: invalid buffer size to copy payload'); } const lengthOfEncryptedPayload = this.iv.length + this.ciphertext.length + this.authTag.length; if (lengthOfEncryptedPayload > Payload.MAX_NANO_TDF_ENCRYPT_PAYLOAD_SIZE) { - throw new Error("TDF encrypted payload can't be more that 2^24"); + throw new ConfigurationError("TDF encrypted payload can't be more that 2^24"); } const lengthAsUint32 = new Uint32Array(1); diff --git a/lib/src/nanotdf/models/Policy/AbstractPolicy.ts b/lib/src/nanotdf/models/Policy/AbstractPolicy.ts index c0d8cf58..60621466 100644 --- a/lib/src/nanotdf/models/Policy/AbstractPolicy.ts +++ b/lib/src/nanotdf/models/Policy/AbstractPolicy.ts @@ -1,5 +1,6 @@ import PolicyInterface from '../../interfaces/PolicyInterface.js'; import PolicyType from '../../enum/PolicyTypeEnum.js'; +import { ConfigurationError } from '../../../errors.js'; abstract class AbstractPolicy implements PolicyInterface { static readonly TYPE_BYTE_OFF = 0; @@ -24,7 +25,7 @@ abstract class AbstractPolicy implements PolicyInterface { // eslint-disable-next-line @typescript-eslint/no-unused-vars type?: PolicyType ): { policy: PolicyInterface; offset: number } { - throw new Error('parsePolicy was not implemented'); + throw new ConfigurationError('parsePolicy was not implemented'); } constructor(type: PolicyType, binding: Uint8Array) { @@ -36,14 +37,14 @@ abstract class AbstractPolicy implements PolicyInterface { * Length of policy */ getLength(): number | never { - throw new Error('length was not implemented'); + throw new ConfigurationError('length was not implemented'); } /** * Return the content of the policy */ toBuffer(): Uint8Array | never { - throw new Error('toBuffer() was not implemented'); + throw new ConfigurationError('toBuffer() was not implemented'); } /** diff --git a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts index 92f4b649..3b8c3de4 100644 --- a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts +++ b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts @@ -1,6 +1,7 @@ import AbstractPolicy from './AbstractPolicy.js'; import { EmbeddedPolicyInterface } from '../../interfaces/PolicyInterface.js'; import PolicyTypes from '../../enum/PolicyTypeEnum.js'; +import { ConfigurationError } from '../../../errors.js'; /** * Embedded Policy @@ -71,7 +72,7 @@ class EmbeddedPolicy extends AbstractPolicy implements EmbeddedPolicyInterface { const buffer = new Uint8Array(this.getLength()); if (this.content.length > EmbeddedPolicy.MAX_POLICY_SIZE) { - throw new Error("TDF Policy can't be more that 2^16"); + throw new ConfigurationError("TDF Policy can't be more that 2^16"); } buffer.set([this.type], 0); diff --git a/lib/src/nanotdf/models/Policy/PolicyFactory.ts b/lib/src/nanotdf/models/Policy/PolicyFactory.ts index 7402524c..db6fc555 100644 --- a/lib/src/nanotdf/models/Policy/PolicyFactory.ts +++ b/lib/src/nanotdf/models/Policy/PolicyFactory.ts @@ -2,7 +2,7 @@ import AbstractPolicy from './AbstractPolicy.js'; import EmbeddedPolicy from './EmbeddedPolicy.js'; import RemotePolicy from './RemotePolicy.js'; import PolicyTypeEnum from '../../enum/PolicyTypeEnum.js'; -import { InvalidPolicyTypeError } from '../../../errors.js'; +import { UnsupportedFeatureError } from '../../../errors.js'; import CurveNameEnum from '../../enum/CurveNameEnum.js'; function parse( @@ -34,7 +34,7 @@ function parse( type )); } else { - throw new InvalidPolicyTypeError(); + throw new UnsupportedFeatureError(`unsupported policy type: ${type}`); } return { diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index eea61fbc..0944407c 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -1,3 +1,4 @@ +import { ConfigurationError, InvalidFileError } from '../../errors.js'; import ProtocolEnum from '../enum/ProtocolEnum.js'; import ResourceLocatorIdentifierEnum from '../enum/ResourceLocatorIdentifierEnum.js'; @@ -59,7 +60,7 @@ export default class ResourceLocator { protocol = ProtocolEnum.Https; break; default: - throw new Error(`resource locator protocol [${protocolStr}] unsupported`); + throw new ConfigurationError(`resource locator protocol [${protocolStr}] unsupported`); } // Set identifier padded length and protocol identifier byte @@ -75,13 +76,13 @@ export default class ResourceLocator { } else if (identifierLength <= 32) { return ResourceLocatorIdentifierEnum.ThirtyTwoBytes; } - throw new Error(`unsupported identifier length: ${identifier.length}`); + throw new ConfigurationError(`unsupported identifier length: ${identifier.length}`); })(); // Create buffer to hold protocol, body length, body, and identifier const lengthOfBody = new TextEncoder().encode(body).length; if (lengthOfBody == 0) { - throw new Error('url body empty'); + throw new ConfigurationError('url body empty'); } const identifierLength = identifierType.valueOf(); const offset = ResourceLocator.BODY_OFFSET + lengthOfBody + identifierLength; @@ -94,13 +95,13 @@ export default class ResourceLocator { // Length of body const lengthOfBody = buff[ResourceLocator.LENGTH_OFFSET]; if (lengthOfBody == 0) { - throw new Error('url body empty'); + throw new InvalidFileError('url body empty'); } // Body as utf8 string const decoder = new TextDecoder(); let offset = ResourceLocator.BODY_OFFSET + lengthOfBody; if (offset > buff.length) { - throw new Error('parse out of bounds error'); + throw new InvalidFileError('url parser: out of bounds error'); } const body = decoder.decode(buff.subarray(ResourceLocator.BODY_OFFSET, offset)); const protocol = protocolAndIdentifierType & 0xf; @@ -109,7 +110,7 @@ export default class ResourceLocator { case ProtocolEnum.Https: break; default: - throw new Error(`unsupported protocol type [${protocol}]`); + throw new InvalidFileError(`url parser: unsupported protocol type [${protocol}]`); } // identifier const identifierTypeNibble = protocolAndIdentifierType & 0xf0; @@ -121,7 +122,7 @@ export default class ResourceLocator { } else if (identifierTypeNibble === ResourceLocator.IDENTIFIER_32_BYTE) { identifierType = ResourceLocatorIdentifierEnum.ThirtyTwoBytes; } else if (identifierTypeNibble !== ResourceLocator.IDENTIFIER_0_BYTE) { - throw new Error(`unsupported key identifier type [${identifierTypeNibble}]`); + throw new InvalidFileError(`url parser: unsupported fragment type [${identifierTypeNibble}]`); } let identifier: string | undefined = undefined; @@ -136,7 +137,7 @@ export default class ResourceLocator { const kidStart = offset; offset = kidStart + identifierType.valueOf(); if (offset > buff.length) { - throw new Error('parse out of bounds error'); + throw new InvalidFileError('url parser: out of bounds error'); } const kidSubarray = buff.subarray(kidStart, offset); // Remove padding (assuming the padding is null bytes, 0x00) @@ -169,7 +170,7 @@ export default class ResourceLocator { case ProtocolEnum.Https: return 'https://' + this.body; default: - throw new Error('Resource locator protocol is not supported.'); + throw new ConfigurationError(`resource locator protocol unsupported [${this.protocol}]`); } } diff --git a/lib/src/nanotdf/models/Signature.ts b/lib/src/nanotdf/models/Signature.ts index dbd67c39..05610bbf 100644 --- a/lib/src/nanotdf/models/Signature.ts +++ b/lib/src/nanotdf/models/Signature.ts @@ -1,5 +1,6 @@ import Header from './Header.js'; import { lengthOfPublicKey, lengthOfSignature } from '../helpers/calculateByCurve.js'; +import { ConfigurationError } from '../../errors.js'; /** * NanoTDF Signature @@ -75,7 +76,7 @@ export default class Signature { */ copyToBuffer(buffer: Uint8Array): void { if (this.length > buffer.length) { - throw new Error('Invalid buffer size to copy signature'); + throw new ConfigurationError('Invalid buffer size to copy signature'); } buffer.set(this.publicKey, 0); diff --git a/lib/src/policy/api.ts b/lib/src/policy/api.ts index 8a575734..1cbbcded 100644 --- a/lib/src/policy/api.ts +++ b/lib/src/policy/api.ts @@ -1,3 +1,4 @@ +import { NetworkError, ServiceError } from '../errors.js'; import { AuthProvider } from '../auth/auth.js'; import { rstrip } from '../utils.js'; import { GetAttributeValuesByFqnsResponse, Value } from './attributes.js'; @@ -30,21 +31,19 @@ export async function attributeFQNsAsValues( redirect: 'follow', referrerPolicy: 'no-referrer', }); - - if (!response.ok) { - throw new Error(`${req.method} ${req.url} => ${response.status} ${response.statusText}`); - } } catch (e) { - console.error(`network error [${req.method} ${req.url}]`, e); - throw e; + throw new NetworkError(`network error [${req.method} ${req.url}]`, e); + } + + if (!response.ok) { + throw new ServiceError(`${req.method} ${req.url} => ${response.status} ${response.statusText}`); } let resp: GetAttributeValuesByFqnsResponse; try { resp = (await response.json()) as GetAttributeValuesByFqnsResponse; } catch (e) { - console.error(`response parse error [${req.method} ${req.url}]`, e); - throw e; + throw new ServiceError(`response parse error [${req.method} ${req.url}]`, e); } const values: Value[] = []; diff --git a/lib/src/policy/granter.ts b/lib/src/policy/granter.ts index 9173d8c8..823ec589 100644 --- a/lib/src/policy/granter.ts +++ b/lib/src/policy/granter.ts @@ -1,3 +1,4 @@ +import { ConfigurationError } from '../errors.js'; import { Attribute, AttributeRuleType, KeyAccessServer, Value } from './attributes.js'; export type KeySplitStep = { @@ -82,7 +83,7 @@ export function plan(dataAttrs: Value[]): KeySplitStep[] { for (const v of dataAttrs) { const { attribute, fqn } = v; if (!attribute) { - throw new Error(`attribute not defined for [${fqn}]`); + throw new ConfigurationError(`attribute not defined for [${fqn}]`); } const valFqn = fqn.toLowerCase(); const attrFqn = attribute.fqn.toLowerCase(); @@ -139,7 +140,7 @@ function simplify( const anyKids = []; for (const bc of children) { if (bc.op != 'anyOf') { - throw new Error('inversion'); + throw new Error('internal: autoconfigure inversion in disjunction'); } if (!bc.kases?.length) { continue; @@ -154,7 +155,7 @@ function simplify( } else { for (const bc of children) { if (bc.op != 'anyOf') { - throw new Error('inversion'); + throw new Error('insternal: autoconfigure inversion in conjunction'); } if (!bc.kases?.length) { continue; diff --git a/lib/src/utils.ts b/lib/src/utils.ts index ee4b5a15..d9513b09 100644 --- a/lib/src/utils.ts +++ b/lib/src/utils.ts @@ -3,6 +3,7 @@ import { exportSPKI, importX509 } from 'jose'; import { base64 } from './encodings/index.js'; import { pemCertToCrypto, pemPublicToCrypto } from './nanotdf-crypto/index.js'; +import { ConfigurationError } from './errors.js'; /** * Check to see if the given URL is 'secure'. This assumes: @@ -113,7 +114,7 @@ export function addNewLines(str: string): string { export async function cryptoPublicToPem(publicKey: CryptoKey): Promise { if (publicKey.type !== 'public') { - throw new TypeError('Incorrect key type'); + throw new ConfigurationError('incorrect key type'); } const exportedPublicKey = await crypto.subtle.exportKey('spki', publicKey); @@ -128,7 +129,10 @@ export async function pemToCryptoPublicKey(pem: string): Promise { } else if (/-----BEGIN CERTIFICATE-----/.test(pem)) { return pemCertToCrypto(pem); } - throw new Error(`unsupported pem type [${pem}]`); + // This can happen in several circumstances: + // - When parsing a PEM key from a KAS server + // - When converting between PEM and CryptoKey formats for user provided session keys (e.g. for DPoP) + throw new TypeError(`unsupported pem type [${pem}]`); } export async function extractPemFromKeyString(keyString: string): Promise { diff --git a/lib/tdf3/src/binary.ts b/lib/tdf3/src/binary.ts index 97ee70f8..cd33306e 100644 --- a/lib/tdf3/src/binary.ts +++ b/lib/tdf3/src/binary.ts @@ -1,3 +1,4 @@ +import { ConfigurationError } from '../../src/errors.js'; import { buffToString, SupportedEncoding, base64ToBytes } from './utils/index.js'; /** @@ -172,7 +173,7 @@ class StringBinary extends Binary { asString(encoding?: SupportedEncoding): string { if (encoding) { - throw new Error( + throw new ConfigurationError( 'Method doesnt accept encoding param, it returns binary string in original format' ); } diff --git a/lib/tdf3/src/client/DecoratedReadableStream.ts b/lib/tdf3/src/client/DecoratedReadableStream.ts index 803e4f58..59567f21 100644 --- a/lib/tdf3/src/client/DecoratedReadableStream.ts +++ b/lib/tdf3/src/client/DecoratedReadableStream.ts @@ -5,6 +5,7 @@ import { isFirefox } from '../../../src/utils.js'; import { type Metadata } from '../tdf.js'; import { type Manifest, type UpsertResponse } from '../models/index.js'; +import { ConfigurationError } from '../../../src/errors.js'; export async function streamToBuffer(stream: ReadableStream): Promise { const accumulator = await new Response(stream).arrayBuffer(); @@ -94,7 +95,7 @@ export class DecoratedReadableStream { options?: BufferEncoding | DecoratedReadableStreamSinkOptions ): Promise { if (options && typeof options === 'string') { - throw new Error('Unsupported Operation: Cannot set encoding in browser'); + throw new ConfigurationError('unsupported operation: Cannot set encoding in browser'); } if (isFirefox()) { await fileSave(new Response(this.stream), { diff --git a/lib/tdf3/src/client/builders.ts b/lib/tdf3/src/client/builders.ts index a5b87fcf..10752d63 100644 --- a/lib/tdf3/src/client/builders.ts +++ b/lib/tdf3/src/client/builders.ts @@ -3,7 +3,7 @@ import { AttributeObject, KeyInfo, Policy } from '../models/index.js'; import { type Metadata } from '../tdf.js'; import { Binary } from '../binary.js'; -import { IllegalArgumentError } from '../../../src/errors.js'; +import { ConfigurationError } from '../../../src/errors.js'; import { PemKeyPair } from '../crypto/declarations.js'; import { EntityObject } from '../../../src/tdf/EntityObject.js'; import { DecoratedReadableStream } from './DecoratedReadableStream.js'; @@ -104,7 +104,7 @@ class EncryptParamsBuilder { */ withStreamSource(readStream: ReadableStream): EncryptParamsBuilder { if (!readStream?.getReader) { - throw new Error( + throw new ConfigurationError( `Source must be a WebReadableStream. Run node streams through stream.Readable.toWeb()` ); } @@ -363,7 +363,7 @@ class EncryptParamsBuilder { */ setStreamWindowSize(numBytes: number) { if (numBytes <= 0) { - throw new Error('Stream window size must be positive'); + throw new ConfigurationError('Stream window size must be positive'); } this._params.windowSize = numBytes; } @@ -577,7 +577,7 @@ class DecryptParamsBuilder { */ setUrlSource(url: string) { if (!/^https?/.exec(url)) { - throw new IllegalArgumentError(`stream source must be a web url, not [${url}]`); + throw new ConfigurationError(`stream source must be a web url, not [${url}]`); } this._params.source = { type: 'remote', location: url }; } @@ -607,7 +607,7 @@ class DecryptParamsBuilder { */ withStreamSource(stream: ReadableStream) { if (!stream?.getReader) { - throw new Error( + throw new ConfigurationError( `Source must be a WebReadableStream. Run node streams through stream.Readable.toWeb()` ); } @@ -688,7 +688,7 @@ class DecryptParamsBuilder { */ build(): Readonly { if (!this._params.source) { - throw new IllegalArgumentError('No source specified'); + throw new ConfigurationError('No source specified'); } return this._deepCopy(this._params as DecryptParams); } diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index c703a2fb..1b752ae0 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -55,7 +55,7 @@ import { EncryptParamsBuilder, } from './builders.js'; import { KasPublicKeyInfo, OriginAllowList } from '../../../src/access.js'; -import { TdfError } from '../../../src/errors.js'; +import { ConfigurationError } from '../../../src/errors.js'; import { EntityObject } from '../../../src/tdf/EntityObject.js'; import { Binary } from '../binary.js'; import { AesGcmCipher } from '../ciphers/aes-gcm-cipher.js'; @@ -98,7 +98,7 @@ const getFirstTwoBytes = async (chunker: Chunker) => new TextDecoder().decode(aw const makeChunkable = async (source: DecryptSource) => { if (!source) { - throw new Error('Invalid source'); + throw new ConfigurationError('invalid source'); } // dump stream to buffer // we don't support streams anyways (see zipreader.js) @@ -297,7 +297,7 @@ export class Client { } else { // handle Deprecated `kasRewrapEndpoint` parameter if (!clientConfig.keyRewrapEndpoint) { - throw new Error('KAS definition not found'); + throw new ConfigurationError('KAS definition not found'); } this.kasEndpoint = clientConfig.keyRewrapEndpoint.replace(/\/rewrap$/, ''); } @@ -315,11 +315,11 @@ export class Client { !!clientConfig.ignoreAllowList ); if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.allows(kasOrigin)) { - throw new TdfError(`Invalid KAS endpoint [${this.kasEndpoint}]`); + throw new ConfigurationError(`Invalid KAS endpoint [${this.kasEndpoint}]`); } } else { if (!validateSecureUrl(this.kasEndpoint)) { - throw new TdfError( + throw new ConfigurationError( `Invalid KAS endpoint [${this.kasEndpoint}]; to force, please list it among allowedKases` ); } @@ -340,7 +340,7 @@ export class Client { this.clientId = clientConfig.clientId; if (!this.authProvider) { if (!clientConfig.clientId) { - throw new Error('Client ID or custom AuthProvider must be defined'); + throw new ConfigurationError('Client ID or custom AuthProvider must be defined'); } //Are we exchanging a refreshToken for a bearer token (normal AuthCode browser auth flow)? @@ -425,7 +425,7 @@ export class Client { if (!avs.length && fqns.length) { // Hydrate avs from policy endpoint givnen the fqns if (!this.policyEndpoint) { - throw new Error('policyEndpoint not set in TDF3 Client constructor'); + throw new ConfigurationError('policyEndpoint not set in TDF3 Client constructor'); } avs = await attributeFQNsAsValues( this.policyEndpoint, @@ -442,7 +442,7 @@ export class Client { avs.length != scope.attributes?.length || !avs.map(({ fqn }) => fqn).every((a) => fqns.indexOf(a) >= 0) ) { - throw new Error( + throw new ConfigurationError( `Attribute mismatch between [${fqns}] and explicit values ${JSON.stringify( avs.map(({ fqn }) => fqn) )}` @@ -530,9 +530,8 @@ export class Client { } // Wrap if it's html. - // FIXME: Support streaming for html format. if (!stream.manifest) { - throw new Error('Missing manifest in encrypt function'); + throw new Error('internal: missing manifest in encrypt function'); } const htmlBuf = wrapHtml(await stream.toBuffer(), stream.manifest, this.readerUrl ?? ''); @@ -575,7 +574,7 @@ export class Client { } } if (!this.authProvider) { - throw new Error('AuthProvider missing'); + throw new ConfigurationError('AuthProvider missing'); } const chunker = await makeChunkable(source); diff --git a/lib/tdf3/src/client/validation.ts b/lib/tdf3/src/client/validation.ts index cf62bddd..0981bcec 100644 --- a/lib/tdf3/src/client/validation.ts +++ b/lib/tdf3/src/client/validation.ts @@ -38,13 +38,13 @@ export const ATTR_ATTRIBUTE_PATTERN = `^(${ATTR_NAMESPACE_PATTERN}${ATTR_VALUE}) export const validateAttributeObject = (attr: unknown): true | never => { const isObject = typeof attr === 'object'; if (!isObject) { - throw new AttributeValidationError(`attribute should be an object`); + throw new AttributeValidationError(`attribute should be an object`, attr); } const { attribute } = attr as Record; const isString = typeof attribute === 'string'; if (!isString) { - throw new AttributeValidationError(`attribute prop should be a string`); + throw new AttributeValidationError(`attribute prop should be a string`, attr); } return validateAttribute(attribute); @@ -52,7 +52,7 @@ export const validateAttributeObject = (attr: unknown): true | never => { export function validateAttribute(attribute: string): true | never { if (!attribute.match(ATTR_ATTRIBUTE_PATTERN)) { - throw new AttributeValidationError(`attribute is in invalid format [${attribute}]`); + throw new AttributeValidationError(`attribute is in invalid format [${attribute}]`, attribute); } const ATTR_NAME_PREFIX = `/${ATTR_NAME_PROP_NAME}/`; @@ -61,18 +61,18 @@ export function validateAttribute(attribute: string): true | never { const attrValueMatch = sageGetMatch(attribute.match(ATTR_VALUE)); if (!attrNameMatch) { - throw new AttributeValidationError(`attribute name matching error`); + throw new AttributeValidationError(`attribute name matching error`, attribute); } if (!attrValueMatch) { - throw new AttributeValidationError(`attribute value matching error`); + throw new AttributeValidationError(`attribute value matching error`, attribute); } const attributeName = attrNameMatch.slice(ATTR_NAME_PREFIX.length); const attributeValue = attrValueMatch.slice(ATTR_VALUE_PREFIX.length); if (attributeName === attributeValue) { - throw new AttributeValidationError(`attribute name should be unique with its value`); + throw new AttributeValidationError(`attribute name should be unique with its value`, attribute); } return true; diff --git a/lib/tdf3/src/crypto/crypto-utils.ts b/lib/tdf3/src/crypto/crypto-utils.ts index e987de6b..59a10750 100644 --- a/lib/tdf3/src/crypto/crypto-utils.ts +++ b/lib/tdf3/src/crypto/crypto-utils.ts @@ -1,5 +1,4 @@ import { base64 } from '../../../src/encodings/index.js'; -import { IllegalArgumentError } from '../../../src/errors.js'; import { type AnyKeyPair, type PemKeyPair } from './declarations.js'; import { rsaPkcs1Sha256 } from './index.js'; @@ -106,7 +105,7 @@ export const toCryptoKeyPair = async (input: AnyKeyPair): Promise return input; } if (!isPemKeyPair(input)) { - throw new Error('invalid keypair'); + throw new Error('internal: generated invalid keypair'); } const k = [input.publicKey, input.privateKey] .map(removePemFormatting) @@ -118,18 +117,3 @@ export const toCryptoKeyPair = async (input: AnyKeyPair): Promise ]); return { privateKey, publicKey }; }; - -export async function cryptoToPem(k: CryptoKey): Promise { - switch (k.type) { - case 'private': { - const exPrivate = await crypto.subtle.exportKey('pkcs8', k); - return formatAsPem(exPrivate, 'PRIVATE KEY'); - } - case 'public': { - const exPublic = await crypto.subtle.exportKey('spki', k); - return formatAsPem(exPublic, 'PUBLIC KEY'); - } - default: - throw new IllegalArgumentError(`unsupported key type [${k.type}]`); - } -} diff --git a/lib/tdf3/src/crypto/index.ts b/lib/tdf3/src/crypto/index.ts index 93d28537..6cbc3933 100644 --- a/lib/tdf3/src/crypto/index.ts +++ b/lib/tdf3/src/crypto/index.ts @@ -13,7 +13,7 @@ import { MIN_ASYMMETRIC_KEY_SIZE_BITS, PemKeyPair, } from './declarations.js'; -import { TdfDecryptError } from '../../../src/errors.js'; +import { ConfigurationError, DecryptError } from '../../../src/errors.js'; import { formatAsPem, removePemFormatting } from './crypto-utils.js'; import { encodeArrayBuffer as hexEncode } from '../../../src/encodings/hex.js'; import { decodeArrayBuffer as base64Decode } from '../../../src/encodings/base64.js'; @@ -34,7 +34,7 @@ export function rsaOaepSha1( modulusLength: number = MIN_ASYMMETRIC_KEY_SIZE_BITS ): RsaHashedKeyGenParams { if (!modulusLength || modulusLength < MIN_ASYMMETRIC_KEY_SIZE_BITS) { - throw new Error('Invalid key size requested'); + throw new ConfigurationError('Invalid key size requested'); } return { name: 'RSA-OAEP', @@ -50,7 +50,7 @@ export function rsaPkcs1Sha256( modulusLength: number = MIN_ASYMMETRIC_KEY_SIZE_BITS ): RsaHashedKeyGenParams { if (!modulusLength || modulusLength < MIN_ASYMMETRIC_KEY_SIZE_BITS) { - throw new Error('Invalid key size requested'); + throw new ConfigurationError('Invalid key size requested'); } return { name: 'RSASSA-PKCS1-v1_5', @@ -100,7 +100,8 @@ export async function generateSigningKeyPair(): Promise { export async function cryptoToPemPair(keysMaybe: unknown): Promise { const keys = keysMaybe as CryptoKeyPair; if (!keys.privateKey || !keys.publicKey) { - throw new Error('invalid'); + // These are only ever generated here, so this should not happen + throw new Error('internal: invalid keys'); } const [exPublic, exPrivate] = await Promise.all([ @@ -291,7 +292,7 @@ async function _doDecrypt( // Catching this error so we can specifically check for OperationError .catch((err) => { if (err.name === 'OperationError') { - throw new TdfDecryptError(err); + throw new DecryptError(err); } throw err; diff --git a/lib/tdf3/src/models/assertion.ts b/lib/tdf3/src/models/assertion.ts index 746bb615..dc08b08c 100644 --- a/lib/tdf3/src/models/assertion.ts +++ b/lib/tdf3/src/models/assertion.ts @@ -1,6 +1,7 @@ import { canonicalizeEx } from 'json-canonicalize'; import { SignJWT, jwtVerify } from 'jose'; import { AssertionKey } from './../client/AssertionConfig.js'; +import { ConfigurationError, InvalidFileError } from '../../../src/errors.js'; export type AssertionKeyAlg = 'RS256' | 'HS256'; export type AssertionType = 'handling' | 'other'; @@ -63,18 +64,18 @@ export async function sign( sig: string, key: AssertionKey ): Promise { - const payload: any = {}; + const payload: Record = {}; payload[kAssertionHash] = assertionHash; payload[kAssertionSignature] = sig; + let token: string; try { - const token = await new SignJWT(payload).setProtectedHeader({ alg: key.alg }).sign(key.key); - - this.binding.method = 'jws'; - this.binding.signature = token; + token = await new SignJWT(payload).setProtectedHeader({ alg: key.alg }).sign(key.key); } catch (error) { - throw new Error(`Signing assertion failed: ${error.message}`); + throw new ConfigurationError(`Signing assertion failed: ${error.message}`, error); } + this.binding.method = 'jws'; + this.binding.signature = token; } /** @@ -92,7 +93,7 @@ export async function verify(this: Assertion, key: AssertionKey): Promise<[strin return [payload[kAssertionHash] as string, payload[kAssertionSignature] as string]; } catch (error) { - throw new Error(`Verifying assertion failed: ${error.message}`); + throw new InvalidFileError(`Verifying assertion failed: ${error.message}`, error); } } diff --git a/lib/tdf3/src/models/encryption-information.ts b/lib/tdf3/src/models/encryption-information.ts index 700ff73c..e288bc41 100644 --- a/lib/tdf3/src/models/encryption-information.ts +++ b/lib/tdf3/src/models/encryption-information.ts @@ -10,6 +10,7 @@ import { type EncryptResult, } from '../crypto/declarations.js'; import { IntegrityAlgorithm } from '../tdf.js'; +import { ConfigurationError } from '../../../src/errors.js'; export type KeyInfo = { readonly unwrappedKeyBinary: Binary; @@ -102,7 +103,9 @@ export class SplitKey { : typeof metadata === 'string' ? metadata : () => { - throw new Error(); + throw new ConfigurationError( + "KAO generation failure: metadata isn't a string or object" + ); } ) as string; @@ -137,9 +140,10 @@ export class SplitKey { } async write(policy: Policy, keyInfo: KeyInfo): Promise { - const algorithm = this.cipher.name; + const algorithm = this.cipher?.name; if (!algorithm) { - throw new Error('Uninitialized cipher type'); + // Hard coded as part of the cipher object. This should not be reachable. + throw new ConfigurationError('uninitialized cipher type'); } const keyAccessObjects = await this.getKeyAccessObjects(policy, keyInfo); diff --git a/lib/tdf3/src/models/policy.ts b/lib/tdf3/src/models/policy.ts index 7f39603b..589ec1db 100644 --- a/lib/tdf3/src/models/policy.ts +++ b/lib/tdf3/src/models/policy.ts @@ -1,4 +1,4 @@ -import { PolicyIntegrityError } from '../../../src/errors.js'; +import { ConfigurationError } from '../../../src/errors.js'; import { AttributeObject } from './attribute-set.js'; export const CURRENT_VERSION = '1.1.0'; @@ -16,7 +16,7 @@ export type Policy = { export function validatePolicyObject(policyMaybe: unknown): policyMaybe is Policy { if (typeof policyMaybe !== 'object') { - throw new PolicyIntegrityError( + throw new ConfigurationError( `The given policy reference must be an object, not: ${policyMaybe}` ); } @@ -27,7 +27,7 @@ export function validatePolicyObject(policyMaybe: unknown): policyMaybe is Polic if (policy.body && !policy.body.dissem) missingFields.push('body.dissem'); if (missingFields.length) { - throw new PolicyIntegrityError( + throw new ConfigurationError( `The given policy object requires the following properties: ${missingFields}` ); } diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 2ef75776..e6744b3a 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -41,16 +41,17 @@ import { import { Binary } from './binary.js'; import { KasPublicKeyAlgorithm, KasPublicKeyInfo, OriginAllowList } from '../../src/access.js'; import { - IllegalArgumentError, - KasDecryptError, - KasUpsertError, - KeyAccessError, - ManifestIntegrityError, - PolicyIntegrityError, - TdfDecryptError, + ConfigurationError, + DecryptError, + InvalidFileError, + IntegrityError, + NetworkError, + PermissionDeniedError, + ServiceError, TdfError, - TdfPayloadExtractionError, + UnauthenticatedError, UnsafeUrlError, + UnsupportedFeatureError as UnsupportedError, } from '../../src/errors.js'; import { htmlWrapperTemplate } from './templates/index.js'; @@ -206,7 +207,7 @@ export async function fetchKasPublicKey( algorithm?: KasPublicKeyAlgorithm ): Promise { if (!kas) { - throw new TdfError('KAS definition not found'); + throw new ConfigurationError('KAS definition not found'); } // Logs insecure KAS. Secure is enforced in constructor validateSecureUrl(kas); @@ -215,16 +216,14 @@ export async function fetchKasPublicKey( if (algorithm) { params.algorithm = algorithm; } + const v2Url = `${kas}/v2/kas_public_key`; try { - const response: { data: string | KasPublicKeyInfo } = await axios.get( - `${kas}/v2/kas_public_key`, - { - params: { - ...params, - v: '2', - }, - } - ); + const response: { data: string | KasPublicKeyInfo } = await axios.get(v2Url, { + params: { + ...params, + v: '2', + }, + }); const publicKey = typeof response.data === 'string' ? await extractPemFromKeyString(response.data) @@ -237,16 +236,32 @@ export async function fetchKasPublicKey( }; } catch (cause) { const status = cause?.response?.status; - if (status != 400 && status != 404) { - throw new TdfError( - `Retrieving KAS public key [${kas}] failed [${cause.name}] [${cause.message}]`, - cause - ); + switch (status) { + case 400: + case 404: + // KAS does not yet implement v2, maybe + break; + case 401: + throw new UnauthenticatedError(`[${v2Url}] requires auth`, cause); + case 403: + throw new PermissionDeniedError(`[${v2Url}] permission denied`, cause); + default: + if (status && status >= 400 && status < 500) { + throw new ConfigurationError( + `[${v2Url}] request error [${status}] [${cause.name}] [${cause.message}]`, + cause + ); + } + throw new NetworkError( + `[${v2Url}] error [${status}] [${cause.name}] [${cause.message}]`, + cause + ); } } // Retry with v1 params + const v1Url = `${kas}/kas_public_key`; try { - const response: { data: string | KasPublicKeyInfo } = await axios.get(`${kas}/kas_public_key`, { + const response: { data: string | KasPublicKeyInfo } = await axios.get(v1Url, { params, }); const publicKey = @@ -261,10 +276,24 @@ export async function fetchKasPublicKey( ...(typeof response.data !== 'string' && response.data.kid && { kid: response.data.kid }), }; } catch (cause) { - throw new TdfError( - `Retrieving KAS public key [${kas}] failed [${cause.name}] [${cause.message}]`, - cause - ); + const status = cause?.response?.status; + switch (status) { + case 401: + throw new UnauthenticatedError(`[${v1Url}] requires auth`, cause); + case 403: + throw new PermissionDeniedError(`[${v1Url}] permission denied`, cause); + default: + if (status && status >= 400 && status < 500) { + throw new ConfigurationError( + `[${v2Url}] request error [${status}] [${cause.name}] [${cause.message}]`, + cause + ); + } + throw new NetworkError( + `[${v1Url}] error [${status}] [${cause.name}] [${cause.message}]`, + cause + ); + } } } /** @@ -302,13 +331,13 @@ export function unwrapHtml(htmlPayload: ArrayBuffer | Uint8Array | Binary | stri const payloadRe = /]*value=['"]?([a-zA-Z0-9+/=]+)['"]?/; const reResult = payloadRe.exec(html); if (reResult === null) { - throw new TdfPayloadExtractionError('Payload is missing'); + throw new InvalidFileError('Payload is missing'); } const base64Payload = reResult[1]; try { return base64ToBuffer(base64Payload); } catch (e) { - throw new TdfPayloadExtractionError('There was a problem extracting the TDF3 payload', e); + throw new InvalidFileError('There was a problem extracting the TDF3 payload', e); } } @@ -363,7 +392,7 @@ export async function buildKeyAccess({ case 'remote': return new KeyAccessRemote(kasUrl, kasKeyIdentifier, pubKey, metadata, sid); default: - throw new KeyAccessError(`buildKeyAccess: Key access type ${type} is unknown`); + throw new ConfigurationError(`buildKeyAccess: Key access type ${type} is unknown`); } } @@ -389,7 +418,7 @@ export async function buildKeyAccess({ } } // All failed. Raise an error. - throw new KeyAccessError('TDF.buildKeyAccess: No source for kasUrl or pubKey'); + throw new ConfigurationError('TDF.buildKeyAccess: No source for kasUrl or pubKey'); } export function validatePolicyObject(policy: Policy): void { @@ -400,7 +429,7 @@ export function validatePolicyObject(policy: Policy): void { if (policy.body && !policy.body.dissem) missingFields.push('body.dissem'); if (missingFields.length) { - throw new PolicyIntegrityError( + throw new ConfigurationError( `The given policy object requires the following properties: ${missingFields}` ); } @@ -422,17 +451,8 @@ async function _generateManifest( ...(mimeType && { mimeType }), }; - if (!policy) { - throw new Error(`No policy provided`); - } const encryptionInformationStr = await encryptionInformation.write(policy, keyInfo); - - if (!encryptionInformationStr) { - throw new Error('Missing encryption information'); - } - const assertions: Assertion[] = []; - return { payload, // generate the manifest first, then insert integrity information into it @@ -458,7 +478,7 @@ async function getSignature( buffToString(new Uint8Array(payloadBinary.asArrayBuffer()), 'utf-8') ); default: - throw new IllegalArgumentError(`Unsupported signature alg [${algorithmType}]`); + throw new ConfigurationError(`Unsupported signature alg [${algorithmType}]`); } } @@ -485,14 +505,14 @@ export async function upsert({ return allowList; } if (!allowedKases) { - throw new Error('Upsert cannot be done without allowlist'); + throw new ConfigurationError('Upsert cannot be done without allowlist'); } return new OriginAllowList(allowedKases); })(); const { keyAccess, policy } = unsavedManifest.encryptionInformation; const isAppIdProvider = authProvider && isAppIdProviderCheck(authProvider); if (authProvider === undefined) { - throw new Error('Upsert cannot be done without auth provider'); + throw new ConfigurationError('Upsert cannot be done without auth provider'); } return Promise.all( keyAccess.map(async (keyAccessObject) => { @@ -503,7 +523,7 @@ export async function upsert({ } if (!allowed.allows(keyAccessObject.url)) { - throw new KasUpsertError(`Unexpected KAS url: [${keyAccessObject.url}]`); + throw new UnsafeUrlError(`Unexpected KAS url: [${keyAccessObject.url}]`); } const url = `${keyAccessObject.url}/${isAppIdProvider ? '' : 'v2/'}upsert`; @@ -545,7 +565,22 @@ export async function upsert({ } return response.data; } catch (e) { - throw new KasUpsertError( + if (e.response) { + if (e.reponse.status >= 500) { + throw new ServiceError('upsert failure', e); + } else if (e.response.status === 403) { + throw new PermissionDeniedError('upsert failure', e); + } else if (e.response.status === 401) { + throw new UnauthenticatedError('upsert auth failure', e); + } else if (e.response.status === 400) { + throw new ConfigurationError('upsert bad request; likely a configuration error', e); + } else { + throw new NetworkError('upsert server error', e); + } + } else if (e.request) { + throw new NetworkError('upsert request failure', e); + } + throw new TdfError( `Unable to perform upsert operation on the KAS: [${e.name}: ${e.message}], response: [${e?.response?.body}]`, e ); @@ -556,14 +591,12 @@ export async function upsert({ export async function writeStream(cfg: EncryptConfiguration): Promise { if (!cfg.authProvider) { - throw new IllegalArgumentError('No authorization middleware defined'); + throw new ConfigurationError('No authorization middleware defined'); } if (!cfg.contentStream) { - throw new IllegalArgumentError('No input stream defined'); - } - if (!cfg.encryptionInformation) { - throw new IllegalArgumentError('No encryption type specified'); + throw new ConfigurationError('No input stream defined'); } + // eslint-disable-next-line @typescript-eslint/no-this-alias const segmentInfos: Segment[] = []; @@ -587,11 +620,6 @@ export async function writeStream(cfg: EncryptConfiguration): Promise cfg.byteLimit) { - throw new Error(`Safe byte limit (${cfg.byteLimit}) exceeded`); + throw new ConfigurationError(`Safe byte limit (${cfg.byteLimit}) exceeded`); } //new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength); crcCounter = unsigned(chunk as Uint8Array, crcCounter); @@ -866,10 +895,11 @@ export function splitLookupTableFactory( const accessibleSplits = new Set(keyAccess.filter(allowed).map(({ sid }) => sid)); if (splitIds.size > accessibleSplits.size) { const disallowedKases = new Set(keyAccess.filter((k) => !allowed(k)).map(({ url }) => url)); - throw new KasDecryptError( + throw new UnsafeUrlError( `Unreconstructable key - disallowed KASes include: ${JSON.stringify([ ...disallowedKases, - ])} from splitIds ${JSON.stringify([...splitIds])}` + ])} from splitIds ${JSON.stringify([...splitIds])}`, + ...disallowedKases ); } const splitPotentials: Record> = Object.fromEntries( @@ -878,7 +908,7 @@ export function splitLookupTableFactory( for (const kao of keyAccess) { const disjunction = splitPotentials[kao.sid ?? '']; if (kao.url in disjunction) { - throw new KasDecryptError( + throw new InvalidFileError( `TODO: Fallback to no split ids. Repetition found for [${kao.url}] on split [${kao.sid}]` ); } @@ -905,7 +935,9 @@ async function unwrapKey({ cryptoService: CryptoService; }) { if (authProvider === undefined) { - throw new KasDecryptError('Upsert can be done without auth provider'); + throw new ConfigurationError( + 'upsert requires auth provider; must be configured in client constructor' + ); } const { keyAccess } = manifest.encryptionInformation; const splitPotentials = splitLookupTableFactory(keyAccess, allowedKases); @@ -980,8 +1012,27 @@ async function unwrapKey({ ); rewrappedKeys.push(new Uint8Array(decryptedKeyBinary.asByteArray())); } catch (e) { - console.error(e); - throw new KasDecryptError( + if (e.response) { + if (e.reponse.status >= 500) { + throw new ServiceError('rewrap failure', e); + } else if (e.response.status === 403) { + throw new PermissionDeniedError('rewrap failure', e); + } else if (e.response.status === 401) { + throw new UnauthenticatedError('rewrap auth failure', e); + } else if (e.response.status === 400) { + throw new InvalidFileError( + 'rewrap bad request; could indicate an invalid policy binding or a configuration error', + e + ); + } else { + throw new NetworkError('rewrap server error', e); + } + } else if (e.request) { + throw new NetworkError('rewrap request failure', e); + } else if (e.name == 'InvalidAccessError' || e.name == 'OperationError') { + throw new DecryptError('unable to unwrap key from kas', e); + } + throw new InvalidFileError( `Unable to decrypt the response from KAS: [${e.name}: ${e.message}], response: [${e?.response?.body}]`, e ); @@ -1006,6 +1057,8 @@ async function decryptChunk( segmentIntegrityAlgorithm: IntegrityAlgorithm, cryptoService: CryptoService ): Promise { + if (segmentIntegrityAlgorithm !== 'GMAC' && segmentIntegrityAlgorithm !== 'HS256') { + } const segmentHashStr = await getSignature( reconstructedKeyBinary, Binary.fromArrayBuffer(encryptedChunk.buffer), @@ -1013,7 +1066,7 @@ async function decryptChunk( cryptoService ); if (hash !== btoa(segmentHashStr)) { - throw new ManifestIntegrityError('Failed integrity check on segment hash'); + throw new IntegrityError('Failed integrity check on segment hash'); } return await cipher.decrypt(encryptedChunk, reconstructedKeyBinary); } @@ -1038,33 +1091,35 @@ async function updateChunkQueue( } requests.push( (async () => { + let buffer: Uint8Array | null; + + const slice = chunkMap.slice(i, i + chunksInOneDownload); try { - const slice = chunkMap.slice(i, i + chunksInOneDownload); const bufferSize = slice.reduce( (currentVal, { encryptedSegmentSize }) => currentVal + (encryptedSegmentSize as number), 0 ); - const buffer: Uint8Array | null = await zipReader.getPayloadSegment( + buffer = await zipReader.getPayloadSegment( centralDirectory, '0.payload', slice[0].encryptedOffset, bufferSize ); - if (buffer) { - sliceAndDecrypt({ - buffer, - cryptoService, - reconstructedKeyBinary, - slice, - cipher, - segmentIntegrityAlgorithm, - }); - } } catch (e) { - throw new TdfDecryptError( - 'Error decrypting payload. This suggests the key used to decrypt the payload is not correct.', - e - ); + if (e instanceof InvalidFileError) { + throw e; + } + throw new NetworkError('unable to fetch payload segment', e); + } + if (buffer) { + sliceAndDecrypt({ + buffer, + cryptoService, + reconstructedKeyBinary, + slice, + cipher, + segmentIntegrityAlgorithm, + }); } })() ); @@ -1095,19 +1150,26 @@ export async function sliceAndDecrypt({ buffer.slice(offset, offset + (encryptedSegmentSize as number)) ); - await decryptChunk( - encryptedChunk, - reconstructedKeyBinary, - slice[index]['hash'], - cipher, - segmentIntegrityAlgorithm, - cryptoService - ) - .then((result) => { - slice[index].decryptedChunk = result; - return null; - }) - .then(_resolve, _reject); + try { + const result = await decryptChunk( + encryptedChunk, + reconstructedKeyBinary, + slice[index]['hash'], + cipher, + segmentIntegrityAlgorithm, + cryptoService + ); + slice[index].decryptedChunk = result; + if (_resolve) { + _resolve(null); + } + } catch (e) { + if (_reject) { + _reject(e); + } else { + throw e; + } + } } } @@ -1115,13 +1177,13 @@ export async function readStream(cfg: DecryptConfiguration) { let { allowList } = cfg; if (!allowList) { if (!cfg.allowedKases) { - throw new Error('Upsert cannot be done without allowlist'); + throw new ConfigurationError('Upsert cannot be done without allowlist'); } allowList = new OriginAllowList(cfg.allowedKases); } const { manifest, zipReader, centralDirectory } = await loadTDFStream(cfg.chunker); if (!manifest) { - throw new Error('Missing manifest data'); + throw new InvalidFileError('Missing manifest data'); } cfg.keyMiddleware ??= async (key) => key; @@ -1146,6 +1208,9 @@ export async function readStream(cfg: DecryptConfiguration) { // check the combined string of hashes const aggregateHash = segments.map(({ hash }) => base64.decode(hash)).join(''); const integrityAlgorithm = rootSignature.alg; + if (integrityAlgorithm !== 'GMAC' && integrityAlgorithm !== 'HS256') { + throw new UnsupportedError(`Unsupported integrity alg [${integrityAlgorithm}]`); + } const payloadSigStr = await getSignature( keyForDecryption, Binary.fromString(aggregateHash), @@ -1157,7 +1222,7 @@ export async function readStream(cfg: DecryptConfiguration) { manifest.encryptionInformation.integrityInformation.rootSignature.sig !== base64.encode(payloadSigStr) ) { - throw new ManifestIntegrityError('Failed integrity check on root signature'); + throw new IntegrityError('Failed integrity check on root signature'); } // // Validate assertions @@ -1195,12 +1260,12 @@ export async function readStream(cfg: DecryptConfiguration) { // check if assertionHash is same as hashOfAssertion if (hashOfAssertion !== assertionHash) { - throw new ManifestIntegrityError('Assertion hash mismatch'); + throw new IntegrityError('Assertion hash mismatch'); } // check if assertionSig is same as encodedHash if (assertionSig !== encodedHash) { - throw new ManifestIntegrityError('Failed integrity check on assertion signature'); + throw new IntegrityError('Failed integrity check on assertion signature'); } } @@ -1228,6 +1293,10 @@ export async function readStream(cfg: DecryptConfiguration) { ); const cipher = new AesGcmCipher(cfg.cryptoService); + const segmentIntegrityAlg = segmentHashAlg || integrityAlgorithm; + if (segmentIntegrityAlg !== 'GMAC' && segmentIntegrityAlg !== 'HS256') { + throw new UnsupportedError(`Unsupported segment hash alg [${segmentIntegrityAlg}]`); + } // Not waiting for Promise to resolve updateChunkQueue( @@ -1236,7 +1305,7 @@ export async function readStream(cfg: DecryptConfiguration) { zipReader, keyForDecryption, cipher, - segmentHashAlg || integrityAlgorithm, + segmentIntegrityAlg, cfg.cryptoService ); diff --git a/lib/tdf3/src/utils/chunkers.ts b/lib/tdf3/src/utils/chunkers.ts index 10c2dd14..759a8666 100644 --- a/lib/tdf3/src/utils/chunkers.ts +++ b/lib/tdf3/src/utils/chunkers.ts @@ -4,6 +4,7 @@ import { isDecoratedReadableStream, } from '../client/DecoratedReadableStream.js'; import axiosRetry from 'axios-retry'; +import { ConfigurationError, NetworkError } from '../../../src/errors.js'; let axiosRemoteChunk: AxiosInstance | null = null; @@ -48,7 +49,7 @@ async function getRemoteChunk(url: string, range?: string): Promise responseType: 'arraybuffer', }); if (!res.data) { - throw new Error( + throw new NetworkError( 'Unexpected response type: Server should have responded with an ArrayBuffer.' ); } @@ -88,30 +89,30 @@ export const fromDataSource = async ({ type, location }: DataSource) => { switch (type) { case 'buffer': if (!(location instanceof Uint8Array)) { - throw new Error('Invalid data source; must be uint8 array'); + throw new ConfigurationError('Invalid data source; must be uint8 array'); } return fromBuffer(location); case 'chunker': if (!(location instanceof Function)) { - throw new Error('Invalid data source; must be uint8 array'); + throw new ConfigurationError('Invalid data source; must be uint8 array'); } return location; case 'file-browser': if (!(location instanceof Blob)) { - throw new Error('Invalid data source; must be at least a Blob'); + throw new ConfigurationError('Invalid data source; must be at least a Blob'); } return fromBrowserFile(location); case 'remote': if (typeof location !== 'string') { - throw new Error('Invalid data source; url not provided'); + throw new ConfigurationError('Invalid data source; url not provided'); } return fromUrl(location); case 'stream': if (!isDecoratedReadableStream(location)) { - throw new Error('Invalid data source; must be DecoratedTdfStream'); + throw new ConfigurationError('Invalid data source; must be DecoratedTdfStream'); } return fromBuffer(await location.toBuffer()); default: - throw new Error(`Data source type not defined, or not supported: ${type}}`); + throw new ConfigurationError(`Data source type not defined, or not supported: ${type}}`); } }; diff --git a/lib/tdf3/src/utils/index.ts b/lib/tdf3/src/utils/index.ts index 1fa940f1..0fa41f7a 100644 --- a/lib/tdf3/src/utils/index.ts +++ b/lib/tdf3/src/utils/index.ts @@ -4,6 +4,7 @@ import * as WebCryptoService from '../crypto/index.js'; import { KeyInfo, SplitKey } from '../models/index.js'; import { AesGcmCipher } from '../ciphers/aes-gcm-cipher.js'; +import { ConfigurationError } from '../../../src/errors.js'; export { ZipReader, readUInt64LE } from './zip-reader.js'; export { ZipWriter } from './zip-writer.js'; @@ -301,7 +302,7 @@ export async function keyMiddleware(): Promise<{ const cipher = new AesGcmCipher(WebCryptoService); const encryptionInformation = new SplitKey(cipher); if (!encryptionInformation?.generateKey) { - throw new Error('Crypto service not initialised'); + throw new ConfigurationError('Crypto service not initialised'); } const key = await encryptionInformation.generateKey(); return { keyForEncryption: key, keyForManifest: key }; diff --git a/lib/tdf3/src/utils/zip-reader.ts b/lib/tdf3/src/utils/zip-reader.ts index e76dff48..1fd6cdbe 100644 --- a/lib/tdf3/src/utils/zip-reader.ts +++ b/lib/tdf3/src/utils/zip-reader.ts @@ -1,3 +1,4 @@ +import { InvalidFileError } from '../../../src/errors.js'; import { Manifest } from '../models/index.js'; import { Chunker } from './chunkers.js'; import { readUInt32LE, readUInt16LE, copyUint8Arr, buffToString } from './index.js'; @@ -91,11 +92,11 @@ export class ZipReader { async getManifest(cdBuffers: CentralDirectory[], manifestFileName: string): Promise { const cdObj = cdBuffers.find(({ fileName }) => fileName === manifestFileName); if (!cdObj) { - throw new Error('Unable to retrieve CD manifest'); + throw new InvalidFileError('Unable to retrieve CD manifest'); } const byteStart = cdObj.relativeOffsetOfLocalHeader + cdObj.headerLength; if (cdObj.uncompressedSize > manifestMaxSize) { - throw new Error( + throw new InvalidFileError( `manifest file too large: ${(cdObj.uncompressedSize >> 10).toLocaleString()} KiB` ); } @@ -107,7 +108,7 @@ export class ZipReader { async adjustHeaders(cdObj: CentralDirectory): Promise { if (!cdObj) { - throw new Error('Unable to retrieve CD adjust'); + throw new InvalidFileError('Unable to retrieve CD adjust'); } // Calculate header length -- tdf3-js writes 0 in all the header fields // and does not include extra field for zip64 @@ -126,7 +127,7 @@ export class ZipReader { ): Promise { const cdObj = cdBuffers.find(({ fileName }) => payloadName === fileName); if (!cdObj) { - throw new Error('Unable to retrieve CD'); + throw new InvalidFileError('Unable to retrieve CD'); } const byteStart = cdObj.relativeOffsetOfLocalHeader + cdObj.headerLength + encrpytedSegmentOffset; @@ -217,7 +218,7 @@ function parseCentralDirectoryWithNoExtras(cdBuffer: Uint8Array): CentralDirecto */ export function parseCDBuffer(cdBuffer: Uint8Array): CentralDirectory { if (readUInt32LE(cdBuffer, 0) !== CD_SIGNATURE) { - throw new Error('Invalid central directory file header signature'); + throw new InvalidFileError('Invalid central directory file header signature'); } const cd = parseCentralDirectoryWithNoExtras(cdBuffer); @@ -240,7 +241,7 @@ export function parseCDBuffer(cdBuffer: Uint8Array): CentralDirectory { // 0 - Original Size 8 bytes if (cd.uncompressedSize === 0xffffffff) { if (index + 8 > zip64EiefBuffer.length) { - throw new Error( + throw new InvalidFileError( 'zip64 extended information extra field does not include uncompressed size' ); } @@ -250,7 +251,9 @@ export function parseCDBuffer(cdBuffer: Uint8Array): CentralDirectory { // 8 - Compressed Size 8 bytes if (cd.compressedSize === 0xffffffff) { if (index + 8 > zip64EiefBuffer.length) { - throw new Error('zip64 extended information extra field does not include compressed size'); + throw new InvalidFileError( + 'zip64 extended information extra field does not include compressed size' + ); } cd.compressedSize = readUInt64LE(zip64EiefBuffer, index); index += 8; @@ -258,7 +261,7 @@ export function parseCDBuffer(cdBuffer: Uint8Array): CentralDirectory { // 16 - Relative Header Offset 8 bytes if (cd.relativeOffsetOfLocalHeader === 0xffffffff) { if (index + 8 > zip64EiefBuffer.length) { - throw new Error( + throw new InvalidFileError( 'zip64 extended information extra field does not include relative header offset' ); } @@ -325,12 +328,12 @@ function sliceExtraFields( const dataStart = i + 4; const dataEnd = dataStart + dataSize; if (dataEnd > extraFieldBuffer.length) { - throw new Error('extra field length exceeds extra field buffer size'); + throw new InvalidFileError('extra field length exceeds extra field buffer size'); } const dataBuffer = new Uint8Array(dataSize); copyUint8Arr(extraFieldBuffer, dataBuffer, 0, dataStart, dataEnd); if (extraFields[headerId]) { - throw new Error(`Conflicting extra field #${headerId} for entry [${cd.fileName}]`); + throw new InvalidFileError(`Conflicting extra field #${headerId} for entry [${cd.fileName}]`); } extraFields[headerId] = dataBuffer; i = dataEnd; diff --git a/lib/tdf3/src/utils/zip-writer.ts b/lib/tdf3/src/utils/zip-writer.ts index 1309edf1..87b289a0 100644 --- a/lib/tdf3/src/utils/zip-writer.ts +++ b/lib/tdf3/src/utils/zip-writer.ts @@ -48,7 +48,7 @@ const ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIZE = 20; // write a 64bit integer by writing 2 32bit integers export function writeUInt64LE(buffer: Uint8Array, n: number, offset: number): void { if (!Number.isSafeInteger(n)) { - throw new Error(`Unsafe number [${n}]`); + throw new Error(`internal: unsafe number [${n}]`); } const high = Math.floor(n / 0x100000000); const low = n % 0x100000000; diff --git a/lib/tests/mocha/unit/errors.spec.ts b/lib/tests/mocha/unit/errors.spec.ts index a07dff36..6814aab3 100644 --- a/lib/tests/mocha/unit/errors.spec.ts +++ b/lib/tests/mocha/unit/errors.spec.ts @@ -1,27 +1,11 @@ import { assert } from 'chai'; -import { - KasDecryptError, - KasUpsertError, - KeyAccessError, - KeySyncError, - ManifestIntegrityError, - PolicyIntegrityError, - TdfDecryptError, - TdfError, - TdfPayloadExtractionError, -} from '../../../src/errors.js'; +import { DecryptError, IntegrityError, TdfError } from '../../../src/errors.js'; describe('Errors', () => { const errorClasses: Record = { - KasDecryptError, - KasUpsertError, - KeyAccessError, - KeySyncError, - ManifestIntegrityError, - PolicyIntegrityError, - TdfDecryptError, + DecryptError, + IntegrityError, TdfError, - TdfPayloadExtractionError, }; Object.keys(errorClasses).forEach((errorName) => { @@ -41,6 +25,10 @@ describe('Errors', () => { assert.instanceOf(err, Error); }); + it('should be instanceof TdfError', () => { + assert.instanceOf(err, TdfError); + }); + it('should throw correctly', () => { assert.throws(() => { throw err; diff --git a/lib/tests/mocha/unit/tdf.spec.ts b/lib/tests/mocha/unit/tdf.spec.ts index e49f0372..62404aea 100644 --- a/lib/tests/mocha/unit/tdf.spec.ts +++ b/lib/tests/mocha/unit/tdf.spec.ts @@ -3,7 +3,7 @@ import { expect } from 'chai'; import * as TDF from '../../../tdf3/src/tdf.js'; import { KeyAccessObject } from '../../../tdf3/src/models/key-access.js'; import { OriginAllowList } from '../../../src/access.js'; -import { KasDecryptError, TdfError } from '../../../src/errors.js'; +import { InvalidFileError, TdfError, UnsafeUrlError } from '../../../src/errors.js'; const sampleCert = ` -----BEGIN CERTIFICATE----- @@ -126,7 +126,7 @@ describe('splitLookupTableFactory', () => { }); }); - it('should throw KasDecryptError for disallowed KASes', () => { + it('should throw UnsafeUrlError for disallowed KASes', () => { const keyAccess: KeyAccessObject[] = [ { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, { sid: 'split2', type: 'remote', url: 'https://kas3', protocol: 'kas' }, // kas3 is not allowed @@ -134,12 +134,12 @@ describe('splitLookupTableFactory', () => { const allowedKases = new OriginAllowList(['https://kas1']); expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( - KasDecryptError, + UnsafeUrlError, 'Unreconstructable key - disallowed KASes include: ["https://kas3"] from splitIds ["split1","split2"]' ); }); - it('should throw KasDecryptError for duplicate URLs in the same splitId', () => { + it('should throw for duplicate URLs in the same splitId', () => { const keyAccess: KeyAccessObject[] = [ { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, { sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' }, // duplicate URL in same splitId @@ -147,7 +147,7 @@ describe('splitLookupTableFactory', () => { const allowedKases = new OriginAllowList(['https://kas1']); expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( - KasDecryptError, + InvalidFileError, 'TODO: Fallback to no split ids. Repetition found for [https://kas1] on split [split1]' ); }); @@ -168,7 +168,7 @@ describe('splitLookupTableFactory', () => { const allowedKases = new OriginAllowList([]); expect(() => TDF.splitLookupTableFactory(keyAccess, allowedKases)).to.throw( - KasDecryptError, + InvalidFileError, 'Unreconstructable key - disallowed KASes include: ["https://kas1"]' ); }); diff --git a/lib/tests/mocha/unit/zip.spec.ts b/lib/tests/mocha/unit/zip.spec.ts index a5386a27..a48a33e5 100644 --- a/lib/tests/mocha/unit/zip.spec.ts +++ b/lib/tests/mocha/unit/zip.spec.ts @@ -39,7 +39,7 @@ describe('zip utilities', () => { expect(b1).to.eql(b0); }); it('unsafe ints throw', () => { - expect(() => writeUInt64LE(Buffer.alloc(0), 2 ** 54, 0)).to.throw(/Unsafe number/); + expect(() => writeUInt64LE(Buffer.alloc(0), 2 ** 54, 0)).to.throw(/unsafe number/); }); }); describe('readUInt64LE', () => { diff --git a/lib/tests/web/nanotdf/models/ResourceLocator.test.ts b/lib/tests/web/nanotdf/models/ResourceLocator.test.ts index b9af078d..a00d19b7 100644 --- a/lib/tests/web/nanotdf/models/ResourceLocator.test.ts +++ b/lib/tests/web/nanotdf/models/ResourceLocator.test.ts @@ -62,7 +62,7 @@ describe('NanoTDF.ResourceLocator', () => { for (const { v, msg } of [ { v: '03 01 61', msg: 'protocol' }, - { v: 'a1 01 61', msg: 'identifier' }, + { v: 'a1 01 61', msg: 'url parser: unsupported' }, { v: '00 00', msg: 'body' }, { v: '10 ff 61 61 ', msg: 'bounds' }, { v: '10 01 61 61 ', msg: 'bounds' }, diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index 62bb5163..1676e480 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1536,9 +1536,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1821,7 +1821,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", + "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", @@ -1833,6 +1833,7 @@ "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" } @@ -4453,6 +4454,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-canonicalize": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/json-canonicalize/-/json-canonicalize-1.0.6.tgz", + "integrity": "sha512-kP2iYpOS5SZHYhIaR1t9oG80d4uTY3jPoaBj+nimy3njtJk8+sRsVatN8pyJRDRtk9Su3+6XqA2U8k0dByJBUQ==", + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 33fe70e7..0fde7360 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -350,9 +350,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -607,7 +607,7 @@ "node_modules/@opentdf/client": { "version": "2.0.0", "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", + "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", @@ -619,6 +619,7 @@ "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" } @@ -2007,9 +2008,9 @@ } }, "node_modules/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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -2312,6 +2313,12 @@ "node": ">=4" } }, + "node_modules/json-canonicalize": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/json-canonicalize/-/json-canonicalize-1.0.6.tgz", + "integrity": "sha512-kP2iYpOS5SZHYhIaR1t9oG80d4uTY3jPoaBj+nimy3njtJk8+sRsVatN8pyJRDRtk9Su3+6XqA2U8k0dByJBUQ==", + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "dev": true, @@ -3951,9 +3958,9 @@ } }, "@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -4111,7 +4118,7 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-KzELD2ECWzt5ci3cmqAb/AAHpPUtO8MibopZgxJioXgvuMyoA+t3VFlGxD7RenVx0Ecm1GjEHzs68IGjHN90rQ==", + "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -4122,6 +4129,7 @@ "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" } @@ -4950,9 +4958,9 @@ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" }, "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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5125,6 +5133,11 @@ "version": "2.5.2", "dev": true }, + "json-canonicalize": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/json-canonicalize/-/json-canonicalize-1.0.6.tgz", + "integrity": "sha512-kP2iYpOS5SZHYhIaR1t9oG80d4uTY3jPoaBj+nimy3njtJk8+sRsVatN8pyJRDRtk9Su3+6XqA2U8k0dByJBUQ==" + }, "json-parse-even-better-errors": { "version": "2.3.1", "dev": true From 96370225adb384b7e1b79f7598e8edb31ddc54cf Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Thu, 17 Oct 2024 07:37:14 -0600 Subject: [PATCH 33/42] Add initial CodeQL workflow configuration (#363) --- .github/workflows/codeql.yaml | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/codeql.yaml diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml new file mode 100644 index 00000000..89181489 --- /dev/null +++ b/.github/workflows/codeql.yaml @@ -0,0 +1,42 @@ +name: "CodeQL" + +on: + schedule: + - cron: '0 13 * * 1' # At 1:00 PM UTC every Monday + pull_request: + paths: + - '.github/workflows/codeql.yaml' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize the CodeQL tools for scanning + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + timeout-minutes: 5 + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + timeout-minutes: 10 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" + timeout-minutes: 10 From 3d602ad66c35e3f751210beac76577ada9b868f0 Mon Sep 17 00:00:00 2001 From: Nick <79929408+ntrevino-virtru@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:37:01 -0600 Subject: [PATCH 34/42] CCR-3144: Expose loadTDFStream on Client. (#364) --- lib/tdf3/src/client/index.ts | 6 ++++++ lib/tdf3/src/tdf.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index 1b752ae0..1b292c5d 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -14,6 +14,7 @@ import { buildKeyAccess, EncryptConfiguration, fetchKasPublicKey, + loadTDFStream, unwrapHtml, validatePolicyObject, readStream, @@ -614,6 +615,11 @@ export class Client { const policyJson = base64.decode(manifest.encryptionInformation.policy); return JSON.parse(policyJson).uuid; } + + async loadTDFStream({ source }: { source: DecryptSource }) { + const chunker = await makeChunkable(source); + return loadTDFStream(chunker); + } } export type { AuthProvider }; diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index e6744b3a..7b686f32 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -876,7 +876,7 @@ export async function writeStream(cfg: EncryptConfiguration): Promise { const zipReader = new ZipReader(chunker); From f851c026455c6d6389c02f11cef478c2e08345c4 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 22 Oct 2024 11:02:34 -0400 Subject: [PATCH 35/42] fix(sdk): Remove stray call to node:Buffer (#365) --- lib/tdf3/src/models/assertion.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/tdf3/src/models/assertion.ts b/lib/tdf3/src/models/assertion.ts index dc08b08c..ea19f3b4 100644 --- a/lib/tdf3/src/models/assertion.ts +++ b/lib/tdf3/src/models/assertion.ts @@ -1,6 +1,7 @@ import { canonicalizeEx } from 'json-canonicalize'; import { SignJWT, jwtVerify } from 'jose'; import { AssertionKey } from './../client/AssertionConfig.js'; +import { hex } from '../../../src/encodings/index.js'; import { ConfigurationError, InvalidFileError } from '../../../src/errors.js'; export type AssertionKeyAlg = 'RS256' | 'HS256'; @@ -47,7 +48,7 @@ export async function hash(this: Assertion): Promise { const result = canonicalizeEx(this, { exclude: ['binding', 'hash', 'sign', 'verify'] }); const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(result)); - return Buffer.from(hash).toString('hex'); + return hex.encodeArrayBuffer(hash); } /** From 406e6fb2efa82859e15aebf62a0dbaf8e64b6585 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 25 Oct 2024 14:27:26 -0400 Subject: [PATCH 36/42] =?UTF-8?q?=F0=9F=86=99=202.1.0=20minor=20feat(core)?= =?UTF-8?q?:=20for=20new=20assertions=20package=20(#369)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- cli/package-lock.json | 18 +++++++++--------- cli/package.json | 4 ++-- lib/package-lock.json | 4 ++-- lib/package.json | 2 +- lib/src/version.ts | 2 +- lib/tdf3/src/version.ts | 2 +- remote-store/package-lock.json | 18 +++++++++--------- remote-store/package.json | 4 ++-- web-app/package-lock.json | 28 ++++++++++++++-------------- web-app/package.json | 4 ++-- 11 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index bbbbb3ac..a75fe0d2 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -version=2.0.0 +version=2.1.0 extras=cli remote-store web-app pkgs=lib $(extras) diff --git a/cli/package-lock.json b/cli/package-lock.json index 9be5f34b..407e104c 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1,15 +1,15 @@ { "name": "@opentdf/cli", - "version": "2.0.0", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@opentdf/cli", - "version": "2.0.0", + "version": "2.1.0", "license": "BSD-3-Clause-Clear", "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", "yargs": "^17.7.2" }, "bin": { @@ -36,9 +36,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", - "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", + "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -370,9 +370,9 @@ } }, "node_modules/@opentdf/client": { - "version": "2.0.0", - "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", + "version": "2.1.0", + "resolved": "file:../lib/opentdf-client-2.1.0.tgz", + "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", diff --git a/cli/package.json b/cli/package.json index 1bee0bf7..43af8b1e 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@opentdf/cli", - "version": "2.0.0", + "version": "2.1.0", "description": "Node based CLI for opentdf", "repository": { "type": "git", @@ -48,7 +48,7 @@ "typescript": "^5.1.6" }, "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", "yargs": "^17.7.2" } } diff --git a/lib/package-lock.json b/lib/package-lock.json index ee635e59..9fb728a9 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -1,12 +1,12 @@ { "name": "@opentdf/client", - "version": "2.0.0", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@opentdf/client", - "version": "2.0.0", + "version": "2.1.0", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", diff --git a/lib/package.json b/lib/package.json index 98c1ad67..f9e8da2e 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,6 +1,6 @@ { "name": "@opentdf/client", - "version": "2.0.0", + "version": "2.1.0", "description": "Access and generate tdf protected content", "homepage": "https://github.com/opentdf/client-web", "bugs": { diff --git a/lib/src/version.ts b/lib/src/version.ts index c87919f3..0a44cf8b 100644 --- a/lib/src/version.ts +++ b/lib/src/version.ts @@ -1,7 +1,7 @@ /** * Exposes the released version number of the `@opentdf/client` package */ -export const version = '2.0.0'; +export const version = '2.1.0'; /** * A string name used to label requests as coming from this library client. diff --git a/lib/tdf3/src/version.ts b/lib/tdf3/src/version.ts index fe19137f..809e3759 100644 --- a/lib/tdf3/src/version.ts +++ b/lib/tdf3/src/version.ts @@ -1,2 +1,2 @@ -export const version = '2.0.0'; +export const version = '2.1.0'; export const clientType = 'tdf3-js-client'; diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index 1676e480..99ef279a 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1,12 +1,12 @@ { "name": "@opentdf/remote-store", - "version": "2.0.0", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@opentdf/remote-store", - "version": "2.0.0", + "version": "2.1.0", "license": "BSD-3-Clause-Clear", "dependencies": { "@aws-sdk/abort-controller": "^3.370.0", @@ -14,7 +14,7 @@ "@aws-sdk/middleware-endpoint": "^3.370.0", "@aws-sdk/protocol-http": "^3.370.0", "@aws-sdk/smithy-client": "^3.370.0", - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", "axios": "^1.6.1" }, "devDependencies": { @@ -1536,9 +1536,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", - "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", + "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1819,9 +1819,9 @@ } }, "node_modules/@opentdf/client": { - "version": "2.0.0", - "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", + "version": "2.1.0", + "resolved": "file:../lib/opentdf-client-2.1.0.tgz", + "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", diff --git a/remote-store/package.json b/remote-store/package.json index 7791d186..443edeec 100644 --- a/remote-store/package.json +++ b/remote-store/package.json @@ -3,7 +3,7 @@ "license": "BSD-3-Clause-Clear", "author": "Virtru", "type": "module", - "version": "2.0.0", + "version": "2.1.0", "description": "Upload a web stream directly to S3", "homepage": "https://github.com/opentdf/client-web", "repository": { @@ -41,7 +41,7 @@ "@aws-sdk/middleware-endpoint": "^3.370.0", "@aws-sdk/protocol-http": "^3.370.0", "@aws-sdk/smithy-client": "^3.370.0", - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", "axios": "^1.6.1" }, "devDependencies": { diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 0fde7360..c8c1493c 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -1,15 +1,15 @@ { "name": "web-app", - "version": "2.0.0", + "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "web-app", - "version": "2.0.0", + "version": "2.1.0", "license": "BSD-3-Clause-Clear", "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", "clsx": "^2.0.0", "native-file-system-adapter": "^3.0.1", "react": "^18.2.0", @@ -350,9 +350,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", - "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", + "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -605,9 +605,9 @@ } }, "node_modules/@opentdf/client": { - "version": "2.0.0", - "resolved": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", + "version": "2.1.0", + "resolved": "file:../lib/opentdf-client-2.1.0.tgz", + "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", @@ -3958,9 +3958,9 @@ } }, "@babel/runtime": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", - "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", + "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -4117,8 +4117,8 @@ } }, "@opentdf/client": { - "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-LgL8v4mPmcu7nlCz/1C1Vl6WKYSlQM//bevC5u2J1AYmkyCys9A3qd7bgXIU6kMxbuU80B7DgmeSRRvp4qHrRQ==", + "version": "file:../lib/opentdf-client-2.1.0.tgz", + "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", diff --git a/web-app/package.json b/web-app/package.json index 84f1ac94..fb3b5282 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -1,6 +1,6 @@ { "name": "web-app", - "version": "2.0.0", + "version": "2.1.0", "license": "BSD-3-Clause-Clear", "type": "module", "scripts": { @@ -15,7 +15,7 @@ "test:ui": "vite build && vitest --ui" }, "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", "clsx": "^2.0.0", "native-file-system-adapter": "^3.0.1", "react": "^18.2.0", From 85294612fb6886fa4da6cf4d070c54168ed634de Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 28 Oct 2024 17:36:51 -0400 Subject: [PATCH 37/42] feat(sdk): Allows skipping verification (#371) Also: - Removes all refs to node:buffer I could find - removes the polyfill from the web-test-runner, to make sure we aren't accidentally including it (at least in things that covers) - updates all .spec and .test files, in turn - renames a bunch of things called `buffer` to something else so I can search for this easier - feat(cli): Adds --assertions to cli for testing encrypting with assertions - feat(cli): Adds --no-verify-assertions to cli for testing decrypt without verifying assertions (for invalid or unverifiable assertions) --- cli/package-lock.json | 53 +---- cli/src/cli.ts | 49 ++++- lib/package-lock.json | 24 +-- lib/package.json | 8 +- lib/src/nanotdf/models/Header.ts | 20 +- lib/src/nanotdf/models/Payload.ts | 12 +- .../nanotdf/models/Policy/EmbeddedPolicy.ts | 12 +- lib/src/nanotdf/models/Policy/RemotePolicy.ts | 10 +- lib/src/nanotdf/models/ResourceLocator.ts | 12 +- lib/src/nanotdf/models/Signature.ts | 8 +- lib/tdf3/src/assertions.ts | 191 ++++++++++++++++++ lib/tdf3/src/ciphers/aes-gcm-cipher.ts | 8 +- lib/tdf3/src/client/AssertionConfig.ts | 29 --- lib/tdf3/src/client/builders.ts | 38 ++-- lib/tdf3/src/client/index.ts | 2 + lib/tdf3/src/models/assertion.ts | 131 ------------ lib/tdf3/src/models/index.ts | 2 +- lib/tdf3/src/models/manifest.ts | 2 +- lib/tdf3/src/tdf.ts | 89 +++----- lib/tdf3/src/utils/chunkers.ts | 4 +- lib/tdf3/src/utils/index.ts | 18 +- lib/tdf3/src/utils/zip-reader.ts | 11 +- lib/tests/mocha/encrypt-decrypt.spec.ts | 5 +- lib/tests/mocha/unit/assertions.spec.ts | 25 +++ lib/tests/mocha/unit/keysplits.spec.ts | 4 +- lib/tests/mocha/unit/tdf.spec.ts | 8 +- lib/tests/mocha/unit/zip.spec.ts | 11 +- lib/tests/server.ts | 18 +- lib/webpack.test.config.cjs | 5 - remote-store/package-lock.json | 53 +---- web-app/package-lock.json | 24 ++- 31 files changed, 420 insertions(+), 466 deletions(-) create mode 100644 lib/tdf3/src/assertions.ts delete mode 100644 lib/tdf3/src/client/AssertionConfig.ts delete mode 100644 lib/tdf3/src/models/assertion.ts create mode 100644 lib/tests/mocha/unit/assertions.spec.ts diff --git a/cli/package-lock.json b/cli/package-lock.json index 407e104c..b7d0ede2 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -36,9 +36,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -372,14 +372,13 @@ "node_modules/@opentdf/client": { "version": "2.1.0", "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -973,30 +972,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -1844,26 +1819,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "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.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", diff --git a/cli/src/cli.ts b/cli/src/cli.ts index fd066c47..f5896835 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -18,7 +18,9 @@ import { } from '@opentdf/client'; import { CLIError, Level, log } from './logger.js'; import { webcrypto } from 'crypto'; +import * as assertions from '@opentdf/client/assertions'; import { attributeFQNsAsValues } from '@opentdf/client/nano'; +import { base64 } from '@opentdf/client/encodings'; type AuthToProcess = { auth?: string; @@ -37,8 +39,9 @@ const bindingTypes = ['ecdsa', 'gmac']; const containerTypes = ['tdf3', 'nano', 'dataset', 'ztdf']; const parseJwt = (jwt: string, field = 1) => { - return JSON.parse(Buffer.from(jwt.split('.')[field], 'base64').toString()); + return JSON.parse(base64.decode(jwt.split('.')[field])); }; + const parseJwtComplete = (jwt: string) => { return { header: parseJwt(jwt, 0), payload: parseJwt(jwt) }; }; @@ -113,12 +116,33 @@ function addParams(client: AnyNanoClient, argv: Partial) { async function tdf3DecryptParamsFor(argv: Partial): Promise { const c = new DecryptParamsBuilder(); + if (argv.noVerifyAssertions) { + c.withNoVerifyAssertions(true); + } c.setFileSource(await openAsBlob(argv.file as string)); return c.build(); } +function parseAssertionConfig(s: string): assertions.AssertionConfig[] { + const u = JSON.parse(s); + // if u is null or empty, return an empty array + if (!u) { + return []; + } + const a = Array.isArray(u) ? u : [u]; + for (const assertion of a) { + if (!assertions.isAssertionConfig(assertion)) { + throw new CLIError('CRITICAL', `invalid assertion config ${JSON.stringify(assertion)}`); + } + } + return a; +} + async function tdf3EncryptParamsFor(argv: Partial): Promise { const c = new EncryptParamsBuilder(); + if (argv.assertions?.length) { + c.withAssertions(parseAssertionConfig(argv.assertions)); + } if (argv.attributes?.length) { c.setAttributes(argv.attributes.split(',')); } @@ -201,13 +225,19 @@ export const handleArgs = (args: string[]) => { group: 'Security:', desc: 'allowed KAS origins, comma separated; defaults to [kasEndpoint]', type: 'string', - validate: (attributes: string) => attributes.split(','), + validate: (uris: string) => uris.split(','), }) .option('ignoreAllowList', { group: 'Security:', desc: 'disable KAS allowlist feature for decrypt', type: 'boolean', }) + .option('noVerifyAssertions', { + alias: 'no-verify-assertions', + group: 'Security', + desc: 'Do not verify assertions', + type: 'boolean', + }) .option('auth', { group: 'OAuth and OIDC:', type: 'string', @@ -252,6 +282,13 @@ export const handleArgs = (args: string[]) => { // Policy, encryption, and container options .options({ + assertions: { + group: 'Encrypt Options:', + desc: 'ZTDF assertion config objects', + type: 'string', + default: '', + validate: parseAssertionConfig, + }, attributes: { group: 'Encrypt Options:', desc: 'Data attributes for the policy', @@ -413,9 +450,9 @@ export const handleArgs = (args: string[]) => { log('DEBUG', 'Handle output.'); if (argv.output) { - await writeFile(argv.output, Buffer.from(plaintext)); + await writeFile(argv.output, new Uint8Array(plaintext)); } else { - console.log(Buffer.from(plaintext).toString('utf8')); + console.log(new TextDecoder().decode(plaintext)); } } const lastRequest = authProvider.requestLog[authProvider.requestLog.length - 1]; @@ -503,9 +540,9 @@ export const handleArgs = (args: string[]) => { log('DEBUG', `Handle cyphertext output ${JSON.stringify(cyphertext)}`); if (argv.output) { - await writeFile(argv.output, Buffer.from(cyphertext)); + await writeFile(argv.output, new Uint8Array(cyphertext)); } else { - console.log(Buffer.from(cyphertext).toString('base64')); + console.log(base64.encodeArrayBuffer(cyphertext)); } } } diff --git a/lib/package-lock.json b/lib/package-lock.json index 9fb728a9..0267c2b5 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -13,7 +13,6 @@ "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -2676,28 +2675,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "6.0.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "license": "MIT", @@ -5148,6 +5125,7 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "dev": true, "funding": [ { "type": "github", diff --git a/lib/package.json b/lib/package.json index f9e8da2e..42734f80 100644 --- a/lib/package.json +++ b/lib/package.json @@ -29,6 +29,13 @@ "require": "./dist/cjs/tdf3/index.js", "import": "./dist/web/tdf3/index.js" }, + "./assertions": { + "default": { + "types": "./dist/types/tdf3/src/assertions.d.ts", + "require": "./dist/cjs/tdf3/src/assertions.js", + "import": "./dist/web/tdf3/src/assertions.js" + } + }, "./encodings": { "default": { "types": "./dist/types/src/encodings/index.d.ts", @@ -64,7 +71,6 @@ "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", diff --git a/lib/src/nanotdf/models/Header.ts b/lib/src/nanotdf/models/Header.ts index 7a11d7c3..71577e3e 100644 --- a/lib/src/nanotdf/models/Header.ts +++ b/lib/src/nanotdf/models/Header.ts @@ -232,20 +232,20 @@ export default class Header { /** * Copy the contents of the header to buffer */ - copyToBuffer(buffer: Uint8Array): void { - if (this.length > buffer.length) { + copyToBuffer(target: Uint8Array): void { + if (this.length > target.length) { throw new InvalidFileError('invalid buffer size to copy tdf header'); } let offset = 0; // Write Magic number and version - buffer.set(this.magicNumberVersion, 0); + target.set(this.magicNumberVersion, 0); offset += this.magicNumberVersion.length; // Write kas resource locator const kasResourceLocatorBuf = this.kas.toBuffer(); - buffer.set(kasResourceLocatorBuf, offset); + target.set(kasResourceLocatorBuf, offset); offset += kasResourceLocatorBuf.length; // Write ECC & Binding Mode @@ -253,7 +253,7 @@ export default class Header { const eccBingingMode = (ecdsaBinding << 7) | this.ephemeralCurveName; const eccBingingModeAsByte = new Uint8Array(1); eccBingingModeAsByte[0] = eccBingingMode; - buffer.set(eccBingingModeAsByte, offset); + target.set(eccBingingModeAsByte, offset); offset += eccBingingModeAsByte.length; // Write symmetric & payload config @@ -262,16 +262,16 @@ export default class Header { (isSignatureEnable << 7) | this.signatureCurveName | this.symmetricCipher; const symmetricPayloadConfigAsByte = new Uint8Array(1); symmetricPayloadConfigAsByte[0] = symmetricPayloadConfig; - buffer.set(symmetricPayloadConfigAsByte, offset); + target.set(symmetricPayloadConfigAsByte, offset); offset += symmetricPayloadConfigAsByte.length; // Write the policy const policyBuffer = this.policy.toBuffer(); - buffer.set(policyBuffer, offset); + target.set(policyBuffer, offset); offset += policyBuffer.length; // Write the ephemeral public key - buffer.set(this.ephemeralPublicKey, offset); + target.set(this.ephemeralPublicKey, offset); } /** @@ -304,8 +304,8 @@ export default class Header { */ toBuffer(): ArrayBuffer { const arrayBuffer = new ArrayBuffer(this.length); - const buffer = new Uint8Array(arrayBuffer); - this.copyToBuffer(buffer); + const target = new Uint8Array(arrayBuffer); + this.copyToBuffer(target); return arrayBuffer; } diff --git a/lib/src/nanotdf/models/Payload.ts b/lib/src/nanotdf/models/Payload.ts index 37645a82..55ae7336 100644 --- a/lib/src/nanotdf/models/Payload.ts +++ b/lib/src/nanotdf/models/Payload.ts @@ -167,8 +167,8 @@ export default class Payload { /** * Copy the contents of the signature to buffer */ - copyToBuffer(buffer: Uint8Array): void { - if (this.length > buffer.length) { + copyToBuffer(target: Uint8Array): void { + if (this.length > target.length) { throw new Error('internal: invalid buffer size to copy payload'); } @@ -188,9 +188,9 @@ export default class Payload { payloadSizeAsBg[1] = lengthAsUint24[1]; payloadSizeAsBg[2] = lengthAsUint24[0]; - buffer.set(payloadSizeAsBg, 0); - buffer.set(this.iv, payloadSizeAsBg.length); - buffer.set(this.ciphertext, payloadSizeAsBg.length + this.iv.length); - buffer.set(this.authTag, payloadSizeAsBg.length + this.iv.length + this.ciphertext.length); + target.set(payloadSizeAsBg, 0); + target.set(this.iv, payloadSizeAsBg.length); + target.set(this.ciphertext, payloadSizeAsBg.length + this.iv.length); + target.set(this.authTag, payloadSizeAsBg.length + this.iv.length + this.ciphertext.length); } } diff --git a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts index 3b8c3de4..321b760b 100644 --- a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts +++ b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts @@ -69,13 +69,13 @@ class EmbeddedPolicy extends AbstractPolicy implements EmbeddedPolicyInterface { * Return the content of the policy */ override toBuffer(): Uint8Array { - const buffer = new Uint8Array(this.getLength()); + const target = new Uint8Array(this.getLength()); if (this.content.length > EmbeddedPolicy.MAX_POLICY_SIZE) { throw new ConfigurationError("TDF Policy can't be more that 2^16"); } - buffer.set([this.type], 0); + target.set([this.type], 0); // Write the policy length, assuming the host system is little endian // TODO: There should be better way to convert to big endian @@ -86,15 +86,15 @@ class EmbeddedPolicy extends AbstractPolicy implements EmbeddedPolicyInterface { const policyContentSizeAsBg = new Uint8Array(2); policyContentSizeAsBg[0] = temp[1]; policyContentSizeAsBg[1] = temp[0]; - buffer.set(policyContentSizeAsBg, 1); + target.set(policyContentSizeAsBg, 1); // Write the policy content - buffer.set(this.content, policyContentSizeAsBg.length + 1); + target.set(this.content, policyContentSizeAsBg.length + 1); // Write the binding. - buffer.set(this.binding, this.content.length + policyContentSizeAsBg.length + 1); + target.set(this.binding, this.content.length + policyContentSizeAsBg.length + 1); - return buffer; + return target; } } diff --git a/lib/src/nanotdf/models/Policy/RemotePolicy.ts b/lib/src/nanotdf/models/Policy/RemotePolicy.ts index 59131533..0a94c472 100644 --- a/lib/src/nanotdf/models/Policy/RemotePolicy.ts +++ b/lib/src/nanotdf/models/Policy/RemotePolicy.ts @@ -56,18 +56,18 @@ class RemotePolicy extends AbstractPolicy implements RemotePolicyInterface { * Return the content of the policy */ override toBuffer(): Uint8Array { - const buffer = new Uint8Array(this.getLength()); + const target = new Uint8Array(this.getLength()); - buffer.set([PolicyTypeEnum.Remote], 0); + target.set([PolicyTypeEnum.Remote], 0); // Write the remote policy location const resourceLocatorAsBuf = this.remotePolicy.toBuffer(); - buffer.set(resourceLocatorAsBuf, 1); + target.set(resourceLocatorAsBuf, 1); // Write the binding. - buffer.set(this.binding, resourceLocatorAsBuf.length + 1); + target.set(this.binding, resourceLocatorAsBuf.length + 1); - return buffer; + return target; } } diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index 0944407c..efd1aa9f 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -178,7 +178,7 @@ export default class ResourceLocator { * Return the contents of the Resource Locator in buffer */ toBuffer(): Uint8Array { - const buffer = new Uint8Array(ResourceLocator.BODY_OFFSET + this.body.length + this.idType); + const target = new Uint8Array(ResourceLocator.BODY_OFFSET + this.body.length + this.idType); let idTypeNibble = 0; switch (this.idType) { case ResourceLocatorIdentifierEnum.TwoBytes: @@ -191,13 +191,13 @@ export default class ResourceLocator { idTypeNibble = ResourceLocator.IDENTIFIER_32_BYTE; break; } - buffer.set([this.protocol | idTypeNibble], ResourceLocator.PROTOCOL_OFFSET); - buffer.set([this.lengthOfBody], ResourceLocator.LENGTH_OFFSET); - buffer.set(new TextEncoder().encode(this.body), ResourceLocator.BODY_OFFSET); + target.set([this.protocol | idTypeNibble], ResourceLocator.PROTOCOL_OFFSET); + target.set([this.lengthOfBody], ResourceLocator.LENGTH_OFFSET); + target.set(new TextEncoder().encode(this.body), ResourceLocator.BODY_OFFSET); if (this.id) { - buffer.set(new TextEncoder().encode(this.id), ResourceLocator.BODY_OFFSET + this.body.length); + target.set(new TextEncoder().encode(this.id), ResourceLocator.BODY_OFFSET + this.body.length); } - return buffer; + return target; } /** diff --git a/lib/src/nanotdf/models/Signature.ts b/lib/src/nanotdf/models/Signature.ts index 05610bbf..091b6283 100644 --- a/lib/src/nanotdf/models/Signature.ts +++ b/lib/src/nanotdf/models/Signature.ts @@ -74,12 +74,12 @@ export default class Signature { /** * Copy the contents of the signature to buffer */ - copyToBuffer(buffer: Uint8Array): void { - if (this.length > buffer.length) { + copyToBuffer(target: Uint8Array): void { + if (this.length > target.length) { throw new ConfigurationError('Invalid buffer size to copy signature'); } - buffer.set(this.publicKey, 0); - buffer.set(this.signature, this.publicKey.length); + target.set(this.publicKey, 0); + target.set(this.signature, this.publicKey.length); } } diff --git a/lib/tdf3/src/assertions.ts b/lib/tdf3/src/assertions.ts new file mode 100644 index 00000000..be3aa833 --- /dev/null +++ b/lib/tdf3/src/assertions.ts @@ -0,0 +1,191 @@ +import { canonicalizeEx } from 'json-canonicalize'; +import { type KeyLike, SignJWT, jwtVerify } from 'jose'; +import { base64, hex } from '../../src/encodings/index.js'; +import { ConfigurationError, IntegrityError, InvalidFileError } from '../../src/errors.js'; + +export type AssertionKeyAlg = 'RS256' | 'HS256'; +export type AssertionType = 'handling' | 'other'; +export type Scope = 'tdo' | 'payload'; +export type AppliesToState = 'encrypted' | 'unencrypted'; +export type BindingMethod = 'jws'; + +// Statement type +export type Statement = { + format: string; + schema: string; + value: string; +}; + +// Binding type +export type Binding = { + method: string; + signature: string; +}; + +// Assertion type +export type Assertion = { + id: string; + type: AssertionType; + scope: Scope; + appliesToState?: AppliesToState; + statement: Statement; + binding: Binding; +}; + +export type AssertionPayload = { + assertionHash: string; + assertionSig: string; +}; + +/** + * Computes the SHA-256 hash of the assertion object, excluding the 'binding' and 'hash' properties. + * + * @returns the hexadecimal string representation of the hash + */ +export async function hash(a: Assertion): Promise { + const result = canonicalizeEx(a, { exclude: ['binding', 'hash', 'sign', 'verify'] }); + + const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(result)); + return hex.encodeArrayBuffer(hash); +} + +/** + * Signs the given hash and signature using the provided key and sets the binding method and signature. + * + * @param hash - The hash to be signed. + * @param sig - The signature to be signed. + * @param {AssertionKey} key - The key used for signing. + * @returns {Promise} A promise that resolves when the signing is complete. + */ +async function sign( + thiz: Assertion, + assertionHash: string, + sig: string, + key: AssertionKey +): Promise { + const payload: AssertionPayload = { + assertionHash, + assertionSig: sig, + }; + + let token: string; + try { + token = await new SignJWT(payload).setProtectedHeader({ alg: key.alg }).sign(key.key); + } catch (error) { + throw new ConfigurationError(`Signing assertion failed: ${error.message}`, error); + } + thiz.binding.method = 'jws'; + thiz.binding.signature = token; + return thiz; +} + +// a function that takes an unknown or any object and asserts that it is or is not an AssertionConfig object +export function isAssertionConfig(obj: unknown): obj is AssertionConfig { + return ( + !!obj && + typeof obj === 'object' && + 'id' in obj && + typeof obj.id === 'string' && + 'type' in obj && + (obj.type === 'handling' || obj.type === 'other') && + 'scope' in obj && + (obj.scope === 'tdo' || obj.scope === 'payload') && + 'appliesToState' in obj && + (obj.appliesToState === 'encrypted' || obj.appliesToState === 'unencrypted') && + 'statement' in obj && + !!obj.statement && + typeof obj.statement === 'object' && + 'format' in obj.statement && + 'schema' in obj.statement && + 'value' in obj.statement + ); +} + +/** + * Verifies the signature of the assertion using the provided key. + * + * @param {AssertionKey} key - The key used for verification. + * @returns {Promise<[string, string]>} A promise that resolves to a tuple containing the assertion hash and signature. + * @throws {Error} If the verification fails. + */ +export async function verify( + thiz: Assertion, + aggregateHash: string, + key: AssertionKey +): Promise { + let payload: AssertionPayload; + try { + const uj = await jwtVerify(thiz.binding.signature, key.key, { + algorithms: [key.alg], + }); + payload = uj.payload as AssertionPayload; + } catch (error) { + throw new InvalidFileError(`Verifying assertion failed: ${error.message}`, error); + } + const { assertionHash, assertionSig } = payload; + + // Get the hash of the assertion + const hashOfAssertion = await hash(thiz); + const combinedHash = aggregateHash + hashOfAssertion; + const encodedHash = base64.encode(combinedHash); + + // check if assertionHash is same as hashOfAssertion + if (hashOfAssertion !== assertionHash) { + throw new IntegrityError('Assertion hash mismatch'); + } + + // check if assertionSig is same as encodedHash + if (assertionSig !== encodedHash) { + throw new IntegrityError('Failed integrity check on assertion signature'); + } +} + +/** + * Creates an Assertion object with the specified properties. + */ +export async function CreateAssertion( + aggregateHash: string, + assertionConfig: AssertionConfig +): Promise { + if (!assertionConfig.signingKey) { + throw new ConfigurationError('Assertion signing key is required'); + } + + const a: Assertion = { + id: assertionConfig.id, + type: assertionConfig.type, + scope: assertionConfig.scope, + appliesToState: assertionConfig.appliesToState, + statement: assertionConfig.statement, + // empty binding + binding: { method: '', signature: '' }, + }; + + const assertionHash = await hash(a); + const combinedHash = aggregateHash + assertionHash; + const encodedHash = base64.encode(combinedHash); + + return await sign(a, assertionHash, encodedHash, assertionConfig.signingKey); +} + +export type AssertionKey = { + alg: AssertionKeyAlg; + key: KeyLike | Uint8Array; +}; + +// AssertionConfig is a shadow of Assertion with the addition of the signing key. +// It is used on creation of the assertion. +export type AssertionConfig = { + id: string; + type: AssertionType; + scope: Scope; + appliesToState: AppliesToState; + statement: Statement; + signingKey?: AssertionKey; +}; + +// AssertionVerificationKeys represents the verification keys for assertions. +export type AssertionVerificationKeys = { + DefaultKey?: AssertionKey; + Keys: Record; +}; diff --git a/lib/tdf3/src/ciphers/aes-gcm-cipher.ts b/lib/tdf3/src/ciphers/aes-gcm-cipher.ts index 3797ad36..dade0160 100644 --- a/lib/tdf3/src/ciphers/aes-gcm-cipher.ts +++ b/lib/tdf3/src/ciphers/aes-gcm-cipher.ts @@ -18,15 +18,15 @@ type ProcessGcmPayload = { payloadAuthTag: Binary; }; // Should this be a Binary, Buffer, or... both? -function processGcmPayload(buffer: ArrayBuffer): ProcessGcmPayload { +function processGcmPayload(source: ArrayBuffer): ProcessGcmPayload { // Read the 12 byte IV from the beginning of the stream - const payloadIv = Binary.fromArrayBuffer(buffer.slice(0, 12)); + const payloadIv = Binary.fromArrayBuffer(source.slice(0, 12)); // Slice the final 16 bytes of the buffer for the authentication tag - const payloadAuthTag = Binary.fromArrayBuffer(buffer.slice(-16)); + const payloadAuthTag = Binary.fromArrayBuffer(source.slice(-16)); return { - payload: Binary.fromArrayBuffer(buffer.slice(12, -16)), + payload: Binary.fromArrayBuffer(source.slice(12, -16)), payloadIv, payloadAuthTag, }; diff --git a/lib/tdf3/src/client/AssertionConfig.ts b/lib/tdf3/src/client/AssertionConfig.ts deleted file mode 100644 index cd065aa8..00000000 --- a/lib/tdf3/src/client/AssertionConfig.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { - AssertionKeyAlg, - AssertionType, - Scope, - AppliesToState, - Statement, -} from '../models/assertion.js'; - -export type AssertionKey = { - alg: AssertionKeyAlg; - key: any; // Replace AnyKey with the actual type of your key -}; - -// AssertionConfig is a shadow of Assertion with the addition of the signing key. -// It is used on creation of the assertion. -export type AssertionConfig = { - id: string; - type: AssertionType; - scope: Scope; - appliesToState: AppliesToState; - statement: Statement; - signingKey?: AssertionKey; -}; - -// AssertionVerificationKeys represents the verification keys for assertions. -export type AssertionVerificationKeys = { - DefaultKey?: AssertionKey; - Keys: Record; -}; diff --git a/lib/tdf3/src/client/builders.ts b/lib/tdf3/src/client/builders.ts index 10752d63..a8e96d7c 100644 --- a/lib/tdf3/src/client/builders.ts +++ b/lib/tdf3/src/client/builders.ts @@ -8,7 +8,7 @@ import { PemKeyPair } from '../crypto/declarations.js'; import { EntityObject } from '../../../src/tdf/EntityObject.js'; import { DecoratedReadableStream } from './DecoratedReadableStream.js'; import { type Chunker } from '../utils/chunkers.js'; -import { AssertionConfig, AssertionVerificationKeys } from './AssertionConfig.js'; +import { AssertionConfig, AssertionVerificationKeys } from '../assertions.js'; import { Value } from '../../../src/policy/attributes.js'; export const DEFAULT_SEGMENT_SIZE: number = 1024 * 1024; @@ -149,7 +149,7 @@ class EncryptParamsBuilder { /** * Specify the content to encrypt, in buffer form. - * @param {Buffer} buf - a buffer to encrypt. + * @param buf to encrypt. */ setBufferSource(buf: ArrayBuffer) { const stream = new ReadableStream({ @@ -163,10 +163,9 @@ class EncryptParamsBuilder { /** * Specify the content to encrypt, in buffer form. Returns this object for method chaining. - * @param {Buffer} buf - a buffer to encrypt - * @return {EncryptParamsBuilder} - this object. + * @param buf - a buffer to encrypt */ - withBufferSource(buf: ArrayBuffer) { + withBufferSource(buf: ArrayBuffer): this { this.setBufferSource(buf); return this; } @@ -520,6 +519,7 @@ export type DecryptParams = { keyMiddleware?: DecryptKeyMiddleware; streamMiddleware?: DecryptStreamMiddleware; assertionVerificationKeys?: AssertionVerificationKeys; + noVerifyAssertions?: boolean; }; /** @@ -554,7 +554,7 @@ class DecryptParamsBuilder { /** * Set the TDF ciphertext to decrypt, in buffer form. - * @param {Buffer} buffer - a buffer to decrypt. + * @param buffer to decrypt. */ setBufferSource(buffer: Uint8Array) { this._params.source = { type: 'buffer', location: buffer }; @@ -562,10 +562,9 @@ class DecryptParamsBuilder { /** * Set the TDF ciphertext to decrypt, in buffer form. Returns this object for method chaining. - * @param {Buffer} buffer - a buffer to decrypt. - * @return {DecryptParamsBuilder} - this object. + * @param buffer to decrypt. */ - withBufferSource(buffer: Uint8Array): DecryptParamsBuilder { + withBufferSource(buffer: Uint8Array): this { this.setBufferSource(buffer); return this; } @@ -587,7 +586,7 @@ class DecryptParamsBuilder { * @param {string} url - a tdf3 remote URL. * @return {DecryptParamsBuilder} - this object. */ - withUrlSource(url: string): DecryptParamsBuilder { + withUrlSource(url: string): this { this.setUrlSource(url); return this; } @@ -602,10 +601,9 @@ class DecryptParamsBuilder { /** * Specify the TDF ciphertext to decrypt, in stream form. Returns this object for method chaining. - * @param {Readable} stream - a Readable stream to decrypt. - * @return {DecryptParamsBuilder} - this object. + * @param stream to decrypt. */ - withStreamSource(stream: ReadableStream) { + withStreamSource(stream: ReadableStream): this { if (!stream?.getReader) { throw new ConfigurationError( `Source must be a WebReadableStream. Run node streams through stream.Readable.toWeb()` @@ -621,7 +619,7 @@ class DecryptParamsBuilder { * @param {string} string - a string to decrypt. */ setStringSource(string: string) { - this.setBufferSource(Buffer.from(string, 'binary')); + this.setBufferSource(new TextEncoder().encode(string)); } /** @@ -629,7 +627,7 @@ class DecryptParamsBuilder { * @param {string} string - a string to decrypt. * @return {DecryptParamsBuilder} - this object. */ - withStringSource(string: string): DecryptParamsBuilder { + withStringSource(string: string): this { this.setStringSource(string); return this; } @@ -648,7 +646,7 @@ class DecryptParamsBuilder { * Returns this object for method chaining. * @param source (node) the path of the local file to decrypt, or the Blob (browser/node) */ - withFileSource(source: Blob): DecryptParamsBuilder { + withFileSource(source: Blob): this { this.setFileSource(source); return this; } @@ -672,11 +670,17 @@ class DecryptParamsBuilder { * @param {ArrayBuffer} arraybuffer - the ArrayBuffer used to load file content from a browser * @return {DecryptParamsBuilder} - this object. */ - withArrayBufferSource(arraybuffer: ArrayBuffer): DecryptParamsBuilder { + withArrayBufferSource(arraybuffer: ArrayBuffer): this { this.setArrayBufferSource(arraybuffer); return this; } + /** Skip assertion verification */ + withNoVerifyAssertions(v: boolean): DecryptParamsBuilder { + this._params.noVerifyAssertions = v; + return this; + } + _deepCopy(_params: DecryptParams) { return freeze({ ..._params }); } diff --git a/lib/tdf3/src/client/index.ts b/lib/tdf3/src/client/index.ts index 1b292c5d..658fe04c 100644 --- a/lib/tdf3/src/client/index.ts +++ b/lib/tdf3/src/client/index.ts @@ -561,6 +561,7 @@ export class Client { keyMiddleware = async (key: Binary) => key, streamMiddleware = async (stream: DecoratedReadableStream) => stream, assertionVerificationKeys, + noVerifyAssertions, }: DecryptParams): Promise { const dpopKeys = await this.dpopKeys; let entityObject; @@ -593,6 +594,7 @@ export class Client { keyMiddleware, progressHandler: this.clientConfig.progressHandler, assertionVerificationKeys, + noVerifyAssertions, }) ); } diff --git a/lib/tdf3/src/models/assertion.ts b/lib/tdf3/src/models/assertion.ts deleted file mode 100644 index ea19f3b4..00000000 --- a/lib/tdf3/src/models/assertion.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { canonicalizeEx } from 'json-canonicalize'; -import { SignJWT, jwtVerify } from 'jose'; -import { AssertionKey } from './../client/AssertionConfig.js'; -import { hex } from '../../../src/encodings/index.js'; -import { ConfigurationError, InvalidFileError } from '../../../src/errors.js'; - -export type AssertionKeyAlg = 'RS256' | 'HS256'; -export type AssertionType = 'handling' | 'other'; -export type Scope = 'tdo' | 'payload'; -export type AppliesToState = 'encrypted' | 'unencrypted'; -export type BindingMethod = 'jws'; - -const kAssertionHash = 'assertionHash'; -const kAssertionSignature = 'assertionSig'; - -// Statement type -export type Statement = { - format: string; - schema: string; - value: string; -}; - -// Binding type -export type Binding = { - method: string; - signature: string; -}; - -// Assertion type -export type Assertion = { - id: string; - type: AssertionType; - scope: Scope; - appliesToState?: AppliesToState; - statement: Statement; - binding: Binding; - hash: () => Promise; - sign: (hash: string, sig: string, key: AssertionKey) => Promise; - verify: (key: AssertionKey) => Promise<[string, string]>; -}; - -/** - * Computes the SHA-256 hash of the assertion object, excluding the 'binding' and 'hash' properties. - * - * @returns {Promise} A promise that resolves to the hexadecimal string representation of the hash. - */ -export async function hash(this: Assertion): Promise { - const result = canonicalizeEx(this, { exclude: ['binding', 'hash', 'sign', 'verify'] }); - - const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(result)); - return hex.encodeArrayBuffer(hash); -} - -/** - * Signs the given hash and signature using the provided key and sets the binding method and signature. - * - * @param {string} hash - The hash to be signed. - * @param {string} sig - The signature to be signed. - * @param {AssertionKey} key - The key used for signing. - * @returns {Promise} A promise that resolves when the signing is complete. - */ -export async function sign( - this: Assertion, - assertionHash: string, - sig: string, - key: AssertionKey -): Promise { - const payload: Record = {}; - payload[kAssertionHash] = assertionHash; - payload[kAssertionSignature] = sig; - - let token: string; - try { - token = await new SignJWT(payload).setProtectedHeader({ alg: key.alg }).sign(key.key); - } catch (error) { - throw new ConfigurationError(`Signing assertion failed: ${error.message}`, error); - } - this.binding.method = 'jws'; - this.binding.signature = token; -} - -/** - * Verifies the signature of the assertion using the provided key. - * - * @param {AssertionKey} key - The key used for verification. - * @returns {Promise<[string, string]>} A promise that resolves to a tuple containing the assertion hash and signature. - * @throws {Error} If the verification fails. - */ -export async function verify(this: Assertion, key: AssertionKey): Promise<[string, string]> { - try { - const { payload } = await jwtVerify(this.binding.signature, key.key, { - algorithms: [key.alg], - }); - - return [payload[kAssertionHash] as string, payload[kAssertionSignature] as string]; - } catch (error) { - throw new InvalidFileError(`Verifying assertion failed: ${error.message}`, error); - } -} - -/** - * Creates an Assertion object with the specified properties. - * - * @param {string} id - The unique identifier for the assertion. - * @param {AssertionType} type - The type of the assertion (e.g., 'handling', 'other'). - * @param {Scope} scope - The scope of the assertion (e.g., 'tdo', 'payload'). - * @param {Statement} statement - The statement associated with the assertion. - * @param {Binding} binding - The binding method and signature for the assertion. - * @param {AppliesToState} [appliesToState] - The state to which the assertion applies (optional). - * @returns {Assertion} The created Assertion object. - */ -export function CreateAssertion( - id: string, - type: AssertionType, - scope: Scope, - statement: Statement, - appliesToState?: AppliesToState, - binding?: Binding -): Assertion { - return { - id, - type, - scope, - appliesToState, - statement, - binding: { method: binding?.method ?? '', signature: binding?.signature ?? '' }, - hash, - sign, - verify, - }; -} diff --git a/lib/tdf3/src/models/index.ts b/lib/tdf3/src/models/index.ts index 12ba37ef..b7a9d0c0 100644 --- a/lib/tdf3/src/models/index.ts +++ b/lib/tdf3/src/models/index.ts @@ -5,4 +5,4 @@ export * from './manifest.js'; export * from './payload.js'; export * from './policy.js'; export * from './upsert-response.js'; -export * from './assertion.js'; +export * from '../assertions.js'; diff --git a/lib/tdf3/src/models/manifest.ts b/lib/tdf3/src/models/manifest.ts index 51e86f81..4ed4ebdd 100644 --- a/lib/tdf3/src/models/manifest.ts +++ b/lib/tdf3/src/models/manifest.ts @@ -1,4 +1,4 @@ -import { type Assertion } from './assertion.js'; +import { type Assertion } from '../assertions.js'; import { type Payload } from './payload.js'; import { type EncryptionInformation } from './encryption-information.js'; diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 7b686f32..d615e8f9 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -5,12 +5,8 @@ import { DecoratedReadableStream } from './client/DecoratedReadableStream.js'; import { EntityObject } from '../../src/tdf/EntityObject.js'; import { pemToCryptoPublicKey, validateSecureUrl } from '../../src/utils.js'; import { DecryptParams } from './client/builders.js'; -import { - AssertionConfig, - AssertionKey, - AssertionVerificationKeys, -} from './client/AssertionConfig.js'; -import { Assertion, CreateAssertion } from './models/assertion.js'; +import { AssertionConfig, AssertionKey, AssertionVerificationKeys } from './assertions.js'; +import * as assertions from './assertions.js'; import { AttributeSet, @@ -166,6 +162,7 @@ export type DecryptConfiguration = { progressHandler?: (bytesProcessed: number) => void; fileStreamServiceWorker?: string; assertionVerificationKeys?: AssertionVerificationKeys; + noVerifyAssertions?: boolean; }; export type UpsertConfiguration = { @@ -452,7 +449,7 @@ async function _generateManifest( }; const encryptionInformationStr = await encryptionInformation.write(policy, keyInfo); - const assertions: Assertion[] = []; + const assertions: assertions.Assertion[] = []; return { payload, // generate the manifest first, then insert integrity information into it @@ -741,31 +738,19 @@ export async function writeStream(cfg: EncryptConfiguration): Promise 0) { await Promise.all( cfg.assertionConfigs.map(async (assertionConfig) => { // Create assertion using the assertionConfig values - const assertion = CreateAssertion( - assertionConfig.id, - assertionConfig.type, - assertionConfig.scope, - assertionConfig.statement, - assertionConfig.appliesToState - ); - - const assertionHash = await assertion.hash(); - const combinedHash = aggregateHash + assertionHash; - const encodedHash = base64.encode(combinedHash); - - // Create assertion key using the signingKey from the config, or a default key - const assertionKey: AssertionKey = assertionConfig.signingKey ?? { + const signingKey: AssertionKey = assertionConfig.signingKey ?? { alg: 'HS256', key: new Uint8Array(cfg.keyForEncryption.unwrappedKeyBinary.asArrayBuffer()), }; - - // Sign the assertion - await assertion.sign(assertionHash, encodedHash, assertionKey); + const assertion = await assertions.CreateAssertion(aggregateHash, { + ...assertionConfig, + signingKey, + }); // Add signed assertion to the signedAssertions array signedAssertions.push(assertion); @@ -838,7 +823,7 @@ export async function writeStream(cfg: EncryptConfiguration): Promise { }; }; -export const fromBuffer = (buffer: Uint8Array | Buffer): Chunker => { +export const fromBuffer = (source: Uint8Array | Buffer): Chunker => { return (byteStart?: number, byteEnd?: number) => { - return Promise.resolve(buffer.slice(byteStart, byteEnd)); + return Promise.resolve(source.slice(byteStart, byteEnd)); }; }; diff --git a/lib/tdf3/src/utils/index.ts b/lib/tdf3/src/utils/index.ts index 0fa41f7a..b8bf7494 100644 --- a/lib/tdf3/src/utils/index.ts +++ b/lib/tdf3/src/utils/index.ts @@ -130,39 +130,39 @@ function base64Slice(buf: Uint8Array, start: number, end: number): string { // https://github.com/feross/buffer/blob/master/index.js#L483 export function buffToString( - buffer: Uint8Array, + source: Uint8Array, encoding: SupportedEncoding = 'utf8', start = 0, - end = buffer.length + end = source.length ) { if (start < 0) { start = 0; } - if (end > buffer.length) { - end = buffer.length; + if (end > source.length) { + end = source.length; } // Return early if start > buffer.length. Done here to prevent potential uint32 // coercion fail below. - if (start > buffer.length || end <= 0 || end <= start) { + if (start > source.length || end <= 0 || end <= start) { return ''; } switch (encoding) { case 'hex': - return hexSlice(buffer, start, end); + return hexSlice(source, start, end); case 'utf8': case 'utf-8': - return utf8Slice(buffer, start, end); + return utf8Slice(source, start, end); case 'latin1': case 'binary': - return latin1Slice(buffer, start, end); + return latin1Slice(source, start, end); case 'base64': - return base64Slice(buffer, start, end); + return base64Slice(source, start, end); } } diff --git a/lib/tdf3/src/utils/zip-reader.ts b/lib/tdf3/src/utils/zip-reader.ts index 1fd6cdbe..1b59fb57 100644 --- a/lib/tdf3/src/utils/zip-reader.ts +++ b/lib/tdf3/src/utils/zip-reader.ts @@ -69,8 +69,8 @@ export class ZipReader { /** * Utility function to get the centralDirectory for the zip file. - * @param {Buffer} chunkBuffer Takes a buffer of a portion of the file - * @return {Object} The central directory represented as an object + * It reads the end of the file to find it. + * @return The central directory represented as an object */ async getCentralDirectory(): Promise { const chunk = await this.getChunk(-1000); @@ -138,10 +138,9 @@ export class ZipReader { } /** - * Takes a portion of a ZIP (must be the last portion of a ZIP to work) and returns an array of Buffers - * that correspond to each central directory. - * @param {Buffer} chunkBuffer The last portion of a zip file - * @returns {Array} An array of buffers + * extracts the CD buffer entries from the end of a zip file. + * @param chunkBuffer The last portion of a zip file + * @returns an array of typed arrays, each element corresponding to a central directory record */ getCDBuffers(chunkBuffer: Uint8Array): Uint8Array[] { const cdBuffers = []; diff --git a/lib/tests/mocha/encrypt-decrypt.spec.ts b/lib/tests/mocha/encrypt-decrypt.spec.ts index 532856e8..a2094aea 100644 --- a/lib/tests/mocha/encrypt-decrypt.spec.ts +++ b/lib/tests/mocha/encrypt-decrypt.spec.ts @@ -7,10 +7,7 @@ import { WebCryptoService } from '../../tdf3/index.js'; import { Client } from '../../tdf3/src/index.js'; import { SplitKey } from '../../tdf3/src/models/encryption-information.js'; import { AesGcmCipher } from '../../tdf3/src/ciphers/aes-gcm-cipher.js'; -import { - AssertionConfig, - AssertionVerificationKeys, -} from '../../tdf3/src/client/AssertionConfig.js'; +import { AssertionConfig, AssertionVerificationKeys } from '../../tdf3/src/assertions.js'; import { Scope } from '../../tdf3/src/client/builders.js'; const Mocks = getMocks(); diff --git a/lib/tests/mocha/unit/assertions.spec.ts b/lib/tests/mocha/unit/assertions.spec.ts new file mode 100644 index 00000000..c3e3491d --- /dev/null +++ b/lib/tests/mocha/unit/assertions.spec.ts @@ -0,0 +1,25 @@ +// tests for assertions.ts + +import { expect } from 'chai'; + +import * as assertions from '../../../tdf3/src/assertions.js'; + +describe('assertions', () => { + describe('isAssertionConfig', () => { + it('validates config', () => { + expect( + assertions.isAssertionConfig({ + id: 'assertion1', + type: 'handling', + scope: 'tdo', + appliesToState: 'unencrypted', + statement: { + format: 'base64binary', + schema: 'text', + value: 'ICAgIDxlZGoOkVkaD4=', + }, + }) + ).to.be.true; + }); + }); +}); diff --git a/lib/tests/mocha/unit/keysplits.spec.ts b/lib/tests/mocha/unit/keysplits.spec.ts index f46638bb..4d6bad44 100644 --- a/lib/tests/mocha/unit/keysplits.spec.ts +++ b/lib/tests/mocha/unit/keysplits.spec.ts @@ -8,8 +8,8 @@ import * as defaultCryptoService from '../../../tdf3/src/crypto/index.js'; describe('keysplits', () => { it('binary xor', () => { - expect(bxor(Buffer.from([0x0f]), Buffer.from([0xf0]))).to.eql(Buffer.from([0xff])); - expect(bxor(Buffer.from([0x0f]), Buffer.from([0x0f]))).to.eql(Buffer.from([0x00])); + expect(bxor(new Uint8Array([0x0f]), new Uint8Array([0xf0]))).to.eql(new Uint8Array([0xff])); + expect(bxor(new Uint8Array([0x0f]), new Uint8Array([0x0f]))).to.eql(new Uint8Array([0x00])); }); it('should return the original byte array with split set to one part', async () => { diff --git a/lib/tests/mocha/unit/tdf.spec.ts b/lib/tests/mocha/unit/tdf.spec.ts index 62404aea..f30c5432 100644 --- a/lib/tests/mocha/unit/tdf.spec.ts +++ b/lib/tests/mocha/unit/tdf.spec.ts @@ -43,13 +43,9 @@ HJg= describe('TDF', () => { it('Encodes the postMessage origin properly in wrapHtml', () => { - const cipherText = 'abcezas123'; + const cipherText = new TextEncoder().encode('abcezas123'); const transferUrl = 'https://local.virtru.com/start?htmlProtocol=1'; - const wrapped = TDF.wrapHtml( - Buffer.from(cipherText), - JSON.stringify({ thisIs: 'metadata' }), - transferUrl - ); + const wrapped = TDF.wrapHtml(cipherText, JSON.stringify({ thisIs: 'metadata' }), transferUrl); const rawHtml = new TextDecoder().decode(wrapped); expect(rawHtml).to.include("'https://local.virtru.com', [channel.port2]);"); }); diff --git a/lib/tests/mocha/unit/zip.spec.ts b/lib/tests/mocha/unit/zip.spec.ts index a48a33e5..a38b34e2 100644 --- a/lib/tests/mocha/unit/zip.spec.ts +++ b/lib/tests/mocha/unit/zip.spec.ts @@ -32,24 +32,25 @@ describe('zip utilities', () => { describe('writeUInt64LE', () => { it('not too different', () => { - const b0 = Buffer.alloc(8); + // allocate a new uint8array with 8 bytes + const b0 = new Uint8Array(8); new DataView(b0.buffer).setBigUint64(0, BigInt(1), true); - const b1 = Buffer.alloc(8); + const b1 = new Uint8Array(8); writeUInt64LE(b1, 1, 0); expect(b1).to.eql(b0); }); it('unsafe ints throw', () => { - expect(() => writeUInt64LE(Buffer.alloc(0), 2 ** 54, 0)).to.throw(/unsafe number/); + expect(() => writeUInt64LE(new Uint8Array(0), 2 ** 54, 0)).to.throw(/unsafe number/); }); }); describe('readUInt64LE', () => { it('one', () => { - const b0 = Buffer.alloc(8); + const b0 = new Uint8Array(8); new DataView(b0.buffer).setBigUint64(0, 1n, true); expect(readUInt64LE(b0, 0)).to.equal(1); }); it('unsafe ints throw', () => { - const b0 = Buffer.alloc(8); + const b0 = new Uint8Array(8); new DataView(b0.buffer).setBigUint64(0, 9007199254740992n, true); expect(() => readUInt64LE(b0, 0)).to.throw(/exceeds/); }); diff --git a/lib/tests/server.ts b/lib/tests/server.ts index 972cada3..9041db3f 100644 --- a/lib/tests/server.ts +++ b/lib/tests/server.ts @@ -35,6 +35,18 @@ type RewrapBody = { clientPublicKey: string; }; +function concat(b: ArrayBufferView[]) { + const length = b.reduce((lk, ak) => lk + ak.byteLength, 0); + const buf = new Uint8Array(length); + let offset = 0; + for (const v of b) { + const uint8view = new Uint8Array(v.buffer, v.byteOffset, v.byteLength); + buf.set(uint8view, offset); + offset += uint8view.byteLength; + } + return buf; +} + function getBody(request: IncomingMessage): Promise { return new Promise((resolve, reject) => { const bodyParts: Uint8Array[] = []; @@ -43,7 +55,7 @@ function getBody(request: IncomingMessage): Promise { bodyParts.push(chunk); }) .on('end', () => { - resolve(Buffer.concat(bodyParts)); + resolve(concat(bodyParts)); }) .on('error', reject); }); @@ -237,11 +249,11 @@ const kas: RequestListener = async (req, res) => { res.statusCode = 206; // Partial Content res.setHeader('Content-Type', 'application/octet-stream'); res.setHeader('Content-Length', rangeData.length); - res.end(Buffer.from(rangeData.buffer)); + res.end(rangeData); } else { res.statusCode = 200; // OK res.setHeader('Content-Type', 'application/octet-stream'); - res.end(Buffer.from(fullRange.buffer)); + res.end(fullRange); } } else if (url.pathname === '/attributes/*/fqn') { const fqnAttributeValues: Record = {}; diff --git a/lib/webpack.test.config.cjs b/lib/webpack.test.config.cjs index 192703f9..814e9606 100644 --- a/lib/webpack.test.config.cjs +++ b/lib/webpack.test.config.cjs @@ -9,11 +9,6 @@ module.exports = { path: path.resolve(__dirname, 'tests/mocha/dist'), filename: '[name].js', }, - plugins: [ - new webpack.ProvidePlugin({ - Buffer: ['buffer', 'Buffer'], - }), - ], resolve: { extensions: ['.js'], }, diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index 99ef279a..80b7c94e 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1536,9 +1536,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1821,14 +1821,13 @@ "node_modules/@opentdf/client": { "version": "2.1.0", "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -3383,30 +3382,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -4234,26 +4209,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "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.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index c8c1493c..bd4a71b9 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -350,9 +350,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -607,14 +607,13 @@ "node_modules/@opentdf/client": { "version": "2.1.0", "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -1295,6 +1294,7 @@ }, "node_modules/buffer": { "version": "6.0.3", + "dev": true, "funding": [ { "type": "github", @@ -2152,6 +2152,7 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "dev": true, "funding": [ { "type": "github", @@ -3958,9 +3959,9 @@ } }, "@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -4118,13 +4119,12 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -4526,6 +4526,7 @@ }, "buffer": { "version": "6.0.3", + "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -5047,7 +5048,8 @@ "dev": true }, "ieee754": { - "version": "1.2.1" + "version": "1.2.1", + "dev": true }, "ignore": { "version": "5.2.4", From 5add5aa1be96abf08c15573080e8e8e537e939f8 Mon Sep 17 00:00:00 2001 From: Elizabeth Healy <35498075+elizabethhealy@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:34:22 -0500 Subject: [PATCH 38/42] fix: Rewrap response handling typo (#372) --- lib/tdf3/src/tdf.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index d615e8f9..32c385b2 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -563,7 +563,7 @@ export async function upsert({ return response.data; } catch (e) { if (e.response) { - if (e.reponse.status >= 500) { + if (e.response.status >= 500) { throw new ServiceError('upsert failure', e); } else if (e.response.status === 403) { throw new PermissionDeniedError('upsert failure', e); @@ -998,7 +998,7 @@ async function unwrapKey({ rewrappedKeys.push(new Uint8Array(decryptedKeyBinary.asByteArray())); } catch (e) { if (e.response) { - if (e.reponse.status >= 500) { + if (e.response.status >= 500) { throw new ServiceError('rewrap failure', e); } else if (e.response.status === 403) { throw new PermissionDeniedError('rewrap failure', e); From d1e0a4538e2f5ba58d42dbad3754131b6a533612 Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Tue, 5 Nov 2024 08:13:28 -0700 Subject: [PATCH 39/42] fix: Remove environment logging in vite.config.ts (#373) The environment may contain sensitive secrets. For this reason we should avoid logging it to the console. --- web-app/vite.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/web-app/vite.config.ts b/web-app/vite.config.ts index aaccc801..012a4036 100644 --- a/web-app/vite.config.ts +++ b/web-app/vite.config.ts @@ -5,7 +5,6 @@ import react from '@vitejs/plugin-react'; const require = createRequire(import.meta.url) function proxy(): Record { - console.log(process.env); const { VITE_PROXY } = process.env; if (VITE_PROXY) { console.log(`using VITE_PROXY [${VITE_PROXY}]`); From f1c7fe631c3e6ccc571dc39aea13f3fb65ec3530 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 5 Nov 2024 16:21:39 -0500 Subject: [PATCH 40/42] feat!(sdk): renames opentdf/client opentdf/sdk (#374) - Renames library from `client` to `sdk` to reflect we are adding more platform-specific features, in addition to the core TDF functionality - Removes remote-store, as it is unmaintained - Resets version numbering to 0.1.0 - tags from here on out will be prefixed with library short name and a slash - renames cli to ctl so we can keep lockstep versioning the different packages --- .github/workflows/build.yaml | 73 +- .github/workflows/format.yaml | 4 +- .github/workflows/gh-semver.bats | 4 +- .github/workflows/gh-semver.sh | 2 +- .github/workflows/guess-dist-tag.bats | 2 +- .github/workflows/guess-dist-tag.sh | 14 +- .github/workflows/large-tests.yaml | 20 +- .github/workflows/publish-to.sh | 13 +- .../workflows/roundtrip/encrypt-decrypt.sh | 4 +- .github/workflows/roundtrip/package-lock.json | 170 +- .github/workflows/roundtrip/package.json | 4 +- .github/workflows/roundtrip/wait-and-test.sh | 12 +- Makefile | 31 +- README.md | 8 +- cli/bin/opentdf.bats | 4 +- cli/package-lock.json | 18 +- cli/package.json | 8 +- cli/src/cli.ts | 12 +- lib/package-lock.json | 8 +- lib/package.json | 12 +- lib/src/index.ts | 4 +- lib/src/nanotdf/Client.ts | 2 +- lib/src/version.ts | 6 +- lib/tdf3/src/version.ts | 2 +- remote-store/.eslintrc.yaml | 13 - remote-store/.mocharc.yaml | 5 - remote-store/README.md | 3 - remote-store/package-lock.json | 5835 ----------------- remote-store/package.json | 63 - remote-store/src/aws-lib-storage/Upload.ts | 432 -- remote-store/src/aws-lib-storage/chunker.ts | 27 - .../aws-lib-storage/chunks/getChunkBuffer.ts | 26 - .../aws-lib-storage/chunks/getChunkStream.ts | 62 - .../aws-lib-storage/chunks/getDataReadable.ts | 5 - .../chunks/getDataReadableStream.ts | 18 - remote-store/src/aws-lib-storage/index.ts | 4 - .../aws-lib-storage/runtimeConfig.browser.ts | 9 - .../aws-lib-storage/runtimeConfig.shared.ts | 7 - .../src/aws-lib-storage/runtimeConfig.ts | 12 - remote-store/src/aws-lib-storage/types.ts | 56 - remote-store/src/index.ts | 185 - remote-store/tests/index.test.ts | 9 - remote-store/tsconfig.json | 32 - scripts/bump-version.sh | 2 +- web-app/package-lock.json | 20 +- web-app/package.json | 4 +- web-app/src/App.tsx | 2 +- web-app/src/session.ts | 4 +- 48 files changed, 208 insertions(+), 7064 deletions(-) delete mode 100644 remote-store/.eslintrc.yaml delete mode 100644 remote-store/.mocharc.yaml delete mode 100644 remote-store/README.md delete mode 100644 remote-store/package-lock.json delete mode 100644 remote-store/package.json delete mode 100644 remote-store/src/aws-lib-storage/Upload.ts delete mode 100644 remote-store/src/aws-lib-storage/chunker.ts delete mode 100644 remote-store/src/aws-lib-storage/chunks/getChunkBuffer.ts delete mode 100644 remote-store/src/aws-lib-storage/chunks/getChunkStream.ts delete mode 100644 remote-store/src/aws-lib-storage/chunks/getDataReadable.ts delete mode 100644 remote-store/src/aws-lib-storage/chunks/getDataReadableStream.ts delete mode 100644 remote-store/src/aws-lib-storage/index.ts delete mode 100644 remote-store/src/aws-lib-storage/runtimeConfig.browser.ts delete mode 100644 remote-store/src/aws-lib-storage/runtimeConfig.shared.ts delete mode 100644 remote-store/src/aws-lib-storage/runtimeConfig.ts delete mode 100644 remote-store/src/aws-lib-storage/types.ts delete mode 100644 remote-store/src/index.ts delete mode 100644 remote-store/tests/index.test.ts delete mode 100644 remote-store/tsconfig.json diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 69a3a6b7..eb6a6474 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -46,8 +46,8 @@ jobs: - run: npm pack - uses: actions/upload-artifact@v4 with: - name: opentdf-client-lib - path: ./lib/opentdf-client-*.tgz + name: opentdf-sdk-lib + path: ./lib/opentdf-sdk-*.tgz - name: SonarCloud Scan if: fromJSON(env.do_sonarscan) uses: SonarSource/sonarcloud-github-action@master @@ -55,33 +55,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - remote-store: - needs: - - lib - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./remote-store - timeout-minutes: 5 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - cache-dependency-path: './remote-store/package-lock.json' - - uses: actions/download-artifact@v4 - with: - name: opentdf-client-lib - path: lib/ - - run: npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-*.tgz - - run: npm install - - run: npm test - - run: npm audit --omit dev && npm audit --audit-level high - - run: npm run license-check - - run: npm run lint - - run: npm pack - cli: needs: - lib @@ -99,9 +72,9 @@ jobs: cache-dependency-path: './cli/package-lock.json' - uses: actions/download-artifact@v4 with: - name: opentdf-client-lib + name: opentdf-sdk-lib path: lib/ - - run: npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-*.tgz + - run: npm uninstall @opentdf/sdk && npm ci && npm i ../lib/opentdf-sdk-*.tgz - run: npm test - run: npm audit --omit dev && npm audit --audit-level high --omit dev - run: npm run license-check @@ -112,8 +85,8 @@ jobs: - run: bats bin/opentdf.bats - uses: actions/upload-artifact@v4 with: - name: opentdf-cli - path: ./cli/opentdf-cli-*.tgz + name: opentdf-ctl + path: ./cli/opentdf-ctl-*.tgz web-app: needs: @@ -132,9 +105,9 @@ jobs: cache-dependency-path: './web-app/package-lock.json' - uses: actions/download-artifact@v4 with: - name: opentdf-client-lib + name: opentdf-sdk-lib path: lib/ - - run: npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-*.tgz + - run: npm uninstall @opentdf/sdk && npm ci && npm i ../lib/opentdf-sdk-*.tgz - run: npm install - run: npm audit --omit dev && npm audit --audit-level high --omit dev - run: npm run license-check @@ -177,11 +150,11 @@ jobs: cache-dependency-path: './web-app/package-lock.json' - uses: actions/download-artifact@v4 with: - name: opentdf-client-lib + name: opentdf-sdk-lib path: lib/ - uses: actions/download-artifact@v4 with: - name: opentdf-cli + name: opentdf-ctl path: cli/ - uses: yokawasa/action-setup-kube-tools@v0.11.1 with: @@ -230,11 +203,11 @@ jobs: cache-dependency-path: './web-app/package-lock.json' - uses: actions/download-artifact@v4 with: - name: opentdf-client-lib + name: opentdf-sdk-lib path: lib/ - uses: actions/download-artifact@v4 with: - name: opentdf-cli + name: opentdf-ctl path: cli/ - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 with: @@ -251,13 +224,13 @@ jobs: ./wait-and-test.sh platform platform-xtest: - needs: + needs: - cli - lib uses: opentdf/tests/.github/workflows/xtest.yml@main with: js-ref: ${{ github.ref }} - + deliver-ghp: needs: - lib @@ -289,7 +262,7 @@ jobs: run: |- if [[ ${{ github.ref }} = refs/heads/release/* ]]; then scripts/check-version-is.sh "${GITHUB_REF##*release/}" - elif [[ ${{ github.ref }} = refs/tags/v* ]]; then + elif [[ ${{ github.ref }} = refs/tags/sdk/v* ]]; then scripts/check-version-is.sh "${GITHUB_REF_NAME#v}" else scripts/check-version-is.sh @@ -303,7 +276,7 @@ jobs: - run: make doc - run: >- echo "::notice file=lib/package.json::Will be published to - [GitHub Packages](https://github.com/opentdf/client-web/pkgs/npm/client) + [GitHub Packages](https://github.com/opentdf/web-sdk/pkgs/npm/client) as ${{ steps.guess-build-metadata.outputs.DIST_TAG }} with version=[${{ steps.guess-build-metadata.outputs.FULL_VERSION }}]" - run: >- @@ -312,8 +285,8 @@ jobs: "${{ steps.guess-build-metadata.outputs.DIST_TAG }}" env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - run: echo "- [Client Library](https://github.com/opentdf/client-web/pkgs/npm/client)">>$GITHUB_STEP_SUMMARY - - run: echo "- [Command Line Tool](https://github.com/opentdf/client-web/pkgs/npm/cli)">>$GITHUB_STEP_SUMMARY + - run: echo "- [Client Library](https://github.com/opentdf/web-sdk/pkgs/npm/client)">>$GITHUB_STEP_SUMMARY + - run: echo "- [Command Line Tool](https://github.com/opentdf/web-sdk/pkgs/npm/cli)">>$GITHUB_STEP_SUMMARY - name: trigger xtest run: >- curl -XPOST -u "virtru-cloudnative:${{secrets.PERSONAL_ACCESS_TOKEN}}" @@ -337,7 +310,7 @@ jobs: if: >- (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release/')) || - (github.event_name == 'release' && startsWith(github.ref, 'refs/tags/')) + (github.event_name == 'release' && startsWith(github.ref, 'refs/tags/sdk/v')) steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -352,10 +325,8 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: >- - echo "- [Client Library](https://www.npmjs.com/package/@opentdf/client/v/${{ needs.deliver-ghp.outputs.FULL_VERSION }})">>$GITHUB_STEP_SUMMARY - - run: >- - echo "- [Remote Store](https://www.npmjs.com/package/@opentdf/remote-store/v/${{ needs.deliver-ghp.outputs.FULL_VERSION }})">>$GITHUB_STEP_SUMMARY + echo "- [Client Library](https://www.npmjs.com/package/@opentdf/sdk/v/${{ needs.deliver-ghp.outputs.FULL_VERSION }})">>$GITHUB_STEP_SUMMARY - run: >- - echo "- [Command Line Tool](https://www.npmjs.com/package/@opentdf/cli/v/${{ needs.deliver-ghp.outputs.FULL_VERSION }})">>$GITHUB_STEP_SUMMARY + echo "- [Command Line Tool](https://www.npmjs.com/package/@opentdf/ctl/v/${{ needs.deliver-ghp.outputs.FULL_VERSION }})">>$GITHUB_STEP_SUMMARY - run: >- - echo "- [unpkg](https://unpkg.com/browse/@opentdf/client@${{ needs.deliver-ghp.outputs.FULL_VERSION }})">>$GITHUB_STEP_SUMMARY \ No newline at end of file + echo "- [unpkg](https://unpkg.com/browse/@opentdf/sdk@${{ needs.deliver-ghp.outputs.FULL_VERSION }})">>$GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/.github/workflows/format.yaml b/.github/workflows/format.yaml index a01a0616..95e6161a 100644 --- a/.github/workflows/format.yaml +++ b/.github/workflows/format.yaml @@ -20,10 +20,10 @@ jobs: - run: git diff-files --ignore-submodules - name: Check that files have been formatted before PR submission run: git diff-files --quiet --ignore-submodules - if: ${{ github.event.pull_request.head.repo.full_name != 'opentdf/client-web' }} + if: ${{ github.event.pull_request.head.repo.full_name != 'opentdf/web-sdk' }} - name: Commit changes id: auto-commit - if: ${{ github.event.pull_request.head.repo.full_name == 'opentdf/client-web' }} + if: ${{ github.event.pull_request.head.repo.full_name == 'opentdf/web-sdk' }} uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: |- diff --git a/.github/workflows/gh-semver.bats b/.github/workflows/gh-semver.bats index 68cf186c..2c76bde3 100755 --- a/.github/workflows/gh-semver.bats +++ b/.github/workflows/gh-semver.bats @@ -20,8 +20,8 @@ } -@test "all tags go to release" { - export GITHUB_REF=refs/tags/v12 +@test "sdk/v prefixed tags go to release" { + export GITHUB_REF=refs/tags/sdk/v12 export MMP_VER=0.0.1 export GITHUB_RUN_NUMBER=1234 run $BATS_TEST_DIRNAME/gh-semver.sh diff --git a/.github/workflows/gh-semver.sh b/.github/workflows/gh-semver.sh index de60b8a2..a2b23b45 100755 --- a/.github/workflows/gh-semver.sh +++ b/.github/workflows/gh-semver.sh @@ -29,7 +29,7 @@ # Tags go to release: # ``` # package.version = 1.2.3 -# tag = v1.2.3 +# tag = sdk/v1.2.3 # workflow run = 256 # git SHA = decaf # ---- diff --git a/.github/workflows/guess-dist-tag.bats b/.github/workflows/guess-dist-tag.bats index 205f4a5b..0af6a3e4 100755 --- a/.github/workflows/guess-dist-tag.bats +++ b/.github/workflows/guess-dist-tag.bats @@ -29,7 +29,7 @@ } @test "all tags go to release" { - export GITHUB_REF=refs/tags/v12 + export GITHUB_REF=refs/tags/sdk/v12 run $BATS_TEST_DIRNAME/guess-dist-tag.sh echo output=[$output] [[ $output == "latest" ]] diff --git a/.github/workflows/guess-dist-tag.sh b/.github/workflows/guess-dist-tag.sh index 1f36afbf..24f14ff9 100755 --- a/.github/workflows/guess-dist-tag.sh +++ b/.github/workflows/guess-dist-tag.sh @@ -1,8 +1,12 @@ #!/usr/bin/env bash -# Guess the desired NPM 'dist' tag based on current git ref -# Release = latest -# Release candidate = rc -# Beta = beta +# Guess the desired NPM distribution tag based on current git ref. +# For more info, see: https://docs.npmjs.com/adding-dist-tags-to-packages +# Releases are tagged with `latest`, on tags like `sdk/v1.2.3` +# Release candidates are tagged `rc`, from branches prefixed with `release/` +# Betas are the main branch. +# Alphas can be manually built from feature branches. +# Aleph is the fallback for unknown branch and tag patterns. +# Notably, our dist-tags sort lexicographically from least to most stable. set -euo pipefail @@ -19,7 +23,7 @@ case "${GITHUB_REF}" in refs/heads/feature*) NPM_DIST_TAG=alpha ;; - refs/tags/v*) + refs/tags/sdk/v*) NPM_DIST_TAG=latest ;; esac diff --git a/.github/workflows/large-tests.yaml b/.github/workflows/large-tests.yaml index 0f712569..bf3eb52f 100644 --- a/.github/workflows/large-tests.yaml +++ b/.github/workflows/large-tests.yaml @@ -29,8 +29,8 @@ jobs: - run: npm pack - uses: actions/upload-artifact@v4 with: - name: opentdf-client-lib - path: ./lib/opentdf-client-*.tgz + name: opentdf-sdk-lib + path: ./lib/opentdf-sdk-*.tgz cli: needs: @@ -49,9 +49,9 @@ jobs: cache-dependency-path: './cli/package-lock.json' - uses: actions/download-artifact@v4 with: - name: opentdf-client-lib + name: opentdf-sdk-lib path: lib/ - - run: npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-*.tgz + - run: npm uninstall @opentdf/sdk && npm ci && npm i ../lib/opentdf-sdk-*.tgz - run: npm test - run: npm audit --omit dev --audit-level moderate - run: npm run license-check @@ -59,8 +59,8 @@ jobs: - run: npm pack - uses: actions/upload-artifact@v4 with: - name: opentdf-cli - path: ./cli/opentdf-cli-*.tgz + name: opentdf-ctl + path: ./cli/opentdf-ctl-*.tgz web-app: needs: @@ -79,9 +79,9 @@ jobs: cache-dependency-path: './web-app/package-lock.json' - uses: actions/download-artifact@v4 with: - name: opentdf-client-lib + name: opentdf-sdk-lib path: lib/ - - run: npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-*.tgz + - run: npm uninstall @opentdf/sdk && npm ci && npm i ../lib/opentdf-sdk-*.tgz - run: npm install - run: npm test - run: npm audit --omit dev --audit-level moderate @@ -107,11 +107,11 @@ jobs: cache-dependency-path: './web-app/package-lock.json' - uses: actions/download-artifact@v4 with: - name: opentdf-client-lib + name: opentdf-sdk-lib path: lib/ - uses: actions/download-artifact@v4 with: - name: opentdf-cli + name: opentdf-ctl path: cli - name: Git clone backend run: | diff --git a/.github/workflows/publish-to.sh b/.github/workflows/publish-to.sh index 6ce1ef07..b577ff70 100755 --- a/.github/workflows/publish-to.sh +++ b/.github/workflows/publish-to.sh @@ -20,14 +20,11 @@ npm publish --access public --tag "$t" # Wait for npm publish to go through... sleep 5 -for x in remote-store cli; do - cd "../$x" - - npm version --no-git-tag-version --allow-same-version "$v" - npm uninstall "@opentdf/client" - npm install "@opentdf/client@$v" - npm publish --access public --tag "$t" -done +cd "../cli" +npm version --no-git-tag-version --allow-same-version "$v" +npm uninstall "@opentdf/sdk" +npm install "@opentdf/sdk@$v" +npm publish --access public --tag "$t" if [[ "$GITHUB_STEP_SUMMARY" ]]; then echo "### Published ${v} (${t})" >>"$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/roundtrip/encrypt-decrypt.sh b/.github/workflows/roundtrip/encrypt-decrypt.sh index ce21e14a..73e4fbdd 100755 --- a/.github/workflows/roundtrip/encrypt-decrypt.sh +++ b/.github/workflows/roundtrip/encrypt-decrypt.sh @@ -35,7 +35,7 @@ _nano_test() { rm -f "${plain}" sample.txt.ntdf sample_out.txt } -_nano_test @opentdf/cli @opentdf/cli +_nano_test @opentdf/ctl @opentdf/ctl _tdf3_test() { counter=$((counter + 1)) @@ -66,4 +66,4 @@ _tdf3_test() { rm -f "${plain}" sample.txt.tdf sample_out.txt } -_tdf3_test @opentdf/cli @opentdf/cli +_tdf3_test @opentdf/ctl @opentdf/ctl diff --git a/.github/workflows/roundtrip/package-lock.json b/.github/workflows/roundtrip/package-lock.json index f271315e..e3e8765a 100644 --- a/.github/workflows/roundtrip/package-lock.json +++ b/.github/workflows/roundtrip/package-lock.json @@ -1,20 +1,21 @@ { - "name": "client-web-roundtrip", + "name": "web-sdk-roundtrip", "version": "0.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "client-web-roundtrip", + "name": "web-sdk-roundtrip", "version": "0.0.1", "dependencies": { - "@opentdf/cli": "file:../../../cli/opentdf-cli-2.0.0.tgz" + "@opentdf/ctl": "file:../../../cli/opentdf-ctl-0.1.0.tgz" } }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -22,32 +23,34 @@ "node": ">=6.9.0" } }, - "node_modules/@opentdf/cli": { - "version": "2.0.0", - "resolved": "file:../../../cli/opentdf-cli-2.0.0.tgz", - "integrity": "sha512-VyP+j6+YeitjJz5xWpVsQbwjiqkPY5OfHLU/fn2I3rU0qlOARqZia47TuS7MLkPmQ/m6Myt1q79ysIXV9Dxlng==", + "node_modules/@opentdf/ctl": { + "version": "0.1.0", + "resolved": "file:../../../cli/opentdf-ctl-0.1.0.tgz", + "integrity": "sha512-dWcbjYLFiT/5yDRAPU+bmRTYAkIkrIH6heSNAZr9knib6msj16OmPvvlypI/VAtBdfNOoIrLfcfde0ABGddt7A==", + "license": "BSD-3-Clause-Clear", "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", "yargs": "^17.7.2" }, "bin": { "opentdf": "bin/opentdf.mjs" } }, - "node_modules/@opentdf/client": { - "version": "2.0.0", - "resolved": "file:../../../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-hrF0E3JpYyYab0HOOQZ8VT+69SFgeRAxdS1f97s5Su2dBBX0IrGgpR0ZlKMbt9nlzCKChia1MIz7jsRTg+3sSg==", + "node_modules/@opentdf/sdk": { + "version": "0.1.0", + "resolved": "file:../../../lib/opentdf-sdk-0.1.0.tgz", + "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", + "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" } @@ -77,12 +80,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { "version": "1.7.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -93,6 +98,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -115,40 +121,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/browser-fs-access": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } + "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", + "license": "Apache-2.0" }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } @@ -186,6 +172,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -197,6 +184,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -205,6 +193,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -225,7 +214,8 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/follow-redirects": { "version": "1.15.9", @@ -237,6 +227,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -247,9 +238,10 @@ } }, "node_modules/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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -267,25 +259,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "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" - } - ] - }, "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", @@ -298,6 +271,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -309,14 +283,22 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } }, + "node_modules/json-canonicalize": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/json-canonicalize/-/json-canonicalize-1.0.6.tgz", + "integrity": "sha512-kP2iYpOS5SZHYhIaR1t9oG80d4uTY3jPoaBj+nimy3njtJk8+sRsVatN8pyJRDRtk9Su3+6XqA2U8k0dByJBUQ==", + "license": "MIT" + }, "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==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -325,6 +307,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -335,12 +318,14 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "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==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", @@ -359,7 +344,8 @@ "type": "github", "url": "https://github.com/sponsors/jimmywarting" } - ] + ], + "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", @@ -393,6 +379,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -449,34 +436,34 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "requires": { "regenerator-runtime": "^0.14.0" } }, - "@opentdf/cli": { - "version": "file:../../../cli/opentdf-cli-2.0.0.tgz", - "integrity": "sha512-VyP+j6+YeitjJz5xWpVsQbwjiqkPY5OfHLU/fn2I3rU0qlOARqZia47TuS7MLkPmQ/m6Myt1q79ysIXV9Dxlng==", + "@opentdf/ctl": { + "version": "file:../../../cli/opentdf-ctl-0.1.0.tgz", + "integrity": "sha512-dWcbjYLFiT/5yDRAPU+bmRTYAkIkrIH6heSNAZr9knib6msj16OmPvvlypI/VAtBdfNOoIrLfcfde0ABGddt7A==", "requires": { - "@opentdf/client": "file:../lib/opentdf-client-2.0.0.tgz", + "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", "yargs": "^17.7.2" } }, - "@opentdf/client": { - "version": "file:../lib/opentdf-client-2.0.0.tgz", - "integrity": "sha512-hrF0E3JpYyYab0HOOQZ8VT+69SFgeRAxdS1f97s5Su2dBBX0IrGgpR0ZlKMbt9nlzCKChia1MIz7jsRTg+3sSg==", + "@opentdf/sdk": { + "version": "file:../lib/opentdf-sdk-0.1.0.tgz", + "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", "streamsaver": "^2.0.6", "uuid": "~9.0.0" } @@ -528,15 +515,6 @@ "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -604,9 +582,9 @@ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" }, "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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -618,11 +596,6 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, "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", @@ -638,6 +611,11 @@ "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==" }, + "json-canonicalize": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/json-canonicalize/-/json-canonicalize-1.0.6.tgz", + "integrity": "sha512-kP2iYpOS5SZHYhIaR1t9oG80d4uTY3jPoaBj+nimy3njtJk8+sRsVatN8pyJRDRtk9Su3+6XqA2U8k0dByJBUQ==" + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", diff --git a/.github/workflows/roundtrip/package.json b/.github/workflows/roundtrip/package.json index 6eeb6827..e51758ea 100644 --- a/.github/workflows/roundtrip/package.json +++ b/.github/workflows/roundtrip/package.json @@ -1,9 +1,9 @@ { - "name": "client-web-roundtrip", + "name": "web-sdk-roundtrip", "version": "0.0.1", "description": "Simple example to encrypt and decrypt files with quickstart backend.", "scripts": {}, "dependencies": { - "@opentdf/cli": "file:../../../cli/opentdf-cli-2.0.0.tgz" + "@opentdf/ctl": "file:../../../cli/opentdf-ctl-0.1.0.tgz" } } diff --git a/.github/workflows/roundtrip/wait-and-test.sh b/.github/workflows/roundtrip/wait-and-test.sh index ec87959a..3ee41c0d 100755 --- a/.github/workflows/roundtrip/wait-and-test.sh +++ b/.github/workflows/roundtrip/wait-and-test.sh @@ -10,14 +10,14 @@ APP="${APP_DIR}/encrypt-decrypt.sh" _configure_app() { app_version=$(cd "${ROOT_DIR}/lib" && node -p "require('./package.json').version") - echo "installing opentdf-cli-${app_version}.tgz into ${APP_DIR}" + echo "installing opentdf-ctl-${app_version}.tgz into ${APP_DIR}" cd "${APP_DIR}" || exit 1 - npm uninstall @opentdf/cli + npm uninstall @opentdf/ctl if ! npm ci; then echo "[ERROR] Couldn't ci roundtrip command line app" return 1 fi - if ! npm i "../../../cli/opentdf-cli-${app_version}.tgz"; then + if ! npm i "../../../cli/opentdf-ctl-${app_version}.tgz"; then return 1 fi return 0 @@ -60,14 +60,14 @@ _init_webapp() { echo "[ERROR] unable to cd ${WEB_APP_DIR}" exit 2 fi - npm uninstall @opentdf/client + npm uninstall @opentdf/sdk if ! npm ci; then echo "[ERROR] Couldn't ci web-app" exit 2 fi - if ! npm i "../lib/opentdf-client-${app_version}.tgz"; then + if ! npm i "../lib/opentdf-sdk-${app_version}.tgz"; then ls -ls ../lib/ - echo "[ERROR] Couldn't install @opentdf/client tarball" + echo "[ERROR] Couldn't install @opentdf/sdk tarball" return 1 fi npm run dev &>"$output" & diff --git a/Makefile b/Makefile index a75fe0d2..548ad71c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -version=2.1.0 -extras=cli remote-store web-app +version=0.1.0 +extras=cli web-app pkgs=lib $(extras) .PHONY: all audit ci clean cli format i license-check lint start test @@ -8,7 +8,7 @@ pkgs=lib $(extras) start: all (cd web-app && npm run dev) -cli: cli/opentdf-cli-$(version).tgz +cli: cli/opentdf-ctl-$(version).tgz clean: rm -f *.tgz @@ -16,29 +16,26 @@ clean: rm -rf */dist rm -rf */node_modules -ci: lib/opentdf-client-$(version).tgz - for x in $(extras); do (cd $$x && npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-$(version).tgz) || exit 1; done +ci: lib/opentdf-sdk-$(version).tgz + for x in $(extras); do (cd $$x && npm uninstall @opentdf/sdk && npm ci && npm i ../lib/opentdf-sdk-$(version).tgz) || exit 1; done i: (cd lib && npm i && npm pack) - for x in $(extras); do (cd $$x && npm uninstall @opentdf/client && npm i && npm i ../lib/opentdf-client-$(version).tgz) || exit 1; done + for x in $(extras); do (cd $$x && npm uninstall @opentdf/sdk && npm i && npm i ../lib/opentdf-sdk-$(version).tgz) || exit 1; done -all: ci lib/opentdf-client-$(version).tgz remote-store/opentdf-remote-store-$(version).tgz web-app/opentdf-web-app-$(version).tgz +all: ci lib/opentdf-sdk-$(version).tgz web-app/opentdf-web-app-$(version).tgz -cli/opentdf-cli-$(version).tgz: lib/opentdf-client-$(version).tgz $(shell find cli -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') - (cd cli && npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-$(version).tgz && npm pack) +cli/opentdf-ctl-$(version).tgz: lib/opentdf-sdk-$(version).tgz $(shell find cli -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') + (cd cli && npm uninstall @opentdf/sdk && npm ci && npm i ../lib/opentdf-sdk-$(version).tgz && npm pack) -remote-store/opentdf-remote-store-$(version).tgz: lib/opentdf-client-$(version).tgz $(shell find remote-store -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') - (cd remote-store && npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-$(version).tgz && npm pack) +web-app/opentdf-web-app-$(version).tgz: lib/opentdf-sdk-$(version).tgz $(shell find web-app -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') + (cd web-app && npm uninstall @opentdf/sdk && npm ci && npm i ../lib/opentdf-sdk-$(version).tgz && npm pack && npm run build) -web-app/opentdf-web-app-$(version).tgz: lib/opentdf-client-$(version).tgz $(shell find web-app -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') - (cd web-app && npm uninstall @opentdf/client && npm ci && npm i ../lib/opentdf-client-$(version).tgz && npm pack && npm run build) - -lib/opentdf-client-$(version).tgz: $(shell find lib -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') +lib/opentdf-sdk-$(version).tgz: $(shell find lib -not -path '*/dist*' -and -not -path '*/coverage*' -and -not -path '*/node_modules*') (cd lib && npm ci --including=dev && npm pack) -dist: lib/opentdf-client-$(version).tgz - (cp lib/opentdf-client-$(version).tgz ./) +dist: lib/opentdf-sdk-$(version).tgz + (cp lib/opentdf-sdk-$(version).tgz ./) audit: for x in $(pkgs); do (cd $$x && npm audit --omit dev) || exit 1; done diff --git a/README.md b/README.md index b72205b2..e65dfb04 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ and some management tasks for ABAC. ## Usage (NanoTDF) ```typescript -import { AuthProviders, NanoTDFClient } from '@opentdf/client'; +import { AuthProviders, NanoTDFClient } from '@opentdf/sdk'; // Configuration Options const kasEndpoint = "http://localhost:65432/kas"; @@ -43,7 +43,7 @@ For long running server-side apps, a client id + secret is allowed with OAuth2. This should not be used in a browser, but within a Deno or Node process. ```typescript -import { AuthProviders } from '@opentdf/client'; +import { AuthProviders } from '@opentdf/sdk'; // Authentication options (vary by middleware) const oidcOrigin = "http://localhost:65432/auth/realms/tdf"; @@ -63,7 +63,7 @@ const authProvider = await AuthProviders.clientSecretAuthProvider({ The `refreshAuthProvider` and `externalAuthProvder` allow the application developer to use existing tokens. ```typescript -import { AuthProviders, NanoTDFClient } from '@opentdf/client'; +import { AuthProviders, NanoTDFClient } from '@opentdf/sdk'; const oidcCredentials: RefreshTokenCredentials = { clientId: keycloakClientId, @@ -97,7 +97,7 @@ which allows us to pin to the same version of `npm` easily. - see - `nvm use` will install `npm` and `node` -[![Build](https://github.com/opentdf/client-web/actions/workflows/build.yaml/badge.svg)](https://github.com/opentdf/client-web/actions/workflows/build.yaml) +[![Build](https://github.com/opentdf/web-sdk/actions/workflows/build.yaml/badge.svg)](https://github.com/opentdf/web-sdk/actions/workflows/build.yaml) To check out, build, and validate your installation, and test the sample web application, you may: diff --git a/cli/bin/opentdf.bats b/cli/bin/opentdf.bats index aa4c4360..9593258c 100755 --- a/cli/bin/opentdf.bats +++ b/cli/bin/opentdf.bats @@ -22,6 +22,6 @@ @test "version command" { run $BATS_TEST_DIRNAME/opentdf.mjs --version echo "$output" - [[ $output == *"@opentdf/client\":\""* ]] - [[ $output == *"@opentdf/cli\":\""* ]] + [[ $output == *"@opentdf/sdk\":\""* ]] + [[ $output == *"@opentdf/ctl\":\""* ]] } diff --git a/cli/package-lock.json b/cli/package-lock.json index b7d0ede2..ad7500e7 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1,15 +1,15 @@ { - "name": "@opentdf/cli", - "version": "2.1.0", + "name": "@opentdf/ctl", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@opentdf/cli", - "version": "2.1.0", + "name": "@opentdf/ctl", + "version": "0.1.0", "license": "BSD-3-Clause-Clear", "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", + "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", "yargs": "^17.7.2" }, "bin": { @@ -369,10 +369,10 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@opentdf/client": { - "version": "2.1.0", - "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", + "node_modules/@opentdf/sdk": { + "version": "0.1.0", + "resolved": "file:../lib/opentdf-sdk-0.1.0.tgz", + "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", diff --git a/cli/package.json b/cli/package.json index 43af8b1e..e6043ab8 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,10 +1,10 @@ { - "name": "@opentdf/cli", - "version": "2.1.0", + "name": "@opentdf/ctl", + "version": "0.1.0", "description": "Node based CLI for opentdf", "repository": { "type": "git", - "url": "git+https://github.com/opentdf/client-web.git", + "url": "git+https://github.com/opentdf/web-sdk.git", "directory": "cli" }, "license": "BSD-3-Clause-Clear", @@ -48,7 +48,7 @@ "typescript": "^5.1.6" }, "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", + "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", "yargs": "^17.7.2" } } diff --git a/cli/src/cli.ts b/cli/src/cli.ts index f5896835..6c6a88d6 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -15,12 +15,12 @@ import { EncryptParamsBuilder, DecryptParams, DecryptParamsBuilder, -} from '@opentdf/client'; +} from '@opentdf/sdk'; import { CLIError, Level, log } from './logger.js'; import { webcrypto } from 'crypto'; -import * as assertions from '@opentdf/client/assertions'; -import { attributeFQNsAsValues } from '@opentdf/client/nano'; -import { base64 } from '@opentdf/client/encodings'; +import * as assertions from '@opentdf/sdk/assertions'; +import { attributeFQNsAsValues } from '@opentdf/sdk/nano'; +import { base64 } from '@opentdf/sdk/encodings'; type AuthToProcess = { auth?: string; @@ -561,8 +561,8 @@ export const handleArgs = (args: string[]) => { .version( 'version', JSON.stringify({ - '@opentdf/cli': process.env.npm_package_version || 'UNRELEASED', - '@opentdf/client': version, + '@opentdf/ctl': process.env.npm_package_version || 'UNRELEASED', + '@opentdf/sdk': version, }) ) .alias('version', 'V') diff --git a/lib/package-lock.json b/lib/package-lock.json index 0267c2b5..8268111a 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -1,12 +1,12 @@ { - "name": "@opentdf/client", - "version": "2.1.0", + "name": "@opentdf/sdk", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@opentdf/client", - "version": "2.1.0", + "name": "@opentdf/sdk", + "version": "0.1.0", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", diff --git a/lib/package.json b/lib/package.json index 42734f80..138f3633 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,10 +1,10 @@ { - "name": "@opentdf/client", - "version": "2.1.0", - "description": "Access and generate tdf protected content", - "homepage": "https://github.com/opentdf/client-web", + "name": "@opentdf/sdk", + "version": "0.1.0", + "description": "OpenTDF for the Web", + "homepage": "https://github.com/opentdf/web-sdk", "bugs": { - "url": "https://github.com/opentdf/client-web/issues" + "url": "https://github.com/opentdf/web-sdk/issues" }, "files": [ "dist/*/src/**", @@ -16,7 +16,7 @@ ], "repository": { "type": "git", - "url": "git+https://github.com/opentdf/client-web.git", + "url": "git+https://github.com/opentdf/web-sdk.git", "directory": "lib" }, "license": "BSD-3-Clause-Clear", diff --git a/lib/src/index.ts b/lib/src/index.ts index ae7b6674..cd9c27a3 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -30,7 +30,7 @@ const defaultOptions: EncryptOptions = { * * @example * ``` - * import { clientSecretAuthProvider, NanoTDFClient } from '@opentdf/client'; + * import { clientSecretAuthProvider, NanoTDFClient } from '@opentdf/sdk'; * * const OIDC_ENDPOINT = 'http://localhost:65432/auth/realms/opentdf-demo'; * const KAS_URL = 'http://localhost:65432/api/kas/'; @@ -195,7 +195,7 @@ export type DatasetConfig = ClientConfig & { * * @example * ``` - * import { clientSecretAuthProvider, NanoTDFDatasetClient } from '@opentdf/client'; + * import { clientSecretAuthProvider, NanoTDFDatasetClient } from '@opentdf/sdk'; * * const OIDC_ENDPOINT = 'http://localhost:65432/auth/realms/tdf'; * const KAS_URL = 'http://localhost:65432/api/kas/'; diff --git a/lib/src/nanotdf/Client.ts b/lib/src/nanotdf/Client.ts index 85ded767..9dd2797d 100644 --- a/lib/src/nanotdf/Client.ts +++ b/lib/src/nanotdf/Client.ts @@ -73,7 +73,7 @@ async function generateSignerKeyPair(): Promise { * @link https://developer.mozilla.org/en-US/docs/Web/API/CryptoKeyPair * * @example - * import { Client, clientAuthProvider, decrypt, encrypt } from '@opentdf/client/nanotdf` + * import { Client, clientAuthProvider, decrypt, encrypt } from '@opentdf/sdk/nanotdf` * * const OIDC_ENDPOINT = 'http://localhost:65432/auth/'; * const KAS_URL = 'http://localhost:65432/kas'; diff --git a/lib/src/version.ts b/lib/src/version.ts index 0a44cf8b..374358aa 100644 --- a/lib/src/version.ts +++ b/lib/src/version.ts @@ -1,9 +1,9 @@ /** - * Exposes the released version number of the `@opentdf/client` package + * Exposes the released version number of the `@opentdf/sdk` package */ -export const version = '2.1.0'; +export const version = '0.1.0'; /** * A string name used to label requests as coming from this library client. */ -export const clientType = 'client-web'; +export const clientType = 'web-sdk'; diff --git a/lib/tdf3/src/version.ts b/lib/tdf3/src/version.ts index 809e3759..fb0106b0 100644 --- a/lib/tdf3/src/version.ts +++ b/lib/tdf3/src/version.ts @@ -1,2 +1,2 @@ -export const version = '2.1.0'; +export const version = '0.1.0'; export const clientType = 'tdf3-js-client'; diff --git a/remote-store/.eslintrc.yaml b/remote-store/.eslintrc.yaml deleted file mode 100644 index 17ef53d6..00000000 --- a/remote-store/.eslintrc.yaml +++ /dev/null @@ -1,13 +0,0 @@ -env: - browser: true -extends: - - plugin:@typescript-eslint/recommended - - prettier -overrides: - - files: - - '*.spec.ts' - rules: - '@typescript-eslint/ban-ts-comment': 'off' -parserOptions: - project: ['**/tsconfig.json'] -root: true diff --git a/remote-store/.mocharc.yaml b/remote-store/.mocharc.yaml deleted file mode 100644 index 67e9408b..00000000 --- a/remote-store/.mocharc.yaml +++ /dev/null @@ -1,5 +0,0 @@ -extension: .ts -require: ts-node/register -spec: tests/**/*.test.ts -node-option: - - loader=ts-node/esm diff --git a/remote-store/README.md b/remote-store/README.md deleted file mode 100644 index 12fee5ba..00000000 --- a/remote-store/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @opentdf/remote-store - -This library extends the @opentdf/client library with functions to enable streaming to and from S3 buckets and other storage services that implement the S3 API. diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json deleted file mode 100644 index 80b7c94e..00000000 --- a/remote-store/package-lock.json +++ /dev/null @@ -1,5835 +0,0 @@ -{ - "name": "@opentdf/remote-store", - "version": "2.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@opentdf/remote-store", - "version": "2.1.0", - "license": "BSD-3-Clause-Clear", - "dependencies": { - "@aws-sdk/abort-controller": "^3.370.0", - "@aws-sdk/client-s3": "^3.370.0", - "@aws-sdk/middleware-endpoint": "^3.370.0", - "@aws-sdk/protocol-http": "^3.370.0", - "@aws-sdk/smithy-client": "^3.370.0", - "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", - "axios": "^1.6.1" - }, - "devDependencies": { - "@aws-sdk/types": "^3.370.0", - "@esm-bundle/chai": "4.3.4-fix.0", - "@types/chai": "^4.3.5", - "@types/mocha": "^10.0.1", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", - "chai": "^4.3.7", - "eslint": "^8.45.0", - "eslint-config-prettier": "^8.8.0", - "license-checker-rseidelsohn": "^4.2.6", - "mocha": "^10.2.0", - "prettier": "^3.0.0", - "ts-node": "^10.9.1", - "typescript": "5.1.6" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@aws-crypto/crc32": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", - "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/crc32c": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", - "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha1-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", - "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", - "dependencies": { - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/abort-controller": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.374.0.tgz", - "integrity": "sha512-pO1pqFBdIF28ZvnJmg58Erj35RLzXsTrjvHghdc/xgtSvodFFCNrUsPg6AP3On8eiw9elpHoS4P8jMx1pHDXEw==", - "deprecated": "This package has moved to @smithy/abort-controller", - "dependencies": { - "@smithy/abort-controller": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-s3": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.621.0.tgz", - "integrity": "sha512-YhGkd2HQTM4HCYJIAVWvfbUMpOF7XUr1W/e2LN3CFP0WTF4zcCJKesJ2iNHrExqC0Ek1+qarMxiXBK95itfjYQ==", - "dependencies": { - "@aws-crypto/sha1-browser": "5.2.0", - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.621.0", - "@aws-sdk/client-sts": "3.621.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", - "@aws-sdk/middleware-bucket-endpoint": "3.620.0", - "@aws-sdk/middleware-expect-continue": "3.620.0", - "@aws-sdk/middleware-flexible-checksums": "3.620.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-location-constraint": "3.609.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-sdk-s3": "3.621.0", - "@aws-sdk/middleware-signing": "3.620.0", - "@aws-sdk/middleware-ssec": "3.609.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/signature-v4-multi-region": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@aws-sdk/xml-builder": "3.609.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", - "@smithy/eventstream-serde-browser": "^3.0.5", - "@smithy/eventstream-serde-config-resolver": "^3.0.3", - "@smithy/eventstream-serde-node": "^3.0.4", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-blob-browser": "^3.1.2", - "@smithy/hash-node": "^3.0.3", - "@smithy/hash-stream-node": "^3.1.2", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/md5-js": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-stream": "^3.1.3", - "@smithy/util-utf8": "^3.0.0", - "@smithy/util-waiter": "^3.1.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-s3/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.621.0.tgz", - "integrity": "sha512-xpKfikN4u0BaUYZA9FGUMkkDmfoIP0Q03+A86WjqDWhcOoqNA1DkHsE4kZ+r064ifkPUfcNuUvlkVTEoBZoFjA==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.621.0.tgz", - "integrity": "sha512-mMjk3mFUwV2Y68POf1BQMTF+F6qxt5tPu6daEUCNGC9Cenk3h2YXQQoS4/eSyYzuBiYk3vx49VgleRvdvkg8rg==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.621.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sts": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.621.0.tgz", - "integrity": "sha512-707uiuReSt+nAx6d0c21xLjLm2lxeKc7padxjv92CIrIocnQSlJPxSCM7r5zBhwiahJA6MNQwmTl2xznU67KgA==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.621.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sts/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/core": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.621.0.tgz", - "integrity": "sha512-CtOwWmDdEiINkGXD93iGfXjN0WmCp9l45cDWHHGa8lRgEDyhuL7bwd/pH5aSzj0j8SiQBG2k0S7DHbd5RaqvbQ==", - "dependencies": { - "@smithy/core": "^2.3.1", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "fast-xml-parser": "4.4.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/core/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.620.1.tgz", - "integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.621.0.tgz", - "integrity": "sha512-/jc2tEsdkT1QQAI5Dvoci50DbSxtJrevemwFsm0B73pwCcOQZ5ZwwSdVqGsPutzYzUVx3bcXg3LRL7jLACqRIg==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.621.0.tgz", - "integrity": "sha512-0EWVnSc+JQn5HLnF5Xv405M8n4zfdx9gyGdpnCmAmFqEDHA8LmBdxJdpUk1Ovp/I5oPANhjojxabIW5f1uU0RA==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.621.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.621.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.621.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.621.0.tgz", - "integrity": "sha512-4JqpccUgz5Snanpt2+53hbOBbJQrSFq7E1sAAbgY6BKVQUsW5qyXqnjvSF32kDeKa5JpBl3bBWLZl04IadcPHw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.621.0", - "@aws-sdk/credential-provider-ini": "3.621.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.621.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.620.1.tgz", - "integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.621.0.tgz", - "integrity": "sha512-Kza0jcFeA/GEL6xJlzR2KFf1PfZKMFnxfGzJzl5yN7EjoGdMijl34KaRyVnfRjnCWcsUpBWKNIDk9WZVMY9yiw==", - "dependencies": { - "@aws-sdk/client-sso": "3.621.0", - "@aws-sdk/token-providers": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.621.0.tgz", - "integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.621.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.620.0.tgz", - "integrity": "sha512-eGLL0W6L3HDb3OACyetZYOWpHJ+gLo0TehQKeQyy2G8vTYXqNTeqYhuI6up9HVjBzU9eQiULVQETmgQs7TFaRg==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-arn-parser": "3.568.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-bucket-endpoint/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-endpoint": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.374.0.tgz", - "integrity": "sha512-bCE1C4JvCqy0dG6yExl0ssvGBVoiG1WzJhcOtUb3Aiyu9x6tueyBonfGYYGGwtxlXAnVBmM+JMG9EeFZ07LIxQ==", - "deprecated": "This package has moved to @smithy/middleware-endpoint", - "dependencies": { - "@smithy/middleware-endpoint": "^1.0.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-endpoint/node_modules/@smithy/middleware-endpoint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-1.1.0.tgz", - "integrity": "sha512-PvpazNjVpxX2ICrzoFYCpFnjB39DKCpZds8lRpAB3p6HGrx6QHBaNvOzVhJGBf0jcAbfCdc5/W0n9z8VWaSSww==", - "dependencies": { - "@smithy/middleware-serde": "^1.1.0", - "@smithy/types": "^1.2.0", - "@smithy/url-parser": "^1.1.0", - "@smithy/util-middleware": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-endpoint/node_modules/@smithy/middleware-serde": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-1.1.0.tgz", - "integrity": "sha512-RiBMxhxuO9VTjHsjJvhzViyceoLhU6gtrnJGpAXY43wE49IstXIGEQz8MT50/hOq5EumX16FCpup0r5DVyfqNQ==", - "dependencies": { - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-endpoint/node_modules/@smithy/querystring-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-1.1.0.tgz", - "integrity": "sha512-Lm/FZu2qW3XX+kZ4WPwr+7aAeHf1Lm84UjNkKyBu16XbmEV7ukfhXni2aIwS2rcVf8Yv5E7wchGGpOFldj9V4Q==", - "dependencies": { - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-endpoint/node_modules/@smithy/url-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-1.1.0.tgz", - "integrity": "sha512-tpvi761kzboiLNGEWczuybMPCJh6WHB3cz9gWAG95mSyaKXmmX8ZcMxoV+irZfxDqLwZVJ22XTumu32S7Ow8aQ==", - "dependencies": { - "@smithy/querystring-parser": "^1.1.0", - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/middleware-endpoint/node_modules/@smithy/util-middleware": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-1.1.0.tgz", - "integrity": "sha512-6hhckcBqVgjWAqLy2vqlPZ3rfxLDhFWEmM7oLh2POGvsi7j0tHkbN7w4DFhuBExVJAbJ/qqxqZdRY6Fu7/OezQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.620.0.tgz", - "integrity": "sha512-QXeRFMLfyQ31nAHLbiTLtk0oHzG9QLMaof5jIfqcUwnOkO8YnQdeqzakrg1Alpy/VQ7aqzIi8qypkBe2KXZz0A==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-expect-continue/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.620.0.tgz", - "integrity": "sha512-ftz+NW7qka2sVuwnnO1IzBku5ccP+s5qZGeRTPgrKB7OzRW85gthvIo1vQR2w+OwHFk7WJbbhhWwbCbktnP4UA==", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@aws-crypto/crc32c": "5.2.0", - "@aws-sdk/types": "3.609.0", - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-flexible-checksums/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.620.0.tgz", - "integrity": "sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.609.0.tgz", - "integrity": "sha512-xzsdoTkszGVqGVPjUmgoP7TORiByLueMHieI1fhQL888WPdqctwAx3ES6d/bA9Q/i8jnc6hs+Fjhy8UvBTkE9A==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-location-constraint/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", - "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-logger/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.620.0.tgz", - "integrity": "sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.621.0.tgz", - "integrity": "sha512-CJrQrtKylcqvyPkRR16JmPZkHroCkWwLErQrg30ZcBPNNok8xbfX6cYqG16XDTnu4lSYzv2Yqc4w4oOBv8xerQ==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-arn-parser": "3.568.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-stream": "^3.1.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-signing": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.620.0.tgz", - "integrity": "sha512-gxI7rubiaanUXaLfJ4NybERa9MGPNg2Ycl/OqANsozrBnR3Pw8vqy3EuVImQOyn2pJ2IFvl8ZPoSMHf4pX56FQ==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-signing/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.609.0.tgz", - "integrity": "sha512-GZSD1s7+JswWOTamVap79QiDaIV7byJFssBW68GYjyRS5EBjNfwA/8s+6uE6g39R3ojyTbYOmvcANoZEhSULXg==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-ssec/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.620.0.tgz", - "integrity": "sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-user-agent/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/protocol-http": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.374.0.tgz", - "integrity": "sha512-9WpRUbINdGroV3HiZZIBoJvL2ndoWk39OfwxWs2otxByppJZNN14bg/lvCx5e8ggHUti7IBk5rb0nqQZ4m05pg==", - "deprecated": "This package has moved to @smithy/protocol-http", - "dependencies": { - "@smithy/protocol-http": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/protocol-http/node_modules/@smithy/protocol-http": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.2.0.tgz", - "integrity": "sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==", - "dependencies": { - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", - "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.621.0.tgz", - "integrity": "sha512-u+ulCaHFveqHaTxgiYrEAyfBVP6GRKjnmDut67CtjhjslshPWYpo/ndtlCW1zc0RDne3uUeK13Pqp7dp7p1d6g==", - "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.374.0.tgz", - "integrity": "sha512-YQBdO/Nv5EXBg/qfMF4GgYYLNN3Y/06MyuVBYILC1TKAnMoLy2FV0VOYyediagepAcWPdJqyUq4MCNNBy0CPRg==", - "deprecated": "This package has moved to @smithy/smithy-client", - "dependencies": { - "@smithy/smithy-client": "^1.0.3", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/fetch-http-handler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-1.1.0.tgz", - "integrity": "sha512-N22C9R44u5WGlcY+Wuv8EXmCAq62wWwriRAuoczMEwAIjPbvHSthyPSLqI4S7kAST1j6niWg8kwpeJ3ReAv3xg==", - "dependencies": { - "@smithy/protocol-http": "^1.2.0", - "@smithy/querystring-builder": "^1.1.0", - "@smithy/types": "^1.2.0", - "@smithy/util-base64": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/is-array-buffer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-1.1.0.tgz", - "integrity": "sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/middleware-stack": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-1.1.0.tgz", - "integrity": "sha512-XynYiIvXNea2BbLcppvpNK0zu8o2woJqgnmxqYTn4FWagH/Hr2QIk8LOsUz7BIJ4tooFhmx8urHKCdlPbbPDCA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/node-http-handler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-1.1.0.tgz", - "integrity": "sha512-d3kRriEgaIiGXLziAM8bjnaLn1fthCJeTLZIwEIpzQqe6yPX0a+yQoLCTyjb2fvdLwkMoG4p7THIIB5cj5lkbg==", - "dependencies": { - "@smithy/abort-controller": "^1.1.0", - "@smithy/protocol-http": "^1.2.0", - "@smithy/querystring-builder": "^1.1.0", - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/protocol-http": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.2.0.tgz", - "integrity": "sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==", - "dependencies": { - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/querystring-builder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-1.1.0.tgz", - "integrity": "sha512-gDEi4LxIGLbdfjrjiY45QNbuDmpkwh9DX4xzrR2AzjjXpxwGyfSpbJaYhXARw9p17VH0h9UewnNQXNwaQyYMDA==", - "dependencies": { - "@smithy/types": "^1.2.0", - "@smithy/util-uri-escape": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/smithy-client": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-1.1.0.tgz", - "integrity": "sha512-j32SGgVhv2G9nBTmel9u3OXux8KG20ssxuFakJrEeDug3kqbl1qrGzVLCe+Eib402UDtA0Sp1a4NZ2SEXDBxag==", - "dependencies": { - "@smithy/middleware-stack": "^1.1.0", - "@smithy/types": "^1.2.0", - "@smithy/util-stream": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/util-base64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-1.1.0.tgz", - "integrity": "sha512-FpYmDmVbOXAxqvoVCwqehUN0zXS+lN8V7VS9O7I8MKeVHdSTsZzlwiMEvGoyTNOXWn8luF4CTDYgNHnZViR30g==", - "dependencies": { - "@smithy/util-buffer-from": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/util-buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-1.1.0.tgz", - "integrity": "sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw==", - "dependencies": { - "@smithy/is-array-buffer": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/util-hex-encoding": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-1.1.0.tgz", - "integrity": "sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/util-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-1.1.0.tgz", - "integrity": "sha512-w3lsdGsntaLQIrwDWJkIFKrFscgZXwU/oxsse09aSTNv5TckPhDeYea3LhsDrU5MGAG3vprhVZAKr33S45coVA==", - "dependencies": { - "@smithy/fetch-http-handler": "^1.1.0", - "@smithy/node-http-handler": "^1.1.0", - "@smithy/types": "^1.2.0", - "@smithy/util-base64": "^1.1.0", - "@smithy/util-buffer-from": "^1.1.0", - "@smithy/util-hex-encoding": "^1.1.0", - "@smithy/util-utf8": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/util-uri-escape": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-1.1.0.tgz", - "integrity": "sha512-/jL/V1xdVRt5XppwiaEU8Etp5WHZj609n0xMTuehmCqdoOFbId1M+aEeDWZsQ+8JbEB/BJ6ynY2SlYmOaKtt8w==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/smithy-client/node_modules/@smithy/util-utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-1.1.0.tgz", - "integrity": "sha512-p/MYV+JmqmPyjdgyN2UxAeYDj9cBqCjp0C/NsTWnnjoZUVqoeZ6IrW915L9CAKWVECgv9lVQGc4u/yz26/bI1A==", - "dependencies": { - "@smithy/util-buffer-from": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", - "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.614.0" - } - }, - "node_modules/@aws-sdk/token-providers/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/types": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", - "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/types/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.568.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.568.0.tgz", - "integrity": "sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", - "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "@smithy/util-endpoints": "^2.0.5", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.568.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", - "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", - "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", - "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@aws-sdk/util-user-agent-node/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/xml-builder": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.609.0.tgz", - "integrity": "sha512-l9XxNcA4HX98rwCC2/KoiWcmEiRfZe4G+mYwDbCFT87JIMj6GBhLDkAzr/W8KAaA2IDr8Vc6J8fZPgVulxxfMA==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/xml-builder/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", - "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", - "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", - "dev": true, - "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/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "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" - } - }, - "node_modules/@eslint/eslintrc/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 - }, - "node_modules/@eslint/js": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", - "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@esm-bundle/chai": { - "version": "4.3.4-fix.0", - "resolved": "https://registry.npmjs.org/@esm-bundle/chai/-/chai-4.3.4-fix.0.tgz", - "integrity": "sha512-26SKdM4uvDWlY8/OOOxSB1AqQWeBosCX3wRYUZO7enTAj03CtVxIiCimYVG2WpULcyV51qapK4qTovwkUr5Mlw==", - "dev": true, - "dependencies": { - "@types/chai": "^4.2.12" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "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, - "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/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/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 - }, - "node_modules/@isaacs/cliui/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, - "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/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "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, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "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, - "engines": { - "node": ">= 8" - } - }, - "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, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", - "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@opentdf/client": { - "version": "2.1.0", - "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", - "license": "BSD-3-Clause-Clear", - "dependencies": { - "axios": "^1.6.1", - "axios-retry": "^3.9.0", - "base64-js": "^1.5.1", - "browser-fs-access": "^0.34.1", - "buffer-crc32": "^0.2.13", - "dpop": "^1.2.0", - "eventemitter3": "^5.0.1", - "jose": "^4.14.4", - "json-canonicalize": "^1.0.6", - "streamsaver": "^2.0.6", - "uuid": "~9.0.0" - } - }, - "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, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@smithy/abort-controller": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-1.1.0.tgz", - "integrity": "sha512-5imgGUlZL4dW4YWdMYAKLmal9ny/tlenM81QZY7xYyb76z9Z/QOg7oM5Ak9HQl8QfFTlGVWwcMXl+54jroRgEQ==", - "dependencies": { - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/chunked-blob-reader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-3.0.0.tgz", - "integrity": "sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/chunked-blob-reader-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.0.tgz", - "integrity": "sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==", - "dependencies": { - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/config-resolver": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", - "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/config-resolver/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/core": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.1.tgz", - "integrity": "sha512-BC7VMXx/1BCmRPCVzzn4HGWAtsrb7/0758EtwOGFJQrlSwJBEjCcDLNZLFoL/68JexYa2s+KmgL/UfmXdG6v1w==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/core/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz", - "integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-codec": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.2.tgz", - "integrity": "sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-hex-encoding": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/eventstream-codec/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-browser": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.5.tgz", - "integrity": "sha512-dEyiUYL/ekDfk+2Ra4GxV+xNnFoCmk1nuIXg+fMChFTrM2uI/1r9AdiTYzPqgb72yIv/NtAj6C3dG//1wwgakQ==", - "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-browser/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.3.tgz", - "integrity": "sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-config-resolver/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-node": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.4.tgz", - "integrity": "sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==", - "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-node/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-universal": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.4.tgz", - "integrity": "sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==", - "dependencies": { - "@smithy/eventstream-codec": "^3.1.2", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-universal/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "dependencies": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/fetch-http-handler/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/hash-blob-browser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.2.tgz", - "integrity": "sha512-hAbfqN2UbISltakCC2TP0kx4LqXBttEv2MqSPE98gVuDFMf05lU+TpC41QtqGP3Ff5A3GwZMPfKnEy0VmEUpmg==", - "dependencies": { - "@smithy/chunked-blob-reader": "^3.0.0", - "@smithy/chunked-blob-reader-native": "^3.0.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/hash-blob-browser/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/hash-node": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", - "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", - "dependencies": { - "@smithy/types": "^3.3.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/hash-node/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/hash-stream-node": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.1.2.tgz", - "integrity": "sha512-PBgDMeEdDzi6JxKwbfBtwQG9eT9cVwsf0dZzLXoJF4sHKHs5HEo/3lJWpn6jibfJwT34I1EBXpBnZE8AxAft6g==", - "dependencies": { - "@smithy/types": "^3.3.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/hash-stream-node/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/invalid-dependency": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", - "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/invalid-dependency/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/md5-js": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.3.tgz", - "integrity": "sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==", - "dependencies": { - "@smithy/types": "^3.3.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/md5-js/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-content-length": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz", - "integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==", - "dependencies": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-content-length/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz", - "integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==", - "dependencies": { - "@smithy/middleware-serde": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-retry": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.13.tgz", - "integrity": "sha512-zvCLfaRYCaUmjbF2yxShGZdolSHft7NNCTA28HVN9hKcEbOH+g5irr1X9s+in8EpambclGnevZY4A3lYpvDCFw==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/service-error-classification": "^3.0.3", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-retry/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-serde": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", - "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-serde/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-stack": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", - "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-stack/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-config-provider": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", - "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", - "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-config-provider/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz", - "integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==", - "dependencies": { - "@smithy/abort-controller": "^3.1.1", - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-http-handler/node_modules/@smithy/abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", - "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-http-handler/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/property-provider": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", - "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/property-provider/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/protocol-http/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "dependencies": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-builder/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", - "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-parser/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/service-error-classification": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", - "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", - "dependencies": { - "@smithy/types": "^3.3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/service-error-classification/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", - "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz", - "integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/signature-v4/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.11.tgz", - "integrity": "sha512-l0BpyYkciNyMaS+PnFFz4aO5sBcXvGLoJd7mX9xrMBIm2nIQBVvYgp2ZpPDMzwjKCavsXu06iuCm0F6ZJZc6yQ==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/smithy-client/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", - "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/url-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", - "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", - "dependencies": { - "@smithy/querystring-parser": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/url-parser/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-body-length-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", - "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", - "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-buffer-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-config-provider": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", - "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.13.tgz", - "integrity": "sha512-ZIRSUsnnMRStOP6OKtW+gCSiVFkwnfQF2xtf32QKAbHR6ACjhbAybDvry+3L5qQYdh3H6+7yD/AiUE45n8mTTw==", - "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.13.tgz", - "integrity": "sha512-voUa8TFJGfD+U12tlNNLCDlXibt9vRdNzRX45Onk/WxZe7TS+hTOZouEZRa7oARGicdgeXvt1A0W45qLGYdy+g==", - "dependencies": { - "@smithy/config-resolver": "^3.0.5", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-endpoints": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", - "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-endpoints/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-hex-encoding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", - "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-middleware": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", - "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-middleware/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-retry": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", - "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", - "dependencies": { - "@smithy/service-error-classification": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-retry/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-stream": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz", - "integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==", - "dependencies": { - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-stream/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-waiter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.2.tgz", - "integrity": "sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==", - "dependencies": { - "@smithy/abort-controller": "^3.1.1", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-waiter/node_modules/@smithy/abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", - "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-waiter/node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true - }, - "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==", - "dev": true, - "peer": true - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", - "integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/type-utils": "6.2.1", - "@typescript-eslint/utils": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", - "integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", - "integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/utils": "6.2.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", - "integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/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 - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "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, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": "*" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axios-retry": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", - "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.15.4", - "is-retry-allowed": "^2.2.0" - } - }, - "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 - }, - "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" - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-fs-access": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.34.1.tgz", - "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==", - "license": "Apache-2.0" - }, - "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 - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "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, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "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==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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 - }, - "node_modules/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/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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 - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dpop": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dpop/-/dpop-1.4.1.tgz", - "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "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 - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", - "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.1", - "@eslint/js": "^8.46.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "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.2", - "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-config-prettier": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.9.0.tgz", - "integrity": "sha512-+sbni7NfVXnOpnRadUA8S28AUlsZt9GjgFvABIRL9Hkn8KqNzOp+7Lw4QWtrwn20KzU3wqu1QoOj2m+7rKRqkA==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "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, - "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-visitor-keys": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", - "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "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" - } - }, - "node_modules/eslint/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/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 - }, - "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, - "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/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "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, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "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, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "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 - }, - "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 - }, - "node_modules/fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "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, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.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, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/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==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "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 - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "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, - "engines": { - "node": "*" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "optional": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", - "dev": true, - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "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==", - "dev": true, - "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==", - "dev": true - }, - "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, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=0.12.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-retry-allowed": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", - "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/jackspeak": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.0.tgz", - "integrity": "sha512-uKmsITSsF4rUWQHzqaRUuyAir3fZfW3f202Ee34lz/gZCi970CPZwyQXLGNgWJvvZbvFyzeyGq0+4fcG/mBKZg==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/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, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-canonicalize": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/json-canonicalize/-/json-canonicalize-1.0.6.tgz", - "integrity": "sha512-kP2iYpOS5SZHYhIaR1t9oG80d4uTY3jPoaBj+nimy3njtJk8+sRsVatN8pyJRDRtk9Su3+6XqA2U8k0dByJBUQ==", - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", - "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "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 - }, - "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, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/license-checker-rseidelsohn": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/license-checker-rseidelsohn/-/license-checker-rseidelsohn-4.2.6.tgz", - "integrity": "sha512-cV69Exm7y7stSVoYpFaQ1rEdmTtA7y1bMgTeeB1fqE0TZRkW1zpn8uIsIKeHK5rMvJYQzEuExNmLOTDXJMplgg==", - "dev": true, - "dependencies": { - "chalk": "4.1.2", - "debug": "^4.3.4", - "lodash.clonedeep": "^4.5.0", - "mkdirp": "^1.0.4", - "nopt": "^5.0.0", - "read-installed-packages": "^2.0.1", - "semver": "^7.3.5", - "spdx-correct": "^3.1.1", - "spdx-expression-parse": "^3.0.1", - "spdx-satisfies": "^5.0.1", - "treeify": "^1.1.0" - }, - "bin": { - "license-checker-rseidelsohn": "bin/license-checker-rseidelsohn" - }, - "engines": { - "node": ">=18", - "npm": ">=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, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true - }, - "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 - }, - "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==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "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==", - "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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "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" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/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, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/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, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/mocha/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/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, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/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, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/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, - "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/mocha/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, - "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/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "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 - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-package-data": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", - "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", - "dev": true, - "dependencies": { - "hosted-git-info": "^6.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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, - "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, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", - "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/read-installed-packages": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/read-installed-packages/-/read-installed-packages-2.0.1.tgz", - "integrity": "sha512-t+fJOFOYaZIjBpTVxiV8Mkt7yQyy4E6MSrrnt5FmPd4enYvpU/9DYGirDmN1XQwkfeuWIhM/iu0t2rm6iSr0CA==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^3.1.0", - "debug": "^4.3.4", - "read-package-json": "^6.0.0", - "semver": "2 || 3 || 4 || 5 || 6 || 7", - "slide": "~1.1.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.2" - } - }, - "node_modules/read-package-json": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", - "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", - "dev": true, - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^5.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-package-json/node_modules/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, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/read-package-json/node_modules/glob": { - "version": "10.3.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", - "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/read-package-json/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/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, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "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, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/spdx-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", - "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", - "dev": true, - "dependencies": { - "array-find-index": "^1.0.2", - "spdx-expression-parse": "^3.0.0", - "spdx-ranges": "^2.0.0" - } - }, - "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, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/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-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, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true - }, - "node_modules/spdx-ranges": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", - "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", - "dev": true - }, - "node_modules/spdx-satisfies": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-5.0.1.tgz", - "integrity": "sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==", - "dev": true, - "dependencies": { - "spdx-compare": "^1.0.0", - "spdx-expression-parse": "^3.0.0", - "spdx-ranges": "^2.0.0" - } - }, - "node_modules/streamsaver": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/streamsaver/-/streamsaver-2.0.6.tgz", - "integrity": "sha512-LK4e7TfCV8HzuM0PKXuVUfKyCB1FtT9L0EGxsFk5Up8njj0bXK8pJM9+Wq2Nya7/jslmCQwRK39LFm55h7NBTw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - } - ], - "license": "MIT" - }, - "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==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, - "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, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "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, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "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, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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, - "engines": { - "node": ">=4" - } - }, - "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "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, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "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, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^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, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/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/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, - "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/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, - "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/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/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 - }, - "node_modules/wrap-ansi/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, - "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/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "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, - "engines": { - "node": ">=10" - } - }, - "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 - }, - "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, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/remote-store/package.json b/remote-store/package.json deleted file mode 100644 index 443edeec..00000000 --- a/remote-store/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@opentdf/remote-store", - "license": "BSD-3-Clause-Clear", - "author": "Virtru", - "type": "module", - "version": "2.1.0", - "description": "Upload a web stream directly to S3", - "homepage": "https://github.com/opentdf/client-web", - "repository": { - "type": "git", - "url": "git+https://github.com/opentdf/client-web.git", - "directory": "remote-store" - }, - "bugs": { - "url": "https://github.com/opentdf/client-web/issues" - }, - "exports": { - "types": "./dist/src/index.d.ts", - "import": "./dist/src/index.js" - }, - "files": [ - "dist/src/**", - "src/**", - "README.md" - ], - "main": "./dist/src/index.js", - "types": "./dist/src/index.d.ts", - "scripts": { - "build": "tsc", - "clean": "rm -rf {coverage,dist}", - "doc": "typedoc --out dist/docs src/index.ts", - "format": "prettier --write \"{tests,src}/**/*.ts\"", - "license-check": "license-checker-rseidelsohn --production --onlyAllow 'Apache-2.0; BSD; CC-BY-4.0; ISC; MIT'", - "lint": "eslint ./src/**/*.ts", - "prepack": "npm run build", - "test": "mocha" - }, - "dependencies": { - "@aws-sdk/abort-controller": "^3.370.0", - "@aws-sdk/client-s3": "^3.370.0", - "@aws-sdk/middleware-endpoint": "^3.370.0", - "@aws-sdk/protocol-http": "^3.370.0", - "@aws-sdk/smithy-client": "^3.370.0", - "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", - "axios": "^1.6.1" - }, - "devDependencies": { - "@aws-sdk/types": "^3.370.0", - "@esm-bundle/chai": "4.3.4-fix.0", - "@types/chai": "^4.3.5", - "@types/mocha": "^10.0.1", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", - "chai": "^4.3.7", - "eslint": "^8.45.0", - "eslint-config-prettier": "^8.8.0", - "license-checker-rseidelsohn": "^4.2.6", - "mocha": "^10.2.0", - "prettier": "^3.0.0", - "ts-node": "^10.9.1", - "typescript": "5.1.6" - } -} diff --git a/remote-store/src/aws-lib-storage/Upload.ts b/remote-store/src/aws-lib-storage/Upload.ts deleted file mode 100644 index bb245709..00000000 --- a/remote-store/src/aws-lib-storage/Upload.ts +++ /dev/null @@ -1,432 +0,0 @@ -import { AbortController, AbortSignal } from '@aws-sdk/abort-controller'; -import { - AbortMultipartUploadCommandOutput, - CompletedPart, - CompleteMultipartUploadCommand, - CompleteMultipartUploadCommandOutput, - CreateMultipartUploadCommand, - CreateMultipartUploadCommandOutput, - PutObjectCommand, - PutObjectCommandInput, - PutObjectTaggingCommand, - S3Client, - Tag, - UploadPartCommand, -} from '@aws-sdk/client-s3'; -import { - EndpointParameterInstructionsSupplier, - getEndpointFromInstructions, - toEndpointV1, -} from '@aws-sdk/middleware-endpoint'; -import { HttpRequest } from '@aws-sdk/protocol-http'; -import { extendedEncodeURIComponent } from '@aws-sdk/smithy-client'; -import { type Endpoint } from '@aws-sdk/types'; -import { EventEmitter } from 'events'; - -import { getChunk } from './chunker.js'; -import { BodyDataTypes, Options, Progress } from './types.js'; - -export interface RawDataPart { - partNumber: number; - data: BodyDataTypes; - lastPart?: boolean; -} - -const MIN_PART_SIZE = 1024 * 1024 * 5; - -export const byteLength = ( - input: RawDataPart['data'] | PutObjectCommandInput['Body'] | ReadableStream -) => { - if (input === null || input === undefined) { - return 0; - } - if (typeof input === 'string') { - return new TextEncoder().encode(input).byteLength; - } - if ('byteLength' in input && typeof input.byteLength === 'number') { - return input.byteLength; - } else if ('length' in input && typeof input.length === 'number') { - return input.length; - } else if ('size' in input && typeof input.size === 'number') { - return input.size; - } - return 0; -}; - -export class Upload extends EventEmitter { - /** - * S3 multipart upload does not allow more than 10000 parts. - */ - private MAX_PARTS = 10000; - - // Defaults. - private queueSize = 4; - private partSize = MIN_PART_SIZE; - private leavePartsOnError = false; - private tags: Tag[] = []; - - private client: S3Client; - private params: PutObjectCommandInput; - - // used for reporting progress. - private totalBytes?: number; - private bytesUploadedSoFar: number; - - // used in the upload. - private abortController: AbortController; - private concurrentUploaders: Promise[] = []; - private createMultiPartPromise?: Promise; - - private uploadedParts: CompletedPart[] = []; - private uploadId?: string; - uploadEvent?: string; - - private isMultiPart = true; - private singleUploadResult?: CompleteMultipartUploadCommandOutput; - - constructor(options: Options) { - super(); - - // set defaults from options. - this.queueSize = options.queueSize || this.queueSize; - this.partSize = options.partSize || this.partSize; - this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError; - this.tags = options.tags || this.tags; - - this.client = options.client; - this.params = options.params; - - this.__validateInput(); - - // set progress defaults - this.totalBytes = byteLength(this.params.Body); - this.bytesUploadedSoFar = 0; - this.abortController = new AbortController(); - } - - async abort(): Promise { - /** - * Abort stops all new uploads and immediately exists the top level promise on this.done() - * Concurrent threads in flight clean up eventually. - */ - this.abortController.abort(); - } - - public async done(): Promise< - CompleteMultipartUploadCommandOutput | AbortMultipartUploadCommandOutput - > { - return await Promise.race([ - this.__doMultipartUpload(), - this.__abortTimeout(this.abortController.signal), - ]); - } - - public override on(event: 'httpUploadProgress', listener: (progress: Progress) => void): this { - this.uploadEvent = event; - return super.on(event, listener); - } - - private async __uploadUsingPut(dataPart: RawDataPart): Promise { - this.isMultiPart = false; - const params = { ...this.params, Body: dataPart.data }; - - const clientConfig = this.client.config; - const requestHandler = clientConfig.requestHandler; - const eventEmitter: EventEmitter | null = - requestHandler instanceof EventEmitter ? requestHandler : null; - const uploadEventListener = (event: ProgressEvent) => { - this.bytesUploadedSoFar = event.loaded; - this.totalBytes = event.total; - this.__notifyProgress({ - loaded: this.bytesUploadedSoFar, - total: this.totalBytes, - part: dataPart.partNumber, - Key: this.params.Key, - Bucket: this.params.Bucket, - }); - }; - - if (eventEmitter !== null) { - // The requestHandler is the xhr-http-handler. - eventEmitter.on('xhr.upload.progress', uploadEventListener); - } - - const resolved = await Promise.all([ - this.client.send(new PutObjectCommand(params)), - clientConfig?.endpoint?.(), - ]); - const putResult = resolved[0]; - let endpoint: Endpoint | undefined = resolved[1]; - - if (!endpoint) { - endpoint = toEndpointV1( - await getEndpointFromInstructions( - params, - PutObjectCommand as EndpointParameterInstructionsSupplier, - { - ...clientConfig, - } - ) - ); - } - - if (!endpoint) { - throw new Error( - 'Could not resolve endpoint from S3 "client.config.endpoint()" nor EndpointsV2.' - ); - } - - if (eventEmitter !== null) { - eventEmitter.off('xhr.upload.progress', uploadEventListener); - } - - const locationKey = this.params - .Key!.split('/') - .map((segment) => extendedEncodeURIComponent(segment)) - .join('/'); - const locationBucket = extendedEncodeURIComponent(this.params.Bucket!); - - const Location: string = (() => { - const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`); - const { forcePathStyle } = this.client.config; - if (forcePathStyle) { - return `${endpoint.protocol}//${endpoint.hostname}/${locationBucket}/${locationKey}`; - } - if (endpointHostnameIncludesBucket) { - return `${endpoint.protocol}//${endpoint.hostname}/${locationKey}`; - } - return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}/${locationKey}`; - })(); - - this.singleUploadResult = { - ...putResult, - Bucket: this.params.Bucket, - Key: this.params.Key, - Location, - }; - const totalSize = byteLength(dataPart.data); - - this.__notifyProgress({ - loaded: totalSize, - total: totalSize, - part: 1, - Key: this.params.Key, - Bucket: this.params.Bucket, - }); - } - - private async __createMultipartUpload(): Promise { - if (!this.createMultiPartPromise) { - const createCommandParams = { ...this.params, Body: undefined }; - this.createMultiPartPromise = this.client.send( - new CreateMultipartUploadCommand(createCommandParams) - ); - } - const createMultipartUploadResult = await this.createMultiPartPromise; - this.uploadId = createMultipartUploadResult.UploadId; - } - - private async __doConcurrentUpload( - dataFeeder: AsyncGenerator - ): Promise { - for await (const dataPart of dataFeeder) { - if (this.uploadedParts.length > this.MAX_PARTS) { - throw new Error( - `Exceeded ${this.MAX_PARTS} as part of the upload to ${this.params.Key} and ${this.params.Bucket}.` - ); - } - - try { - if (this.abortController.signal.aborted) { - return; - } - - // Use put instead of multi-part for one chunk uploads. - if (dataPart.partNumber === 1 && dataPart.lastPart) { - return await this.__uploadUsingPut(dataPart); - } - - if (!this.uploadId) { - await this.__createMultipartUpload(); - if (this.abortController.signal.aborted) { - return; - } - } - - const partSize: number = byteLength(dataPart.data) || 0; - - const requestHandler = this.client.config.requestHandler; - const eventEmitter: EventEmitter | null = - requestHandler instanceof EventEmitter ? requestHandler : null; - - let lastSeenBytes = 0; - const uploadEventListener = (event: ProgressEvent, request: HttpRequest) => { - const requestPartSize = Number(request.query['partNumber']) || -1; - - if (requestPartSize !== dataPart.partNumber) { - // ignored, because the emitted event is not for this part. - return; - } - - if (event.total && partSize) { - this.bytesUploadedSoFar += event.loaded - lastSeenBytes; - lastSeenBytes = event.loaded; - } - - this.__notifyProgress({ - loaded: this.bytesUploadedSoFar, - total: this.totalBytes, - part: dataPart.partNumber, - Key: this.params.Key, - Bucket: this.params.Bucket, - }); - }; - - if (eventEmitter !== null) { - // The requestHandler is the xhr-http-handler. - eventEmitter.on('xhr.upload.progress', uploadEventListener); - } - - const partResult = await this.client.send( - new UploadPartCommand({ - ...this.params, - UploadId: this.uploadId, - Body: dataPart.data, - PartNumber: dataPart.partNumber, - }) - ); - - if (eventEmitter !== null) { - eventEmitter.off('xhr.upload.progress', uploadEventListener); - } - - if (this.abortController.signal.aborted) { - return; - } - - if (!partResult.ETag) { - throw new Error( - `Part ${dataPart.partNumber} is missing ETag in UploadPart response. Missing Bucket CORS configuration for ETag header?` - ); - } - - this.uploadedParts.push({ - PartNumber: dataPart.partNumber, - ETag: partResult.ETag, - ...(partResult.ChecksumCRC32 && { ChecksumCRC32: partResult.ChecksumCRC32 }), - ...(partResult.ChecksumCRC32C && { ChecksumCRC32C: partResult.ChecksumCRC32C }), - ...(partResult.ChecksumSHA1 && { ChecksumSHA1: partResult.ChecksumSHA1 }), - ...(partResult.ChecksumSHA256 && { ChecksumSHA256: partResult.ChecksumSHA256 }), - }); - - if (eventEmitter === null) { - this.bytesUploadedSoFar += partSize; - } - - this.__notifyProgress({ - loaded: this.bytesUploadedSoFar, - total: this.totalBytes, - part: dataPart.partNumber, - Key: this.params.Key, - Bucket: this.params.Bucket, - }); - } catch (e) { - // Failed to create multi-part or put - if (!this.uploadId) { - throw e; - } - // on leavePartsOnError throw an error so users can deal with it themselves, - // otherwise swallow the error. - if (this.leavePartsOnError) { - throw e; - } - } - } - } - - private async __doMultipartUpload(): Promise { - // Set up data input chunks. - const dataFeeder = getChunk(this.params.Body, this.partSize); - - // Create and start concurrent uploads. - for (let index = 0; index < this.queueSize; index++) { - const currentUpload = this.__doConcurrentUpload(dataFeeder); - this.concurrentUploaders.push(currentUpload); - } - - // Create and start concurrent uploads. - await Promise.all(this.concurrentUploaders); - if (this.abortController.signal.aborted) { - throw Object.assign(new Error('Upload aborted.'), { name: 'AbortError' }); - } - - let result; - if (this.isMultiPart) { - this.uploadedParts.sort((a, b) => a.PartNumber! - b.PartNumber!); - - const uploadCompleteParams = { - ...this.params, - Body: undefined, - UploadId: this.uploadId, - MultipartUpload: { - Parts: this.uploadedParts, - }, - }; - result = await this.client.send(new CompleteMultipartUploadCommand(uploadCompleteParams)); - } else { - result = this.singleUploadResult!; - } - - // Add tags to the object after it's completed the upload. - if (this.tags.length) { - await this.client.send( - new PutObjectTaggingCommand({ - ...this.params, - Tagging: { - TagSet: this.tags, - }, - }) - ); - } - - return result; - } - - private __notifyProgress(progress: Progress): void { - if (this.uploadEvent) { - this.emit(this.uploadEvent, progress); - } - } - - private async __abortTimeout( - abortSignal: AbortSignal - ): Promise { - return new Promise((resolve, reject) => { - abortSignal.onabort = () => { - const abortError = new Error('Upload aborted.'); - abortError.name = 'AbortError'; - reject(abortError); - }; - }); - } - - private __validateInput(): void { - if (!this.params) { - throw new Error(`InputError: Upload requires params to be passed to upload.`); - } - - if (!this.client) { - throw new Error(`InputError: Upload requires a AWS client to do uploads with.`); - } - - if (this.partSize < MIN_PART_SIZE) { - throw new Error( - `EntityTooSmall: Your proposed upload partsize [${this.partSize}] is smaller than the minimum allowed size [${MIN_PART_SIZE}] (5MB)` - ); - } - - if (this.queueSize < 1) { - throw new Error(`Queue size: Must have at least one uploading queue.`); - } - } -} diff --git a/remote-store/src/aws-lib-storage/chunker.ts b/remote-store/src/aws-lib-storage/chunker.ts deleted file mode 100644 index acc87561..00000000 --- a/remote-store/src/aws-lib-storage/chunker.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { getChunkBuffer } from './chunks/getChunkBuffer.js'; -import { getChunkStream } from './chunks/getChunkStream.js'; -import { getDataReadable } from './chunks/getDataReadable.js'; -import { getDataReadableStream } from './chunks/getDataReadableStream.js'; -import { BodyDataTypes } from './types.js'; - -export const getChunk = (data: BodyDataTypes, partSize: number) => { - if (Object.prototype.hasOwnProperty.call(data, 'pipe')) { - return getChunkStream(data, partSize, getDataReadable); - } else if (data instanceof String || typeof data === 'string') { - // chunk Strings, Uint8Array. - return getChunkBuffer(new TextEncoder().encode(data as string), partSize); - } else if (data instanceof Uint8Array) { - return getChunkBuffer(data, partSize); - } - if (typeof (data as { stream: unknown }).stream === 'function') { - // approximate support for Blobs. - const streamable: Blob = data as Blob; - return getChunkStream(streamable.stream(), partSize, getDataReadableStream); - } else if (data instanceof ReadableStream) { - return getChunkStream(data as ReadableStream, partSize, getDataReadableStream); - } else { - throw new Error( - 'Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;.' - ); - } -}; diff --git a/remote-store/src/aws-lib-storage/chunks/getChunkBuffer.ts b/remote-store/src/aws-lib-storage/chunks/getChunkBuffer.ts deleted file mode 100644 index b4cf1100..00000000 --- a/remote-store/src/aws-lib-storage/chunks/getChunkBuffer.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { RawDataPart } from '../Upload.js'; - -export async function* getChunkBuffer( - data: Uint8Array, - partSize: number -): AsyncGenerator { - let partNumber = 1; - let startByte = 0; - let endByte = partSize; - - while (endByte < data.byteLength) { - yield { - partNumber, - data: data.slice(startByte, endByte), - }; - partNumber += 1; - startByte = endByte; - endByte = startByte + partSize; - } - - yield { - partNumber, - data: data.slice(startByte), - lastPart: true, - }; -} diff --git a/remote-store/src/aws-lib-storage/chunks/getChunkStream.ts b/remote-store/src/aws-lib-storage/chunks/getChunkStream.ts deleted file mode 100644 index 0c9503a6..00000000 --- a/remote-store/src/aws-lib-storage/chunks/getChunkStream.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RawDataPart } from '../Upload.js'; - -interface Buffers { - chunks: Uint8Array[]; - length: number; -} - -export async function* getChunkStream( - data: T, - partSize: number, - getNextData: (data: T) => AsyncGenerator -): AsyncGenerator { - let partNumber = 1; - const currentBuffer: Buffers = { chunks: [], length: 0 }; - - for await (const datum of getNextData(data)) { - currentBuffer.chunks.push(datum); - currentBuffer.length += datum.length; - - while (currentBuffer.length >= partSize) { - /** - * Concat all the buffers together once if there is more than one to concat. Attempt - * to minimize concats as Buffer.Concat is an extremely expensive operation. - */ - const dataChunk = - currentBuffer.chunks.length > 1 - ? concatUint8(currentBuffer.chunks) - : currentBuffer.chunks[0]; - - yield { - partNumber, - data: dataChunk.slice(0, partSize), - }; - - // Reset the buffer. - currentBuffer.chunks = [dataChunk.slice(partSize)]; - currentBuffer.length = currentBuffer.chunks[0].length; - partNumber += 1; - } - } - yield { - partNumber, - data: concatUint8(currentBuffer.chunks), - lastPart: true, - }; -} - -function concatUint8(uint8Arrays: Uint8Array[]): Uint8Array { - const newLength = uint8Arrays.reduce( - (accumulator, currentValue) => accumulator + currentValue.length, - 0 - ); - const combinedUint8Array = new Uint8Array(newLength); - - let offset = 0; - for (const uint8Array of uint8Arrays) { - combinedUint8Array.set(uint8Array, offset); - offset += uint8Array.length; - } - - return combinedUint8Array; -} diff --git a/remote-store/src/aws-lib-storage/chunks/getDataReadable.ts b/remote-store/src/aws-lib-storage/chunks/getDataReadable.ts deleted file mode 100644 index 5c3fecdc..00000000 --- a/remote-store/src/aws-lib-storage/chunks/getDataReadable.ts +++ /dev/null @@ -1,5 +0,0 @@ -export async function* getDataReadable(data: any): AsyncGenerator { - for await (const chunk of data) { - yield chunk; - } -} diff --git a/remote-store/src/aws-lib-storage/chunks/getDataReadableStream.ts b/remote-store/src/aws-lib-storage/chunks/getDataReadableStream.ts deleted file mode 100644 index e642328b..00000000 --- a/remote-store/src/aws-lib-storage/chunks/getDataReadableStream.ts +++ /dev/null @@ -1,18 +0,0 @@ -export async function* getDataReadableStream(data: ReadableStream): AsyncGenerator { - // Get a lock on the stream. - const reader = data.getReader(); - - try { - while (true) { - // Read from the stream. - const { done, value } = await reader.read(); - // Exit if we're done. - if (done) return; - // Else yield the chunk. - yield value; - } - } finally { - // release the lock for reading from this stream. - reader.releaseLock(); - } -} diff --git a/remote-store/src/aws-lib-storage/index.ts b/remote-store/src/aws-lib-storage/index.ts deleted file mode 100644 index 73cb0bdf..00000000 --- a/remote-store/src/aws-lib-storage/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { Upload } from './Upload.js'; -// its a aws lib https://github.com/aws/aws-sdk-js-v3/tree/main/lib/lib-storage -// had to move it here to make it work with -// https://developer.salesforce.com/docs/component-library/tools/locker-service-console diff --git a/remote-store/src/aws-lib-storage/runtimeConfig.browser.ts b/remote-store/src/aws-lib-storage/runtimeConfig.browser.ts deleted file mode 100644 index 01820599..00000000 --- a/remote-store/src/aws-lib-storage/runtimeConfig.browser.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ClientSharedValues } from './runtimeConfig.shared.js'; - -/** - * @internal - */ -export const ClientDefaultValues = { - ...ClientSharedValues, - runtime: 'browser', -}; diff --git a/remote-store/src/aws-lib-storage/runtimeConfig.shared.ts b/remote-store/src/aws-lib-storage/runtimeConfig.shared.ts deleted file mode 100644 index d0e49667..00000000 --- a/remote-store/src/aws-lib-storage/runtimeConfig.shared.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @internal - */ -export const ClientSharedValues = { - // eslint-disable-next-line @typescript-eslint/no-empty-function - lstatSync: () => {}, -}; diff --git a/remote-store/src/aws-lib-storage/runtimeConfig.ts b/remote-store/src/aws-lib-storage/runtimeConfig.ts deleted file mode 100644 index 92ba9152..00000000 --- a/remote-store/src/aws-lib-storage/runtimeConfig.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { lstatSync } from 'node:fs'; - -import { ClientSharedValues } from './runtimeConfig.shared.js'; - -/** - * @internal - */ -export const ClientDefaultValues = { - ...ClientSharedValues, - runtime: 'node', - lstatSync, -}; diff --git a/remote-store/src/aws-lib-storage/types.ts b/remote-store/src/aws-lib-storage/types.ts deleted file mode 100644 index d6cc2c9d..00000000 --- a/remote-store/src/aws-lib-storage/types.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { PutObjectCommandInput, S3Client, Tag } from '@aws-sdk/client-s3'; - -export interface Progress { - loaded?: number; - total?: number; - part?: number; - Key?: string; - Bucket?: string; -} - -// string | Uint8Array | Buffer | Readable | ReadableStream | Blob. -export type BodyDataTypes = PutObjectCommandInput['Body']; - -/** - * @deprecated redundant, use {@link S3Client} directly. - */ -export type ServiceClients = S3Client; - -export interface Configuration { - /** - * The size of the concurrent queue manager to upload parts in parallel. Set to 1 for synchronous uploading of parts. Note that the uploader will buffer at most queueSize * partSize bytes into memory at any given time. - * default: 4 - */ - queueSize: number; - - /** - * Default: 5 mb - * The size in bytes for each individual part to be uploaded. Adjust the part size to ensure the number of parts does not exceed maxTotalParts. See 5mb is the minimum allowed part size. - */ - partSize: number; - - /** - * Default: false - * Whether to abort the multipart upload if an error occurs. Set to true if you want to handle failures manually. If set to false (default) - * the upload will drop parts that have failed. - */ - leavePartsOnError: boolean; - - /** - * The tags to apply to the object. - */ - tags: Tag[]; -} - -export interface Options extends Partial { - /** - * This is the data that is uploaded. - */ - params: PutObjectCommandInput; - - /** - * A service client. - * This the target where we upload data. - */ - client: S3Client; -} diff --git a/remote-store/src/index.ts b/remote-store/src/index.ts deleted file mode 100644 index 22d45441..00000000 --- a/remote-store/src/index.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { - S3Client, - GetObjectCommand, - S3ClientConfig, - AbortMultipartUploadCommandOutput, - CompleteMultipartUploadCommandOutput, -} from '@aws-sdk/client-s3'; -import { - DecryptParams, - DecryptParamsBuilder, - EncryptParams, - EncryptParamsBuilder, -} from '@opentdf/client'; -import axios from 'axios'; - -import { Upload } from './aws-lib-storage/index.js'; -import { Options, Progress } from './aws-lib-storage/types.js'; - -export type VirtruS3Config = S3ClientConfig & { - Bucket?: string; -}; - -export type VirtruCreds = S3ClientConfig['credentials']; - -export type FetchCreds = { - AWSAccessKeyId: string; - AWSSecretAccessKey: string; - AWSSessionToken: string; -}; - -export type VirtruTempS3Credentials = { - data: { - bucket: string; - fields: FetchCreds; - url: string; - }; -}; - -/** - * Specify the remote content to encrypt in stream form. - * withRemoteStore() has not been implemented because setRemoteStore() is async so withRemoteStore() can't be chained with a build() call. - * @param builder A set of client params - * @param fileName The name of the remote file to write TDF ciphertext to. - * @param config The object containing remote storage configuration. - *
A detailed spec for the interface can be found [here]{@link https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html} - * @param credentialURL The url to request remote storage credentials from. - *
Credentials can be generated using [GetFederationToken]{@link https://docs.aws.amazon.com/STS/latest/APIReference/API_GetFederationToken.html} - * @return A Client options object - */ -export const setRemoteStoreAsStream = async ( - builder: DecryptParamsBuilder | EncryptParamsBuilder, - fileName: string, - config: VirtruS3Config, - credentialURL?: string -): Promise => { - let virtruTempS3Credentials: VirtruTempS3Credentials | undefined; - let storageParams: VirtruS3Config; - - // Param validation - if (!fileName) { - throw new Error('Passing a fileName is required for setRemoteStore()'); - } - - if (credentialURL) { - // Check for string or string object - virtruTempS3Credentials = await axios.get(credentialURL); - } - - const BUCKET_NAME: string | undefined = - config?.Bucket || virtruTempS3Credentials?.data?.bucket || undefined; - - const FILE_NAME: string = fileName; - - // Build a storage config object from 'config' or 'virtruTempS3Credentials' - if (virtruTempS3Credentials) { - const credentials: VirtruCreds = { - accessKeyId: virtruTempS3Credentials.data.fields.AWSAccessKeyId, - secretAccessKey: virtruTempS3Credentials.data.fields.AWSSecretAccessKey, - sessionToken: virtruTempS3Credentials.data.fields.AWSSessionToken, - }; - - storageParams = { - credentials, - region: virtruTempS3Credentials.data.url.split('.')[1], - forcePathStyle: false, - maxAttempts: 3, - useAccelerateEndpoint: true, - }; - } else { - storageParams = config; - } - - const s3 = new S3Client(storageParams); - - const s3download = await s3.send( - new GetObjectCommand({ - Key: FILE_NAME, - Bucket: BUCKET_NAME, - }) - ); - - const s3Stream = s3download.Body; - - builder.setStreamSource(s3Stream as ReadableStream); - return builder.build(); -}; - -/** - * - * Dump the stream content to remote storage. This will consume the stream. - * @param {string} fileName - the name of the remote file to write TDF ciphertext to. - * @param {S3ClientConfig} [config] - the object containing remote storage configuration. - *
A detailed spec for the interface can be found [here]{@link https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html} - * @param {string} [credentialURL] - the url to request remote storage credentials from. - * @return {RemoteUploadResponse} - an object containing metadata for the uploaded file. - */ -export const toRemoteStore = async ( - stream: ReadableStream, - fileName: string, - config: VirtruS3Config, - credentialURL: string, - progressHandler?: (event: Progress) => void -): Promise => { - // State - const CONCURRENT_UPLOADS = 6; - const MAX_UPLOAD_PART_SIZE = 1024 * 1024 * 5; // 5MB - let storageParams: VirtruS3Config; - let virtruTempS3Credentials: VirtruTempS3Credentials | undefined; - - // Param validation - if (!config) { - try { - virtruTempS3Credentials = await axios.get(credentialURL); - } catch (e) { - console.error(e); - } - } - - // Build a storage config object from 'config' or 'virtruTempS3Credentials' - if (virtruTempS3Credentials) { - const credentials: VirtruCreds = { - accessKeyId: virtruTempS3Credentials.data.fields.AWSAccessKeyId, - secretAccessKey: virtruTempS3Credentials.data.fields.AWSSecretAccessKey, - sessionToken: virtruTempS3Credentials.data.fields.AWSSessionToken, - }; - - storageParams = { - credentials, - region: virtruTempS3Credentials.data.url.split('.')[1], - forcePathStyle: false, - maxAttempts: 3, - useAccelerateEndpoint: true, - }; - } else { - storageParams = config; - } - - const BUCKET_NAME: string | undefined = - config?.Bucket || virtruTempS3Credentials?.data?.bucket || undefined; - - const FILE_NAME = fileName || 'upload.tdf'; - - const s3 = new S3Client(storageParams); - - // Managed Parallel Upload - const uploadParams: Options['params'] = { - Bucket: BUCKET_NAME, - Key: FILE_NAME, - Body: stream, - }; - - const parallelUpload = new Upload({ - client: s3, - queueSize: CONCURRENT_UPLOADS, // optional concurrency configuration - partSize: MAX_UPLOAD_PART_SIZE, // optional size of each part, defaults to 5MB, cannot be smaller than 5MB - leavePartsOnError: false, // optional manually handle dropped parts - params: uploadParams, - }); - - if (progressHandler) { - parallelUpload.on('httpUploadProgress', progressHandler); - } - - return await parallelUpload.done(); -}; diff --git a/remote-store/tests/index.test.ts b/remote-store/tests/index.test.ts deleted file mode 100644 index fc573b7c..00000000 --- a/remote-store/tests/index.test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { expect } from 'chai'; - -import { setRemoteStoreAsStream } from '../src/index.js'; - -describe('setRemoteStoreAsStream', () => { - it('is a function', () => { - expect(typeof setRemoteStoreAsStream).to.equal('function'); - }); -}); diff --git a/remote-store/tsconfig.json b/remote-store/tsconfig.json deleted file mode 100644 index affe8690..00000000 --- a/remote-store/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "alwaysStrict": true, - "baseUrl": "./", - "composite": true, - "declaration": true, - "declarationDir": "./dist", - "declarationMap": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "inlineSourceMap": true, - "isolatedModules": true, - "lib": ["dom", "dom.iterable", "es2020", "ES2022.Error"], - "module": "es2020", - "moduleResolution": "node16", - "noImplicitAny": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noUnusedLocals": true, - "outDir": "dist", - "skipLibCheck": true, - "strict": false, - "strictBindCallApply": true, - "strictFunctionTypes": true, - "strictNullChecks": true, - "strictPropertyInitialization": false, - "target": "es2020", - }, - "include": ["src", "tests"], - "exclude": ["**/node_modules"] -} diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index 880cb352..0969715e 100755 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -22,7 +22,7 @@ elif [[ $(git status --porcelain) ]]; then exit 1 fi -packages=(lib cli remote-store web-app) +packages=(lib cli web-app) old_version=$(cd "${packages[0]}" && node -p "require('./package.json').version") echo npm --no-git-tag-version version "${increment_type}" (cd "${packages[0]}" && npm --no-git-tag-version version "${increment_type}") diff --git a/web-app/package-lock.json b/web-app/package-lock.json index bd4a71b9..003976cf 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -1,15 +1,15 @@ { "name": "web-app", - "version": "2.1.0", + "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "web-app", - "version": "2.1.0", + "version": "0.1.0", "license": "BSD-3-Clause-Clear", "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", + "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", "clsx": "^2.0.0", "native-file-system-adapter": "^3.0.1", "react": "^18.2.0", @@ -604,10 +604,10 @@ "node": ">= 8" } }, - "node_modules/@opentdf/client": { - "version": "2.1.0", - "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", + "node_modules/@opentdf/sdk": { + "version": "0.1.0", + "resolved": "file:../lib/opentdf-sdk-0.1.0.tgz", + "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", @@ -4117,9 +4117,9 @@ "fastq": "^1.6.0" } }, - "@opentdf/client": { - "version": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-uE8lpCTtSsoLZtrVh5NARUO9vMhAbzKgw7r4O4eyKoJvbi8La7p0IfuiBiLWrvdDZgARruHAbTYNC8Vi1a/80Q==", + "@opentdf/sdk": { + "version": "file:../lib/opentdf-sdk-0.1.0.tgz", + "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", diff --git a/web-app/package.json b/web-app/package.json index fb3b5282..905eec23 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -1,6 +1,6 @@ { "name": "web-app", - "version": "2.1.0", + "version": "0.1.0", "license": "BSD-3-Clause-Clear", "type": "module", "scripts": { @@ -15,7 +15,7 @@ "test:ui": "vite build && vitest --ui" }, "dependencies": { - "@opentdf/client": "file:../lib/opentdf-client-2.1.0.tgz", + "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", "clsx": "^2.0.0", "native-file-system-adapter": "^3.0.1", "react": "^18.2.0", diff --git a/web-app/src/App.tsx b/web-app/src/App.tsx index 6592bfc6..75d9cbeb 100644 --- a/web-app/src/App.tsx +++ b/web-app/src/App.tsx @@ -2,7 +2,7 @@ import { clsx } from 'clsx'; import { useState, useEffect, type ChangeEvent } from 'react'; import { showSaveFilePicker } from 'native-file-system-adapter'; import './App.css'; -import { type Chunker, type DecryptSource, NanoTDFClient, TDF3Client } from '@opentdf/client'; +import { type Chunker, type DecryptSource, NanoTDFClient, TDF3Client } from '@opentdf/sdk'; import { type SessionInformation, OidcClient } from './session.js'; import { c } from './config.js'; diff --git a/web-app/src/session.ts b/web-app/src/session.ts index a54d3233..fd5145c8 100644 --- a/web-app/src/session.ts +++ b/web-app/src/session.ts @@ -1,7 +1,7 @@ import { decodeJwt } from 'jose'; import { default as dpopFn } from 'dpop'; -import { base64 } from '@opentdf/client/encodings'; -import { AuthProvider, HttpRequest, withHeaders } from '@opentdf/client'; +import { base64 } from '@opentdf/sdk/encodings'; +import { AuthProvider, HttpRequest, withHeaders } from '@opentdf/sdk'; export type OpenidConfiguration = { issuer: string; From 2fe2c43ee3c481f6f40eba11a50e0ab8155ea024 Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Wed, 6 Nov 2024 14:07:51 -0700 Subject: [PATCH 41/42] fix: Changes to make regex patterns more efficient, accurate and simpler (#376) * validation.ts regex fixes The `.` character in a regex can match any character. This needs to be escaped in order to match a literal `.`. This not only strengthens the patterns, but also will help make the `www` search more efficient. In addition the WWW_HOST TLD part of the pattern was switched from `^s` to `a-z`. `^s` will match any character except `s`, it was assumed that `^\s` was expected (to match any non-whitespace character). However the `a-z` check is simpler. * tdf.ts: Make html payload regex more efficient The key change in this regex is from `[^>]*` to to `[^>]*?`. The added `?` will change this to a non-greed match, resulting in as few characters as possible to match (vs as many as possible). This will reduce the amount of backtracking the regex engine will need to do when evaluating. * validation.ts: WWW_HOST switched to not capture any groups This removes the negative `www.` check as it's not believed that this group is checked. In additional all groups have been switched to non-capturing to allow the pattern to be more efficient. * validation.ts: Further simplify WWW_HOST pattern This removes the `www` prefix check as that condition will be handled by the following group (which with the `+` can match subdomains). In addition the subdomain portion was further simplified. By using a `*` instead of two nested optional groups the refex engine should be more efficent at matching the pattern. --- lib/tdf3/src/client/validation.ts | 4 ++-- lib/tdf3/src/tdf.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/tdf3/src/client/validation.ts b/lib/tdf3/src/client/validation.ts index 0981bcec..8f08fdfa 100644 --- a/lib/tdf3/src/client/validation.ts +++ b/lib/tdf3/src/client/validation.ts @@ -12,10 +12,10 @@ const SCHEME = '(https?://)'; const HOST_PORT = '([a-z0-9][a-z0-9]{1,}:[0-9]{1,4})'; // validate url host be like `www.example.com` -const WWW_HOST = '((?:www.|(?!www))([a-z0-9][a-z0-9-]*[a-z0-9].)+[^s]{2,})'; +const WWW_HOST = '([a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z]{2,}'; // validate url host be like `127.0.0.1:4000` -const IP_HOST_PORT = '([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]{1,4})'; +const IP_HOST_PORT = '([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}:[0-9]{1,4})'; // validate host is one of those above const HOST = `(${HOST_PORT}|${WWW_HOST}|${IP_HOST_PORT})`; diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 32c385b2..699c2633 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -325,7 +325,7 @@ export function unwrapHtml(htmlPayload: ArrayBuffer | Uint8Array | Binary | stri } else { html = htmlPayload.toString(); } - const payloadRe = /]*value=['"]?([a-zA-Z0-9+/=]+)['"]?/; + const payloadRe = /]*?value=['"]?([a-zA-Z0-9+/=]+)['"]?/; const reResult = payloadRe.exec(html); if (reResult === null) { throw new InvalidFileError('Payload is missing'); From 496f07ca7029ded39bd0c71a59f1c7220dd419c1 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 12 Nov 2024 11:55:13 -0500 Subject: [PATCH 42/42] fix(core): npm audit fix (#380) Updates a lot of other deps, except for the hard ones (typescript and eslint, mostly) --- cli/package-lock.json | 408 +- cli/package.json | 22 +- cli/src/cli.ts | 13 +- lib/package-lock.json | 3264 ++++++++------- lib/package.json | 26 +- lib/tdf3/src/models/encryption-information.ts | 12 +- web-app/package-lock.json | 3482 +++++++++++------ web-app/package.json | 28 +- web-app/tests/package-lock.json | 161 +- web-app/tests/package.json | 2 +- 10 files changed, 4582 insertions(+), 2836 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index ad7500e7..c894ad6b 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -17,20 +17,20 @@ }, "devDependencies": { "@esm-bundle/chai": "4.3.4-fix.0", - "@types/mocha": "10.0.1", - "@types/node": "^20.4.5", - "@types/readable-stream": "^2.3.15", - "@types/sinon": "^10.0.15", - "@types/yargs": "^17.0.24", + "@types/mocha": "10.0.9", + "@types/node": "^22.9.0", + "@types/readable-stream": "^4.0.18", + "@types/sinon": "^17.0.3", + "@types/yargs": "^17.0.33", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", - "chai": "^4.3.7", - "eslint": "^8.46.0", + "chai": "^5.1.2", + "eslint": "^8.9.0", "eslint-config-prettier": "^8.9.0", - "license-checker-rseidelsohn": "^4.2.6", - "mocha": "^10.2.0", - "prettier": "^3.0.0", - "sinon": "^15.2.0", + "license-checker-rseidelsohn": "^4.4.2", + "mocha": "^10.8.2", + "prettier": "^3.3.3", + "sinon": "^19.0.2", "ts-node": "^10.9.2", "typescript": "^5.1.6" } @@ -372,7 +372,7 @@ "node_modules/@opentdf/sdk": { "version": "0.1.0", "resolved": "file:../lib/opentdf-sdk-0.1.0.tgz", - "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", + "integrity": "sha512-x4uSWK8u5CQe5st/tseiPah3PUs8s/CGeFIbf+7I6v8hQ83R0UpLNn8O0k7k46rE0f2z564EYRkpZlZljI2A3w==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", @@ -403,44 +403,49 @@ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^2.0.0", + "@sinonjs/commons": "^3.0.1", "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" } }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "node_modules/@sinonjs/samsam/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, - "dependencies": { - "type-detect": "4.0.8" + "license": "MIT", + "engines": { + "node": ">=4" } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true, + "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@tsconfig/node10": { "version": "1.0.11", @@ -479,25 +484,28 @@ "dev": true }, "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", + "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.8" } }, "node_modules/@types/readable-stream": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", - "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.18.tgz", + "integrity": "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "safe-buffer": "~5.1.1" @@ -510,10 +518,11 @@ "dev": true }, "node_modules/@types/sinon": { - "version": "10.0.20", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.20.tgz", - "integrity": "sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, + "license": "MIT", "dependencies": { "@types/sinonjs__fake-timers": "*" } @@ -525,10 +534,11 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -791,10 +801,11 @@ } }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "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, + "license": "MIT", "engines": { "node": ">=6" } @@ -865,12 +876,13 @@ } }, "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==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12" } }, "node_modules/asynckit": { @@ -1003,21 +1015,20 @@ } }, "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", "dev": true, + "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.0.8" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" } }, "node_modules/chalk": { @@ -1037,15 +1048,13 @@ } }, "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">= 16" } }, "node_modules/chokidar": { @@ -1155,12 +1164,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1184,13 +1194,11 @@ } }, "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, + "license": "MIT", "engines": { "node": ">=6" } @@ -1211,10 +1219,11 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -1677,15 +1686,6 @@ "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, - "engines": { - "node": "*" - } - }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -2056,7 +2056,8 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", @@ -2081,10 +2082,11 @@ } }, "node_modules/license-checker-rseidelsohn": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/license-checker-rseidelsohn/-/license-checker-rseidelsohn-4.3.0.tgz", - "integrity": "sha512-A2LQ+3kUIG1hCJ/hh4WUvPsyhooT7o5mFhNyTean0cqH3rZeB1ZUCthxlcdgWESSqx+3DLC6J/8ghbiWRYKdUA==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/license-checker-rseidelsohn/-/license-checker-rseidelsohn-4.4.2.tgz", + "integrity": "sha512-Sf8WaJhd2vELvCne+frS9AXqnY/vv591s2/nZcJDwTnoNgltG4mAmoenffVb8L2YPRYbxARLyrHJBC38AVfpuA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "chalk": "4.1.2", "debug": "^4.3.4", @@ -2099,7 +2101,7 @@ "treeify": "^1.1.0" }, "bin": { - "license-checker-rseidelsohn": "bin/license-checker-rseidelsohn" + "license-checker-rseidelsohn": "bin/license-checker-rseidelsohn.js" }, "engines": { "node": ">=18", @@ -2131,7 +2133,8 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -2156,13 +2159,11 @@ } }, "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" }, "node_modules/lru-cache": { "version": "7.18.3", @@ -2189,12 +2190,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -2259,31 +2261,32 @@ } }, "node_modules/mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", - "dev": true, - "dependencies": { - "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": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.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" + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -2305,10 +2308,11 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -2316,12 +2320,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -2356,10 +2354,11 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -2368,25 +2367,17 @@ "dev": true }, "node_modules/nise": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" + "path-to-regexp": "^8.1.0" } }, "node_modules/nopt": { @@ -2558,10 +2549,14 @@ } }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } }, "node_modules/path-type": { "version": "4.0.0", @@ -2573,12 +2568,13 @@ } }, "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">= 14.16" } }, "node_modules/picomatch": { @@ -2603,10 +2599,11 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -2657,6 +2654,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -2861,10 +2859,11 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -2903,17 +2902,17 @@ } }, "node_modules/sinon": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", - "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", - "deprecated": "16.1.1", + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", + "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.3.0", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.4", + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.2", + "@sinonjs/samsam": "^8.0.1", + "diff": "^7.0.0", + "nise": "^6.1.1", "supports-color": "^7.2.0" }, "funding": { @@ -2922,10 +2921,11 @@ } }, "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -3205,6 +3205,7 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -3235,10 +3236,11 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", @@ -3303,10 +3305,11 @@ } }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -3374,10 +3377,11 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "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" } diff --git a/cli/package.json b/cli/package.json index e6043ab8..0298a42b 100644 --- a/cli/package.json +++ b/cli/package.json @@ -30,20 +30,20 @@ }, "devDependencies": { "@esm-bundle/chai": "4.3.4-fix.0", - "@types/mocha": "10.0.1", - "@types/node": "^20.4.5", - "@types/readable-stream": "^2.3.15", - "@types/sinon": "^10.0.15", - "@types/yargs": "^17.0.24", + "@types/mocha": "10.0.9", + "@types/node": "^22.9.0", + "@types/readable-stream": "^4.0.18", + "@types/sinon": "^17.0.3", + "@types/yargs": "^17.0.33", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", - "chai": "^4.3.7", - "eslint": "^8.46.0", + "chai": "^5.1.2", + "eslint": "^8.9.0", "eslint-config-prettier": "^8.9.0", - "license-checker-rseidelsohn": "^4.2.6", - "mocha": "^10.2.0", - "prettier": "^3.0.0", - "sinon": "^15.2.0", + "license-checker-rseidelsohn": "^4.4.2", + "mocha": "^10.8.2", + "prettier": "^3.3.3", + "sinon": "^19.0.2", "ts-node": "^10.9.2", "typescript": "^5.1.6" }, diff --git a/cli/src/cli.ts b/cli/src/cli.ts index 6c6a88d6..c20555b9 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -1,6 +1,7 @@ import './polyfills.js'; -import { openAsBlob } from 'node:fs'; -import { open, readFile, stat, writeFile } from 'node:fs/promises'; +import { createWriteStream, openAsBlob } from 'node:fs'; +import { readFile, stat, writeFile } from 'node:fs/promises'; +import { Writable } from 'node:stream'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; import { @@ -420,8 +421,8 @@ export const handleArgs = (args: string[]) => { log('DEBUG', `About to decrypt [${argv.file}]`); const ct = await client.decrypt(await tdf3DecryptParamsFor(argv)); if (argv.output) { - const filehandle = await open(argv.output, 'w'); - await filehandle.writeFile(ct.stream); + const destination = createWriteStream(argv.output); + await ct.stream.pipeTo(Writable.toWeb(destination)); } else { console.log(await ct.toString()); } @@ -514,8 +515,8 @@ export const handleArgs = (args: string[]) => { throw new CLIError('CRITICAL', 'Encrypt configuration error: No output?'); } if (argv.output) { - const filehandle = await open(argv.output, 'w'); - await filehandle.writeFile(ct.stream); + const destination = createWriteStream(argv.output); + await ct.stream.pipeTo(Writable.toWeb(destination)); } else { console.log(await ct.toString()); } diff --git a/lib/package-lock.json b/lib/package-lock.json index 8268111a..e879ad19 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -23,10 +23,10 @@ }, "devDependencies": { "@esm-bundle/chai": "~4.3.4-fix.0", - "@types/buffer-crc32": "^0.2.2", + "@types/buffer-crc32": "^0.2.4", "@types/chai": "~4.3.5", "@types/jest": "^29.5.3", - "@types/jsdom": "^21.1.4", + "@types/jsdom": "^21.1.7", "@types/jsonwebtoken": "~9.0.2", "@types/mocha": "~10.0.1", "@types/node": "^20.4.5", @@ -37,10 +37,10 @@ "@types/wicg-file-system-access": "^2020.9.6", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", - "@web/dev-server-esbuild": "^0.4.4", - "@web/dev-server-rollup": "^0.5.4", - "@web/test-runner": "^0.17.3", - "@web/test-runner-commands": "^0.8.3", + "@web/dev-server-esbuild": "^1.0.3", + "@web/dev-server-rollup": "^0.6.4", + "@web/test-runner": "^0.19.0", + "@web/test-runner-commands": "^0.9.0", "audit-ci": "^6.6.1", "c8": "^8.0.1", "chai": "^4.3.7", @@ -48,47 +48,24 @@ "eslint": "^8.46.0", "eslint-config-prettier": "^8.9.0", "glob": "^10.3.3", - "jsdom": "^22.1.0", - "karma": "^6.4.2", + "jsdom": "^25.0.1", + "karma": "^6.4.4", "karma-chrome-launcher": "^3.2.0", "karma-mocha": "^2.0.1", "license-checker-rseidelsohn": "^4.2.6", - "mocha": "^10.2.0", - "nyc": "^15.1.0", - "prettier": "^3.0.0", + "mocha": "^10.8.2", + "nyc": "^17.1.0", + "prettier": "^3.3.3", "process": "^0.11.10", - "rollup": "^3.27.0", + "rollup": "^4.25.0", "sinon": "~15.2.0", "tsconfig-paths": "^4.2.0", "typedoc": "^0.24.8", "typescript": "5.1.6", - "webpack": "^5.88.2", + "webpack": "^5.96.1", "webpack-cli": "^5.1.4" } }, - "node_modules/@75lb/deep-merge": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.2.tgz", - "integrity": "sha512-08K9ou5VNbheZFxM5tDWoqjA3ImC50DiuuJ2tj1yEPRfkp8lLLg6XAaJ4On+a0yAXor/8ay5gHnAIshRM44Kpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.21", - "typical": "^7.1.1" - }, - "engines": { - "node": ">=12.17" - } - }, - "node_modules/@75lb/deep-merge/node_modules/typical": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", - "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", - "dev": true, - "engines": { - "node": ">=12.17" - } - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "dev": true, @@ -98,31 +75,38 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.22.6", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true, "license": "MIT", "engines": { @@ -130,25 +114,27 @@ } }, "node_modules/@babel/core": { - "version": "7.22.8", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "@nicolo-ribaudo/semver-v6": "^6.3.3", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -158,135 +144,113 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/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" + } + }, "node_modules/@babel/generator": { - "version": "7.23.0", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.6", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-validator-option": "^7.22.5", - "@nicolo-ribaudo/semver-v6": "^6.3.3", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1" + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/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/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", + "node_modules/@babel/helper-compilation-targets/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": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.5", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, "license": "MIT", "engines": { @@ -294,7 +258,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "license": "MIT", "engines": { @@ -302,7 +268,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, "license": "MIT", "engines": { @@ -310,35 +278,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.6", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.22.20", + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/types": "^7.26.0" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.0", - "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -357,32 +318,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.2", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -391,6 +353,8 @@ }, "node_modules/@babel/traverse/node_modules/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, "license": "MIT", "engines": { @@ -398,13 +362,14 @@ } }, "node_modules/@babel/types": { - "version": "7.23.0", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -431,19 +396,412 @@ "node": ">=10.0.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.18", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", "cpu": [ - "arm64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" + "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -490,26 +848,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "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" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, "node_modules/@eslint/js": { "version": "8.46.0", "dev": true, @@ -855,13 +1193,15 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -876,7 +1216,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.0", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "license": "MIT", "engines": { @@ -884,12 +1226,14 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.5", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { @@ -898,12 +1242,14 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@mdn/browser-compat-data": { @@ -911,14 +1257,6 @@ "dev": true, "license": "CC0-1.0" }, - "node_modules/@nicolo-ribaudo/semver-v6": { - "version": "6.3.3", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -972,169 +1310,340 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz", - "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.1.tgz", + "integrity": "sha512-0kdAbmic3J09I6dT8e9vE2JOCSt13wHCW5x/ly8TSt2bDtuIWe2TgLZZDHdcziw9AVCzflMAXCrVyRIhIs44Ng==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.3.0", - "tar-fs": "3.0.4", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" + "debug": "^4.3.7", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.3", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">=16.3.0" + "node": ">=18" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "typescript": ">= 4.7.4" + "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { - "typescript": { + "rollup": { "optional": true } } }, - "node_modules/@puppeteer/browsers/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==", + "node_modules/@rollup/pluginutils": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", + "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" }, "engines": { - "node": ">=8" + "node": ">=14.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@puppeteer/browsers/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==", + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, + "license": "MIT", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@puppeteer/browsers/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==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.25.0.tgz", + "integrity": "sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@puppeteer/browsers/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.25.0.tgz", + "integrity": "sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@puppeteer/browsers/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==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.25.0.tgz", + "integrity": "sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg==", + "cpu": [ + "arm64" + ], "dev": true, - "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" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@puppeteer/browsers/node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.25.0.tgz", + "integrity": "sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=12" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@puppeteer/browsers/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==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.25.0.tgz", + "integrity": "sha512-xpEIXhiP27EAylEpreCozozsxWQ2TJbOLSivGfXhU4G1TBVEYtUPi2pOZBnvGXHyOdLAUUhPnJzH3ah5cqF01g==", + "cpu": [ + "arm64" + ], "dev": true, - "engines": { - "node": ">=12" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.0.2", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.25.0.tgz", + "integrity": "sha512-sC5FsmZGlJv5dOcURrsnIK7ngc3Kirnx3as2XU9uER+zjfyqIjdcMVgzy4cOawhsssqzoAX19qmxgJ8a14Qrqw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@rollup/pluginutils": { - "version": "5.0.2", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.25.0.tgz", + "integrity": "sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.25.0.tgz", + "integrity": "sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.25.0.tgz", + "integrity": "sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.25.0.tgz", + "integrity": "sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.25.0.tgz", + "integrity": "sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.25.0.tgz", + "integrity": "sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.25.0.tgz", + "integrity": "sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.25.0.tgz", + "integrity": "sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.25.0.tgz", + "integrity": "sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.25.0.tgz", + "integrity": "sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.25.0.tgz", + "integrity": "sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.25.0.tgz", + "integrity": "sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@sinclair/typebox": { "version": "0.25.24", @@ -1185,19 +1694,12 @@ "dev": true, "license": "MIT" }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/accepts": { "version": "1.3.5", @@ -1223,7 +1725,9 @@ } }, "node_modules/@types/buffer-crc32": { - "version": "0.2.2", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@types/buffer-crc32/-/buffer-crc32-0.2.4.tgz", + "integrity": "sha512-GSrhSZOK1/wazf2CjDp3CVJQKWzSc5Ugq3NyZ/RQqg1MWtmA9mAT6i6LzGKhzcRxDOl8aLB+AzvObDSlrMpvLw==", "dev": true, "license": "MIT", "dependencies": { @@ -1249,7 +1753,8 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/connect": { "version": "3.4.35", @@ -1303,7 +1808,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.40.2", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, "license": "MIT", "dependencies": { @@ -1312,7 +1819,9 @@ } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "license": "MIT", "dependencies": { @@ -1321,7 +1830,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.1", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true, "license": "MIT" }, @@ -1388,7 +1899,9 @@ } }, "node_modules/@types/jsdom": { - "version": "21.1.4", + "version": "21.1.7", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", + "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", "dev": true, "license": "MIT", "dependencies": { @@ -1481,6 +1994,8 @@ }, "node_modules/@types/resolve": { "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true, "license": "MIT" }, @@ -1571,6 +2086,7 @@ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@types/node": "*" @@ -1759,46 +2275,46 @@ } }, "node_modules/@web/browser-logs": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.3.4.tgz", - "integrity": "sha512-0UkoUj1DdQjxaVBArHZRAGoiE5584/dSQ0V3hYWRqVDxaE3CwkfQ7kwb6i3Z1xJ8HZ9nuLMNycu3vLQwfhDnpg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", + "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", "dev": true, + "license": "MIT", "dependencies": { "errorstacks": "^2.2.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/config-loader": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.2.2.tgz", - "integrity": "sha512-HhoXMGivHbQ880MKQ1JChYCjWsMS4MUNOF35ktLV/0pZiX+J7oobybsPuyhS+gTnZsU7Duqnk3+HQYB7cNS4fA==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.3.2.tgz", + "integrity": "sha512-Vrjv/FexBGmAdnCYpJKLHX1dfT1UaUdvHmX1JRaWos9OvDf/tFznYJ5SpJwww3Rl87/ewvLSYG7kfsMqEAsizQ==", "dev": true, - "dependencies": { - "semver": "^7.3.4" - }, + "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/dev-server": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.3.7.tgz", - "integrity": "sha512-He/QTO1C+zWJesgOmGbuBX5p5OEbH9hxgELDVIscQAdOq91PpQN/4s8PJ3LIRpkbXAZBxdwCoRUZHENxHgOtjg==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.4.6.tgz", + "integrity": "sha512-jj/1bcElAy5EZet8m2CcUdzxT+CRvUjIXGh8Lt7vxtthkN9PzY9wlhWx/9WOs5iwlnG1oj0VGo6f/zvbPO0s9w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.11", "@types/command-line-args": "^5.0.0", - "@web/config-loader": "^0.2.2", - "@web/dev-server-core": "^0.6.3", - "@web/dev-server-rollup": "^0.5.4", + "@web/config-loader": "^0.3.0", + "@web/dev-server-core": "^0.7.2", + "@web/dev-server-rollup": "^0.6.1", "camelcase": "^6.2.0", "command-line-args": "^5.1.1", "command-line-usage": "^7.0.1", "debounce": "^1.2.0", "deepmerge": "^4.2.2", - "ip": "^1.1.5", + "internal-ip": "^6.2.0", "nanocolors": "^0.2.1", "open": "^8.0.2", "portfinder": "^1.0.32" @@ -1808,19 +2324,20 @@ "web-dev-server": "dist/bin.js" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/dev-server-core": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.6.3.tgz", - "integrity": "sha512-BWlgxIXQbg3RqUdz9Cfeh3XqFv0KcjQi4DLaZy9s63IlXgNZTzesTfDzliP/mIdWd5r8KZYh/P3n6LMi7CLPjQ==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.4.tgz", + "integrity": "sha512-nHSNrJ1J9GjmSceKNHpWRMjvpfE2NTV9EYUffPIr7j0sIV59gK7NI/4+9slotJ/ODXw0+e1gSeJshTOhjjVNxQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/koa": "^2.11.6", "@types/ws": "^7.4.0", - "@web/parse5-utils": "^2.0.2", - "chokidar": "^3.4.3", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^4.0.1", "clone": "^2.1.2", "es-module-lexer": "^1.0.0", "get-stream": "^6.0.0", @@ -1834,10 +2351,26 @@ "mime-types": "^2.1.27", "parse5": "^6.0.1", "picomatch": "^2.2.2", - "ws": "^7.4.2" + "ws": "^7.5.10" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-core/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" }, "engines": { - "node": ">=16.0.0" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@web/dev-server-core/node_modules/lru-cache": { @@ -1845,41 +2378,58 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", "dev": true, + "license": "ISC", "engines": { "node": ">=16.14" } }, + "node_modules/@web/dev-server-core/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@web/dev-server-esbuild": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-0.4.4.tgz", - "integrity": "sha512-gxXvj1mw0/b8HP2ARaXgQEmWH/nyPWvRuzSyEvybMm9oThe//z6K0ksj2qyffT/X7yblhEReKqWK7djCaB0M0Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-1.0.3.tgz", + "integrity": "sha512-oImN4/cpyfQC8+JcCx61M7WIo09zE2aDMFuwh+brqxuNXIBRQ+hnRGQK7fEIZSQeWWT5dFrWmH4oYZfqzCAlfQ==", "dev": true, + "license": "MIT", "dependencies": { "@mdn/browser-compat-data": "^4.0.0", - "@web/dev-server-core": "^0.6.2", - "esbuild": "^0.16 || ^0.17", + "@web/dev-server-core": "^0.7.4", + "esbuild": "^0.24.0", "parse5": "^6.0.1", "ua-parser-js": "^1.0.33" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/dev-server-rollup": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.5.4.tgz", - "integrity": "sha512-lIN+lwj84Oh8Whe4vHijjMVe7NLJUzLxiiUsOleUtrBp1b7Us9QyUNCJK/iYitHJJDhCw6JcLJbCJ5H+vW969Q==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.4.tgz", + "integrity": "sha512-sJZfTGCCrdku5xYnQQG51odGI092hKY9YFM0X3Z0tRY3iXKXcYRaLZrErw5KfCxr6g0JRuhe4BBhqXTA5Q2I3Q==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/plugin-node-resolve": "^15.0.1", - "@web/dev-server-core": "^0.6.2", + "@web/dev-server-core": "^0.7.2", "nanocolors": "^0.2.1", "parse5": "^6.0.1", - "rollup": "^3.15.0", - "whatwg-url": "^11.0.0" + "rollup": "^4.4.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/parse5-utils": { @@ -1896,18 +2446,19 @@ } }, "node_modules/@web/test-runner": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.17.3.tgz", - "integrity": "sha512-FzN3b+sC9Ig9MIbGp3TvNu2sK7iqJM34NpUi03z9w4dfW6/eFJRMcZfe5TlVh6thvGzEiMCAdgGKlOkGeMZ+XA==", - "dev": true, - "dependencies": { - "@web/browser-logs": "^0.3.3", - "@web/config-loader": "^0.2.1", - "@web/dev-server": "^0.3.3", - "@web/test-runner-chrome": "^0.14.4", - "@web/test-runner-commands": "^0.8.3", - "@web/test-runner-core": "^0.12.0", - "@web/test-runner-mocha": "^0.8.2", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.19.0.tgz", + "integrity": "sha512-qLUupi88OK1Kl52cWPD/2JewUCRUxYsZ1V1DyLd05P7u09zCdrUYrtkB/cViWyxlBe/TOvqkSNpcTv6zLJ9GoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/browser-logs": "^0.4.0", + "@web/config-loader": "^0.3.0", + "@web/dev-server": "^0.4.0", + "@web/test-runner-chrome": "^0.17.0", + "@web/test-runner-commands": "^0.9.0", + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-mocha": "^0.9.0", "camelcase": "^6.2.0", "command-line-args": "^5.1.1", "command-line-usage": "^7.0.1", @@ -1923,43 +2474,46 @@ "wtr": "dist/bin.js" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/test-runner-chrome": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.14.4.tgz", - "integrity": "sha512-JVee+hCJMFE3mxxg+b60n/CGlKyBnfhLAT0Uskf4om8rnR2fmxrjtNIXluqv2jovWm3VeahB5DkpUrUb1CYP1w==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.17.0.tgz", + "integrity": "sha512-Il5N9z41NKWCrQM1TVgRaDWWYoJtG5Ha4fG+cN1MWL2OlzBS4WoOb4lFV3EylZ7+W3twZOFr1zy2Rx61yDYd/A==", "dev": true, + "license": "MIT", "dependencies": { - "@web/test-runner-core": "^0.12.0", - "@web/test-runner-coverage-v8": "^0.7.3", + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-coverage-v8": "^0.8.0", "async-mutex": "0.4.0", "chrome-launcher": "^0.15.0", - "puppeteer-core": "^20.0.0" + "puppeteer-core": "^23.2.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/test-runner-commands": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.8.3.tgz", - "integrity": "sha512-5HJXqf5Xw2GMC/zJLuPL649i2kr+ATDfcIZ3d3a5EvRb05wU9EtMCGm4npgYCqNFZKrq1HHwU64vnC2fhd35GQ==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz", + "integrity": "sha512-zeLI6QdH0jzzJMDV5O42Pd8WLJtYqovgdt0JdytgHc0d1EpzXDsc7NTCJSImboc2NcayIsWAvvGGeRF69SMMYg==", "dev": true, + "license": "MIT", "dependencies": { - "@web/test-runner-core": "^0.12.0", + "@web/test-runner-core": "^0.13.0", "mkdirp": "^1.0.4" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/test-runner-core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.12.0.tgz", - "integrity": "sha512-p318c1HzszyjqF0bl7oAsw6s8Xpd/xBIbMW7w5ktZwzm+r1KuNYh4RRuvkg1iMFkqu/6F8UeMR4+TJ0EYyJegw==", + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.4.tgz", + "integrity": "sha512-84E1025aUSjvZU1j17eCTwV7m5Zg3cZHErV3+CaJM9JPCesZwLraIa0ONIQ9w4KLgcDgJFw9UnJ0LbFf42h6tg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.11", "@types/babel__code-frame": "^7.0.2", @@ -1968,16 +2522,16 @@ "@types/debounce": "^1.2.0", "@types/istanbul-lib-coverage": "^2.0.3", "@types/istanbul-reports": "^3.0.0", - "@web/browser-logs": "^0.3.4", - "@web/dev-server-core": "^0.6.2", - "chokidar": "^3.4.3", + "@web/browser-logs": "^0.4.0", + "@web/dev-server-core": "^0.7.3", + "chokidar": "^4.0.1", "cli-cursor": "^3.1.0", "co-body": "^6.1.0", "convert-source-map": "^2.0.0", "debounce": "^1.2.0", "dependency-graph": "^0.11.0", "globby": "^11.0.1", - "ip": "^1.1.5", + "internal-ip": "^6.2.0", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.0.2", @@ -1989,29 +2543,61 @@ "source-map": "^0.7.3" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-core/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@web/test-runner-core/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@web/test-runner-core/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@web/test-runner-coverage-v8": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.7.3.tgz", - "integrity": "sha512-hFlMFLEonDTS+TqKAE5RUJPq1HdsT0YqZD4z0x2y/E65UfYNB6ZJpV567KDCG+9ph1xynkKyqsiIhK1ufktVJA==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", + "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", "dev": true, + "license": "MIT", "dependencies": { - "@web/test-runner-core": "^0.12.0", + "@web/test-runner-core": "^0.13.0", "istanbul-lib-coverage": "^3.0.0", "lru-cache": "^8.0.4", "picomatch": "^2.2.2", "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/test-runner-coverage-v8/node_modules/lru-cache": { @@ -2019,20 +2605,22 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", "dev": true, + "license": "ISC", "engines": { "node": ">=16.14" } }, "node_modules/@web/test-runner-mocha": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.8.2.tgz", - "integrity": "sha512-AS/Zc8dQo/8gGxizVLihxqOeJ5NM10jyv0L+ZIa9S7UDJuN1ge4xi2tbvCnSEcyX54gb6OG0bR+Ogy+Dzhvq7Q==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.9.0.tgz", + "integrity": "sha512-ZL9F6FXd0DBQvo/h/+mSfzFTSRVxzV9st/AHhpgABtUtV/AIpVE9to6+xdkpu6827kwjezdpuadPfg+PlrBWqQ==", "dev": true, + "license": "MIT", "dependencies": { - "@web/test-runner-core": "^0.12.0" + "@web/test-runner-core": "^0.13.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@web/test-runner/node_modules/convert-source-map": { @@ -2041,57 +2629,73 @@ "license": "MIT" }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, "license": "MIT", "dependencies": { @@ -2099,7 +2703,9 @@ } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2107,67 +2713,79 @@ } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -2214,19 +2832,18 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true, "license": "Apache-2.0" }, - "node_modules/abab": { - "version": "2.0.6", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/abbrev": { "version": "1.1.1", "dev": true, @@ -2245,7 +2862,9 @@ } }, "node_modules/acorn": { - "version": "8.9.0", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", "bin": { @@ -2255,14 +2874,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "dev": true, @@ -2272,14 +2883,16 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "license": "MIT", "dependencies": { - "debug": "4" + "debug": "^4.3.4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/aggregate-error": { @@ -2294,8 +2907,37 @@ "node": ">=8" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "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" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/ansi-colors": { - "version": "4.1.1", + "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, "license": "MIT", "engines": { @@ -2342,17 +2984,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/anymatch": { "version": "3.1.2", "dev": true, @@ -2391,6 +3022,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2424,6 +3056,7 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -2445,6 +3078,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.14" } @@ -2454,6 +3088,7 @@ "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.4.0" } @@ -2503,10 +3138,11 @@ } }, "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/balanced-match": { "version": "1.0.2", @@ -2514,12 +3150,56 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", - "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", "dev": true, + "license": "Apache-2.0", "optional": true }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", + "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.20.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "funding": [ @@ -2552,6 +3232,7 @@ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -2565,7 +3246,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, "license": "MIT", "dependencies": { @@ -2577,7 +3260,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -2600,20 +3283,6 @@ "dev": true, "license": "MIT" }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -2645,7 +3314,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.21.9", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -2663,10 +3334,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -2675,6 +3346,31 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-crc32": { "version": "0.2.13", "license": "MIT", @@ -2684,20 +3380,11 @@ }, "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, "license": "MIT" }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bytes": { "version": "3.1.2", "dev": true, @@ -2816,7 +3503,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001511", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "dev": true, "funding": [ { @@ -2851,24 +3540,12 @@ "node": ">=4" } }, - "node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/chalk-template": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.2" }, @@ -2884,6 +3561,7 @@ "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" }, @@ -2899,6 +3577,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2915,6 +3594,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2926,13 +3606,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/chalk-template/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2942,6 +3624,7 @@ "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" }, @@ -2949,14 +3632,6 @@ "node": ">=8" } }, - "node_modules/chalk/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/check-error": { "version": "1.0.2", "dev": true, @@ -2996,6 +3671,7 @@ "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", @@ -3018,12 +3694,15 @@ } }, "node_modules/chromium-bidi": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.16.tgz", - "integrity": "sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.8.0.tgz", + "integrity": "sha512-uJydbGdTw0DEUjhoogGveneJVWX/9YuqkWePzMmkBYwtdAqo5d3J/ovNKFr+/2hWXYmYCr6it8mSSTIj6SS6Ug==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "mitt": "3.0.0" + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.23.8" }, "peerDependencies": { "devtools-protocol": "*" @@ -3161,19 +3840,6 @@ "type-is": "^1.6.16" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/colorette": { "version": "2.0.20", "dev": true, @@ -3202,6 +3868,7 @@ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^3.1.0", "find-replace": "^3.0.0", @@ -3213,14 +3880,15 @@ } }, "node_modules/command-line-usage": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", - "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", + "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^6.2.2", "chalk-template": "^0.4.0", - "table-layout": "^3.0.0", + "table-layout": "^4.1.0", "typical": "^7.1.1" }, "engines": { @@ -3232,21 +3900,25 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.17" } }, "node_modules/command-line-usage/node_modules/typical": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", - "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", + "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.17" } }, "node_modules/commander": { "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, "license": "MIT" }, @@ -3353,15 +4025,6 @@ "node": ">= 0.10" } }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dev": true, - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "dev": true, @@ -3376,14 +4039,16 @@ } }, "node_modules/cssstyle": { - "version": "3.0.0", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "dev": true, "license": "MIT", "dependencies": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/custom-event": { @@ -3396,44 +4061,23 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14" } }, "node_modules/data-urls": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/data-urls/node_modules/tr46": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "12.0.1", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/date-format": { @@ -3451,11 +4095,13 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.4", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3511,6 +4157,19 @@ "node": ">=0.10.0" } }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/default-require-extensions": { "version": "3.0.1", "dev": true, @@ -3564,6 +4223,7 @@ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, + "license": "MIT", "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -3612,10 +4272,11 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1147663", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", - "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==", - "dev": true + "version": "0.0.1354347", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1354347.tgz", + "integrity": "sha512-BlmkSqV0V84E2WnEnoPnwyix57rQxAM5SKJjf4TbYOCGLAWtz8CDH8RIaGOjPgPCXo2Mce3kxSY497OySidY3Q==", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/di": { "version": "0.0.1", @@ -3623,7 +4284,9 @@ "license": "MIT" }, "node_modules/diff": { - "version": "5.0.0", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -3671,17 +4334,6 @@ "void-elements": "^2.0.0" } }, - "node_modules/domexception": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/dpop": { "version": "1.2.0", "license": "MIT", @@ -3705,7 +4357,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.447", + "version": "1.5.56", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", + "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", "dev": true, "license": "ISC" }, @@ -3727,6 +4381,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -3783,7 +4438,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.15.0", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "license": "MIT", "dependencies": { @@ -3858,7 +4515,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.17.18", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3866,35 +4525,39 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.18", - "@esbuild/android-arm64": "0.17.18", - "@esbuild/android-x64": "0.17.18", - "@esbuild/darwin-arm64": "0.17.18", - "@esbuild/darwin-x64": "0.17.18", - "@esbuild/freebsd-arm64": "0.17.18", - "@esbuild/freebsd-x64": "0.17.18", - "@esbuild/linux-arm": "0.17.18", - "@esbuild/linux-arm64": "0.17.18", - "@esbuild/linux-ia32": "0.17.18", - "@esbuild/linux-loong64": "0.17.18", - "@esbuild/linux-mips64el": "0.17.18", - "@esbuild/linux-ppc64": "0.17.18", - "@esbuild/linux-riscv64": "0.17.18", - "@esbuild/linux-s390x": "0.17.18", - "@esbuild/linux-x64": "0.17.18", - "@esbuild/netbsd-x64": "0.17.18", - "@esbuild/openbsd-x64": "0.17.18", - "@esbuild/sunos-x64": "0.17.18", - "@esbuild/win32-arm64": "0.17.18", - "@esbuild/win32-ia32": "0.17.18", - "@esbuild/win32-x64": "0.17.18" + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" } }, "node_modules/escalade": { - "version": "3.1.1", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -3922,6 +4585,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -3943,6 +4607,7 @@ "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" } @@ -3952,6 +4617,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -4044,21 +4710,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "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" - } - }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, @@ -4146,11 +4797,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -4238,6 +4884,8 @@ }, "node_modules/estree-walker": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, "license": "MIT" }, @@ -4283,6 +4931,30 @@ "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "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/expect": { "version": "29.5.0", "dev": true, @@ -4308,6 +4980,7 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -4328,6 +5001,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -4347,7 +5021,8 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.1", @@ -4395,6 +5070,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "license": "MIT", "dependencies": { "pend": "~1.2.0" } @@ -4484,6 +5160,7 @@ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^3.0.1" }, @@ -4550,7 +5227,9 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "license": "ISC", "dependencies": { @@ -4660,6 +5339,8 @@ }, "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": { @@ -4725,6 +5406,7 @@ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, + "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -4740,6 +5422,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4754,6 +5437,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -4766,6 +5450,7 @@ "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" } @@ -4804,6 +5489,8 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true, "license": "BSD-2-Clause" }, @@ -4875,7 +5562,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", + "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" }, @@ -4895,14 +5584,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -4996,14 +5677,16 @@ } }, "node_modules/html-encoding-sniffer": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, "license": "MIT", "dependencies": { - "whatwg-encoding": "^2.0.0" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/html-escaper": { @@ -5083,16 +5766,17 @@ } }, "node_modules/http-proxy-agent": { - "version": "5.0.0", + "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": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/http-proxy/node_modules/eventemitter3": { @@ -5101,15 +5785,27 @@ "license": "MIT" }, "node_modules/https-proxy-agent": { - "version": "5.0.1", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" }, "engines": { - "node": ">= 6" + "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": { @@ -5125,6 +5821,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, "funding": [ { @@ -5222,6 +5920,25 @@ "dev": true, "license": "ISC" }, + "node_modules/internal-ip": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", + "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-gateway": "^6.0.0", + "ipaddr.js": "^1.9.1", + "is-ip": "^3.1.0", + "p-event": "^4.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/internal-ip?sponsor=1" + } + }, "node_modules/interpret": { "version": "3.1.1", "dev": true, @@ -5230,17 +5947,12 @@ "node": ">=10.13.0" } }, - "node_modules/ip": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", - "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", - "dev": true - }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, + "license": "MIT", "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" @@ -5253,31 +5965,38 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, - "node_modules/is-binary-path": { - "version": "2.1.0", + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", "dev": true, "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", "dev": true, "license": "MIT", "dependencies": { - "builtin-modules": "^3.3.0" + "binary-extensions": "^2.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/is-core-module": { @@ -5347,8 +6066,23 @@ "node": ">=0.10.0" } }, + "node_modules/is-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-regex": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-module": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true, "license": "MIT" }, @@ -5494,26 +6228,20 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/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, - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/istanbul-lib-processinfo": { @@ -5965,6 +6693,8 @@ }, "node_modules/jest-worker": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "license": "MIT", "dependencies": { @@ -5978,6 +6708,8 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -5986,6 +6718,8 @@ }, "node_modules/jest-worker/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, "license": "MIT", "dependencies": { @@ -6012,6 +6746,8 @@ }, "node_modules/js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, @@ -6030,42 +6766,43 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsdom": { - "version": "22.1.0", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", "dev": true, "license": "MIT", "dependencies": { - "abab": "^2.0.6", - "cssstyle": "^3.0.0", - "data-urls": "^4.0.0", + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", "decimal.js": "^10.4.3", - "domexception": "^4.0.0", "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.4", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.1", - "ws": "^8.13.0", - "xml-name-validator": "^4.0.0" + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "canvas": "^2.5.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { "canvas": { @@ -6081,30 +6818,7 @@ "entities": "^4.4.0" }, "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/jsdom/node_modules/tr46": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/jsdom/node_modules/whatwg-url": { - "version": "12.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=14" + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/jsdom/node_modules/ws": { @@ -6130,14 +6844,16 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-canonicalize": { @@ -6149,6 +6865,13 @@ "dev": true, "license": "MIT" }, + "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", "dev": true, @@ -6207,7 +6930,9 @@ "license": "MIT" }, "node_modules/karma": { - "version": "6.4.2", + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, "license": "MIT", "dependencies": { @@ -6230,7 +6955,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^4.4.1", + "socket.io": "^4.7.2", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.30", @@ -6640,6 +7365,7 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" @@ -6650,6 +7376,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6658,7 +7385,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.0", @@ -6691,7 +7419,8 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", @@ -6834,14 +7563,13 @@ } }, "node_modules/lru-cache": { - "version": "6.0.0", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/lunr": { @@ -6892,7 +7620,8 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/media-typer": { "version": "0.3.0", @@ -6916,11 +7645,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6989,10 +7720,11 @@ } }, "node_modules/mitt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", - "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", - "dev": true + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" }, "node_modules/mkdirp": { "version": "1.0.4", @@ -7005,38 +7737,33 @@ "node": ">=10" } }, - "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==", - "dev": true - }, "node_modules/mocha": { - "version": "10.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "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" + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -7044,14 +7771,12 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/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, "license": "MIT", "dependencies": { @@ -7059,44 +7784,26 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -7106,7 +7813,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -7116,22 +7825,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/mocha/node_modules/nanoid": { - "version": "3.3.3", - "dev": true, - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "dev": true, @@ -7163,16 +7856,10 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, @@ -7227,6 +7914,7 @@ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -7243,48 +7931,6 @@ "path-to-regexp": "^1.7.0" } }, - "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==", - "dev": true, - "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-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/node-fetch/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==", - "dev": true - }, - "node_modules/node-fetch/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==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-preload": { "version": "0.2.1", "dev": true, @@ -7297,7 +7943,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.12", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true, "license": "MIT" }, @@ -7309,13 +7957,30 @@ "node": ">=0.10.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/nwsapi": { - "version": "2.2.6", + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz", + "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==", "dev": true, "license": "MIT" }, "node_modules/nyc": { - "version": "15.1.0", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", + "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", "dev": true, "license": "ISC", "dependencies": { @@ -7326,12 +7991,12 @@ "decamelize": "^1.2.0", "find-cache-dir": "^3.2.0", "find-up": "^4.1.0", - "foreground-child": "^2.0.0", + "foreground-child": "^3.3.0", "get-package-type": "^0.1.0", "glob": "^7.1.6", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-instrument": "^6.0.2", "istanbul-lib-processinfo": "^2.0.2", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", @@ -7351,7 +8016,7 @@ "nyc": "bin/nyc.js" }, "engines": { - "node": ">=8.9" + "node": ">=18" } }, "node_modules/nyc/node_modules/camelcase": { @@ -7392,18 +8057,6 @@ "node": ">=8" } }, - "node_modules/nyc/node_modules/foreground-child": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/nyc/node_modules/glob": { "version": "7.2.3", "dev": true, @@ -7594,6 +8247,32 @@ "node": ">= 0.8.0" } }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", "dev": true, @@ -7633,6 +8312,19 @@ "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", "dev": true, @@ -7642,57 +8334,20 @@ } }, "node_modules/pac-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "pac-resolver": "^7.0.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/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, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" }, "engines": { "node": ">= 14" @@ -7703,6 +8358,7 @@ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, + "license": "MIT", "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -7802,7 +8458,9 @@ } }, "node_modules/path-to-regexp": { - "version": "1.8.0", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, "license": "MIT", "dependencies": { @@ -7845,10 +8503,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, @@ -7927,6 +8588,7 @@ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", "dev": true, + "license": "MIT", "dependencies": { "async": "^2.6.4", "debug": "^3.2.7", @@ -7941,6 +8603,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" } @@ -7950,6 +8613,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -7966,7 +8630,9 @@ } }, "node_modules/prettier": { - "version": "3.0.0", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "license": "MIT", "bin": { @@ -8027,99 +8693,50 @@ "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" - } - }, - "node_modules/proxy-agent": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", - "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/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, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" + "node": ">=0.4.0" } }, - "node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", - "debug": "4" + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" }, "engines": { "node": ">= 14" } }, - "node_modules/proxy-agent/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/proxy-from-env": { "version": "1.1.0", "license": "MIT" }, - "node_modules/psl": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -8127,35 +8744,29 @@ } }, "node_modules/puppeteer-core": { - "version": "20.9.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz", - "integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==", + "version": "23.7.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.7.1.tgz", + "integrity": "sha512-Om/qCZhd+HLoAr7GltrRAZpS3uOXwHu7tXAoDbNcJADHjG2zeAlDArgyIPXYGG4QB/EQUHk13Q6RklNxGM73Pg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "1.4.6", - "chromium-bidi": "0.4.16", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1147663", - "ws": "8.13.0" + "@puppeteer/browsers": "2.4.1", + "chromium-bidi": "0.8.0", + "debug": "^4.3.7", + "devtools-protocol": "0.0.1354347", + "typed-query-selector": "^2.12.0", + "ws": "^8.18.0" }, "engines": { - "node": ">=16.3.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=18" } }, "node_modules/puppeteer-core/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -8181,10 +8792,11 @@ } }, "node_modules/qs": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", - "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -8195,11 +8807,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "dev": true, - "license": "MIT" - }, "node_modules/queue-microtask": { "version": "1.2.3", "dev": true, @@ -8223,7 +8830,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", @@ -8289,14 +8897,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/read-installed-packages/node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.18.3", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/read-installed-packages/node_modules/json-parse-even-better-errors": { "version": "3.0.0", "dev": true, @@ -8552,22 +9152,47 @@ } }, "node_modules/rollup": { - "version": "3.27.0", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.25.0.tgz", + "integrity": "sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==", "dev": true, "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.25.0", + "@rollup/rollup-android-arm64": "4.25.0", + "@rollup/rollup-darwin-arm64": "4.25.0", + "@rollup/rollup-darwin-x64": "4.25.0", + "@rollup/rollup-freebsd-arm64": "4.25.0", + "@rollup/rollup-freebsd-x64": "4.25.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.25.0", + "@rollup/rollup-linux-arm-musleabihf": "4.25.0", + "@rollup/rollup-linux-arm64-gnu": "4.25.0", + "@rollup/rollup-linux-arm64-musl": "4.25.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.25.0", + "@rollup/rollup-linux-riscv64-gnu": "4.25.0", + "@rollup/rollup-linux-s390x-gnu": "4.25.0", + "@rollup/rollup-linux-x64-gnu": "4.25.0", + "@rollup/rollup-linux-x64-musl": "4.25.0", + "@rollup/rollup-win32-arm64-msvc": "4.25.0", + "@rollup/rollup-win32-ia32-msvc": "4.25.0", + "@rollup/rollup-win32-x64-msvc": "4.25.0", "fsevents": "~2.3.2" } }, "node_modules/rrweb-cssom": { - "version": "0.6.0", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", "dev": true, "license": "MIT" }, @@ -8630,6 +9255,8 @@ }, "node_modules/schema-utils": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "license": "MIT", "dependencies": { @@ -8645,41 +9272,12 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "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" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "3.5.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, "node_modules/semver": { - "version": "7.5.4", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -8688,7 +9286,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -8811,14 +9411,6 @@ "type-detect": "4.0.8" } }, - "node_modules/sinon/node_modules/diff": { - "version": "5.1.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/sinon/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -8909,6 +9501,7 @@ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -8982,6 +9575,7 @@ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, + "license": "MIT", "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -8992,26 +9586,15 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", - "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/socks-proxy-agent/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" + "socks": "^2.8.3" }, "engines": { "node": ">= 14" @@ -9027,6 +9610,8 @@ }, "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, "license": "MIT", "dependencies": { @@ -9036,6 +9621,8 @@ }, "node_modules/source-map-support/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": { @@ -9165,15 +9752,6 @@ "through": "~2.3.4" } }, - "node_modules/stream-read-all": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", - "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/streamroller": { "version": "3.1.5", "dev": true, @@ -9198,10 +9776,11 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", "dev": true, + "license": "MIT", "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -9269,6 +9848,16 @@ "node": ">=4" } }, + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "dev": true, @@ -9280,17 +9869,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "dev": true, @@ -9308,22 +9886,15 @@ "license": "MIT" }, "node_modules/table-layout": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", - "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", + "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", "dev": true, + "license": "MIT", "dependencies": { - "@75lb/deep-merge": "^1.1.1", "array-back": "^6.2.2", - "command-line-args": "^5.2.1", - "command-line-usage": "^7.0.0", - "stream-read-all": "^3.0.1", - "typical": "^7.1.1", "wordwrapjs": "^5.1.0" }, - "bin": { - "table-layout": "bin/cli.js" - }, "engines": { "node": ">=12.17" } @@ -9333,21 +9904,15 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true, - "engines": { - "node": ">=12.17" - } - }, - "node_modules/table-layout/node_modules/typical": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", - "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=12.17" } }, "node_modules/tapable": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, "license": "MIT", "engines": { @@ -9355,14 +9920,18 @@ } }, "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, + "license": "MIT", "dependencies": { - "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" } }, "node_modules/tar-stream": { @@ -9370,6 +9939,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, + "license": "MIT", "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", @@ -9377,7 +9947,9 @@ } }, "node_modules/terser": { - "version": "5.18.2", + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -9394,15 +9966,17 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.9", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -9426,14 +10000,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "6.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "dev": true, @@ -9467,13 +10033,11 @@ } }, "node_modules/text-decoder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", - "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", + "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", "dev": true, - "dependencies": { - "b4a": "^1.6.4" - } + "license": "Apache-2.0" }, "node_modules/text-table": { "version": "0.2.0", @@ -9485,23 +10049,35 @@ "dev": true, "license": "MIT" }, - "node_modules/tmp": { - "version": "0.2.1", + "node_modules/tldts": { + "version": "6.1.60", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.60.tgz", + "integrity": "sha512-TYVHm7G9NCnhgqOsFalbX6MG1Po5F4efF+tLfoeiOGQq48Oqgwcgz8upY2R1BHWa4aDrj28RYx0dkYJ63qCFMg==", "dev": true, "license": "MIT", "dependencies": { - "rimraf": "^3.0.0" + "tldts-core": "^6.1.60" }, - "engines": { - "node": ">=8.17.0" + "bin": { + "tldts": "bin/cli.js" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", + "node_modules/tldts-core": { + "version": "6.1.60", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.60.tgz", + "integrity": "sha512-XHjoxak8SFQnHnmYHb3PcnW5TZ+9ErLZemZei3azuIRhQLw4IExsVbL3VZJdHcLeNaXq6NqawgpDPpjBOg4B5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.1", "dev": true, "license": "MIT", + "dependencies": { + "rimraf": "^3.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8.17.0" } }, "node_modules/to-regex-range": { @@ -9525,36 +10101,29 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.3", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "node": ">=16" } }, "node_modules/tr46": { - "version": "3.0.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.1.1" + "punycode": "^2.3.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/treeify": { @@ -9590,10 +10159,11 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -9645,6 +10215,13 @@ "node": ">= 0.6" } }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", + "dev": true, + "license": "MIT" + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "dev": true, @@ -9712,6 +10289,7 @@ "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9739,35 +10317,12 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, - "node_modules/unbzip2-stream/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/universalify": { "version": "0.1.2", "dev": true, @@ -9785,7 +10340,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -9803,8 +10360,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -9821,14 +10378,12 @@ "punycode": "^2.1.0" } }, - "node_modules/url-parse": { - "version": "1.5.10", + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true, - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", @@ -9894,18 +10449,22 @@ "license": "MIT" }, "node_modules/w3c-xmlserializer": { - "version": "4.0.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, "license": "MIT", "dependencies": { - "xml-name-validator": "^4.0.0" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/watchpack": { - "version": "2.4.0", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, "license": "MIT", "dependencies": { @@ -9925,33 +10484,34 @@ } }, "node_modules/webpack": { - "version": "5.88.2", + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", "dev": true, "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -10043,18 +10603,22 @@ } }, "node_modules/whatwg-encoding": { - "version": "2.0.0", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/whatwg-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==", "dev": true, "license": "MIT", "dependencies": { @@ -10065,23 +10629,27 @@ } }, "node_modules/whatwg-mimetype": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/whatwg-url": { - "version": "11.0.0", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "^3.0.0", + "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/which": { @@ -10113,12 +10681,15 @@ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.17" } }, "node_modules/workerpool": { - "version": "6.2.1", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true, "license": "Apache-2.0" }, @@ -10251,11 +10822,13 @@ } }, "node_modules/xml-name-validator": { - "version": "4.0.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, "license": "Apache-2.0", "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/xmlchars": { @@ -10272,7 +10845,9 @@ } }, "node_modules/yallist": { - "version": "4.0.0", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" }, @@ -10387,6 +10962,7 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -10410,6 +10986,16 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/lib/package.json b/lib/package.json index 138f3633..d1659d0c 100644 --- a/lib/package.json +++ b/lib/package.json @@ -81,10 +81,10 @@ }, "devDependencies": { "@esm-bundle/chai": "~4.3.4-fix.0", - "@types/buffer-crc32": "^0.2.2", + "@types/buffer-crc32": "^0.2.4", "@types/chai": "~4.3.5", "@types/jest": "^29.5.3", - "@types/jsdom": "^21.1.4", + "@types/jsdom": "^21.1.7", "@types/jsonwebtoken": "~9.0.2", "@types/mocha": "~10.0.1", "@types/node": "^20.4.5", @@ -95,10 +95,10 @@ "@types/wicg-file-system-access": "^2020.9.6", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", - "@web/dev-server-esbuild": "^0.4.4", - "@web/dev-server-rollup": "^0.5.4", - "@web/test-runner": "^0.17.3", - "@web/test-runner-commands": "^0.8.3", + "@web/dev-server-esbuild": "^1.0.3", + "@web/dev-server-rollup": "^0.6.4", + "@web/test-runner": "^0.19.0", + "@web/test-runner-commands": "^0.9.0", "audit-ci": "^6.6.1", "c8": "^8.0.1", "chai": "^4.3.7", @@ -106,21 +106,21 @@ "eslint": "^8.46.0", "eslint-config-prettier": "^8.9.0", "glob": "^10.3.3", - "jsdom": "^22.1.0", - "karma": "^6.4.2", + "jsdom": "^25.0.1", + "karma": "^6.4.4", "karma-chrome-launcher": "^3.2.0", "karma-mocha": "^2.0.1", "license-checker-rseidelsohn": "^4.2.6", - "mocha": "^10.2.0", - "nyc": "^15.1.0", - "prettier": "^3.0.0", + "mocha": "^10.8.2", + "nyc": "^17.1.0", + "prettier": "^3.3.3", "process": "^0.11.10", - "rollup": "^3.27.0", + "rollup": "^4.25.0", "sinon": "~15.2.0", "tsconfig-paths": "^4.2.0", "typedoc": "^0.24.8", "typescript": "5.1.6", - "webpack": "^5.88.2", + "webpack": "^5.96.1", "webpack-cli": "^5.1.4" } } diff --git a/lib/tdf3/src/models/encryption-information.ts b/lib/tdf3/src/models/encryption-information.ts index e288bc41..20b99743 100644 --- a/lib/tdf3/src/models/encryption-information.ts +++ b/lib/tdf3/src/models/encryption-information.ts @@ -101,12 +101,12 @@ export class SplitKey { typeof metadata === 'object' ? JSON.stringify(metadata) : typeof metadata === 'string' - ? metadata - : () => { - throw new ConfigurationError( - "KAO generation failure: metadata isn't a string or object" - ); - } + ? metadata + : () => { + throw new ConfigurationError( + "KAO generation failure: metadata isn't a string or object" + ); + } ) as string; const metadataBinary = Binary.fromArrayBuffer(new TextEncoder().encode(metadataStr)); diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 003976cf..229b90cc 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -10,30 +10,30 @@ "license": "BSD-3-Clause-Clear", "dependencies": { "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", - "clsx": "^2.0.0", + "clsx": "^2.1.1", "native-file-system-adapter": "^3.0.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "^18.3.1", + "react-dom": "^18.3.1" }, "devDependencies": { - "@playwright/test": "^1.36.2", - "@rollup/plugin-inject": "^5.0.3", - "@types/react": "^18.2.17", - "@types/react-dom": "^18.2.7", + "@playwright/test": "^1.48.2", + "@rollup/plugin-inject": "^5.0.5", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "@types/wicg-file-system-access": "^2023.10.5", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", - "@vitejs/plugin-react": "^4.0.4", - "@vitest/ui": "^0.33.0", + "@vitejs/plugin-react": "^4.3.3", + "@vitest/ui": "^2.1.4", "buffer": "^6.0.3", - "eslint": "^8.46.0", + "eslint": "^8.9.0", "eslint-config-prettier": "^8.9.0", "license-checker": "^25.0.1", - "playwright": "^1.36.2", - "prettier": "^3.0.0", + "playwright": "^1.48.2", + "prettier": "^3.3.3", "typescript": "^5.1.6", - "vite": "^4.4.7", - "vitest": "^0.33.0" + "vite": "^5.4.11", + "vitest": "^2.1.4" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -45,31 +45,38 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.22.9", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true, "license": "MIT", "engines": { @@ -77,24 +84,26 @@ } }, "node_modules/@babel/core": { - "version": "7.22.9", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -107,8 +116,8 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -116,39 +125,43 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.0", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.9", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/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": { @@ -157,8 +170,8 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -167,61 +180,35 @@ }, "node_modules/@babel/helper-compilation-targets/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" }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -231,37 +218,19 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, "license": "MIT", "engines": { @@ -269,7 +238,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "license": "MIT", "engines": { @@ -277,7 +248,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, "license": "MIT", "engines": { @@ -285,35 +258,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.6", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.22.20", + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/types": "^7.26.0" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.0", - "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -322,11 +288,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -336,11 +304,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -362,32 +332,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.2", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -395,20 +366,91 @@ } }, "node_modules/@babel/types": { - "version": "7.23.0", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.11", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -422,292 +464,880 @@ "node": ">=12" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=12" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.1", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], "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" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@eslint/js": { - "version": "8.46.0", + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10.10.0" + "node": ">=12" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=12" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "BSD-3-Clause" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@jest/schemas": { - "version": "29.6.0", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.6.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.1", + "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/eslintrc/node_modules/globals": { + "version": "13.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@opentdf/sdk": { + "version": "0.1.0", + "resolved": "file:../lib/opentdf-sdk-0.1.0.tgz", + "integrity": "sha512-x4uSWK8u5CQe5st/tseiPah3PUs8s/CGeFIbf+7I6v8hQ83R0UpLNn8O0k7k46rE0f2z564EYRkpZlZljI2A3w==", + "license": "BSD-3-Clause-Clear", + "dependencies": { + "axios": "^1.6.1", + "axios-retry": "^3.9.0", + "base64-js": "^1.5.1", + "browser-fs-access": "^0.34.1", + "buffer-crc32": "^0.2.13", + "dpop": "^1.2.0", + "eventemitter3": "^5.0.1", + "jose": "^4.14.4", + "json-canonicalize": "^1.0.6", + "streamsaver": "^2.0.6", + "uuid": "~9.0.0" + } + }, + "node_modules/@playwright/test": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", + "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.25.0.tgz", + "integrity": "sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.25.0.tgz", + "integrity": "sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.25.0.tgz", + "integrity": "sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.25.0.tgz", + "integrity": "sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.25.0.tgz", + "integrity": "sha512-xpEIXhiP27EAylEpreCozozsxWQ2TJbOLSivGfXhU4G1TBVEYtUPi2pOZBnvGXHyOdLAUUhPnJzH3ah5cqF01g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.25.0.tgz", + "integrity": "sha512-sC5FsmZGlJv5dOcURrsnIK7ngc3Kirnx3as2XU9uER+zjfyqIjdcMVgzy4cOawhsssqzoAX19qmxgJ8a14Qrqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.25.0.tgz", + "integrity": "sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.25.0.tgz", + "integrity": "sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.25.0.tgz", + "integrity": "sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.25.0.tgz", + "integrity": "sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.25.0.tgz", + "integrity": "sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.25.0.tgz", + "integrity": "sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">=6.0.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.25.0.tgz", + "integrity": "sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ==", + "cpu": [ + "s390x" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">=6.0.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.25.0.tgz", + "integrity": "sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.25.0.tgz", + "integrity": "sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.25.0.tgz", + "integrity": "sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.25.0.tgz", + "integrity": "sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">= 8" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.25.0.tgz", + "integrity": "sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@opentdf/sdk": { - "version": "0.1.0", - "resolved": "file:../lib/opentdf-sdk-0.1.0.tgz", - "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", - "license": "BSD-3-Clause-Clear", - "dependencies": { - "axios": "^1.6.1", - "axios-retry": "^3.9.0", - "base64-js": "^1.5.1", - "browser-fs-access": "^0.34.1", - "buffer-crc32": "^0.2.13", - "dpop": "^1.2.0", - "eventemitter3": "^5.0.1", - "jose": "^4.14.4", - "json-canonicalize": "^1.0.6", - "streamsaver": "^2.0.6", - "uuid": "~9.0.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@playwright/test": { - "version": "1.36.2", + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@types/node": "*", - "playwright-core": "1.36.2" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "fsevents": "2.3.2" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/@polka/url": { - "version": "1.0.0-next.21", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/plugin-inject": { - "version": "5.0.3", + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "license": "MIT", "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "estree-walker": "^2.0.2", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "@babel/types": "^7.0.0" } }, - "node_modules/@rollup/pluginutils": { - "version": "5.0.2", + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/chai": { - "version": "4.3.5", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/chai-subset": { - "version": "1.3.3", + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "license": "MIT", "dependencies": { - "@types/chai": "*" + "@babel/types": "^7.20.7" } }, "node_modules/@types/estree": { - "version": "1.0.0", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true, "license": "MIT" }, @@ -719,7 +1349,9 @@ "node_modules/@types/node": { "version": "18.7.15", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/prop-types": { "version": "15.7.5", @@ -727,28 +1359,26 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.2.17", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.2.7", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "license": "MIT", "dependencies": { "@types/react": "*" } }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/semver": { "version": "7.5.0", "dev": true, @@ -943,141 +1573,165 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "4.0.4", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", + "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.22.9", - "@babel/plugin-transform-react-jsx-self": "^7.22.5", - "@babel/plugin-transform-react-jsx-source": "^7.22.5", - "react-refresh": "^0.14.0" + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0" + "vite": "^4.2.0 || ^5.0.0" } }, "node_modules/@vitest/expect": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.4.tgz", + "integrity": "sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "0.33.0", - "@vitest/utils": "0.33.0", - "chai": "^4.3.7" + "@vitest/spy": "2.1.4", + "@vitest/utils": "2.1.4", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner": { - "version": "0.33.0", + "node_modules/@vitest/mocker": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.4.tgz", + "integrity": "sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "0.33.0", - "p-limit": "^4.0.0", - "pathe": "^1.1.1" + "@vitest/spy": "2.1.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" }, "funding": { "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "4.0.0", + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/estree": "^1.0.0" } }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", + "node_modules/@vitest/pretty-format": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.4.tgz", + "integrity": "sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12.20" + "dependencies": { + "tinyrainbow": "^1.2.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/snapshot": { - "version": "0.33.0", + "node_modules/@vitest/runner": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.4.tgz", + "integrity": "sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==", "dev": true, "license": "MIT", "dependencies": { - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "pretty-format": "^29.5.0" + "@vitest/utils": "2.1.4", + "pathe": "^1.1.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/snapshot/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true, - "license": "MIT" - }, - "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.1", + "node_modules/@vitest/snapshot": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.4.tgz", + "integrity": "sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@vitest/pretty-format": "2.1.4", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" }, - "engines": { - "node": ">=12" + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.4.tgz", + "integrity": "sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^2.1.1" + "tinyspy": "^3.0.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/ui": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-2.1.4.tgz", + "integrity": "sha512-Zd9e5oU063c+j9N9XzGJagCLNvG71x/2tOme3Js4JEZKX55zsgxhJwUgLI8hkN6NjMLpdJO8d7nVUUuPGAA58Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "0.33.0", - "fast-glob": "^3.3.0", - "fflate": "^0.8.0", - "flatted": "^3.2.7", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "sirv": "^2.0.3" + "@vitest/utils": "2.1.4", + "fflate": "^0.8.2", + "flatted": "^3.3.1", + "pathe": "^1.1.2", + "sirv": "^3.0.0", + "tinyglobby": "^0.2.9", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": ">=0.30.1 <1" + "vitest": "2.1.4" } }, "node_modules/@vitest/utils": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.4.tgz", + "integrity": "sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==", "dev": true, "license": "MIT", "dependencies": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" + "@vitest/pretty-format": "2.1.4", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -1107,14 +1761,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv": { "version": "6.12.6", "dev": true, @@ -1176,11 +1822,13 @@ "license": "MIT" }, "node_modules/assertion-error": { - "version": "1.1.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=12" } }, "node_modules/asynckit": { @@ -1262,7 +1910,9 @@ "license": "Apache-2.0" }, "node_modules/browserslist": { - "version": "4.21.10", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -1280,10 +1930,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -1326,6 +1976,8 @@ }, "node_modules/cac": { "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, "license": "MIT", "engines": { @@ -1341,7 +1993,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001518", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "dev": true, "funding": [ { @@ -1360,20 +2014,20 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "4.3.7", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", "dev": true, "license": "MIT", "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" } }, "node_modules/chalk": { @@ -1390,15 +2044,19 @@ } }, "node_modules/check-error": { - "version": "1.0.2", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">= 16" } }, "node_modules/clsx": { - "version": "2.0.0", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", "engines": { "node": ">=6" @@ -1435,7 +2093,9 @@ "license": "MIT" }, "node_modules/convert-source-map": { - "version": "1.9.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, @@ -1458,11 +2118,13 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.4", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1482,12 +2144,11 @@ } }, "node_modules/deep-eql": { - "version": "4.1.3", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, "engines": { "node": ">=6" } @@ -1515,14 +2176,6 @@ "wrappy": "1" } }, - "node_modules/diff-sequences": { - "version": "29.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "dev": true, @@ -1555,12 +2208,16 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.477", + "version": "1.5.56", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", + "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", "dev": true, "license": "ISC" }, "node_modules/esbuild": { - "version": "0.18.11", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1571,32 +2228,35 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.11", - "@esbuild/android-arm64": "0.18.11", - "@esbuild/android-x64": "0.18.11", - "@esbuild/darwin-arm64": "0.18.11", - "@esbuild/darwin-x64": "0.18.11", - "@esbuild/freebsd-arm64": "0.18.11", - "@esbuild/freebsd-x64": "0.18.11", - "@esbuild/linux-arm": "0.18.11", - "@esbuild/linux-arm64": "0.18.11", - "@esbuild/linux-ia32": "0.18.11", - "@esbuild/linux-loong64": "0.18.11", - "@esbuild/linux-mips64el": "0.18.11", - "@esbuild/linux-ppc64": "0.18.11", - "@esbuild/linux-riscv64": "0.18.11", - "@esbuild/linux-s390x": "0.18.11", - "@esbuild/linux-x64": "0.18.11", - "@esbuild/netbsd-x64": "0.18.11", - "@esbuild/openbsd-x64": "0.18.11", - "@esbuild/sunos-x64": "0.18.11", - "@esbuild/win32-arm64": "0.18.11", - "@esbuild/win32-ia32": "0.18.11", - "@esbuild/win32-x64": "0.18.11" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escalade": { - "version": "3.1.1", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -1855,6 +2515,16 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "license": "MIT" }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "dev": true, @@ -1927,7 +2597,9 @@ } }, "node_modules/fflate": { - "version": "0.8.0", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", "dev": true, "license": "MIT" }, @@ -1983,7 +2655,9 @@ } }, "node_modules/flatted": { - "version": "3.2.7", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, "license": "ISC" }, @@ -2045,20 +2719,14 @@ }, "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-func-name": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/glob": { "version": "7.2.3", "dev": true, @@ -2091,6 +2759,8 @@ }, "node_modules/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, "license": "MIT", "engines": { @@ -2304,14 +2974,16 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-canonicalize": { @@ -2337,6 +3009,8 @@ }, "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": { @@ -2346,11 +3020,6 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "dev": true, - "license": "MIT" - }, "node_modules/levn": { "version": "0.4.1", "dev": true, @@ -2399,17 +3068,6 @@ "semver": "bin/semver" } }, - "node_modules/local-pkg": { - "version": "0.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/locate-path": { "version": "6.0.0", "dev": true, @@ -2440,12 +3098,11 @@ } }, "node_modules/loupe": { - "version": "2.3.6", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.0" - } + "license": "MIT" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -2459,14 +3116,13 @@ } }, "node_modules/magic-string": { - "version": "0.27.0", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/merge2": { @@ -2478,11 +3134,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -2537,19 +3195,10 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mlly": { - "version": "1.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.9.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "ufo": "^1.1.2" - } - }, "node_modules/mrmime": { - "version": "1.0.1", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, "license": "MIT", "engines": { @@ -2557,12 +3206,16 @@ } }, "node_modules/ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.6", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -2628,7 +3281,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true, "license": "MIT" }, @@ -2794,20 +3449,26 @@ } }, "node_modules/pathe": { - "version": "1.1.1", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true, "license": "MIT" }, "node_modules/pathval": { - "version": "1.1.1", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">= 14.16" } }, "node_modules/picocolors": { - "version": "1.0.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, @@ -2822,44 +3483,42 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pkg-types": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, "node_modules/playwright": { - "version": "1.36.2", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, - "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.36.2" + "playwright-core": "1.48.2" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.36.2", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/postcss": { - "version": "8.4.31", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -2877,9 +3536,9 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -2894,7 +3553,9 @@ } }, "node_modules/prettier": { - "version": "3.0.0", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "license": "MIT", "bin": { @@ -2907,30 +3568,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/pretty-format": { - "version": "29.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -2965,7 +3602,9 @@ "license": "MIT" }, "node_modules/react": { - "version": "18.2.0", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -2975,23 +3614,22 @@ } }, "node_modules/react-dom": { - "version": "18.2.0", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, - "node_modules/react-is": { - "version": "18.2.0", - "dev": true, - "license": "MIT" - }, "node_modules/react-refresh": { - "version": "0.14.0", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true, "license": "MIT", "engines": { @@ -3098,10 +3736,13 @@ } }, "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -3136,7 +3777,9 @@ } }, "node_modules/scheduler": { - "version": "0.23.0", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -3177,20 +3820,24 @@ }, "node_modules/siginfo": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/sirv": { - "version": "2.0.3", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", "dev": true, "license": "MIT", "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", "totalist": "^3.0.0" }, "engines": { - "node": ">= 10" + "node": ">=18" } }, "node_modules/slash": { @@ -3210,7 +3857,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -3272,11 +3921,15 @@ }, "node_modules/stackback": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/std-env": { - "version": "3.3.3", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "dev": true, "license": "MIT" }, @@ -3314,17 +3967,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.8.2" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, @@ -3353,32 +3995,89 @@ "license": "MIT" }, "node_modules/tinybench": { - "version": "2.5.0", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tinypool": { - "version": "0.6.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": "^18.0.0 || >=20.0.0" } }, - "node_modules/tinyspy": { - "version": "2.1.1", + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=14.0.0" } }, "node_modules/to-regex-range": { @@ -3396,6 +4095,8 @@ }, "node_modules/totalist": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", "engines": { @@ -3432,14 +4133,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.20.2", "dev": true, @@ -3463,13 +4156,10 @@ "node": ">=14.17" } }, - "node_modules/ufo": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, "node_modules/update-browserslist-db": { - "version": "1.0.11", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -3487,8 +4177,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -3533,33 +4223,34 @@ } }, "node_modules/vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -3577,6 +4268,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -3589,80 +4283,132 @@ } }, "node_modules/vite-node": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.4.tgz", + "integrity": "sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.4", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0" + "debug": "^4.3.7", + "pathe": "^1.1.2", + "vite": "^5.0.0" }, "bin": { "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=v14.18.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/vitest": { - "version": "0.33.0", + "node_modules/vite/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/vite/node_modules/rollup": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.25.0.tgz", + "integrity": "sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==", "dev": true, "license": "MIT", "dependencies": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.33.0", - "@vitest/runner": "0.33.0", - "@vitest/snapshot": "0.33.0", - "@vitest/spy": "0.33.0", - "@vitest/utils": "0.33.0", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", - "chai": "^4.3.7", - "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.6.0", - "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.33.0", - "why-is-node-running": "^2.2.2" + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.25.0", + "@rollup/rollup-android-arm64": "4.25.0", + "@rollup/rollup-darwin-arm64": "4.25.0", + "@rollup/rollup-darwin-x64": "4.25.0", + "@rollup/rollup-freebsd-arm64": "4.25.0", + "@rollup/rollup-freebsd-x64": "4.25.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.25.0", + "@rollup/rollup-linux-arm-musleabihf": "4.25.0", + "@rollup/rollup-linux-arm64-gnu": "4.25.0", + "@rollup/rollup-linux-arm64-musl": "4.25.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.25.0", + "@rollup/rollup-linux-riscv64-gnu": "4.25.0", + "@rollup/rollup-linux-s390x-gnu": "4.25.0", + "@rollup/rollup-linux-x64-gnu": "4.25.0", + "@rollup/rollup-linux-x64-musl": "4.25.0", + "@rollup/rollup-win32-arm64-msvc": "4.25.0", + "@rollup/rollup-win32-ia32-msvc": "4.25.0", + "@rollup/rollup-win32-x64-msvc": "4.25.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/vitest": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.4.tgz", + "integrity": "sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.4", + "@vitest/mocker": "2.1.4", + "@vitest/pretty-format": "^2.1.4", + "@vitest/runner": "2.1.4", + "@vitest/snapshot": "2.1.4", + "@vitest/spy": "2.1.4", + "@vitest/utils": "2.1.4", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.4", + "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": ">=v14.18.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@vitest/browser": "*", - "@vitest/ui": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.4", + "@vitest/ui": "2.1.4", "happy-dom": "*", - "jsdom": "*", - "playwright": "*", - "safaridriver": "*", - "webdriverio": "*" + "jsdom": "*" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, + "@types/node": { + "optional": true + }, "@vitest/browser": { "optional": true }, @@ -3674,34 +4420,9 @@ }, "jsdom": { "optional": true - }, - "playwright": { - "optional": true - }, - "safaridriver": { - "optional": true - }, - "webdriverio": { - "optional": true } } }, - "node_modules/vitest/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true, - "license": "MIT" - }, - "node_modules/vitest/node_modules/magic-string": { - "version": "0.30.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/web-streams-polyfill": { "version": "3.2.1", "license": "MIT", @@ -3725,7 +4446,9 @@ } }, "node_modules/why-is-node-running": { - "version": "2.2.2", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -3767,77 +4490,93 @@ "dev": true }, "@ampproject/remapping": { - "version": "2.2.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, "@babel/code-frame": { - "version": "7.22.13", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.22.9", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true }, "@babel/core": { - "version": "7.22.9", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "dependencies": { "semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } }, "@babel/generator": { - "version": "7.23.0", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, "requires": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" } }, "@babel/helper-compilation-targets": { - "version": "7.22.9", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, "dependencies": { "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, "requires": { "yallist": "^3.0.2" @@ -3845,117 +4584,98 @@ }, "semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "yallist": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, "@babel/helper-module-imports": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" } }, "@babel/helper-module-transforms": { - "version": "7.22.9", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" } }, "@babel/helper-plugin-utils": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true }, - "@babel/helper-simple-access": { - "version": "7.22.5", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, "@babel/helper-string-parser": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.20", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true }, "@babel/helpers": { - "version": "7.22.6", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" } }, - "@babel/highlight": { - "version": "7.22.20", + "@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/types": "^7.26.0" } }, - "@babel/parser": { - "version": "7.23.0", - "dev": true - }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" } }, "@babel/runtime": { @@ -3966,42 +4686,200 @@ "regenerator-runtime": "^0.14.0" } }, - "@babel/template": { - "version": "7.22.15", + "@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + } + }, + "@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + } + }, + "@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } + "optional": true }, - "@babel/traverse": { - "version": "7.23.2", + "@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } + "optional": true }, - "@babel/types": { - "version": "7.23.0", + "@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } + "optional": true }, - "@esbuild/darwin-arm64": { - "version": "0.18.11", + "@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "dev": true, "optional": true }, @@ -4061,40 +4939,43 @@ "version": "1.2.1", "dev": true }, - "@jest/schemas": { - "version": "29.6.0", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.27.8" - } - }, "@jridgewell/gen-mapping": { - "version": "0.3.3", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { - "version": "3.1.0", + "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 }, "@jridgewell/set-array": { - "version": "1.1.2", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.18", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@nodelib/fs.scandir": { @@ -4119,7 +5000,7 @@ }, "@opentdf/sdk": { "version": "file:../lib/opentdf-sdk-0.1.0.tgz", - "integrity": "sha512-aqQrsIuXjY9zpC5mPbeZRaer8UnfqoSvyGvGUHXgFaiGG1a4HuLkCPn8CIdoQKDDAs5i5L52SJ4cG9kStKa3/A==", + "integrity": "sha512-x4uSWK8u5CQe5st/tseiPah3PUs8s/CGeFIbf+7I6v8hQ83R0UpLNn8O0k7k46rE0f2z564EYRkpZlZljI2A3w==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", @@ -4135,25 +5016,29 @@ } }, "@playwright/test": { - "version": "1.36.2", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", "dev": true, "requires": { - "@types/node": "*", - "fsevents": "2.3.2", - "playwright-core": "1.36.2" + "playwright": "1.48.2" } }, "@polka/url": { - "version": "1.0.0-next.21", + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", "dev": true }, "@rollup/plugin-inject": { - "version": "5.0.3", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", + "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", "estree-walker": "^2.0.2", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3" } }, "@rollup/pluginutils": { @@ -4165,23 +5050,177 @@ "picomatch": "^2.3.1" } }, - "@sinclair/typebox": { - "version": "0.27.8", - "dev": true + "@rollup/rollup-android-arm-eabi": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.25.0.tgz", + "integrity": "sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA==", + "dev": true, + "optional": true }, - "@types/chai": { - "version": "4.3.5", - "dev": true + "@rollup/rollup-android-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.25.0.tgz", + "integrity": "sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.25.0.tgz", + "integrity": "sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.25.0.tgz", + "integrity": "sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.25.0.tgz", + "integrity": "sha512-xpEIXhiP27EAylEpreCozozsxWQ2TJbOLSivGfXhU4G1TBVEYtUPi2pOZBnvGXHyOdLAUUhPnJzH3ah5cqF01g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.25.0.tgz", + "integrity": "sha512-sC5FsmZGlJv5dOcURrsnIK7ngc3Kirnx3as2XU9uER+zjfyqIjdcMVgzy4cOawhsssqzoAX19qmxgJ8a14Qrqw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.25.0.tgz", + "integrity": "sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.25.0.tgz", + "integrity": "sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.25.0.tgz", + "integrity": "sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.25.0.tgz", + "integrity": "sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.25.0.tgz", + "integrity": "sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.25.0.tgz", + "integrity": "sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.25.0.tgz", + "integrity": "sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.25.0.tgz", + "integrity": "sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.25.0.tgz", + "integrity": "sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.25.0.tgz", + "integrity": "sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.25.0.tgz", + "integrity": "sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.25.0.tgz", + "integrity": "sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg==", + "dev": true, + "optional": true + }, + "@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } }, - "@types/chai-subset": { - "version": "1.3.3", + "@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "requires": { - "@types/chai": "*" + "@babel/types": "^7.20.7" } }, "@types/estree": { - "version": "1.0.0", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "@types/json-schema": { @@ -4190,32 +5229,33 @@ }, "@types/node": { "version": "18.7.15", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@types/prop-types": { "version": "15.7.5", "dev": true }, "@types/react": { - "version": "18.2.17", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "dev": true, "requires": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, "@types/react-dom": { - "version": "18.2.7", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "requires": { "@types/react": "*" } }, - "@types/scheduler": { - "version": "0.16.2", - "dev": true - }, "@types/semver": { "version": "7.5.0", "dev": true @@ -4312,95 +5352,115 @@ } }, "@vitejs/plugin-react": { - "version": "4.0.4", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", + "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", "dev": true, "requires": { - "@babel/core": "^7.22.9", - "@babel/plugin-transform-react-jsx-self": "^7.22.5", - "@babel/plugin-transform-react-jsx-source": "^7.22.5", - "react-refresh": "^0.14.0" + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" } }, "@vitest/expect": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.4.tgz", + "integrity": "sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==", "dev": true, "requires": { - "@vitest/spy": "0.33.0", - "@vitest/utils": "0.33.0", - "chai": "^4.3.7" + "@vitest/spy": "2.1.4", + "@vitest/utils": "2.1.4", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" } }, - "@vitest/runner": { - "version": "0.33.0", + "@vitest/mocker": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.4.tgz", + "integrity": "sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==", "dev": true, "requires": { - "@vitest/utils": "0.33.0", - "p-limit": "^4.0.0", - "pathe": "^1.1.1" + "@vitest/spy": "2.1.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" }, "dependencies": { - "p-limit": { - "version": "4.0.0", + "estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "requires": { - "yocto-queue": "^1.0.0" + "@types/estree": "^1.0.0" } - }, - "yocto-queue": { - "version": "1.0.0", - "dev": true } } }, + "@vitest/pretty-format": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.4.tgz", + "integrity": "sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==", + "dev": true, + "requires": { + "tinyrainbow": "^1.2.0" + } + }, + "@vitest/runner": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.4.tgz", + "integrity": "sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==", + "dev": true, + "requires": { + "@vitest/utils": "2.1.4", + "pathe": "^1.1.2" + } + }, "@vitest/snapshot": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.4.tgz", + "integrity": "sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==", "dev": true, "requires": { - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "pretty-format": "^29.5.0" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true - }, - "magic-string": { - "version": "0.30.1", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } + "@vitest/pretty-format": "2.1.4", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" } }, "@vitest/spy": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.4.tgz", + "integrity": "sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==", "dev": true, "requires": { - "tinyspy": "^2.1.1" + "tinyspy": "^3.0.2" } }, "@vitest/ui": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-2.1.4.tgz", + "integrity": "sha512-Zd9e5oU063c+j9N9XzGJagCLNvG71x/2tOme3Js4JEZKX55zsgxhJwUgLI8hkN6NjMLpdJO8d7nVUUuPGAA58Q==", "dev": true, "requires": { - "@vitest/utils": "0.33.0", - "fast-glob": "^3.3.0", - "fflate": "^0.8.0", - "flatted": "^3.2.7", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "sirv": "^2.0.3" + "@vitest/utils": "2.1.4", + "fflate": "^0.8.2", + "flatted": "^3.3.1", + "pathe": "^1.1.2", + "sirv": "^3.0.0", + "tinyglobby": "^0.2.9", + "tinyrainbow": "^1.2.0" } }, "@vitest/utils": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.4.tgz", + "integrity": "sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==", "dev": true, "requires": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" + "@vitest/pretty-format": "2.1.4", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" } }, "abbrev": { @@ -4416,10 +5476,6 @@ "dev": true, "requires": {} }, - "acorn-walk": { - "version": "8.2.0", - "dev": true - }, "ajv": { "version": "6.12.6", "dev": true, @@ -4458,7 +5514,9 @@ "dev": true }, "assertion-error": { - "version": "1.1.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true }, "asynckit": { @@ -4515,13 +5573,15 @@ "integrity": "sha512-HPaRf2yimp8kWSuWJXc8Mi78dPbDzfduA+Gyq14H4jlMvd6XNfIRm36Y2yRLaa4x0gwcGuepj4zf14oiTlxrxQ==" }, "browserslist": { - "version": "4.21.10", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" } }, "buffer": { @@ -4539,6 +5599,8 @@ }, "cac": { "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true }, "callsites": { @@ -4546,20 +5608,22 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001518", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "dev": true }, "chai": { - "version": "4.3.7", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", "dev": true, "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" } }, "chalk": { @@ -4572,11 +5636,15 @@ } }, "check-error": { - "version": "1.0.2", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true }, "clsx": { - "version": "2.0.0" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" }, "color-convert": { "version": "1.9.3", @@ -4602,7 +5670,9 @@ "dev": true }, "convert-source-map": { - "version": "1.9.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "cross-spawn": { @@ -4619,10 +5689,12 @@ "dev": true }, "debug": { - "version": "4.3.4", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "debuglog": { @@ -4630,11 +5702,10 @@ "dev": true }, "deep-eql": { - "version": "4.1.3", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true }, "deep-is": { "version": "0.1.4", @@ -4653,10 +5724,6 @@ "wrappy": "1" } }, - "diff-sequences": { - "version": "29.4.3", - "dev": true - }, "dir-glob": { "version": "3.0.1", "dev": true, @@ -4677,39 +5744,46 @@ "integrity": "sha512-+Cus+OlLk9uFWbPZX/RsLpMviYAmyJpJpooto2NDQ0lnk0/S2TblPunC4nVtETOxCIsXvu4YILIOPC7LIHHXIg==" }, "electron-to-chromium": { - "version": "1.4.477", + "version": "1.5.56", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", + "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", "dev": true }, "esbuild": { - "version": "0.18.11", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.18.11", - "@esbuild/android-arm64": "0.18.11", - "@esbuild/android-x64": "0.18.11", - "@esbuild/darwin-arm64": "0.18.11", - "@esbuild/darwin-x64": "0.18.11", - "@esbuild/freebsd-arm64": "0.18.11", - "@esbuild/freebsd-x64": "0.18.11", - "@esbuild/linux-arm": "0.18.11", - "@esbuild/linux-arm64": "0.18.11", - "@esbuild/linux-ia32": "0.18.11", - "@esbuild/linux-loong64": "0.18.11", - "@esbuild/linux-mips64el": "0.18.11", - "@esbuild/linux-ppc64": "0.18.11", - "@esbuild/linux-riscv64": "0.18.11", - "@esbuild/linux-s390x": "0.18.11", - "@esbuild/linux-x64": "0.18.11", - "@esbuild/netbsd-x64": "0.18.11", - "@esbuild/openbsd-x64": "0.18.11", - "@esbuild/sunos-x64": "0.18.11", - "@esbuild/win32-arm64": "0.18.11", - "@esbuild/win32-ia32": "0.18.11", - "@esbuild/win32-x64": "0.18.11" + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "escalade": { - "version": "3.1.1", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-string-regexp": { @@ -4866,6 +5940,12 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, + "expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "dev": true @@ -4914,7 +5994,9 @@ } }, "fflate": { - "version": "0.8.0", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", "dev": true }, "file-entry-cache": { @@ -4950,7 +6032,9 @@ } }, "flatted": { - "version": "3.2.7", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "follow-redirects": { @@ -4983,10 +6067,8 @@ }, "gensync": { "version": "1.0.0-beta.2", - "dev": true - }, - "get-func-name": { - "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "glob": { @@ -5010,6 +6092,8 @@ }, "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": { @@ -5132,7 +6216,9 @@ } }, "jsesc": { - "version": "2.5.2", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true }, "json-canonicalize": { @@ -5154,10 +6240,8 @@ }, "json5": { "version": "2.2.3", - "dev": true - }, - "jsonc-parser": { - "version": "3.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "levn": { @@ -5197,10 +6281,6 @@ } } }, - "local-pkg": { - "version": "0.4.3", - "dev": true - }, "locate-path": { "version": "6.0.0", "dev": true, @@ -5219,11 +6299,10 @@ } }, "loupe": { - "version": "2.3.6", - "dev": true, - "requires": { - "get-func-name": "^2.0.0" - } + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", + "dev": true }, "lru-cache": { "version": "6.0.0", @@ -5233,10 +6312,12 @@ } }, "magic-string": { - "version": "0.27.0", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "merge2": { @@ -5244,10 +6325,12 @@ "dev": true }, "micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, @@ -5282,26 +6365,22 @@ "minimist": "^1.2.6" } }, - "mlly": { - "version": "1.4.0", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "ufo": "^1.1.2" - } - }, "mrmime": { - "version": "1.0.1", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "nanoid": { - "version": "3.3.6", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true }, "native-file-system-adapter": { @@ -5325,7 +6404,9 @@ "optional": true }, "node-releases": { - "version": "2.0.13", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "nopt": { @@ -5433,48 +6514,52 @@ "dev": true }, "pathe": { - "version": "1.1.1", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true }, "pathval": { - "version": "1.1.1", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true }, "picocolors": { - "version": "1.0.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { "version": "2.3.1", "dev": true }, - "pkg-types": { - "version": "1.0.3", - "dev": true, - "requires": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, "playwright": { - "version": "1.36.2", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, "requires": { - "playwright-core": "1.36.2" + "fsevents": "2.3.2", + "playwright-core": "1.48.2" } }, "playwright-core": { - "version": "1.36.2", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true }, "postcss": { - "version": "8.4.31", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "requires": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" } }, "prelude-ls": { @@ -5482,24 +6567,11 @@ "dev": true }, "prettier": { - "version": "3.0.0", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true }, - "pretty-format": { - "version": "29.6.1", - "dev": true, - "requires": { - "@jest/schemas": "^29.6.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "dev": true - } - } - }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -5514,24 +6586,26 @@ "dev": true }, "react": { - "version": "18.2.0", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "requires": { "loose-envify": "^1.1.0" } }, "react-dom": { - "version": "18.2.0", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "requires": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" } }, - "react-is": { - "version": "18.2.0", - "dev": true - }, "react-refresh": { - "version": "0.14.0", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true }, "read-installed": { @@ -5603,10 +6677,12 @@ } }, "rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", "dev": true, + "optional": true, + "peer": true, "requires": { "fsevents": "~2.3.2" } @@ -5619,7 +6695,9 @@ } }, "scheduler": { - "version": "0.23.0", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "requires": { "loose-envify": "^1.1.0" } @@ -5644,14 +6722,18 @@ }, "siginfo": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, "sirv": { - "version": "2.0.3", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", "dev": true, "requires": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, @@ -5664,7 +6746,9 @@ "dev": true }, "source-map-js": { - "version": "1.0.2", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true }, "spdx-compare": { @@ -5715,10 +6799,14 @@ }, "stackback": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, "std-env": { - "version": "3.3.3", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "dev": true }, "streamsaver": { @@ -5737,13 +6825,6 @@ "version": "3.1.1", "dev": true }, - "strip-literal": { - "version": "1.0.1", - "dev": true, - "requires": { - "acorn": "^8.8.2" - } - }, "supports-color": { "version": "5.5.0", "dev": true, @@ -5760,19 +6841,58 @@ "dev": true }, "tinybench": { - "version": "2.5.0", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true + }, + "tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", "dev": true }, + "tinyglobby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "requires": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "dependencies": { + "fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true + } + } + }, "tinypool": { - "version": "0.6.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", "dev": true }, - "tinyspy": { - "version": "2.1.1", + "tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", "dev": true }, - "to-fast-properties": { - "version": "2.0.0", + "tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true }, "to-regex-range": { @@ -5786,6 +6906,8 @@ }, "totalist": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true }, "treeify": { @@ -5804,10 +6926,6 @@ "prelude-ls": "^1.2.1" } }, - "type-detect": { - "version": "4.0.8", - "dev": true - }, "type-fest": { "version": "0.20.2", "dev": true @@ -5816,16 +6934,14 @@ "version": "5.1.6", "dev": true }, - "ufo": { - "version": "1.1.2", - "dev": true - }, "update-browserslist-db": { - "version": "1.0.11", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" } }, "uri-js": { @@ -5853,70 +6969,92 @@ } }, "vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, "requires": { - "esbuild": "^0.18.10", - "fsevents": "~2.3.2", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.21.3", + "fsevents": "~2.3.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "dependencies": { + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "rollup": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.25.0.tgz", + "integrity": "sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.25.0", + "@rollup/rollup-android-arm64": "4.25.0", + "@rollup/rollup-darwin-arm64": "4.25.0", + "@rollup/rollup-darwin-x64": "4.25.0", + "@rollup/rollup-freebsd-arm64": "4.25.0", + "@rollup/rollup-freebsd-x64": "4.25.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.25.0", + "@rollup/rollup-linux-arm-musleabihf": "4.25.0", + "@rollup/rollup-linux-arm64-gnu": "4.25.0", + "@rollup/rollup-linux-arm64-musl": "4.25.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.25.0", + "@rollup/rollup-linux-riscv64-gnu": "4.25.0", + "@rollup/rollup-linux-s390x-gnu": "4.25.0", + "@rollup/rollup-linux-x64-gnu": "4.25.0", + "@rollup/rollup-linux-x64-musl": "4.25.0", + "@rollup/rollup-win32-arm64-msvc": "4.25.0", + "@rollup/rollup-win32-ia32-msvc": "4.25.0", + "@rollup/rollup-win32-x64-msvc": "4.25.0", + "@types/estree": "1.0.6", + "fsevents": "~2.3.2" + } + } } }, "vite-node": { - "version": "0.33.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.4.tgz", + "integrity": "sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==", "dev": true, "requires": { "cac": "^6.7.14", - "debug": "^4.3.4", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0" + "debug": "^4.3.7", + "pathe": "^1.1.2", + "vite": "^5.0.0" } }, "vitest": { - "version": "0.33.0", - "dev": true, - "requires": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.33.0", - "@vitest/runner": "0.33.0", - "@vitest/snapshot": "0.33.0", - "@vitest/spy": "0.33.0", - "@vitest/utils": "0.33.0", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", - "chai": "^4.3.7", - "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.6.0", - "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.33.0", - "why-is-node-running": "^2.2.2" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true - }, - "magic-string": { - "version": "0.30.1", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.4.tgz", + "integrity": "sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==", + "dev": true, + "requires": { + "@vitest/expect": "2.1.4", + "@vitest/mocker": "2.1.4", + "@vitest/pretty-format": "^2.1.4", + "@vitest/runner": "2.1.4", + "@vitest/snapshot": "2.1.4", + "@vitest/spy": "2.1.4", + "@vitest/utils": "2.1.4", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.4", + "why-is-node-running": "^2.3.0" } }, "web-streams-polyfill": { @@ -5931,7 +7069,9 @@ } }, "why-is-node-running": { - "version": "2.2.2", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "requires": { "siginfo": "^2.0.0", diff --git a/web-app/package.json b/web-app/package.json index 905eec23..4b38d5de 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -16,29 +16,29 @@ }, "dependencies": { "@opentdf/sdk": "file:../lib/opentdf-sdk-0.1.0.tgz", - "clsx": "^2.0.0", + "clsx": "^2.1.1", "native-file-system-adapter": "^3.0.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "^18.3.1", + "react-dom": "^18.3.1" }, "devDependencies": { - "@playwright/test": "^1.36.2", - "@rollup/plugin-inject": "^5.0.3", - "@types/react": "^18.2.17", - "@types/react-dom": "^18.2.7", + "@playwright/test": "^1.48.2", + "@rollup/plugin-inject": "^5.0.5", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "@types/wicg-file-system-access": "^2023.10.5", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", - "@vitejs/plugin-react": "^4.0.4", - "@vitest/ui": "^0.33.0", + "@vitejs/plugin-react": "^4.3.3", + "@vitest/ui": "^2.1.4", "buffer": "^6.0.3", - "eslint": "^8.46.0", + "eslint": "^8.9.0", "eslint-config-prettier": "^8.9.0", "license-checker": "^25.0.1", - "playwright": "^1.36.2", - "prettier": "^3.0.0", + "playwright": "^1.48.2", + "prettier": "^3.3.3", "typescript": "^5.1.6", - "vite": "^4.4.7", - "vitest": "^0.33.0" + "vite": "^5.4.11", + "vitest": "^2.1.4" } } diff --git a/web-app/tests/package-lock.json b/web-app/tests/package-lock.json index f2663acc..dc084f65 100644 --- a/web-app/tests/package-lock.json +++ b/web-app/tests/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "devDependencies": { "@playwright/test": "^1.35.1", - "send": "^0.18.0" + "send": "^1.1.0" } }, "node_modules/@playwright/test": { @@ -29,20 +29,23 @@ } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -69,10 +72,11 @@ "dev": true }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -137,16 +141,27 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "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, - "bin": { - "mime": "cli.js" + "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": ">=4" + "node": ">= 0.6" } }, "node_modules/ms": { @@ -207,27 +222,27 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", + "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "debug": "^4.3.5", + "destroy": "^1.2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "http-errors": "^2.0.0", + "mime-types": "^2.1.35", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" } }, "node_modules/setprototypeof": { @@ -266,20 +281,12 @@ } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } + "ms": "^2.1.3" } }, "depd": { @@ -301,9 +308,9 @@ "dev": true }, "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true }, "escape-html": { @@ -350,12 +357,21 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "mime-db": { + "version": "1.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==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -394,24 +410,23 @@ "dev": true }, "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", + "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", "dev": true, "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "debug": "^4.3.5", + "destroy": "^1.2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "http-errors": "^2.0.0", + "mime-types": "^2.1.35", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" } }, "setprototypeof": { diff --git a/web-app/tests/package.json b/web-app/tests/package.json index 796e39e3..c8a1863f 100644 --- a/web-app/tests/package.json +++ b/web-app/tests/package.json @@ -12,6 +12,6 @@ "license": "ISC", "devDependencies": { "@playwright/test": "^1.35.1", - "send": "^0.18.0" + "send": "^1.1.0" } }