diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9977224..34bfca4 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,5 +13,15 @@ updates: directory: "/" schedule: interval: "weekly" - cooldown: - default-days: 15 + cooldown: + default-days: 15 + groups: + dev-dependencies: + dependency-type: "development" + update-types: + - "minor" + - "patch" + prod-dependencies: + dependency-type: "production" + update-types: + - "patch" diff --git a/.github/package.json b/.github/package.json index 15ae830..4acff79 100644 --- a/.github/package.json +++ b/.github/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/github-workflows", - "version": "0.3.2", + "version": "0.4.0", "private": true, "engines": { "node": ">=24.0" diff --git a/.github/workflows/test-dco.yml b/.github/workflows/test-dco.yml index 150de0c..e9c11ef 100644 --- a/.github/workflows/test-dco.yml +++ b/.github/workflows/test-dco.yml @@ -11,5 +11,5 @@ jobs: name: Tests (dco) runs-on: ubuntu-latest steps: - - name: Check for Developer Certificate of Origin (DCO) compiance + - name: Check for Developer Certificate of Origin (DCO) compliance uses: KineticCafe/actions-dco@6e1652ef3027ce128e65e6edd215ae053350bd16 # v2.1.1 diff --git a/.github/workflows/test-lint.yml b/.github/workflows/test-lint.yml index 8ae38e6..cfcb96e 100644 --- a/.github/workflows/test-lint.yml +++ b/.github/workflows/test-lint.yml @@ -27,4 +27,4 @@ jobs: npm ci --ignore-scripts - name: Linting run: | - ./node_modules/.bin/biome ci --no-errors-on-unmatched + npm run test:lint diff --git a/.github/workflows/test-sast.yml b/.github/workflows/test-sast.yml index 042b019..3a5e3b7 100644 --- a/.github/workflows/test-sast.yml +++ b/.github/workflows/test-sast.yml @@ -73,6 +73,28 @@ jobs: # ort-cli-args: "-P ort.analyzer.enabledPackageManagers=NPM" # fail-on: "violations" + license: + name: "License headers" + runs-on: ubuntu-latest + if: (github.actor != 'dependabot[bot]') + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Setup Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: ${{ env.NODE_VERSION }} + registry-url: https://registry.npmjs.org + cache: npm + - name: Install dependencies + run: | + npm ci --ignore-scripts + - name: License check + run: | + npm run test:sast:license + lockfile: name: "lockfile-lint: SAST package-lock.json" runs-on: ubuntu-latest diff --git a/license.json b/.license.config.json similarity index 88% rename from license.json rename to .license.config.json index 95848b7..ee3e249 100644 --- a/license.json +++ b/.license.config.json @@ -1,5 +1,5 @@ { - "license": "license.template", + "license": ".license.template", "licenseFormats": { "js|ts": { "eachLine": { @@ -16,7 +16,7 @@ "commitlint.config.cjs", "docs/**/*", "LICENSE", - "license.template", + ".license.template", "**/.gitignore", "**/*.fuzz.js", "**/*.perf.js", diff --git a/license.template b/.license.template similarity index 100% rename from license.template rename to .license.template diff --git a/package-lock.json b/package-lock.json index 9a1921a..58899c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@datastream/monorepo", - "version": "0.3.2", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@datastream/monorepo", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "workspaces": [ "packages/*", @@ -30,7 +30,7 @@ }, ".github": { "name": "@datastream/github-workflows", - "version": "0.3.2", + "version": "0.4.0", "devDependencies": { "license-check-and-add": "4.0.5", "lockfile-lint": "5.0.0" @@ -273,52 +273,52 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1030.0.tgz", - "integrity": "sha512-8VVoVOy7bTERDwY1emGktBMB3f7eTDbjvb0RqRR1rtCdGGtelocdGJeazkZvWS3yQmErN5GK6Puvq+4Uq6BHqw==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1032.0.tgz", + "integrity": "sha512-pzvsXRUrlq5q0HTmpEUF07koRw1cikeWY4M5brPQimMBZx5VahiIVyacNwD1tr40rKwo72SyFDToBWSnXFVYKA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/eventstream-serde-browser": "^4.2.13", - "@smithy/eventstream-serde-config-resolver": "^4.3.13", - "@smithy/eventstream-serde-node": "^4.2.13", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -327,53 +327,53 @@ } }, "node_modules/@aws-sdk/client-dynamodb": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1030.0.tgz", - "integrity": "sha512-mJlCunrAcjOvRyjDiOSNNFEJWwGkfHChqNHZI36oZwnbWyVBkMa43Qhc54sWIhZVXzYONeQ+hviF6zLbFBTUAw==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1032.0.tgz", + "integrity": "sha512-kkXiZBNdWCQAg/8opqAu10TxzdpqMkcGrNAT2ScdfWhCpzYZ2pmSpP8W7BOlA32jYIWnYrEdb808UZsNWYBPAA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/dynamodb-codec": "^3.972.28", - "@aws-sdk/middleware-endpoint-discovery": "^3.972.10", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/dynamodb-codec": "^3.973.1", + "@aws-sdk/middleware-endpoint-discovery": "^3.972.11", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", - "@smithy/util-waiter": "^4.2.15", + "@smithy/util-waiter": "^4.2.16", "tslib": "^2.6.2" }, "engines": { @@ -381,54 +381,54 @@ } }, "node_modules/@aws-sdk/client-kinesis": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1030.0.tgz", - "integrity": "sha512-6uYjDKyorp5yEUpGNz5g23md3C8HQzDcxSWFn2rGxhbmoQifztk79RabbC1T4jd2HscC0vI+UqacekqrKJsr+w==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1032.0.tgz", + "integrity": "sha512-cJtlG6acyKa5OeNVb4Q3DY3gOCL1lYE7wuUheF/LqhPSf1o7L+nz0pMbS05PjclISd/jX4x2yXzBiUTyFQZHcg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/eventstream-serde-browser": "^4.2.13", - "@smithy/eventstream-serde-config-resolver": "^4.3.13", - "@smithy/eventstream-serde-node": "^4.2.13", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", - "@smithy/util-waiter": "^4.2.15", + "@smithy/util-waiter": "^4.2.16", "tslib": "^2.6.2" }, "engines": { @@ -436,55 +436,55 @@ } }, "node_modules/@aws-sdk/client-lambda": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1030.0.tgz", - "integrity": "sha512-z02i8O8qpDVHQX5KMsB1cIn/RP0v2/dyLDIToRHZEbxy5SiiamSC3Gk+BxApILN2XQU+ZBhLlopaG8nrkyXTiQ==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1032.0.tgz", + "integrity": "sha512-HLNMYSus976SNtEl9w9HKDmW5rY61FlnBZdux63tUVDuIk82ycF31ZktigEBz0D0rtc7wi1WulpqJHyT8s6jxg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/eventstream-serde-browser": "^4.2.13", - "@smithy/eventstream-serde-config-resolver": "^4.3.13", - "@smithy/eventstream-serde-node": "^4.2.13", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", - "@smithy/util-stream": "^4.5.22", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", + "@smithy/util-stream": "^4.5.23", "@smithy/util-utf8": "^4.2.2", - "@smithy/util-waiter": "^4.2.15", + "@smithy/util-waiter": "^4.2.16", "tslib": "^2.6.2" }, "engines": { @@ -492,66 +492,66 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1030.0.tgz", - "integrity": "sha512-sgGb4ub0JXnHaXnok5td7A1KGwENFPwOrwgzvpkeWq9w16Sl7x2KhYtVl+Fdd/7LAvaEtm3HqrYtNmm2d0OXmQ==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1032.0.tgz", + "integrity": "sha512-A1wjVhV3IgsZ5td2l4AWgK03EjZ+ldwbiorxuO1hPf7RHJtSdr6oq/gKzyUwP7Tm7ma/M2xS/tplg5C8XB8RWg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/middleware-bucket-endpoint": "^3.972.9", - "@aws-sdk/middleware-expect-continue": "^3.972.9", - "@aws-sdk/middleware-flexible-checksums": "^3.974.7", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-location-constraint": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-sdk-s3": "^3.972.28", - "@aws-sdk/middleware-ssec": "^3.972.9", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/signature-v4-multi-region": "^3.996.16", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/eventstream-serde-browser": "^4.2.13", - "@smithy/eventstream-serde-config-resolver": "^4.3.13", - "@smithy/eventstream-serde-node": "^4.2.13", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-blob-browser": "^4.2.14", - "@smithy/hash-node": "^4.2.13", - "@smithy/hash-stream-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/md5-js": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/middleware-bucket-endpoint": "^3.972.10", + "@aws-sdk/middleware-expect-continue": "^3.972.10", + "@aws-sdk/middleware-flexible-checksums": "^3.974.9", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-location-constraint": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-sdk-s3": "^3.972.30", + "@aws-sdk/middleware-ssec": "^3.972.10", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/signature-v4-multi-region": "^3.996.18", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-blob-browser": "^4.2.15", + "@smithy/hash-node": "^4.2.14", + "@smithy/hash-stream-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/md5-js": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", - "@smithy/util-stream": "^4.5.22", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", + "@smithy/util-stream": "^4.5.23", "@smithy/util-utf8": "^4.2.2", - "@smithy/util-waiter": "^4.2.15", + "@smithy/util-waiter": "^4.2.16", "tslib": "^2.6.2" }, "engines": { @@ -559,49 +559,49 @@ } }, "node_modules/@aws-sdk/client-sns": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1030.0.tgz", - "integrity": "sha512-mz9Q4U6I+gp6v7oeg7Ul0/45jG+9XAXQypy+XH6SpVNTlvsnE3TOkdPxUUDQOHcSHDFYHHS7yfjn1ExKRvNEEw==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1032.0.tgz", + "integrity": "sha512-WebJZGkQArdZ4YTvZZKmHdqbkcG4hyf6fzba1Z2yG+fIyzNB/MTODRHPByzaq9tKL8bK6wWCU9/9dgLCPIs4cQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -610,51 +610,51 @@ } }, "node_modules/@aws-sdk/client-sqs": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1030.0.tgz", - "integrity": "sha512-v+m4uejMysJ+Ay9SKDqg8zzdw2WfOGwKIGeYEPR12Wn7j5vKRPXa5Yixnzi07qMGAgOiFj9iEjV2tcqkPqD4ww==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1032.0.tgz", + "integrity": "sha512-n102sARTLi53Da0JT/2Kvg/bQ4bv+JqA+YQ8OlaM4CgsPn61sMv0x9PxdF6s/KbgZ2HMwYBszNzuvUttN+Beqg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-sdk-sqs": "^3.972.19", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/md5-js": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-sdk-sqs": "^3.972.20", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/md5-js": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -663,51 +663,51 @@ } }, "node_modules/@aws-sdk/client-ssm": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.1030.0.tgz", - "integrity": "sha512-FKu4tINBafrEp6FfoJDaM+KvTqwwK5gnVTrc0ZYbAQ5L7oMuCx02MEQvRI6VLaNhuIqXMKijKo2lodyLY+00WA==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.1032.0.tgz", + "integrity": "sha512-IkFS5VbAuLhyDIwfkeWvBsdY6fQpr9adDaA8q1dBVyW4qZEF8qfNB6Oq7s+NkUStWnkquKlBJtHv0qzW81RuNg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-node": "^3.972.30", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-node": "^3.972.32", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", - "@smithy/util-waiter": "^4.2.15", + "@smithy/util-waiter": "^4.2.16", "tslib": "^2.6.2" }, "engines": { @@ -715,23 +715,23 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.973.27", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.27.tgz", - "integrity": "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A==", + "version": "3.974.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.1.tgz", + "integrity": "sha512-gy/gffKz0zaHDaqRiLCdIvgHmaAL/HXuAtMcBP7euYSFx4BsbsdlfmUBJag+Gqe62z6/XuloKyQyaiH+kS3Vrg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/xml-builder": "^3.972.17", - "@smithy/core": "^3.23.14", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/signature-v4": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/xml-builder": "^3.972.18", + "@smithy/core": "^3.23.15", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", - "@smithy/util-middleware": "^4.2.13", + "@smithy/util-middleware": "^4.2.14", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -740,13 +740,13 @@ } }, "node_modules/@aws-sdk/crc64-nvme": { - "version": "3.972.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.6.tgz", - "integrity": "sha512-NMbiqKdruhwwgI6nzBVe2jWMkXjaoQz2YOs3rFX+2F3gGyrJDkDPwMpV/RsTFeq2vAQ055wZNtOXFK4NYSkM8g==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.7.tgz", + "integrity": "sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.14.0", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -754,16 +754,16 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.25.tgz", - "integrity": "sha512-6QfI0wv4jpG5CrdO/AO0JfZ2ux+tKwJPrUwmvxXF50vI5KIypKVGNF6b4vlkYEnKumDTI1NX2zUBi8JoU5QU3A==", + "version": "3.972.27", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.27.tgz", + "integrity": "sha512-xfUt2CUZDC+Tf16A6roD1b4pk/nrXdkoLY3TEhv198AXDtBo5xUJP1zd0e8SmuKLN4PpIBX96OizZbmMlcI6oQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/types": "^4.14.0", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -771,21 +771,21 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.27", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.27.tgz", - "integrity": "sha512-3V3Usj9Gs93h865DqN4M2NWJhC5kXU9BvZskfN3+69omuYlE3TZxOEcVQtBGLOloJB7BVfJKXVLqeNhOzHqSlQ==", + "version": "3.972.29", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.29.tgz", + "integrity": "sha512-hjNeYb6oLyHgMihra83ie0J/T2y9om3cy1qC90h9DRgvYXEoN4BCFf8bHguZjKhXunnv7YkmZRuYL5Mkk77eCA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/util-stream": "^4.5.22", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/types": "^3.973.8", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" }, "engines": { @@ -793,25 +793,25 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.29.tgz", - "integrity": "sha512-SiBuAnXecCbT/OpAf3vqyI/AVE3mTaYr9ShXLybxZiPLBiPCCOIWSGAtYYGQWMRvobBTiqOewaB+wcgMMZI2Aw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-env": "^3.972.25", - "@aws-sdk/credential-provider-http": "^3.972.27", - "@aws-sdk/credential-provider-login": "^3.972.29", - "@aws-sdk/credential-provider-process": "^3.972.25", - "@aws-sdk/credential-provider-sso": "^3.972.29", - "@aws-sdk/credential-provider-web-identity": "^3.972.29", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/credential-provider-imds": "^4.2.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", + "version": "3.972.31", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.31.tgz", + "integrity": "sha512-PuQ7e8WYzAPpzvFcajxf8c0LqSzakVHVlKw8M0oubk8Kf347YOCCqT1seQrHs5AdZuIh2RD9LX4O+Xa5ImEBfQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/credential-provider-env": "^3.972.27", + "@aws-sdk/credential-provider-http": "^3.972.29", + "@aws-sdk/credential-provider-login": "^3.972.31", + "@aws-sdk/credential-provider-process": "^3.972.27", + "@aws-sdk/credential-provider-sso": "^3.972.31", + "@aws-sdk/credential-provider-web-identity": "^3.972.31", + "@aws-sdk/nested-clients": "^3.996.21", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -819,19 +819,19 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.29.tgz", - "integrity": "sha512-OGOslTbOlxXexKMqhxCEbBQbUIfuhGxU5UXw3Fm56ypXHvrXH4aTt/xb5Y884LOoteP1QST1lVZzHfcTnWhiPQ==", + "version": "3.972.31", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.31.tgz", + "integrity": "sha512-bBmWDmtSpmLOZR6a0kmowBcVL1hiL8Vlap/RXeMpFd7JbWl87YcwqL6T9LH/0oBVEZXu1dUZAtojgSuZgMO5xw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/nested-clients": "^3.996.21", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -839,23 +839,23 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.30", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.30.tgz", - "integrity": "sha512-FMnAnWxc8PG+ZrZ2OBKzY4luCUJhe9CG0B9YwYr4pzrYGLXBS2rl+UoUvjGbAwiptxRL6hyA3lFn03Bv1TLqTw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.25", - "@aws-sdk/credential-provider-http": "^3.972.27", - "@aws-sdk/credential-provider-ini": "^3.972.29", - "@aws-sdk/credential-provider-process": "^3.972.25", - "@aws-sdk/credential-provider-sso": "^3.972.29", - "@aws-sdk/credential-provider-web-identity": "^3.972.29", - "@aws-sdk/types": "^3.973.7", - "@smithy/credential-provider-imds": "^4.2.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", + "version": "3.972.32", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.32.tgz", + "integrity": "sha512-9aj0x9hGYUondBZSD0XkksAdHhOKttFw4BWpLCeggeg40qSJxGrAP++g0GCm0VqWc1WtC/NRFiAVzPCy56vmog==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.27", + "@aws-sdk/credential-provider-http": "^3.972.29", + "@aws-sdk/credential-provider-ini": "^3.972.31", + "@aws-sdk/credential-provider-process": "^3.972.27", + "@aws-sdk/credential-provider-sso": "^3.972.31", + "@aws-sdk/credential-provider-web-identity": "^3.972.31", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -863,17 +863,17 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.25.tgz", - "integrity": "sha512-HR7ynNRdNhNsdVCOCegy1HsfsRzozCOPtD3RzzT1JouuaHobWyRfJzCBue/3jP7gECHt+kQyZUvwg/cYLWurNQ==", + "version": "3.972.27", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.27.tgz", + "integrity": "sha512-1CZvfb1WzudWWIFAVQkd1OI/T1RxPcSvNWzNsb2BMBVsBJzBtB8dV5f2nymHVU4UqwxipdVt/DAbgdDRf33JDg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -881,19 +881,19 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.29.tgz", - "integrity": "sha512-HWv4SEq3jZDYPlwryZVef97+U8CxxRos5mK8sgGO1dQaFZpV5giZLzqGE5hkDmh2csYcBO2uf5XHjPTpZcJlig==", + "version": "3.972.31", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.31.tgz", + "integrity": "sha512-x8Mx18S48XMl9bEEpYwmXDTvjWGPIfDadReN37Lc099/DUrlL4Zs9T9rwwggo6DkKS1aev6v+MTUx7JTa87TZQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/token-providers": "3.1026.0", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/nested-clients": "^3.996.21", + "@aws-sdk/token-providers": "3.1032.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -901,18 +901,18 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.29.tgz", - "integrity": "sha512-PdMBza1WEKEUPFEmMGCfnU2RYCz9MskU2e8JxjyUOsMKku7j9YaDKvbDi2dzC0ihFoM6ods2SbhfAAro+Gwlew==", + "version": "3.972.31", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.31.tgz", + "integrity": "sha512-zfuNMIkGfjYsHis9qytYf74Bcmq6Ji9Xwf4w53baRCI/b2otTwZv3SW1uRiJ5Di7999QzRGhHZ96+eUeo3gSOA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/nested-clients": "^3.996.21", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -920,16 +920,15 @@ } }, "node_modules/@aws-sdk/dynamodb-codec": { - "version": "3.972.28", - "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.972.28.tgz", - "integrity": "sha512-wx5jKLKPVJRsr/dwK9Xp26+SDb95xHlZU9Bgm2AglnMxQ0DlRlq3PyKlGi9y0OCuWZ7hLNcQJ7uDSN+PgsiuGg==", + "version": "3.973.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.1.tgz", + "integrity": "sha512-BuxJyHW+fnuGLFZ84z5txzlfKXLVbf3hmWH4wQ9q5a/P6O5slNg6j2eUE2kQMYWt3A3PheUR4tgRBUC7j9i/nQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@smithy/core": "^3.23.14", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", + "@aws-sdk/core": "^3.974.1", + "@smithy/core": "^3.23.15", + "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, @@ -952,16 +951,16 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.1030.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1030.0.tgz", - "integrity": "sha512-1Hn+m1sioy3OMvF/I1uDz9QjpqcE3QSsHvz0Y0UXyMthNCpvAEvN4qO9RWBDGfVqddY1Flsp0rfvjwYP4KVr+w==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1032.0.tgz", + "integrity": "sha512-jXXKbrRWYvLlCCO8suiOiFrkcsO/zVYjdPZpVnDLSO6Nled7VvxwRkjnM1/l5CnOHAW6VGhR3nrU/+LmqeGQYg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", "buffer": "5.6.0", "events": "3.3.0", "stream-browserify": "3.0.0", @@ -971,21 +970,21 @@ "node": ">=20.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.1030.0" + "@aws-sdk/client-s3": "^3.1032.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.9.tgz", - "integrity": "sha512-COToYKgquDyligbcAep7ygs48RK+mwe/IYprq4+TSrVFzNOYmzWvHf6werpnKV5VYpRiwdn+Wa5ZXkPqLVwcTg==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.10.tgz", + "integrity": "sha512-Vbc2frZH7wXlMNd+ZZSXUEs/l1Sv8Jj4zUnIfwrYF5lwaLdXHZ9xx4U3rjUcaye3HRhFVc+E5DbBxpRAbB16BA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", + "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-arn-parser": "^3.972.3", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, @@ -994,17 +993,17 @@ } }, "node_modules/@aws-sdk/middleware-endpoint-discovery": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.10.tgz", - "integrity": "sha512-b3hf8dPxWonxFKgxBijMehVblgbY0gPprTvyuHYMxnOPfiCIY467kZltPoeOCQYLr9v0v0HuL9fIGtT6utd15w==", + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.11.tgz", + "integrity": "sha512-vXARCZVFQHdsd6qPPZyC/hh+5x2XsCYKqUQDCqnUlpGpChMpDojOOacQWdLJ+FFXKN8X3cmLOGrtgx/zysCKqQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/endpoint-cache": "^3.972.5", - "@aws-sdk/types": "^3.973.7", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1012,15 +1011,15 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.9.tgz", - "integrity": "sha512-V/FNCjFxnh4VGu+HdSiW4Yg5GELihA1MIDSAdsEPvuayXBVmr0Jaa6jdLAZLH38KYXl/vVjri9DQJWnTAujHEA==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.10.tgz", + "integrity": "sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1028,24 +1027,24 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.974.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.7.tgz", - "integrity": "sha512-uU4/ch2CLHB8Phu1oTKnnQ4e8Ujqi49zEnQYBhWYT53zfFvtJCdGsaOoypBr8Fm/pmCBssRmGoIQ4sixgdLP9w==", + "version": "3.974.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.9.tgz", + "integrity": "sha512-ye6xVuMEQ5NCT+yQOryGYsuCXnOwu7iGFGzV+qpXZOWtqXIAAaFostapxj6RCubw36rekVwmdB2lcspFuyNfYQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/crc64-nvme": "^3.972.6", - "@aws-sdk/types": "^3.973.7", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/crc64-nvme": "^3.972.7", + "@aws-sdk/types": "^3.973.8", "@smithy/is-array-buffer": "^4.2.2", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-stream": "^4.5.22", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.23", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -1054,15 +1053,15 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.9.tgz", - "integrity": "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.10.tgz", + "integrity": "sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1070,14 +1069,14 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.9.tgz", - "integrity": "sha512-TyfOi2XNdOZpNKeTJwRUsVAGa+14nkyMb2VVGG+eDgcWG/ed6+NUo72N3hT6QJioxym80NSinErD+LBRF0Ir1w==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.10.tgz", + "integrity": "sha512-rI3NZvJcEvjoD0+0PI0iUAwlPw2IlSlhyvgBK/3WkKJQE/YiKFedd9dMN2lVacdNxPNhxL/jzQaKQdrGtQagjQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1085,14 +1084,14 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.9.tgz", - "integrity": "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.10.tgz", + "integrity": "sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1100,16 +1099,16 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.10.tgz", - "integrity": "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ==", + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.11.tgz", + "integrity": "sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", + "@aws-sdk/types": "^3.973.8", "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1117,24 +1116,24 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.972.28", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.28.tgz", - "integrity": "sha512-qJHcJQH9UNPUrnPlRtCozKjtqAaypQ5IgQxTNoPsVYIQeuwNIA8Rwt3NvGij1vCDYDfCmZaPLpnJEHlZXeFqmg==", + "version": "3.972.30", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.30.tgz", + "integrity": "sha512-hoQRxjJu4tt3gEOQin21rJKotClJC+x7AmCh9ylRct1DJeaNI/BRlFxMbuhJe54bG6xANPagSs0my8K30QyV9g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-arn-parser": "^3.972.3", - "@smithy/core": "^3.23.14", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/signature-v4": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", + "@smithy/core": "^3.23.15", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-stream": "^4.5.22", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.23", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -1143,15 +1142,15 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sqs": { - "version": "3.972.19", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.19.tgz", - "integrity": "sha512-S7AWsrOTcs52AdS4uWPtP6n7tloOscfeNfJWK4wvNPJBI01lrfHb6g+tYRckwDzruhhdaPpn/CARZ+YPw6oMGw==", + "version": "3.972.20", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.20.tgz", + "integrity": "sha512-yt0w5FKyH8Or7OT/Bp3fDRAtI4/f6uaaRKnW9TmU9qv8c1HFh43C9nQYZ26IcyRm+tYFdrB65yNTav/YThu36A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" @@ -1161,14 +1160,14 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.9.tgz", - "integrity": "sha512-wSA2BR7L0CyBNDJeSrleIIzC+DzL93YNTdfU0KPGLiocK6YsRv1nPAzPF+BFSdcs0Qa5ku5Kcf4KvQcWwKGenQ==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.10.tgz", + "integrity": "sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1176,19 +1175,19 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.29.tgz", - "integrity": "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ==", + "version": "3.972.31", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.31.tgz", + "integrity": "sha512-L+hXN2HDomlIsWSHW5DVD7ppccCeRnlHXZ5uHG34ePTjF5bm0I1fmrJLbUGiW97xRXWryit5cjdP4Sx2FwiGog==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@smithy/core": "^3.23.14", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "@smithy/util-retry": "^4.3.0", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@smithy/core": "^3.23.15", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-retry": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -1196,48 +1195,48 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.996.19", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", - "integrity": "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q==", + "version": "3.996.21", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.21.tgz", + "integrity": "sha512-Me3d/ua2lb2G0bQfFmvCeQQp3+nN6GSPqMxDmi/IQlQ8CrlpQ5C0JJHpz2AnOUkEFI0lBNrAL3Vnt29l44ndkA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/region-config-resolver": "^3.972.12", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.7", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.17", + "@smithy/config-resolver": "^4.4.16", + "@smithy/core": "^3.23.15", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-retry": "^4.5.3", + "@smithy/middleware-serde": "^4.2.18", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.5.3", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", + "@smithy/util-defaults-mode-browser": "^4.3.47", + "@smithy/util-defaults-mode-node": "^4.2.52", + "@smithy/util-endpoints": "^3.4.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -1246,16 +1245,16 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.11.tgz", - "integrity": "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg==", + "version": "3.972.12", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.12.tgz", + "integrity": "sha512-QQI43Mxd53nBij0pm8HXC+t4IOC6gnhhZfzxE0OATQyO6QfPV4e+aTIRRuAJKA6Nig/cR8eLwPryqYTX9ZrjAQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/config-resolver": "^4.4.14", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/config-resolver": "^4.4.16", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1263,17 +1262,17 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.996.16", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.16.tgz", - "integrity": "sha512-EMdXYB4r/k5RWq86fugjRhid5JA+Z6MpS7n4sij4u5/C+STrkvuf9aFu41rJA9MjUzxCLzv8U2XL8cH2GSRYpQ==", + "version": "3.996.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.18.tgz", + "integrity": "sha512-4KT8UXRmvNAP5zKq9UI1MIwbnmSChZncBt89RKu/skMqZSSWGkBZTAJsZ+no+txfmF3kVaUFv31CTBZkQ5BJpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "^3.972.28", - "@aws-sdk/types": "^3.973.7", - "@smithy/protocol-http": "^5.3.13", - "@smithy/signature-v4": "^5.3.13", - "@smithy/types": "^4.14.0", + "@aws-sdk/middleware-sdk-s3": "^3.972.30", + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1281,18 +1280,18 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.1026.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1026.0.tgz", - "integrity": "sha512-Ieq/HiRrbEtrYP387Nes0XlR7H1pJiJOZKv+QyQzMYpvTiDs0VKy2ZB3E2Zf+aFovWmeE7lRE4lXyF7dYM6GgA==", + "version": "3.1032.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1032.0.tgz", + "integrity": "sha512-n+PU8Z+gll7p3wDrH+Wo6fkt8sPrVnq30YYM6Ryga95oJlEneNMEbDHj0iqjMX3V7gaGdJo/hJWyPo4lscP+mA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", + "@aws-sdk/core": "^3.974.1", + "@aws-sdk/nested-clients": "^3.996.21", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1300,13 +1299,13 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.973.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.7.tgz", - "integrity": "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg==", + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", + "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.14.0", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -1327,16 +1326,16 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.996.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.6.tgz", - "integrity": "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg==", + "version": "3.996.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.7.tgz", + "integrity": "sha512-ty4LQxN1QC+YhUP28NfEgZDEGXkyqOQy+BDriBozqHsrYO4JMgiPhfizqOGF7P+euBTZ5Ez6SKlLAMCLo8tzmw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", - "@smithy/util-endpoints": "^3.3.4", + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-endpoints": "^3.4.1", "tslib": "^2.6.2" }, "engines": { @@ -1357,29 +1356,29 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.9.tgz", - "integrity": "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.10.tgz", + "integrity": "sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.973.15", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.15.tgz", - "integrity": "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w==", + "version": "3.973.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.17.tgz", + "integrity": "sha512-utF5qjjbuJQuU9VdCkWl7L87sr93cApsrD+uxGfUnlafX8iyEzJrb7EZnufjThURZVTOtelRMXrblWxpefElUg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/types": "^3.973.7", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/types": "^4.14.0", + "@aws-sdk/middleware-user-agent": "^3.972.31", + "@aws-sdk/types": "^3.973.8", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, @@ -1396,13 +1395,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.17", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.17.tgz", - "integrity": "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.18.tgz", + "integrity": "sha512-BMDNVG1ETXRhl1tnisQiYBef3RShJ1kfZA7x7afivTFMLirfHNTb6U71K569HNXhSXbQZsweHvSDZ6euBw8hPA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.14.0", + "@smithy/types": "^4.14.1", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" }, @@ -1742,9 +1741,9 @@ } }, "node_modules/@cloudflare/workers-types": { - "version": "4.20260416.2", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260416.2.tgz", - "integrity": "sha512-f7VGuKsHckH5n9KATTPJQ6AGdc2q58eM2waGzzDoCKw+PBtw9j2TWdRz8tLkviv7XcjkcuKy181vQFffXJicrA==", + "version": "4.20260418.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260418.1.tgz", + "integrity": "sha512-bywXb2XmeSqrLCQYipcupLneqx015YhhNWz2v9b9iatpe8Cg551vP7ZuD5S2a6GfBka0dDnO70kIBiBvFglcrg==", "dev": true, "license": "MIT OR Apache-2.0" }, @@ -3282,9 +3281,9 @@ } }, "node_modules/@nodable/entities": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-1.1.0.tgz", - "integrity": "sha512-bidpxmTBP0pOsxULw6XlxzQpTgrAGLDHGBK/JuWhPDL6ZV0GZ/PmN9CA9do6e+A9lYI6qx6ikJUtJYRxup141g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", "dev": true, "funding": [ { @@ -4939,9 +4938,9 @@ } }, "node_modules/ajv-cmd": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/ajv-cmd/-/ajv-cmd-0.11.0.tgz", - "integrity": "sha512-aQBWyTwiuQuxAUZcXwfUSkQMS8iZ8sMpK/mVC6NM8O1nlB3zsLWeInGxIkR9tMA2bWcuBbovqN56c+D2gCY7+A==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/ajv-cmd/-/ajv-cmd-0.12.0.tgz", + "integrity": "sha512-6beMoFAH2TACcQClTjK7AuYfi1zzhJXhjgyTKfvGSn73KhwqvMglWD327ZXhAHBcdf7v2VNtTI7WTOMTwu07/A==", "license": "MIT", "workspaces": [ ".github" @@ -4957,8 +4956,7 @@ "ajv-keywords": "5.1.0", "commander": "14.0.3", "esbuild": "^0.28.0", - "redos-detector": "6.1.4", - "sast-json-schema": "^0.1.0" + "sast-json-schema": "0.2.3" }, "bin": { "ajv": "cli.js" @@ -5233,10 +5231,10 @@ "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", "license": "MIT" }, - "node_modules/charset-detector": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charset-detector/-/charset-detector-0.0.2.tgz", - "integrity": "sha512-aZBFdf9aE168W7w3t9JNC0w9hZdTKjtq1hsrfbziJA4DrNI22Mfrc74gw3aADIA9bCQV2IpnbjyQcDHa3qM4rg==", + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", "license": "MIT" }, "node_modules/cheerio": { @@ -6014,9 +6012,9 @@ } }, "node_modules/fast-check": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.6.0.tgz", - "integrity": "sha512-h7H6Dm0Fy+H4ciQYFxFjXnXkzR2kr9Fb22c0UBpHnm59K2zpr2t13aPTHlltFiNT6zuxp6HMPAVVvgur4BLdpA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.7.0.tgz", + "integrity": "sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ==", "dev": true, "funding": [ { @@ -6076,9 +6074,9 @@ "license": "BSD-3-Clause" }, "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", "dev": true, "funding": [ { @@ -6092,9 +6090,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.6.0.tgz", - "integrity": "sha512-5G+uaEBbOm9M4dgMOV3K/rBzfUNGqGqoUTaYJM3hBwM8t71w07gxLQZoTsjkY8FtfjabqgQHEkeIySBDYeBmJw==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.1.tgz", + "integrity": "sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==", "dev": true, "funding": [ { @@ -6104,8 +6102,8 @@ ], "license": "MIT", "dependencies": { - "@nodable/entities": "^1.1.0", - "fast-xml-builder": "^1.1.4", + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, @@ -8335,13 +8333,20 @@ "license": "MIT" }, "node_modules/sast-json-schema": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/sast-json-schema/-/sast-json-schema-0.1.0.tgz", - "integrity": "sha512-aVtzdQ3jYop1if6YcSeVzCC8VD+iXqg00IUBuXEGWelSVKmcc4iJMN/CfKlakzXzeNmXfX1dwXpNigGDvaufpg==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/sast-json-schema/-/sast-json-schema-0.2.3.tgz", + "integrity": "sha512-84DyjPfOHYodSRPGeCXQEOSmUnByNLnqEkOlzWcsJyniVvjinVjDtSUZK3PtWz45e3dee0NZX3aJp2CA2l2XfQ==", "license": "MIT", "workspaces": [ ".github" ], + "dependencies": { + "ajv": "8.18.0", + "redos-detector": "6.1.4" + }, + "bin": { + "sast-json-schema": "cli.js" + }, "engines": { "node": ">=24" }, @@ -8871,9 +8876,9 @@ } }, "node_modules/typescript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -10005,10 +10010,10 @@ }, "packages/aws": { "name": "@datastream/aws", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "devDependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.0.0", @@ -10068,10 +10073,10 @@ }, "packages/base64": { "name": "@datastream/base64", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10079,11 +10084,11 @@ }, "packages/charset": { "name": "@datastream/charset", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2", - "charset-detector": "0.0.2", + "@datastream/core": "0.4.0", + "chardet": "2.1.1", "iconv-lite": "0.7.2" }, "engines": { @@ -10092,10 +10097,10 @@ }, "packages/compress": { "name": "@datastream/compress", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10119,10 +10124,10 @@ }, "packages/core": { "name": "@datastream/core", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "devDependencies": { - "@datastream/object": "0.3.2" + "@datastream/object": "0.4.0" }, "engines": { "node": ">=24" @@ -10130,11 +10135,11 @@ }, "packages/csv": { "name": "@datastream/csv", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2", - "@datastream/object": "0.3.2" + "@datastream/core": "0.4.0", + "@datastream/object": "0.4.0" }, "engines": { "node": ">=24" @@ -10142,10 +10147,10 @@ }, "packages/digest": { "name": "@datastream/digest", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2", + "@datastream/core": "0.4.0", "hash-wasm": "4.12.0" }, "engines": { @@ -10154,10 +10159,10 @@ }, "packages/encrypt": { "name": "@datastream/encrypt", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10173,10 +10178,10 @@ }, "packages/fetch": { "name": "@datastream/fetch", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10184,10 +10189,10 @@ }, "packages/file": { "name": "@datastream/file", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10195,10 +10200,10 @@ }, "packages/indexeddb": { "name": "@datastream/indexeddb", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2", + "@datastream/core": "0.4.0", "idb": "8.0.3" }, "engines": { @@ -10207,10 +10212,10 @@ }, "packages/ipfs": { "name": "@datastream/ipfs", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10218,10 +10223,10 @@ }, "packages/json": { "name": "@datastream/json", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10229,10 +10234,10 @@ }, "packages/object": { "name": "@datastream/object", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10240,10 +10245,10 @@ }, "packages/string": { "name": "@datastream/string", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "engines": { "node": ">=24" @@ -10251,18 +10256,18 @@ }, "packages/validate": { "name": "@datastream/validate", - "version": "0.3.2", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@datastream/core": "0.3.2", - "ajv-cmd": "0.11.0" + "@datastream/core": "0.4.0", + "ajv-cmd": "0.12.0" }, "engines": { "node": ">=24" } }, "websites/datastream.js.org": { - "version": "0.3.2", + "version": "0.4.0", "dependencies": { "@plausible-analytics/tracker": "0.4.4", "@willfarrell-ds/svelte": "0.0.0-alpha.6", diff --git a/package.json b/package.json index f0274f1..197f1d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/monorepo", - "version": "0.3.2", + "version": "0.4.0", "description": "Streams made easy.", "private": true, "type": "module", @@ -9,20 +9,22 @@ }, "engineStrict": true, "scripts": { - "prepare": "husky", + "prepare": "husky || true", "git:pre-commit": "npm run git:lint-staged && npm run git:test-staged", "git:commit-msg": "commitlint --config commitlint.config.cjs --edit", - "git:lint-staged": "npm run test:lint", - "git:test-staged": "which node && node -v && node --test ./packages/*", + "git:lint-staged": "npm run test:lint:staged", + "git:test-staged": "which node && node -v && npm run test:unit", "lint": "biome check --write --no-errors-on-unmatched", "build": "bin/esbuild", + "pretest": "npm run build", "test": "npm run test:lint && npm run test:unit && npm run test:types && npm run test:sast && npm run test:perf && npm run test:dast", - "test:lint": "biome check --staged --no-errors-on-unmatched", + "test:lint": "biome ci --no-errors-on-unmatched", + "test:lint:staged": "biome check --staged --no-errors-on-unmatched", "test:unit": "npm run test:unit:node && npm run test:unit:web", - "test:unit:node": "node --test --conditions=node", - "test:unit:web": "node --test --conditions=webstream", + "test:unit:node": "node --test --conditions=node --test-force-exit --experimental-test-coverage --test-coverage-exclude=packages/file/** --test-coverage-exclude=**/*.test.js --test-coverage-exclude=**/*.fuzz.js --test-coverage-exclude=**/*.perf.js --test-coverage-lines=96 --test-coverage-branches=93 --test-coverage-functions=95", + "test:unit:web": "node --test --conditions=webstream --experimental-test-coverage --test-coverage-exclude=packages/file/** --test-coverage-exclude=**/*.test.js --test-coverage-exclude=**/*.fuzz.js --test-coverage-exclude=**/*.perf.js --test-coverage-lines=95 --test-coverage-branches=93 --test-coverage-functions=95", "test:sast": "npm run test:sast:license && npm run test:sast:lockfile && npm run test:sast:semgrep && npm run test:sast:trufflehog && npm run test:sast:trivy && npm run test:sast:ort", - "test:sast:license": "license-check-and-add check -f license.json", + "test:sast:license": "license-check-and-add check -f .license.config.json", "test:sast:lockfile": "lockfile-lint --path package-lock.json --type npm --allowed-hosts npm --validate-https", "test:sast:ort": "docker run ghcr.io/oss-review-toolkit/ort --help", "test:sast:semgrep": "semgrep scan --config auto", @@ -32,11 +34,6 @@ "test:perf": "node --test --test-concurrency ./**/*.perf.js", "test:dast": "npm run test:dast:fuzz", "test:dast:fuzz": "node --test ./**/*.fuzz.js", - "test:packages:unit": "npm run test:packages:unit:node && npm run test:packages:unit:web", - "test:packages:unit:node": "node --test --test-force-exit --experimental-test-coverage --test-coverage-lines=96 --test-coverage-branches=99 --test-coverage-functions=95", - "test:packages:unit:web": "node --test --test-force-exit --experimental-test-coverage --test-coverage-lines=96 --test-coverage-branches=99 --test-coverage-functions=95", - "test:packages:perf": "node --test --test-concurrency ./packages/**/*.perf.js", - "test:packages:fuzz": "node --test ./packages/**/*.fuzz.js", "rm": "npm run rm:macos && npm run rm:node_modules && npm run rm:lock", "rm:macos": "find . -name '.DS_Store' -type f -prune -exec rm -rf '{}' +", "rm:lock": "find . -name 'package-lock.json' -type f -prune -exec rm -rf '{}' +", @@ -44,8 +41,8 @@ "update": "npm update --workspaces && npm install --workspaces", "outdated": "npm outdated --workspaces", "audit": "npm audit fix --workspaces", - "release:license:add": "license-check-and-add add -f license.json", - "release:license:remove": "license-check-and-add remove -f license.json", + "release:license:add": "license-check-and-add add -f .license.config.json", + "release:license:remove": "license-check-and-add remove -f .license.config.json", "release:sync": "npm version $npm_package_version --workspaces; find ./packages -name \"package.json\" -exec sed -i '' -E \"s|\\\"@datastream/(.*)\\\": ([^,]*)|\\\"@datastream/\\1\\\": $(npm pkg get version)|g\" {} \\; && npm run rm && npm install", "release:tag": "git tag $npm_package_version" }, diff --git a/packages/aws/dynamodb.js b/packages/aws/dynamodb.js index c3360bf..5459659 100644 --- a/packages/aws/dynamodb.js +++ b/packages/aws/dynamodb.js @@ -110,7 +110,7 @@ export const awsDynamoDBGetItemStream = async (options, streamOptions = {}) => { }); } - await timeout(3 ** retryCount); // 3^10 == 59sec + await timeout(3 ** retryCount, { signal: streamOptions.signal }); // 3^10 == 59sec retryCount++; keys = UnprocessedKeys; } @@ -183,7 +183,7 @@ const dynamodbBatchWrite = async ( }); } - await timeout(3 ** retryCount); // 3^10 == 59sec + await timeout(3 ** retryCount, { signal: streamOptions?.signal }); // 3^10 == 59sec return dynamodbBatchWrite( options, UnprocessedItems[options.TableName], diff --git a/packages/aws/package.json b/packages/aws/package.json index 7c0e861..3cf3934 100644 --- a/packages/aws/package.json +++ b/packages/aws/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/aws", - "version": "0.3.2", + "version": "0.4.0", "description": "AWS service streaming integrations for CloudWatch Logs, DynamoDB, Kinesis, Lambda, S3, SNS, and SQS", "type": "module", "engines": { @@ -148,7 +148,7 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "peerDependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.0.0", diff --git a/packages/base64/index.node.js b/packages/base64/index.node.js index 0dd2ea3..05e9bc4 100644 --- a/packages/base64/index.node.js +++ b/packages/base64/index.node.js @@ -1,27 +1,33 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT +import { Buffer } from "node:buffer"; import { createTransformStream } from "@datastream/core"; +const toBuffer = (chunk) => + Buffer.isBuffer(chunk) + ? chunk + : chunk instanceof Uint8Array + ? Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) + : Buffer.from(chunk); + export const base64EncodeStream = (_options = {}, streamOptions = {}) => { - let extra = ""; + let extra; // Buffer | undefined const transform = (chunk, enqueue) => { + let buf = toBuffer(chunk); if (extra) { - chunk = extra + chunk; - extra = ""; + buf = Buffer.concat([extra, buf]); + extra = undefined; } - - // 3 bytes == 4 char - const remaining = chunk.length % 3; + const remaining = buf.length % 3; if (remaining > 0) { - extra = chunk.slice(chunk.length - remaining); - chunk = chunk.slice(0, chunk.length - remaining); + extra = Buffer.from(buf.subarray(buf.length - remaining)); + buf = buf.subarray(0, buf.length - remaining); } - - enqueue(btoa(chunk)); + if (buf.length > 0) enqueue(buf.toString("base64")); }; const flush = (enqueue) => { - if (extra) { - enqueue(btoa(extra)); + if (extra && extra.length > 0) { + enqueue(extra.toString("base64")); } }; return createTransformStream(transform, flush, streamOptions); @@ -30,22 +36,22 @@ export const base64EncodeStream = (_options = {}, streamOptions = {}) => { export const base64DecodeStream = (_options = {}, streamOptions = {}) => { let extra = ""; const transform = (chunk, enqueue) => { - chunk = extra + chunk; - - // 4 char == 3 bytes - const remaining = chunk.length % 4; - - extra = chunk.slice(chunk.length - remaining); - chunk = chunk.slice(0, chunk.length - remaining); - - enqueue(atob(chunk)); + const str = + typeof chunk === "string" ? chunk : toBuffer(chunk).toString("ascii"); + let s = extra.length > 0 ? extra + str : str; + extra = ""; + const remaining = s.length % 4; + if (remaining > 0) { + extra = s.slice(s.length - remaining); + s = s.slice(0, s.length - remaining); + } + if (s.length > 0) enqueue(Buffer.from(s, "base64")); }; const flush = (enqueue) => { - if (extra) { - enqueue(atob(extra)); + if (extra.length > 0) { + enqueue(Buffer.from(extra, "base64")); } }; - streamOptions.decodeStrings = false; return createTransformStream(transform, flush, streamOptions); }; diff --git a/packages/base64/index.test.js b/packages/base64/index.test.js index 89cce27..67d8719 100644 --- a/packages/base64/index.test.js +++ b/packages/base64/index.test.js @@ -1,4 +1,5 @@ import { deepStrictEqual } from "node:assert"; +import { Buffer } from "node:buffer"; import test from "node:test"; import base64Default, { base64DecodeStream, @@ -7,9 +8,12 @@ import base64Default, { import { createReadableStream, pipejoin, + streamToBuffer, streamToString, } from "@datastream/core"; +const decoder = new TextDecoder(); + let variant = "unknown"; for (const execArgv of process.execArgv) { const flag = "--conditions="; @@ -31,7 +35,7 @@ test(`${variant}: base64EncodeStream should encode`, async (_t) => { test(`${variant}: base64DecodeStream should decode`, async (_t) => { const input = "decode"; const streams = [createReadableStream(btoa(input)), base64DecodeStream()]; - const output = await streamToString(pipejoin(streams)); + const output = decoder.decode(await streamToBuffer(pipejoin(streams))); deepStrictEqual(output, input); }); @@ -45,7 +49,7 @@ test(`${variant}: base64Stream should encode/decode`, async (_t) => { base64EncodeStream(), base64DecodeStream(), ]; - const output = await streamToString(pipejoin(streams)); + const output = decoder.decode(await streamToBuffer(pipejoin(streams))); deepStrictEqual(output, input); } @@ -65,7 +69,7 @@ test(`${variant}: base64DecodeStream should handle multiple chunks with remainde const input = btoa("aaaabbbbcccc"); const chunks = [input.slice(0, 4), input.slice(4, 8), input.slice(8)]; // 4 chars each, 4 % 4 = 0, but test chunking const streams = [createReadableStream(chunks), base64DecodeStream()]; - const output = await streamToString(pipejoin(streams)); + const output = decoder.decode(await streamToBuffer(pipejoin(streams))); deepStrictEqual(output, "aaaabbbbcccc"); }); @@ -93,29 +97,50 @@ test(`${variant}: base64DecodeStream should decode partial base64`, async (_t) = const input = btoa("hello"); const chunks = [input.slice(0, 2), input.slice(2)]; // 2 and rest const streams = [createReadableStream(chunks), base64DecodeStream()]; - const output = await streamToString(pipejoin(streams)); + const output = decoder.decode(await streamToBuffer(pipejoin(streams))); deepStrictEqual(output, "hello"); }); // Test decode flush with remaining characters test(`${variant}: base64DecodeStream should flush remaining characters`, async (_t) => { - // btoa("a") = "YQ==" (4 chars), btoa("ab") = "YWI=" (4 chars) - // Split so last chunk has 2 chars (not multiple of 4) const input = btoa("ab"); // "YWI=" - const chunks = [input.slice(0, 2)]; // Only send "YW" - leaves 2 chars in extra - // The stream should end with extra = "I=" and flush should decode it + const chunks = [input.slice(0, 2)]; // Only send "YW" const streams = [createReadableStream(chunks), base64DecodeStream()]; + const output = await streamToBuffer(pipejoin(streams)); + + deepStrictEqual(output.byteLength, 1); +}); + +// *** Binary correctness *** // +test(`${variant}: base64EncodeStream should encode all 256 byte values`, async (_t) => { + const bytes = new Uint8Array(256); + for (let i = 0; i < 256; i++) bytes[i] = i; + const streams = [createReadableStream([bytes]), base64EncodeStream()]; const output = await streamToString(pipejoin(streams)); + deepStrictEqual(output, Buffer.from(bytes).toString("base64")); +}); - // "YW" + "I=" would decode to "ab", but since we only sent "YW", - // extra becomes "YW" (2 % 4 = 2), then flush decodes it - // Actually "YW" is incomplete base64 - let's think again - // When chunk = "YW", remaining = 2 % 4 = 2, extra = "YW" (last 2 chars) - // chunk becomes "" (first 0 chars), so nothing enqueued in transform - // Then flush is called with extra = "YW" - // Buffer.from("YW", "base64") decodes to "a" (partial decode) - deepStrictEqual(output.length, 1); +test(`${variant}: base64DecodeStream should round-trip all 256 byte values`, async (_t) => { + const bytes = new Uint8Array(256); + for (let i = 0; i < 256; i++) bytes[i] = i; + const b64 = Buffer.from(bytes).toString("base64"); + const streams = [createReadableStream([b64]), base64DecodeStream()]; + const output = await streamToBuffer(pipejoin(streams)); + deepStrictEqual(Uint8Array.from(output), bytes); +}); + +test(`${variant}: base64EncodeStream should encode Uint8Array chunks across boundary`, async (_t) => { + // 4 bytes per chunk, 4%3 = 1 remainder per chunk + const chunks = [ + new Uint8Array([1, 2, 3, 4]), + new Uint8Array([5, 6, 7, 8]), + new Uint8Array([9, 10, 11, 12]), + ]; + const streams = [createReadableStream(chunks), base64EncodeStream()]; + const output = await streamToString(pipejoin(streams)); + const flat = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); + deepStrictEqual(output, Buffer.from(flat).toString("base64")); }); // *** default export *** // diff --git a/packages/base64/index.web.js b/packages/base64/index.web.js index 0dd2ea3..9176bbd 100644 --- a/packages/base64/index.web.js +++ b/packages/base64/index.web.js @@ -1,27 +1,54 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT +/* global btoa, atob */ import { createTransformStream } from "@datastream/core"; +const utf8Encoder = new TextEncoder(); + +const toBytes = (chunk) => { + if (chunk instanceof Uint8Array) return chunk; + if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk); + if (typeof chunk === "string") return utf8Encoder.encode(chunk); + return new Uint8Array(chunk); +}; + +const concat = (a, b) => { + const out = new Uint8Array(a.length + b.length); + out.set(a, 0); + out.set(b, a.length); + return out; +}; + +const bytesToBinaryString = (bytes) => { + let s = ""; + for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]); + return s; +}; + +const binaryStringToBytes = (s) => { + const out = new Uint8Array(s.length); + for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 0xff; + return out; +}; + export const base64EncodeStream = (_options = {}, streamOptions = {}) => { - let extra = ""; + let extra; // Uint8Array | undefined const transform = (chunk, enqueue) => { + let bytes = toBytes(chunk); if (extra) { - chunk = extra + chunk; - extra = ""; + bytes = concat(extra, bytes); + extra = undefined; } - - // 3 bytes == 4 char - const remaining = chunk.length % 3; + const remaining = bytes.length % 3; if (remaining > 0) { - extra = chunk.slice(chunk.length - remaining); - chunk = chunk.slice(0, chunk.length - remaining); + extra = bytes.slice(bytes.length - remaining); + bytes = bytes.subarray(0, bytes.length - remaining); } - - enqueue(btoa(chunk)); + if (bytes.length > 0) enqueue(btoa(bytesToBinaryString(bytes))); }; const flush = (enqueue) => { - if (extra) { - enqueue(btoa(extra)); + if (extra && extra.length > 0) { + enqueue(btoa(bytesToBinaryString(extra))); } }; return createTransformStream(transform, flush, streamOptions); @@ -30,22 +57,22 @@ export const base64EncodeStream = (_options = {}, streamOptions = {}) => { export const base64DecodeStream = (_options = {}, streamOptions = {}) => { let extra = ""; const transform = (chunk, enqueue) => { - chunk = extra + chunk; - - // 4 char == 3 bytes - const remaining = chunk.length % 4; - - extra = chunk.slice(chunk.length - remaining); - chunk = chunk.slice(0, chunk.length - remaining); - - enqueue(atob(chunk)); + const str = + typeof chunk === "string" ? chunk : bytesToBinaryString(toBytes(chunk)); + let s = extra.length > 0 ? extra + str : str; + extra = ""; + const remaining = s.length % 4; + if (remaining > 0) { + extra = s.slice(s.length - remaining); + s = s.slice(0, s.length - remaining); + } + if (s.length > 0) enqueue(binaryStringToBytes(atob(s))); }; const flush = (enqueue) => { - if (extra) { - enqueue(atob(extra)); + if (extra.length > 0) { + enqueue(binaryStringToBytes(atob(extra))); } }; - streamOptions.decodeStrings = false; return createTransformStream(transform, flush, streamOptions); }; diff --git a/packages/base64/package.json b/packages/base64/package.json index 639a9ee..ed8dc8b 100644 --- a/packages/base64/package.json +++ b/packages/base64/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/base64", - "version": "0.3.2", + "version": "0.4.0", "description": "Base64 encoding and decoding transform streams", "type": "module", "engines": { @@ -60,6 +60,6 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" } } diff --git a/packages/charset/decode.node.js b/packages/charset/decode.node.js index 4297e79..81b9525 100644 --- a/packages/charset/decode.node.js +++ b/packages/charset/decode.node.js @@ -1,8 +1,9 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT + +import { getSupportedEncoding } from "@datastream/charset/detect"; import { createTransformStream } from "@datastream/core"; import iconv from "iconv-lite"; -import { getSupportedEncoding } from "./detect.js"; export const charsetDecodeStream = ({ charset } = {}, streamOptions = {}) => { charset = getSupportedEncoding(charset); diff --git a/packages/charset/detect.js b/packages/charset/detect.js index 6ebc404..bcd3466 100644 --- a/packages/charset/detect.js +++ b/packages/charset/detect.js @@ -1,7 +1,7 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT import { createPassThroughStream } from "@datastream/core"; -import detect from "charset-detector"; +import { analyse } from "chardet"; const charsetKeys = [ "UTF-8", @@ -37,11 +37,15 @@ export const charsetDetectStream = ({ resultKey } = {}, streamOptions = {}) => { const charsets = Object.fromEntries(charsetKeys.map((k) => [k, 0])); let chunkCount = 0; const passThrough = (chunk) => { - const matches = detect(chunk); + const matches = analyse( + typeof chunk === "string" ? Buffer.from(chunk) : chunk, + ); chunkCount++; if (matches.length) { for (const match of matches) { - charsets[match.charsetName] += match.confidence; + if (match.name in charsets) { + charsets[match.name] += match.confidence; + } } } }; diff --git a/packages/charset/encode.node.js b/packages/charset/encode.node.js index 21e9456..b167dba 100644 --- a/packages/charset/encode.node.js +++ b/packages/charset/encode.node.js @@ -1,8 +1,9 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT + +import { getSupportedEncoding } from "@datastream/charset/detect"; import { createTransformStream } from "@datastream/core"; import iconv from "iconv-lite"; -import { getSupportedEncoding } from "./detect.js"; export const charsetEncodeStream = ({ charset } = {}, streamOptions = {}) => { charset = getSupportedEncoding(charset); diff --git a/packages/charset/index.test.js b/packages/charset/index.test.js index bc3b17a..b8bf89e 100644 --- a/packages/charset/index.test.js +++ b/packages/charset/index.test.js @@ -312,6 +312,18 @@ test(`${variant}: charsetDecodeStream should handle empty chunks`, async (_t) => deepStrictEqual(output, "test"); }); +// *** charsetDetectStream identifies known encodings *** // +test(`${variant}: charsetDetectStream should identify UTF-8 for multibyte input`, async (_t) => { + const input = [Buffer.from("测试 Hello 世界 Bonjour", "utf8")]; + const streams = [createReadableStream(input), charsetDetectStream()]; + + await pipeline(streams); + const { value } = streams[1].result(); + + strictEqual(value.charset, "UTF-8"); + ok(value.confidence > 0, `confidence ${value.confidence} should be > 0`); +}); + // *** charsetDetectStream concurrent isolation regression *** // test(`${variant}: charsetDetectStream instances should not share state`, async (_t) => { const input1 = [Buffer.from("Hello World")]; diff --git a/packages/charset/package.json b/packages/charset/package.json index 21f5ded..2bddb09 100644 --- a/packages/charset/package.json +++ b/packages/charset/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/charset", - "version": "0.3.2", + "version": "0.4.0", "description": "Character encoding detection, decoding, and conversion streams", "type": "module", "engines": { @@ -108,8 +108,8 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2", - "charset-detector": "0.0.2", + "@datastream/core": "0.4.0", + "chardet": "2.1.1", "iconv-lite": "0.7.2" } } diff --git a/packages/compress/index.test.js b/packages/compress/index.test.js index 3d77e7e..63f655e 100644 --- a/packages/compress/index.test.js +++ b/packages/compress/index.test.js @@ -37,10 +37,12 @@ for (const execArgv of process.execArgv) { const compressibleBody = JSON.stringify(new Array(1024).fill(0)); +let zstdCompressStream; +let zstdDecompressStream; if (variant === "node") { - const { zstdCompressStream, zstdDecompressStream } = await import( + ({ zstdCompressStream, zstdDecompressStream } = await import( "@datastream/compress/zstd" - ); + )); // *** zstd *** // test(`${variant}: zstdCompressStream should compress`, async (_t) => { @@ -154,6 +156,111 @@ if (variant === "node") { const output = await streamToString(pipejoin(streams)); strictEqual(output, compressibleBody); }); + + // *** maxOutputSize within limit (covers normal-path push) *** // + test(`${variant}: gzipDecompressStream should pass through within maxOutputSize`, async (_t) => { + const input = gzipSync(compressibleBody); + const streams = [ + createReadableStream(input), + gzipDecompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, compressibleBody); + }); + + test(`${variant}: deflateDecompressStream should pass through within maxOutputSize`, async (_t) => { + const input = deflateSync(compressibleBody); + const streams = [ + createReadableStream(input), + deflateDecompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, compressibleBody); + }); + + test(`${variant}: brotliDecompressStream should pass through within maxOutputSize`, async (_t) => { + const input = brotliCompressSync(compressibleBody); + const streams = [ + createReadableStream(input), + brotliDecompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, compressibleBody); + }); + + // *** zstd decompress maxOutputSize *** // + test(`${variant}: zstdDecompressStream should enforce maxOutputSize`, async (_t) => { + const input = zstdCompressSync(compressibleBody); + const streams = [ + createReadableStream(input), + zstdDecompressStream({ maxOutputSize: 100 }), + ]; + try { + await pipeline(streams); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxOutputSize")); + } + }); + + test(`${variant}: zstdDecompressStream should pass through within maxOutputSize`, async (_t) => { + const input = zstdCompressSync(compressibleBody); + const streams = [ + createReadableStream(input), + zstdDecompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, compressibleBody); + }); + + // *** compress maxOutputSize *** // + test(`${variant}: gzipCompressStream should enforce maxOutputSize`, async (_t) => { + const input = compressibleBody; + const streams = [ + createReadableStream(input), + gzipCompressStream({ maxOutputSize: 5 }), + ]; + try { + await pipeline(streams); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxOutputSize")); + } + }); + + test(`${variant}: gzipCompressStream should pass through within maxOutputSize`, async (_t) => { + const input = compressibleBody; + const streams = [ + createReadableStream(input), + gzipCompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, gzipSync(compressibleBody).toString()); + }); + + test(`${variant}: deflateCompressStream should enforce maxOutputSize`, async (_t) => { + const input = compressibleBody; + const streams = [ + createReadableStream(input), + deflateCompressStream({ maxOutputSize: 5 }), + ]; + try { + await pipeline(streams); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxOutputSize")); + } + }); + + test(`${variant}: deflateCompressStream should pass through within maxOutputSize`, async (_t) => { + const input = compressibleBody; + const streams = [ + createReadableStream(input), + deflateCompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, deflateSync(compressibleBody).toString()); + }); } // *** web variant decompression bomb protection *** // diff --git a/packages/compress/package.json b/packages/compress/package.json index daf0a16..5086bad 100644 --- a/packages/compress/package.json +++ b/packages/compress/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/compress", - "version": "0.3.2", + "version": "0.4.0", "description": "Compression and decompression streams for gzip, deflate, brotli, and zstd", "type": "module", "engines": { @@ -140,7 +140,7 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "peerDependencies": { "brotli-wasm": "^3.0.0", diff --git a/packages/core/index.d.ts b/packages/core/index.d.ts index 62f189a..e53fed2 100644 --- a/packages/core/index.d.ts +++ b/packages/core/index.d.ts @@ -133,3 +133,10 @@ export function timeout( ms: number, options?: { signal?: AbortSignal }, ): Promise; + +// Shared helpers +export function resolveLazy(value: T | (() => T)): T; +export function shallowClone(obj: T): T; +export function deepClone(obj: T): T; +export function shallowEqual(a: unknown, b: unknown): boolean; +export function deepEqual(a: unknown, b: unknown): boolean; diff --git a/packages/core/index.node.js b/packages/core/index.node.js index 8c5b193..f50d0bd 100644 --- a/packages/core/index.node.js +++ b/packages/core/index.node.js @@ -476,6 +476,43 @@ export const createWritableStream = (write, final, streamOptions) => { }); }; +// *** Shared helpers *** +export const resolveLazy = (value) => + typeof value === "function" ? value() : value; + +export const shallowClone = (obj) => ({ ...obj }); + +export const deepClone = (obj) => { + try { + return structuredClone(obj); + } catch (e) { + throw new Error("Failed to clone chunk, possibly circular reference", { + cause: e, + }); + } +}; + +export const shallowEqual = (a, b) => { + if (a === b) return true; + if (a == null || b == null) return false; + const keysA = Object.keys(a); + if (keysA.length !== Object.keys(b).length) return false; + for (const key of keysA) { + if (a[key] !== b[key]) return false; + } + return true; +}; + +export const deepEqual = (a, b) => { + try { + return JSON.stringify(a) === JSON.stringify(b); + } catch (e) { + throw new Error("Failed to stringify chunk, possibly circular reference", { + cause: e, + }); + } +}; + export const timeout = (ms, { signal } = {}) => { if (signal?.aborted) { return Promise.reject( diff --git a/packages/core/index.test.js b/packages/core/index.test.js index 7cff41a..f1a3c8f 100644 --- a/packages/core/index.test.js +++ b/packages/core/index.test.js @@ -1,17 +1,22 @@ import { deepStrictEqual, ok, strictEqual } from "node:assert"; -import test from "node:test"; +import test, { mock } from "node:test"; import { backpressureGauge, createPassThroughStream, createReadableStream, createTransformStream, createWritableStream, + deepClone, + deepEqual, isReadable, isWritable, makeOptions, pipejoin, pipeline, + resolveLazy, result, + shallowClone, + shallowEqual, streamToArray, streamToBuffer, streamToObject, @@ -19,7 +24,16 @@ import { timeout, } from "@datastream/core"; import { objectCountStream } from "@datastream/object"; -import sinon from "sinon"; + +const spy = (impl) => { + const fn = mock.fn(impl); + Object.defineProperty(fn, "callCount", { + get() { + return fn.mock.callCount(); + }, + }); + return fn; +}; let variant = "unknown"; for (const execArgv of process.execArgv) { @@ -296,7 +310,7 @@ if (variant === "node") { // *** createPassThroughStream *** // test(`${variant}: createPassThroughStream should create a pass through stream`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); + const transform = spy(); const streams = [ createReadableStream(input), createPassThroughStream(transform, {}), @@ -312,8 +326,8 @@ test(`${variant}: createPassThroughStream should create a pass through stream`, test(`${variant}: createPassThroughStream should create a pass through stream with flush`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); - const flush = sinon.spy(); + const transform = spy(); + const flush = spy(); const streams = [ createReadableStream(input), createPassThroughStream(transform, flush, {}), @@ -390,7 +404,7 @@ test(`${variant}: createPassThroughStream should catch flush error`, async (_t) // *** createTransformStream *** // test(`${variant}: createTransformStream should create a transform stream`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); + const transform = spy(); const streams = [ createReadableStream(input), createTransformStream(transform, {}), @@ -406,8 +420,8 @@ test(`${variant}: createTransformStream should create a transform stream`, async test(`${variant}: createTransformStream should create a transform stream with flush`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); - const flush = sinon.spy(); + const transform = spy(); + const flush = spy(); const streams = [ createReadableStream(input), createTransformStream(transform, flush, {}), @@ -486,7 +500,7 @@ test(`${variant}: createTransformStream should catch flush error`, async (_t) => // *** createWritableStream *** // test(`${variant}: createWritableStream should create a writable stream`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); + const transform = spy(); const streams = [ createReadableStream(input), createWritableStream(transform, {}), @@ -503,8 +517,8 @@ test(`${variant}: createWritableStream should create a writable stream`, async ( test(`${variant}: createWritableStream should create a writable stream with final`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); - const final = sinon.spy(); + const transform = spy(); + const final = spy(); const streams = [ createReadableStream(input), createWritableStream(transform, final, {}), @@ -587,7 +601,7 @@ test(`${variant}: createWritableStream should catch final error`, async (_t) => /*if (variant === "node") { test(`${variant}: createBranchStream should create a branch stream`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); + const transform = spy(); const stream = createWritableStream(transform); stream.result = () => ({ key: "a", value: 1 }); @@ -611,7 +625,7 @@ test(`${variant}: createWritableStream should catch final error`, async (_t) => // *** pipeline *** // test(`${variant}: pipeline should add writable to end of streams array`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); + const transform = spy(); const streams = [ createReadableStream(input), objectCountStream(), @@ -627,7 +641,7 @@ test(`${variant}: pipeline should add writable to end of streams array`, async ( test(`${variant}: pipeline should throw error when promise passed in`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); + const transform = spy(); const streams = [ createReadableStream(input), Promise.resolve(objectCountStream()), @@ -661,7 +675,7 @@ test(`${variant}: pipeline should throw error when a stream thrown an error`, as // *** pipejoin *** // test(`${variant}: pipejoin should throw error when promise passed in`, async (_t) => { const input = ["a", "b", "c"]; - const transform = sinon.spy(); + const transform = spy(); const streams = [ createReadableStream(input), Promise.resolve(objectCountStream()), @@ -718,91 +732,86 @@ if (variant === "node") { signal: undefined, }); }); -} else if (variant === "webstream") { - // test(`${variant}: makeOptions should return interoperable structure`, async (_t) => { - // // Web Stream always is in object mode - // const options = makeOptions({ highWaterMark: 1, chunkSize: 2 }) - // deepStrictEqual(options, { - // writableStrategy: { - // highWaterMark: 1, - // size: { chunk: 2 } - // }, - // readableStrategy: { - // highWaterMark: 1, - // size: { chunk: 2 } - // }, - // signal: undefined - // }) - // }) - - // *** timeout abort cleanup regression *** // - test(`${variant}: timeout should clear timer when aborted`, async (_t) => { - const controller = new AbortController(); - const promise = timeout(60_000, { signal: controller.signal }); - controller.abort(); - try { - await promise; - throw new Error("Should have thrown"); - } catch (e) { - strictEqual(e.message, "Aborted"); - deepStrictEqual(e.cause, { code: "AbortError" }); - } - }); +} - test(`${variant}: timeout should reject immediately if signal already aborted`, async (_t) => { - const controller = new AbortController(); - controller.abort(); - try { - await timeout(60_000, { signal: controller.signal }); - throw new Error("Should have thrown"); - } catch (e) { - strictEqual(e.message, "Aborted"); - } - }); +// *** timeout abort cleanup regression *** // +test(`${variant}: timeout should clear timer when aborted`, async (_t) => { + const controller = new AbortController(); + const promise = timeout(60_000, { signal: controller.signal }); + controller.abort(); + try { + await promise; + throw new Error("Should have thrown"); + } catch (e) { + strictEqual(e.message, "Aborted"); + deepStrictEqual(e.cause, { code: "AbortError" }); + } +}); - // *** maxBufferSize *** // - test(`${variant}: streamToArray should throw when exceeding maxBufferSize`, async (_t) => { - const stream = createReadableStream(["aaa", "bbb", "ccc"]); - try { - await streamToArray(stream, { maxBufferSize: 6 }); - throw new Error("Should have thrown"); - } catch (e) { - ok(e.message.includes("maxBufferSize")); - } - }); +test(`${variant}: timeout should reject immediately if signal already aborted`, async (_t) => { + const controller = new AbortController(); + controller.abort(); + try { + await timeout(60_000, { signal: controller.signal }); + throw new Error("Should have thrown"); + } catch (e) { + strictEqual(e.message, "Aborted"); + } +}); - test(`${variant}: streamToArray should not throw when within maxBufferSize`, async (_t) => { - const stream = createReadableStream(["aaa", "bbb"]); - const result = await streamToArray(stream, { maxBufferSize: 6 }); - deepStrictEqual(result, ["aaa", "bbb"]); - }); +// *** maxBufferSize *** // +test(`${variant}: streamToArray should throw when exceeding maxBufferSize`, async (_t) => { + const stream = createReadableStream(["aaa", "bbb", "ccc"]); + try { + await streamToArray(stream, { maxBufferSize: 6 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); - test(`${variant}: streamToString should throw when exceeding maxBufferSize`, async (_t) => { - const stream = createReadableStream(["aaa", "bbb", "ccc"]); - try { - await streamToString(stream, { maxBufferSize: 6 }); - throw new Error("Should have thrown"); - } catch (e) { - ok(e.message.includes("maxBufferSize")); - } - }); +test(`${variant}: streamToArray should not throw when within maxBufferSize`, async (_t) => { + const stream = createReadableStream(["aaa", "bbb"]); + const result = await streamToArray(stream, { maxBufferSize: 6 }); + deepStrictEqual(result, ["aaa", "bbb"]); +}); - test(`${variant}: streamToObject should throw when exceeding maxBufferSize`, async (_t) => { - const stream = createReadableStream([ - { a: 1 }, - { b: 2 }, - { c: 3 }, - { d: 4 }, - ]); - try { - await streamToObject(stream, { maxBufferSize: 2 }); - throw new Error("Should have thrown"); - } catch (e) { - ok(e.message.includes("maxBufferSize")); - } - }); +test(`${variant}: streamToString should throw when exceeding maxBufferSize`, async (_t) => { + const stream = createReadableStream(["aaa", "bbb", "ccc"]); + try { + await streamToString(stream, { maxBufferSize: 6 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToObject should throw when exceeding maxBufferSize`, async (_t) => { + const stream = createReadableStream([{ a: 1 }, { b: 2 }, { c: 3 }, { d: 4 }]); + try { + await streamToObject(stream, { maxBufferSize: 2 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToBuffer should throw when exceeding maxBufferSize`, async (_t) => { + const stream = createReadableStream([ + Buffer.from("aaa"), + Buffer.from("bbb"), + Buffer.from("ccc"), + ]); + try { + await streamToBuffer(stream, { maxBufferSize: 6 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); - // *** createReadableStream queue limit regression *** // +// *** createReadableStream queue limit regression *** // +if (variant === "node") { test(`${variant}: createReadableStream should throw when queue exceeds limit`, async (_t) => { const stream = createReadableStream(undefined, { highWaterMark: 3 }); stream.push("a"); @@ -816,3 +825,62 @@ if (variant === "node") { } }); } + +// *** deepClone / deepEqual error paths *** // +test(`${variant}: deepClone throws for non-cloneable values`, () => { + try { + deepClone({ fn: () => {} }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("clone chunk")); + } +}); + +test(`${variant}: deepEqual throws for circular references`, () => { + const a = {}; + a.self = a; + try { + deepEqual(a, a); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("stringify chunk")); + } +}); + +// *** shared helpers *** // +test(`${variant}: resolveLazy passes through values and calls thunks`, () => { + strictEqual(resolveLazy(5), 5); + strictEqual(resolveLazy("x"), "x"); + strictEqual( + resolveLazy(() => 42), + 42, + ); +}); + +test(`${variant}: shallowClone copies own enumerable properties`, () => { + const src = { a: 1, b: { c: 2 } }; + const copy = shallowClone(src); + deepStrictEqual(copy, src); + strictEqual(copy === src, false); + strictEqual(copy.b === src.b, true); +}); + +test(`${variant}: deepClone deep-copies via structuredClone`, () => { + const src = { a: 1, b: { c: 2 } }; + const copy = deepClone(src); + deepStrictEqual(copy, src); + strictEqual(copy.b === src.b, false); +}); + +test(`${variant}: shallowEqual compares own keys`, () => { + strictEqual(shallowEqual({ a: 1 }, { a: 1 }), true); + strictEqual(shallowEqual({ a: 1 }, { a: 2 }), false); + strictEqual(shallowEqual({ a: 1 }, { a: 1, b: 2 }), false); + strictEqual(shallowEqual(null, null), true); + strictEqual(shallowEqual(null, { a: 1 }), false); +}); + +test(`${variant}: deepEqual via JSON serialization`, () => { + strictEqual(deepEqual({ a: { b: 1 } }, { a: { b: 1 } }), true); + strictEqual(deepEqual({ a: { b: 1 } }, { a: { b: 2 } }), false); +}); diff --git a/packages/core/index.web.js b/packages/core/index.web.js index f7bf7c2..16b5887 100644 --- a/packages/core/index.web.js +++ b/packages/core/index.web.js @@ -293,6 +293,43 @@ export const createWritableStream = (write, close, streamOptions) => { ); }; +// *** Shared helpers *** +export const resolveLazy = (value) => + typeof value === "function" ? value() : value; + +export const shallowClone = (obj) => ({ ...obj }); + +export const deepClone = (obj) => { + try { + return structuredClone(obj); + } catch (e) { + throw new Error("Failed to clone chunk, possibly circular reference", { + cause: e, + }); + } +}; + +export const shallowEqual = (a, b) => { + if (a === b) return true; + if (a == null || b == null) return false; + const keysA = Object.keys(a); + if (keysA.length !== Object.keys(b).length) return false; + for (const key of keysA) { + if (a[key] !== b[key]) return false; + } + return true; +}; + +export const deepEqual = (a, b) => { + try { + return JSON.stringify(a) === JSON.stringify(b); + } catch (e) { + throw new Error("Failed to stringify chunk, possibly circular reference", { + cause: e, + }); + } +}; + export const timeout = (ms, { signal } = {}) => { if (signal?.aborted) { return Promise.reject( diff --git a/packages/core/package.json b/packages/core/package.json index 5e8b060..d9f48ef 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/core", - "version": "0.3.2", + "version": "0.4.0", "description": "Stream creation utilities and pipeline functions for Web Streams API and Node.js streams", "type": "module", "engines": { @@ -61,6 +61,6 @@ "homepage": "https://datastream.js.org", "dependencies": {}, "devDependencies": { - "@datastream/object": "0.3.2" + "@datastream/object": "0.4.0" } } diff --git a/packages/csv/index.js b/packages/csv/index.js index 29cbdd4..831c843 100644 --- a/packages/csv/index.js +++ b/packages/csv/index.js @@ -3,6 +3,7 @@ import { // createPassThroughStream, createTransformStream, + resolveLazy, } from "@datastream/core"; import { objectFromEntriesStream, @@ -33,8 +34,6 @@ const stripBOM = (str) => { return str.charCodeAt(0) === 0xfeff ? str.slice(1) : str; }; -const resolveLazy = (value) => (typeof value === "function" ? value() : value); - export const csvDetectDelimitersStream = (options = {}, streamOptions = {}) => { const { chunkSize = 1024, // 1KB @@ -659,6 +658,20 @@ const csvSteamifyParser = (options = {}) => { let buffer = ""; const errors = {}; + const mergeErrors = (incoming) => { + for (const id in incoming) { + if (errors[id]) { + errors[id].idx.push(...incoming[id].idx); + } else { + errors[id] = { + id: incoming[id].id, + message: incoming[id].message, + idx: [...incoming[id].idx], + }; + } + } + }; + const resolveOptions = () => { delimiterChar = resolveLazy(delimiterChar) ?? defaultDelimiterChar; newlineChar = resolveLazy(newlineChar) ?? defaultNewlineChar; @@ -700,7 +713,7 @@ const csvSteamifyParser = (options = {}) => { ctx.numCols = result.numCols; ctx.idx = result.idx; buffer = result.tail; - if (result.errors) Object.assign(errors, result.errors); + if (result.errors) mergeErrors(result.errors); const rows = result.rows; for (let i = 0; i < rows.length; i++) enqueue(rows[i]); } else { @@ -708,7 +721,7 @@ const csvSteamifyParser = (options = {}) => { ctx.errors = null; csvParseInline(text, ctx, false, enqueue); buffer = ctx.tail; - if (ctx.errors !== null) Object.assign(errors, ctx.errors); + if (ctx.errors !== null) mergeErrors(ctx.errors); } }; @@ -721,14 +734,14 @@ const csvSteamifyParser = (options = {}) => { const result = parser(remaining, ctx, true); ctx.numCols = result.numCols; ctx.idx = result.idx; - if (result.errors) Object.assign(errors, result.errors); + if (result.errors) mergeErrors(result.errors); const rows = result.rows; for (let i = 0; i < rows.length; i++) enqueue(rows[i]); } else { ctx.tail = ""; ctx.errors = null; csvParseInline(remaining, ctx, true, enqueue); - if (ctx.errors !== null) Object.assign(errors, ctx.errors); + if (ctx.errors !== null) mergeErrors(ctx.errors); } } }; diff --git a/packages/csv/index.test.js b/packages/csv/index.test.js index 9f3a799..e11aaaa 100644 --- a/packages/csv/index.test.js +++ b/packages/csv/index.test.js @@ -222,6 +222,29 @@ test(`${variant}: csvParseStream should preserve formula triggers in unquoted fi deepStrictEqual(output, [["=1+2", "+1", "-1", "@SUM"]]); }); +test(`${variant}: csvParseStream should accumulate error idx across chunks (custom parser)`, async (_t) => { + let call = 0; + const customParser = (_text, _ctx, _isFlushing) => { + call += 1; + // Each call reports a SyntheticError on the same id with a different idx + return { + rows: [], + tail: "", + numCols: 1, + idx: call, + errors: { Synthetic: { id: "Synthetic", message: "syn", idx: [call] } }, + }; + }; + const streams = [ + createReadableStream(["aaaaaaaaa", "bbbbbbbbb", "ccccccccc"]), + csvParseStream({ parser: customParser, chunkSize: 1 }), + ]; + const result = await pipeline(streams); + + // All three call indices should appear, not just the last one + deepStrictEqual(result.csvErrors.Synthetic.idx, [1, 2, 3]); +}); + test(`${variant}: csvParseStream should track unterminated quote on flush`, async (_t) => { const streams = [ createReadableStream('"ok",val\r\n"unterminated'), diff --git a/packages/csv/package.json b/packages/csv/package.json index 9aa749b..3d18188 100644 --- a/packages/csv/package.json +++ b/packages/csv/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/csv", - "version": "0.3.2", + "version": "0.4.0", "description": "CSV parsing and formatting transform streams", "type": "module", "engines": { @@ -63,7 +63,7 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2", - "@datastream/object": "0.3.2" + "@datastream/core": "0.4.0", + "@datastream/object": "0.4.0" } } diff --git a/packages/digest/package.json b/packages/digest/package.json index 82d2483..24030bc 100644 --- a/packages/digest/package.json +++ b/packages/digest/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/digest", - "version": "0.3.2", + "version": "0.4.0", "description": "Cryptographic hash digest pass-through streams", "type": "module", "engines": { @@ -60,7 +60,7 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2", + "@datastream/core": "0.4.0", "hash-wasm": "4.12.0" } } diff --git a/packages/encrypt/index.test.js b/packages/encrypt/index.test.js index 36fe1a5..db282e0 100644 --- a/packages/encrypt/index.test.js +++ b/packages/encrypt/index.test.js @@ -307,6 +307,76 @@ test(`${variant}: generateEncryptionKey should throw for unsupported bits`, (_t) throws(() => generateEncryptionKey({ bits: 512 }), /Unsupported key size/); }); +// *** validation error cases *** // +test(`${variant}: encryptStream should throw for invalid key length`, (_t) => { + throws(() => encryptStream({ key: randomBytes(16) }), /32 bytes/); + throws(() => encryptStream({}), /32 bytes/); +}); + +test(`${variant}: encryptStream should throw for invalid IV length`, (_t) => { + throws( + () => encryptStream({ key, iv: randomBytes(8) }), + /IV for AES-256-GCM/, + ); +}); + +test(`${variant}: encryptStream should throw for invalid aad`, (_t) => { + throws(() => encryptStream({ key, aad: "not-a-buffer" }), /aad must be/); +}); + +test(`${variant}: decryptStream should throw for invalid key length`, (_t) => { + throws( + () => decryptStream({ key: randomBytes(16), iv: randomBytes(12) }), + /32 bytes/, + ); +}); + +test(`${variant}: decryptStream should throw for invalid IV length`, (_t) => { + throws( + () => decryptStream({ key, iv: randomBytes(8) }), + /IV for AES-256-GCM/, + ); +}); + +test(`${variant}: decryptStream should throw for missing authTag on GCM`, (_t) => { + throws( + () => decryptStream({ key, iv: randomBytes(12) }), + /authTag for AES-256-GCM/, + ); +}); + +// *** within-limit paths *** // +test(`${variant}: encryptStream maxInputSize within limit should succeed`, async (_t) => { + const input = "a".repeat(50); + const enc = encryptStream({ key, maxInputSize: 100 }); + const streams = [createReadableStream(input), enc]; + await pipeline(streams); + strictEqual(enc.result().value.algorithm, "AES-256-GCM"); +}); + +test(`${variant}: decryptStream maxOutputSize within limit should succeed`, async (_t) => { + const input = "small"; + const enc = encryptStream({ key, algorithm: "AES-256-CTR" }); + const encryptedChunks = []; + const encStream = createReadableStream(input).pipe(enc); + for await (const chunk of encStream) { + encryptedChunks.push(chunk); + } + const { iv } = enc.result().value; + const dec = decryptStream({ + key, + iv, + algorithm: "AES-256-CTR", + maxOutputSize: 1000, + }); + const decStream = createReadableStream(encryptedChunks).pipe(dec); + const decryptedChunks = []; + for await (const chunk of decStream) { + decryptedChunks.push(chunk); + } + strictEqual(Buffer.concat(decryptedChunks).toString("utf8"), input); +}); + // *** default export *** // test(`${variant}: default export should include all functions`, (_t) => { deepStrictEqual(Object.keys(encryptDefault).sort(), [ diff --git a/packages/encrypt/index.web.js b/packages/encrypt/index.web.js index 7f1acb4..9efa1dd 100644 --- a/packages/encrypt/index.web.js +++ b/packages/encrypt/index.web.js @@ -65,7 +65,8 @@ const concatBuffers = (chunks) => { // Max safe counter: 2^64 blocks = 2^68 bytes (256 EB). // Beyond this, keystream reuse breaks confidentiality. -const MAX_CTR_BLOCKS = 2 ** 64; +// BigInt so the comparison stays meaningful past 2^53. +const MAX_CTR_BLOCKS = 1n << 64n; const incrementCounter = (iv, blockOffset) => { if (blockOffset >= MAX_CTR_BLOCKS) { @@ -75,10 +76,10 @@ const incrementCounter = (iv, blockOffset) => { } const counter = new Uint8Array(iv); let carry = blockOffset; - for (let i = counter.length - 1; i >= 0 && carry > 0; i--) { - const sum = counter[i] + (carry & 0xff); - counter[i] = sum & 0xff; - carry = (carry >> 8) + (sum >> 8); + for (let i = counter.length - 1; i >= 0 && carry > 0n; i--) { + const sum = BigInt(counter[i]) + (carry & 0xffn); + counter[i] = Number(sum & 0xffn); + carry = (carry >> 8n) + (sum >> 8n); } return counter; }; @@ -186,7 +187,7 @@ const aesCtrEncrypt = async ({ key, iv }, streamOptions) => { false, ["encrypt"], ); - let blockOffset = 0; + let blockOffset = 0n; const transform = async (chunk, enqueue) => { const buf = chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk); @@ -196,7 +197,7 @@ const aesCtrEncrypt = async ({ key, iv }, streamOptions) => { cryptoKey, buf, ); - blockOffset += Math.ceil(buf.byteLength / 16); + blockOffset += BigInt(Math.ceil(buf.byteLength / 16)); enqueue(new Uint8Array(encrypted)); }; const stream = createTransformStream(transform, streamOptions); @@ -217,7 +218,7 @@ const aesCtrDecrypt = async ({ key, iv, maxOutputSize }, streamOptions) => { false, ["decrypt"], ); - let blockOffset = 0; + let blockOffset = 0n; let outputSize = 0; const transform = async (chunk, enqueue) => { const buf = @@ -228,7 +229,7 @@ const aesCtrDecrypt = async ({ key, iv, maxOutputSize }, streamOptions) => { cryptoKey, buf, ); - blockOffset += Math.ceil(buf.byteLength / 16); + blockOffset += BigInt(Math.ceil(buf.byteLength / 16)); const result = new Uint8Array(decrypted); if (maxOutputSize != null) { outputSize += result.byteLength; diff --git a/packages/encrypt/package.json b/packages/encrypt/package.json index 11ae25e..d11b07c 100644 --- a/packages/encrypt/package.json +++ b/packages/encrypt/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/encrypt", - "version": "0.3.2", + "version": "0.4.0", "description": "Symmetric encryption/decryption streams", "type": "module", "engines": { @@ -60,7 +60,7 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" }, "peerDependencies": { "libsodium-wrappers": ">=0.7.0" diff --git a/packages/fetch/index.js b/packages/fetch/index.js index e091cd4..865b94a 100644 --- a/packages/fetch/index.js +++ b/packages/fetch/index.js @@ -246,9 +246,11 @@ export const fetchRateLimit = async (options, streamOptions = {}) => { } await response.body?.cancel(); const retryAfter = response.headers.get("Retry-After"); - const backoffMs = retryAfter + // Full jitter (AWS architecture blog) avoids retry-storm sync-up. + const baseMs = retryAfter ? Number.parseInt(retryAfter, 10) * 1000 || 1000 : Math.min(1000 * 2 ** (options.retryCount - 1), 30_000); + const backoffMs = retryAfter ? baseMs : Math.random() * baseMs; await timeout(backoffMs, streamOptions); return fetchRateLimit(options, streamOptions); } diff --git a/packages/fetch/package.json b/packages/fetch/package.json index 19f9534..6e71c3e 100644 --- a/packages/fetch/package.json +++ b/packages/fetch/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/fetch", - "version": "0.3.2", + "version": "0.4.0", "description": "HTTP fetch-based readable and writable streams with pagination and rate limiting", "type": "module", "engines": { @@ -60,6 +60,6 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" } } diff --git a/packages/file/index.node.js b/packages/file/index.node.js index de23729..66603c5 100644 --- a/packages/file/index.node.js +++ b/packages/file/index.node.js @@ -7,7 +7,7 @@ import { lstatSync, openSync, } from "node:fs"; -import { extname, resolve } from "node:path"; +import { extname, isAbsolute, relative, resolve } from "node:path"; import { makeOptions } from "@datastream/core"; export const fileReadStream = ( @@ -47,7 +47,8 @@ const enforcePath = (path, basePath) => { if (basePath != null) { const resolvedPath = resolve(path); const resolvedBase = resolve(basePath); - if (!resolvedPath.startsWith(resolvedBase)) { + const rel = relative(resolvedBase, resolvedPath); + if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) { throw new Error("Path traversal detected"); } try { diff --git a/packages/file/index.test.js b/packages/file/index.test.js index b500cad..196cfa8 100644 --- a/packages/file/index.test.js +++ b/packages/file/index.test.js @@ -62,6 +62,15 @@ test(`${variant}: fileWriteStream should reject path traversal`, () => { }); }); +test(`${variant}: fileReadStream should reject sibling-prefix bypass`, () => { + // basePath '/tmp/foo' must not contain '/tmp/foobar/secret' + throws( + () => + fileReadStream({ path: `${testDir}-sibling/x.csv`, basePath: testDir }), + { message: "Path traversal detected" }, + ); +}); + // *** Symlink rejection *** // test(`${variant}: fileReadStream should reject symlinks`, () => { const linkPath = join(testDir, "link.csv"); diff --git a/packages/file/package.json b/packages/file/package.json index c606126..6134c34 100644 --- a/packages/file/package.json +++ b/packages/file/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/file", - "version": "0.3.2", + "version": "0.4.0", "description": "File system readable and writable streams with extension type enforcement", "type": "module", "engines": { @@ -60,6 +60,6 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" } } diff --git a/packages/indexeddb/package.json b/packages/indexeddb/package.json index 7a3065a..d73b8f4 100644 --- a/packages/indexeddb/package.json +++ b/packages/indexeddb/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/indexeddb", - "version": "0.3.2", + "version": "0.4.0", "description": "IndexedDB readable and writable streams for browser storage", "type": "module", "engines": { @@ -60,7 +60,7 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2", + "@datastream/core": "0.4.0", "idb": "8.0.3" } } diff --git a/packages/ipfs/package.json b/packages/ipfs/package.json index c7edbc4..bab3405 100644 --- a/packages/ipfs/package.json +++ b/packages/ipfs/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/ipfs", - "version": "0.3.2", + "version": "0.4.0", "description": "IPFS get and add streaming operations", "type": "module", "engines": { @@ -61,6 +61,6 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" } } diff --git a/packages/json/index.js b/packages/json/index.js index 66ba907..d825048 100644 --- a/packages/json/index.js +++ b/packages/json/index.js @@ -96,6 +96,7 @@ export const jsonParseStream = (options = {}, streamOptions = {}) => { let inString = false; let escaped = false; let started = false; + let sawNonWhitespace = false; let elementStart = -1; let idx = 0; const errors = {}; @@ -223,6 +224,7 @@ export const jsonParseStream = (options = {}, streamOptions = {}) => { `jsonParseStream buffer (${buffer.length + chunk.length}) exceeds maxBufferSize (${maxBufferSize})`, ); } + if (!sawNonWhitespace && /\S/.test(chunk)) sawNonWhitespace = true; buffer += chunk; scan(enqueue); }; @@ -234,6 +236,9 @@ export const jsonParseStream = (options = {}, streamOptions = {}) => { emitElement(trimmed, enqueue); } } + if (!started && sawNonWhitespace) { + trackError("NoArrayStart", "Input did not contain a top-level array"); + } buffer = ""; }; diff --git a/packages/json/index.test.js b/packages/json/index.test.js index ae89841..607820c 100644 --- a/packages/json/index.test.js +++ b/packages/json/index.test.js @@ -246,6 +246,26 @@ test(`${variant}: jsonParseStream should track parse errors in result`, async (_ deepStrictEqual(value.ParseError.idx, [1]); }); +test(`${variant}: jsonParseStream should track NoArrayStart when no '[' seen`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream('{"a":1}'), parse]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + deepStrictEqual(output, []); + const { value } = parse.result(); + deepStrictEqual(value.NoArrayStart?.id, "NoArrayStart"); + deepStrictEqual(value.NoArrayStart?.idx, [0]); +}); + +test(`${variant}: jsonParseStream should not flag NoArrayStart for empty input`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream(""), parse]; + await streamToArray(pipejoin(streams)); + const { value } = parse.result(); + deepStrictEqual(value.NoArrayStart, undefined); +}); + test(`${variant}: jsonParseStream should throw when buffer exceeds maxBufferSize`, async (_t) => { let error; try { diff --git a/packages/json/package.json b/packages/json/package.json index ff01cc1..7fb8b9b 100644 --- a/packages/json/package.json +++ b/packages/json/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/json", - "version": "0.3.2", + "version": "0.4.0", "description": "JSON and NDJSON (JSON Lines) parsing and formatting transform streams", "type": "module", "engines": { @@ -63,6 +63,6 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" } } diff --git a/packages/object/index.js b/packages/object/index.js index 9aa4087..61cec69 100644 --- a/packages/object/index.js +++ b/packages/object/index.js @@ -4,6 +4,10 @@ import { createPassThroughStream, createReadableStream, createTransformStream, + deepClone, + deepEqual, + shallowClone, + shallowEqual, } from "@datastream/core"; export const objectReadableStream = (input = [], streamOptions = {}) => { @@ -220,38 +224,6 @@ export const objectToEntriesStream = ({ keys }, streamOptions = {}) => { return createTransformStream(transform, streamOptions); }; -const deepClone = (obj) => { - try { - return structuredClone(obj); - } catch (e) { - throw new Error("Failed to clone chunk, possibly circular reference", { - cause: e, - }); - } -}; -const shallowClone = (obj) => ({ ...obj }); - -const shallowEqual = (a, b) => { - if (a === b) return true; - if (a == null || b == null) return false; - const keysA = Object.keys(a); - if (keysA.length !== Object.keys(b).length) return false; - for (const key of keysA) { - if (a[key] !== b[key]) return false; - } - return true; -}; - -const deepEqual = (a, b) => { - try { - return JSON.stringify(a) === JSON.stringify(b); - } catch (e) { - throw new Error("Failed to stringify chunk, possibly circular reference", { - cause: e, - }); - } -}; - export const objectSkipConsecutiveDuplicatesStream = ( options = {}, streamOptions = {}, diff --git a/packages/object/package.json b/packages/object/package.json index 422f666..5f68a75 100644 --- a/packages/object/package.json +++ b/packages/object/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/object", - "version": "0.3.2", + "version": "0.4.0", "description": "Object transform streams for picking, omitting, pivoting, batching, and key mapping", "type": "module", "engines": { @@ -60,6 +60,6 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" } } diff --git a/packages/string/package.json b/packages/string/package.json index cf646f5..68bde9b 100644 --- a/packages/string/package.json +++ b/packages/string/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/string", - "version": "0.3.2", + "version": "0.4.0", "description": "String transform streams for splitting, replacing, counting, and deduplication", "type": "module", "engines": { @@ -60,6 +60,6 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2" + "@datastream/core": "0.4.0" } } diff --git a/packages/validate/package.json b/packages/validate/package.json index b67e6fb..82291a8 100644 --- a/packages/validate/package.json +++ b/packages/validate/package.json @@ -1,6 +1,6 @@ { "name": "@datastream/validate", - "version": "0.3.2", + "version": "0.4.0", "description": "JSON Schema validation transform streams using Ajv", "type": "module", "engines": { @@ -60,7 +60,7 @@ }, "homepage": "https://datastream.js.org", "dependencies": { - "@datastream/core": "0.3.2", - "ajv-cmd": "0.11.0" + "@datastream/core": "0.4.0", + "ajv-cmd": "0.12.0" } } diff --git a/websites/datastream.js.org/package.json b/websites/datastream.js.org/package.json index 237b073..3a0a4c4 100644 --- a/websites/datastream.js.org/package.json +++ b/websites/datastream.js.org/package.json @@ -2,7 +2,7 @@ "name": "datastream.js.org", "description": "SvelteKit SSR", "private": true, - "version": "0.3.2", + "version": "0.4.0", "type": "module", "scripts": { "start": "vite dev",