diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e5574bd..b03b065 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,11 @@ updates: directory: "/" schedule: interval: "weekly" + groups: + everything: + patterns: + - "*" - package-ecosystem: npm directory: "/" schedule: - interval: "weekly" \ No newline at end of file + interval: "weekly" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c6cbe5..e2e49cd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,8 @@ on: pull_request: types: [closed] branches: [main] + paths: + - 'package.json' env: NODE_VERSION: 24.x diff --git a/.github/workflows/test-pref.yml b/.github/workflows/test-perf.yml similarity index 100% rename from .github/workflows/test-pref.yml rename to .github/workflows/test-perf.yml diff --git a/.github/workflows/test-sast.yml b/.github/workflows/test-sast.yml index eee8755..f06b33a 100644 --- a/.github/workflows/test-sast.yml +++ b/.github/workflows/test-sast.yml @@ -1,4 +1,4 @@ -name: "Test (sast)" +name: Tests (sast) on: pull_request: @@ -31,7 +31,7 @@ jobs: ignore-unfixed: true exit-code: 1 format: github - + trivy-license: name: "Trivy: Licensing" runs-on: ubuntu-latest @@ -56,12 +56,12 @@ jobs: hide-progress: true exit-code: 0 format: table - + lockfile: name: "lockfile-lint: SAST package-lock.json" runs-on: ubuntu-latest if: (github.actor != 'dependabot[bot]') - + steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -77,7 +77,7 @@ jobs: run: | ./node_modules/.bin/lockfile-lint --path package-lock.json --type npm --allowed-hosts npm --validate-https - + # https://github.com/github/codeql-action codeql: name: "CodeQL: SAST" diff --git a/.github/workflows/test-types.yml b/.github/workflows/test-types.yml new file mode 100644 index 0000000..192df75 --- /dev/null +++ b/.github/workflows/test-types.yml @@ -0,0 +1,29 @@ +name: Tests (types) + +on: + pull_request: + +env: + NODE_VERSION: 24.x + +permissions: + contents: read + +jobs: + types: + name: Tests (types) + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - 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 + - name: Install dependencies + run: | + npm ci --ignore-scripts + - name: Check typings + run: npm run test:types diff --git a/.github/workflows/website-cloudflare-pages.yml b/.github/workflows/website-cloudflare-pages.yml new file mode 100644 index 0000000..df6799b --- /dev/null +++ b/.github/workflows/website-cloudflare-pages.yml @@ -0,0 +1,47 @@ +name: Publish Website + +on: + workflow_dispatch: + push: + paths: + - "websites/**" + branches: + - main + +env: + NODE_VERSION: 24.x + DOMAIN_NAME: 1auth.js.org + +permissions: + contents: read + +jobs: + website: + name: Publish website + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - 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" + - name: Install dependencies + run: | + npm ci --ignore-scripts --workspace websites/${{ env.DOMAIN_NAME }} + - name: Build website + working-directory: websites/${{ env.DOMAIN_NAME }} + run: | + npm run build + - name: Publish website + uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3.14.1 + with: + workingDirectory: websites/${{ env.DOMAIN_NAME }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + command: | + pages deploy diff --git a/README.md b/README.md index ccf7089..8423e1f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

GitHub Actions unit test status GitHub Actions dast test status - GitHub Actions perf test status + GitHub Actions perf test status GitHub Actions SAST test status GitHub Actions lint test status
@@ -134,4 +134,4 @@ session({ ## License -Licensed under [MIT License](LICENSE). Copyright (c) 1985-2025 [will Farrell](https://github.com/willfarrell) and all [contributors](https://github.com/willfarrell/1auth/graphs/contributors). +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/SECURITY.md b/SECURITY.md index d5d362a..448cbe8 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -28,8 +28,20 @@ Only the latest major version is supported for security updates. ## Threat model +The primary threats this library is designed to mitigate: + +- **Credential stuffing / brute force:** Timing-safe authentication with minimum duration (`setTimeout`), Argon2id password hashing with configurable cost. +- **Session hijacking:** HMAC-signed session IDs, encrypted session storage, per-session encryption keys. +- **Credential theft at rest:** Per-record ChaCha20-Poly1305 encryption with per-user derived keys. +- **Account enumeration:** Constant-time authentication responses via `setTimeout` to prevent timing side-channels. +- **Token replay:** OTP tokens are expired/removed after single use. + ## Trust Boundaries +- **Client ↔ Application Server:** All user inputs (credentials, tokens, session IDs) are validated at entry. +- **Application Server ↔ Database:** All sensitive fields are encrypted before storage; digests are used for lookups instead of plaintext. +- **Application Server ↔ Notification Service:** Tokens are sent through notification channels, never returned in API responses directly. + ## Reporting a Vulnerability The core OSS team and community take all security vulnerabilities diff --git a/biome.json b/biome.json index 12bb61b..ff5d2e4 100644 --- a/biome.json +++ b/biome.json @@ -1,12 +1,12 @@ { - "$schema": "https://biomejs.dev/schemas/2.3.14/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.6/schema.json", "vcs": { - "enabled": false, + "enabled": true, "clientKind": "git", - "useIgnoreFile": false + "useIgnoreFile": true }, "files": { - "ignoreUnknown": false + "ignoreUnknown": true }, "formatter": { "enabled": true, @@ -15,9 +15,21 @@ "linter": { "enabled": true, "rules": { - "recommended": true + "recommended": true, + "complexity": { + "noBannedTypes": "off" + }, + "correctness": { + "noUnusedFunctionParameters": "off" + }, + "suspicious": { + "noExplicitAny": "off" + } } }, + "html": { + "experimentalFullSupportEnabled": true + }, "javascript": { "formatter": { "quoteStyle": "double" @@ -30,5 +42,15 @@ "organizeImports": "on" } } - } + }, + "overrides": [ + { + "includes": ["**/*.svelte"], + "css": { + "linter": { + "enabled": false + } + } + } + ] } diff --git a/docs/GOVERNANCE.md b/docs/GOVERNANCE.md index 39a29eb..054d05a 100644 --- a/docs/GOVERNANCE.md +++ b/docs/GOVERNANCE.md @@ -2,15 +2,15 @@ ## Roles -### [Owner](TODO link to org group) +### [Owner](https://github.com/orgs/1auth-js/teams/owner) Also known as a core maintainer. Have a long history with the project, have a deep understanding of the codebase, and decide the direction of the project. -### [Security](TODO link to org group) +### [Security](https://github.com/orgs/1auth-js/teams/security) Are responsible to respond and remediate security disclosures. -### [Reviewer](TODO link to org group) +### [Reviewer](https://github.com/orgs/1auth-js/teams/reviewer) Group of people responsible for reviewing pull requests. diff --git a/docs/img/1auth-logo.svg b/docs/img/1auth-logo.svg new file mode 100644 index 0000000..f7855e1 --- /dev/null +++ b/docs/img/1auth-logo.svg @@ -0,0 +1 @@ +Untitled \ No newline at end of file diff --git a/license.json b/license.json index d3279e0..7b906a8 100644 --- a/license.json +++ b/license.json @@ -24,6 +24,7 @@ "**/*.md", "**/*.yml", "test/**/*", - "website/**/*" + "websites/**/*", + ".DS_Store" ] } diff --git a/package-lock.json b/package-lock.json index 9165553..37919fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@1auth/monorepo", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@1auth/monorepo", - "version": "0.0.0-beta.1", - "hasInstallScript": true, + "version": "0.0.0-beta.2", "license": "MIT", "workspaces": [ "packages/*", + "websites/*", ".github" ], "devDependencies": { @@ -20,7 +20,7 @@ "aws-sdk-client-mock": "^4.0.0", "fast-check": "^4.0.0", "husky": "^9.0.0", - "license-check-and-add": "4.0.5", + "license-check-and-add": "^4.0.0", "tinybench": "^6.0.0" }, "engines": { @@ -93,6 +93,10 @@ "resolved": "packages/session", "link": true }, + "node_modules/@1auth/store-d1": { + "resolved": "packages/store-d1", + "link": true + }, "node_modules/@1auth/store-dynamodb": { "resolved": "packages/store-dynamodb", "link": true @@ -241,53 +245,53 @@ } }, "node_modules/@aws-sdk/client-dynamodb": { - "version": "3.985.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.985.0.tgz", - "integrity": "sha512-e11U2wheDF3hhYOQse3nA0ZsvKGJXf74bwrNnU3gnPhafK7mGfvu6WzJNGIrJBf1aDYsNJ/U5yZL7fe1mBS8fg==", + "version": "3.1007.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1007.0.tgz", + "integrity": "sha512-wGkXr8jG9p2AYwUdxxo1q/F0AYUT8g1mL0OntbBPBCr8fDuicOf1r2M28lV7lEiIrRCAxKVOzRJ6gHef6IpErA==", "license": "Apache-2.0", "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/credential-provider-node": "^3.972.6", - "@aws-sdk/dynamodb-codec": "^3.972.8", - "@aws-sdk/middleware-endpoint-discovery": "^3.972.3", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.7", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.985.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.5", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.22.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.13", - "@smithy/middleware-retry": "^4.4.30", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.29", - "@smithy/util-defaults-mode-node": "^4.2.32", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", - "@smithy/util-waiter": "^4.2.8", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/credential-provider-node": "^3.972.19", + "@aws-sdk/dynamodb-codec": "^3.972.20", + "@aws-sdk/middleware-endpoint-discovery": "^3.972.7", + "@aws-sdk/middleware-host-header": "^3.972.7", + "@aws-sdk/middleware-logger": "^3.972.7", + "@aws-sdk/middleware-recursion-detection": "^3.972.7", + "@aws-sdk/middleware-user-agent": "^3.972.20", + "@aws-sdk/region-config-resolver": "^3.972.7", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@aws-sdk/util-user-agent-browser": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.973.5", + "@smithy/config-resolver": "^4.4.10", + "@smithy/core": "^3.23.9", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/hash-node": "^4.2.11", + "@smithy/invalid-dependency": "^4.2.11", + "@smithy/middleware-content-length": "^4.2.11", + "@smithy/middleware-endpoint": "^4.4.23", + "@smithy/middleware-retry": "^4.4.40", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@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.39", + "@smithy/util-defaults-mode-node": "^4.2.42", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.12", "tslib": "^2.6.2" }, "engines": { @@ -295,102 +299,52 @@ } }, "node_modules/@aws-sdk/client-sqs": { - "version": "3.985.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.985.0.tgz", - "integrity": "sha512-aFBV3ggSmVLGOpU5oCb+FhwN8xGqX3bnv6VBQnbdW8krqdg+a+KsFIRjNKs7O7gYhb1Z2lC/izu2R1pFKiep+w==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/credential-provider-node": "^3.972.6", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-sdk-sqs": "^3.972.6", - "@aws-sdk/middleware-user-agent": "^3.972.7", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.985.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.5", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.22.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/md5-js": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.13", - "@smithy/middleware-retry": "^4.4.30", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.29", - "@smithy/util-defaults-mode-node": "^4.2.32", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.985.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.985.0.tgz", - "integrity": "sha512-81J8iE8MuXhdbMfIz4sWFj64Pe41bFi/uqqmqOC5SlGv+kwoyLsyKS/rH2tW2t5buih4vTUxskRjxlqikTD4oQ==", + "version": "3.1007.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1007.0.tgz", + "integrity": "sha512-I0MzooPlcWgCPV76mKGPvAZtSgGmIuHevvl9KU7IvCHOHQPIP1Rx+1RW5u0jFoTTgq9YuudyAvFU8DmHW28fNQ==", "license": "Apache-2.0", "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.7", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.985.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.5", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.22.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.13", - "@smithy/middleware-retry": "^4.4.30", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.29", - "@smithy/util-defaults-mode-node": "^4.2.32", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/credential-provider-node": "^3.972.19", + "@aws-sdk/middleware-host-header": "^3.972.7", + "@aws-sdk/middleware-logger": "^3.972.7", + "@aws-sdk/middleware-recursion-detection": "^3.972.7", + "@aws-sdk/middleware-sdk-sqs": "^3.972.14", + "@aws-sdk/middleware-user-agent": "^3.972.20", + "@aws-sdk/region-config-resolver": "^3.972.7", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@aws-sdk/util-user-agent-browser": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.973.5", + "@smithy/config-resolver": "^4.4.10", + "@smithy/core": "^3.23.9", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/hash-node": "^4.2.11", + "@smithy/invalid-dependency": "^4.2.11", + "@smithy/md5-js": "^4.2.11", + "@smithy/middleware-content-length": "^4.2.11", + "@smithy/middleware-endpoint": "^4.4.23", + "@smithy/middleware-retry": "^4.4.40", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@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.39", + "@smithy/util-defaults-mode-node": "^4.2.42", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -398,24 +352,24 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.973.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.7.tgz", - "integrity": "sha512-wNZZQQNlJ+hzD49cKdo+PY6rsTDElO8yDImnrI69p2PLBa7QomeUKAJWYp9xnaR38nlHqWhMHZuYLCQ3oSX+xg==", + "version": "3.973.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.19.tgz", + "integrity": "sha512-56KePyOcZnKTWCd89oJS1G6j3HZ9Kc+bh/8+EbvtaCCXdP6T7O7NzCiPuHRhFLWnzXIaXX3CxAz0nI5My9spHQ==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/xml-builder": "^3.972.4", - "@smithy/core": "^3.22.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/xml-builder": "^3.972.10", + "@smithy/core": "^3.23.9", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/signature-v4": "^5.3.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -423,16 +377,16 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.5.tgz", - "integrity": "sha512-LxJ9PEO4gKPXzkufvIESUysykPIdrV7+Ocb9yAhbhJLE4TiAYqbCVUE+VuKP1leGR1bBfjWjYgSV5MxprlX3mQ==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.17.tgz", + "integrity": "sha512-MBAMW6YELzE1SdkOniqr51mrjapQUv8JXSGxtwRjQV0mwVDutVsn22OPAUt4RcLRvdiHQmNBDEFP9iTeSVCOlA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -440,21 +394,21 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.7.tgz", - "integrity": "sha512-L2uOGtvp2x3bTcxFTpSM+GkwFIPd8pHfGWO1764icMbo7e5xJh0nfhx1UwkXLnwvocTNEf8A7jISZLYjUSNaTg==", + "version": "3.972.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.19.tgz", + "integrity": "sha512-9EJROO8LXll5a7eUFqu48k6BChrtokbmgeMWmsH7lBb6lVbtjslUYz/ShLi+SHkYzTomiGBhmzTW7y+H4BxsnA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/types": "^3.973.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.9", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.11", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/types": "^3.973.5", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" }, "engines": { @@ -462,25 +416,25 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.5.tgz", - "integrity": "sha512-SdDTYE6jkARzOeL7+kudMIM4DaFnP5dZVeatzw849k4bSXDdErDS188bgeNzc/RA2WGrlEpsqHUKP6G7sVXhZg==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.18.tgz", + "integrity": "sha512-vthIAXJISZnj2576HeyLBj4WTeX+I7PwWeRkbOa0mVX39K13SCGxCgOFuKj2ytm9qTlLOmXe4cdEnroteFtJfw==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/credential-provider-env": "^3.972.5", - "@aws-sdk/credential-provider-http": "^3.972.7", - "@aws-sdk/credential-provider-login": "^3.972.5", - "@aws-sdk/credential-provider-process": "^3.972.5", - "@aws-sdk/credential-provider-sso": "^3.972.5", - "@aws-sdk/credential-provider-web-identity": "^3.972.5", - "@aws-sdk/nested-clients": "3.985.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/credential-provider-env": "^3.972.17", + "@aws-sdk/credential-provider-http": "^3.972.19", + "@aws-sdk/credential-provider-login": "^3.972.18", + "@aws-sdk/credential-provider-process": "^3.972.17", + "@aws-sdk/credential-provider-sso": "^3.972.18", + "@aws-sdk/credential-provider-web-identity": "^3.972.18", + "@aws-sdk/nested-clients": "^3.996.8", + "@aws-sdk/types": "^3.973.5", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -488,19 +442,19 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.5.tgz", - "integrity": "sha512-uYq1ILyTSI6ZDCMY5+vUsRM0SOCVI7kaW4wBrehVVkhAxC6y+e9rvGtnoZqCOWL1gKjTMouvsf4Ilhc5NCg1Aw==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.18.tgz", + "integrity": "sha512-kINzc5BBxdYBkPZ0/i1AMPMOk5b5QaFNbYMElVw5QTX13AKj6jcxnv/YNl9oW9mg+Y08ti19hh01HhyEAxsSJQ==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/nested-clients": "3.985.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/nested-clients": "^3.996.8", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -508,23 +462,23 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.6.tgz", - "integrity": "sha512-DZ3CnAAtSVtVz+G+ogqecaErMLgzph4JH5nYbHoBMgBkwTUV+SUcjsjOJwdBJTHu3Dm6l5LBYekZoU2nDqQk2A==", + "version": "3.972.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.19.tgz", + "integrity": "sha512-yDWQ9dFTr+IMxwanFe7+tbN5++q8psZBjlUwOiCXn1EzANoBgtqBwcpYcHaMGtn0Wlfj4NuXdf2JaEx1lz5RaQ==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.5", - "@aws-sdk/credential-provider-http": "^3.972.7", - "@aws-sdk/credential-provider-ini": "^3.972.5", - "@aws-sdk/credential-provider-process": "^3.972.5", - "@aws-sdk/credential-provider-sso": "^3.972.5", - "@aws-sdk/credential-provider-web-identity": "^3.972.5", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/credential-provider-env": "^3.972.17", + "@aws-sdk/credential-provider-http": "^3.972.19", + "@aws-sdk/credential-provider-ini": "^3.972.18", + "@aws-sdk/credential-provider-process": "^3.972.17", + "@aws-sdk/credential-provider-sso": "^3.972.18", + "@aws-sdk/credential-provider-web-identity": "^3.972.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -532,17 +486,17 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.5.tgz", - "integrity": "sha512-HDKF3mVbLnuqGg6dMnzBf1VUOywE12/N286msI9YaK9mEIzdsGCtLTvrDhe3Up0R9/hGFbB+9l21/TwF5L1C6g==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.17.tgz", + "integrity": "sha512-c8G8wT1axpJDgaP3xzcy+q8Y1fTi9A2eIQJvyhQ9xuXrUZhlCfXbC0vM9bM1CUXiZppFQ1p7g0tuUMvil/gCPg==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -550,19 +504,19 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.5.tgz", - "integrity": "sha512-8urj3AoeNeQisjMmMBhFeiY2gxt6/7wQQbEGun0YV/OaOOiXrIudTIEYF8ZfD+NQI6X1FY5AkRsx6O/CaGiybA==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.18.tgz", + "integrity": "sha512-YHYEfj5S2aqInRt5ub8nDOX8vAxgMvd84wm2Y3WVNfFa/53vOv9T7WOAqXI25qjj3uEcV46xxfqdDQk04h5XQA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/client-sso": "3.985.0", - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/token-providers": "3.985.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/nested-clients": "^3.996.8", + "@aws-sdk/token-providers": "3.1005.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -570,18 +524,18 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.5.tgz", - "integrity": "sha512-OK3cULuJl6c+RcDZfPpaK5o3deTOnKZbxm7pzhFNGA3fI2hF9yDih17fGRazJzGGWaDVlR9ejZrpDef4DJCEsw==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.18.tgz", + "integrity": "sha512-OqlEQpJ+J3T5B96qtC1zLLwkBloechP+fezKbCH0sbd2cCc0Ra55XpxWpk/hRj69xAOYtHvoC4orx6eTa4zU7g==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/nested-clients": "3.985.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/nested-clients": "^3.996.8", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -589,17 +543,17 @@ } }, "node_modules/@aws-sdk/dynamodb-codec": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.972.8.tgz", - "integrity": "sha512-5ngfn6fQPSNc7G9LlingK4SXfzcJtv5pOP++erc7HmCq0LcDj//0pcpLgxpDII0sBTh0FcR/iw9i4fBZwSJ2Cg==", + "version": "3.972.20", + "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.972.20.tgz", + "integrity": "sha512-MQ2W0zeBMNaQYgHcQ7aul7g5783qFdP2AKcJnpaID0ekl2QbiKF+St1JMx5lgOXHlnERD9X3exr2B0SIg35oOA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@smithy/core": "^3.22.1", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", + "@aws-sdk/core": "^3.973.19", + "@smithy/core": "^3.23.9", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -607,9 +561,9 @@ } }, "node_modules/@aws-sdk/endpoint-cache": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.2.tgz", - "integrity": "sha512-3L7mwqSLJ6ouZZKtCntoNF0HTYDNs1FDQqkGjoPWXcv1p0gnLotaDmLq1rIDqfu4ucOit0Re3ioLyYDUTpSroA==", + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.4.tgz", + "integrity": "sha512-GdASDnWanLnHxKK0hqV97xz23QmfA/C8yGe0PiuEmWiHSe+x+x+mFEj4sXqx9IbfyPncWz8f4EhNwBSG9cgYCg==", "license": "Apache-2.0", "peer": true, "dependencies": { @@ -621,17 +575,17 @@ } }, "node_modules/@aws-sdk/middleware-endpoint-discovery": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.3.tgz", - "integrity": "sha512-xAxA8/TOygQmMrzcw9CrlpTHCGWSG/lvzrHCySfSZpDN4/yVSfXO+gUwW9WxeskBmuv9IIFATOVpzc9EzfTZ0Q==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.7.tgz", + "integrity": "sha512-ZeFfgAVOGR+fDq/JAPsVA3P07ba74hIppoGfmQyfzZMfAQAzc9Lbg5pndZU8EanzfKnlXbv6y09OMrSkTsUuOg==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/endpoint-cache": "^3.972.2", - "@aws-sdk/types": "^3.973.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/endpoint-cache": "^3.972.4", + "@aws-sdk/types": "^3.973.5", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -639,15 +593,15 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.3.tgz", - "integrity": "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.7.tgz", + "integrity": "sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -655,14 +609,14 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.3.tgz", - "integrity": "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.7.tgz", + "integrity": "sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -670,16 +624,16 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.3.tgz", - "integrity": "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.7.tgz", + "integrity": "sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", + "@aws-sdk/types": "^3.973.5", "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -687,17 +641,17 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sqs": { - "version": "3.972.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.6.tgz", - "integrity": "sha512-6e+dZ1qPEIDO8ASIu09QNVrwXAzuLOuD5jd1M7oj41e+/wShJPn2oG8ZDYUGTnGBOrc4h1UILWYodzMzzTrkiQ==", + "version": "3.972.14", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.14.tgz", + "integrity": "sha512-MmN/j0D3MLkR0cca8/V2GXjGAkcgp1tlrQZZduLb6G+UhfOJuzFW3rSrCeiXTBgiXSIIZ6sc/gsuACpg/5TL1Q==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -705,18 +659,19 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.7.tgz", - "integrity": "sha512-HUD+geASjXSCyL/DHPQc/Ua7JhldTcIglVAoCV8kiVm99IaFSlAbTvEnyhZwdE6bdFyTL+uIaWLaCFSRsglZBQ==", + "version": "3.972.20", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.20.tgz", + "integrity": "sha512-3kNTLtpUdeahxtnJRnj/oIdLAUdzTfr9N40KtxNhtdrq+Q1RPMdCJINRXq37m4t5+r3H70wgC3opW46OzFcZYA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.985.0", - "@smithy/core": "^3.22.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@smithy/core": "^3.23.9", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-retry": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -724,49 +679,49 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.985.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.985.0.tgz", - "integrity": "sha512-TsWwKzb/2WHafAY0CE7uXgLj0FmnkBTgfioG9HO+7z/zCPcl1+YU+i7dW4o0y+aFxFgxTMG+ExBQpqT/k2ao8g==", + "version": "3.996.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.8.tgz", + "integrity": "sha512-6HlLm8ciMW8VzfB80kfIx16PBA9lOa9Dl+dmCBi78JDhvGlx3I7Rorwi5PpVRkL31RprXnYna3yBf6UKkD/PqA==", "license": "Apache-2.0", "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.7", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.985.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.5", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.22.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.13", - "@smithy/middleware-retry": "^4.4.30", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.29", - "@smithy/util-defaults-mode-node": "^4.2.32", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/middleware-host-header": "^3.972.7", + "@aws-sdk/middleware-logger": "^3.972.7", + "@aws-sdk/middleware-recursion-detection": "^3.972.7", + "@aws-sdk/middleware-user-agent": "^3.972.20", + "@aws-sdk/region-config-resolver": "^3.972.7", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@aws-sdk/util-user-agent-browser": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.973.5", + "@smithy/config-resolver": "^4.4.10", + "@smithy/core": "^3.23.9", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/hash-node": "^4.2.11", + "@smithy/invalid-dependency": "^4.2.11", + "@smithy/middleware-content-length": "^4.2.11", + "@smithy/middleware-endpoint": "^4.4.23", + "@smithy/middleware-retry": "^4.4.40", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@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.39", + "@smithy/util-defaults-mode-node": "^4.2.42", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -774,16 +729,16 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.3.tgz", - "integrity": "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.7.tgz", + "integrity": "sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/config-resolver": "^4.4.10", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -791,18 +746,18 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.985.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.985.0.tgz", - "integrity": "sha512-+hwpHZyEq8k+9JL2PkE60V93v2kNhUIv7STFt+EAez1UJsJOQDhc5LpzEX66pNjclI5OTwBROs/DhJjC/BtMjQ==", + "version": "3.1005.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1005.0.tgz", + "integrity": "sha512-vMxd+ivKqSxU9bHx5vmAlFKDAkjGotFU56IOkDa5DaTu1WWwbcse0yFHEm9I537oVvodaiwMl3VBwgHfzQ2rvw==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/core": "^3.973.7", - "@aws-sdk/nested-clients": "3.985.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.19", + "@aws-sdk/nested-clients": "^3.996.8", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -810,13 +765,13 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.973.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.1.tgz", - "integrity": "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==", + "version": "3.973.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.5.tgz", + "integrity": "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -824,9 +779,9 @@ } }, "node_modules/@aws-sdk/util-dynamodb": { - "version": "3.985.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.985.0.tgz", - "integrity": "sha512-bf+DvndbrtbNgGtFT4kqDRC5Udi3W1C3Q4028n1i1+PRbRGPLVaXkfsis393YmiyIHca0WPRsCH9/dE9ROlbuw==", + "version": "3.996.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.996.2.tgz", + "integrity": "sha512-ddpwaZmjBzcApYN7lgtAXjk+u+GO8fiPsxzuc59UqP+zqdxI1gsenPvkyiHiF9LnYnyRGijz6oN2JylnN561qQ==", "license": "Apache-2.0", "peer": true, "dependencies": { @@ -836,20 +791,20 @@ "node": ">=20.0.0" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "^3.985.0" + "@aws-sdk/client-dynamodb": "^3.1003.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.985.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.985.0.tgz", - "integrity": "sha512-vth7UfGSUR3ljvaq8V4Rc62FsM7GUTH/myxPWkaEgOrprz1/Pc72EgTXxj+cPPPDAfHFIpjhkB7T7Td0RJx+BA==", + "version": "3.996.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.4.tgz", + "integrity": "sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-endpoints": "^3.2.8", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-endpoints": "^3.3.2", "tslib": "^2.6.2" }, "engines": { @@ -857,9 +812,9 @@ } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.965.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.4.tgz", - "integrity": "sha512-H1onv5SkgPBK2P6JR2MjGgbOnttoNzSPIRoeZTNPZYyaplwGg50zS3amXvXqF0/qfXpWEC9rLWU564QTB9bSog==", + "version": "3.965.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", + "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", "license": "Apache-2.0", "peer": true, "dependencies": { @@ -870,29 +825,29 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.3.tgz", - "integrity": "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.7.tgz", + "integrity": "sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.5.tgz", - "integrity": "sha512-GsUDF+rXyxDZkkJxUsDxnA67FG+kc5W1dnloCFLl6fWzceevsCYzJpASBzT+BPjwUgREE6FngfJYYYMQUY5fZQ==", + "version": "3.973.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.5.tgz", + "integrity": "sha512-Dyy38O4GeMk7UQ48RupfHif//gqnOPbq/zlvRssc11E2mClT+aUfc3VS2yD8oLtzqO3RsqQ9I3gOBB4/+HjPOw==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.7", - "@aws-sdk/types": "^3.973.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/middleware-user-agent": "^3.972.20", + "@aws-sdk/types": "^3.973.5", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -908,14 +863,14 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.4.tgz", - "integrity": "sha512-0zJ05ANfYqI6+rGqj8samZBFod0dPPousBjLEqg8WdxSgbMAkRgLyn81lP215Do0rFJ/17LIXwr7q0yK24mP6Q==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.10.tgz", + "integrity": "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@smithy/types": "^4.12.0", - "fast-xml-parser": "5.3.4", + "@smithy/types": "^4.13.0", + "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" }, "engines": { @@ -923,9 +878,9 @@ } }, "node_modules/@aws/lambda-invoke-store": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.3.tgz", - "integrity": "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", + "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", "license": "Apache-2.0", "peer": true, "engines": { @@ -957,10 +912,20 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@biomejs/biome": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.14.tgz", - "integrity": "sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.6.tgz", + "integrity": "sha512-QnHe81PMslpy3mnpL8DnO2M4S4ZnYPkjlGCLWBZT/3R9M6b5daArWMMtEfP52/n174RKnwRIf3oT8+wc9ihSfQ==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -974,20 +939,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.3.14", - "@biomejs/cli-darwin-x64": "2.3.14", - "@biomejs/cli-linux-arm64": "2.3.14", - "@biomejs/cli-linux-arm64-musl": "2.3.14", - "@biomejs/cli-linux-x64": "2.3.14", - "@biomejs/cli-linux-x64-musl": "2.3.14", - "@biomejs/cli-win32-arm64": "2.3.14", - "@biomejs/cli-win32-x64": "2.3.14" + "@biomejs/cli-darwin-arm64": "2.4.6", + "@biomejs/cli-darwin-x64": "2.4.6", + "@biomejs/cli-linux-arm64": "2.4.6", + "@biomejs/cli-linux-arm64-musl": "2.4.6", + "@biomejs/cli-linux-x64": "2.4.6", + "@biomejs/cli-linux-x64-musl": "2.4.6", + "@biomejs/cli-win32-arm64": "2.4.6", + "@biomejs/cli-win32-x64": "2.4.6" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.14.tgz", - "integrity": "sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.6.tgz", + "integrity": "sha512-NW18GSyxr+8sJIqgoGwVp5Zqm4SALH4b4gftIA0n62PTuBs6G2tHlwNAOj0Vq0KKSs7Sf88VjjmHh0O36EnzrQ==", "cpu": [ "arm64" ], @@ -1002,9 +967,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.14.tgz", - "integrity": "sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.6.tgz", + "integrity": "sha512-4uiE/9tuI7cnjtY9b07RgS7gGyYOAfIAGeVJWEfeCnAarOAS7qVmuRyX6d7JTKw28/mt+rUzMasYeZ+0R/U1Mw==", "cpu": [ "x64" ], @@ -1019,13 +984,16 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.14.tgz", - "integrity": "sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.6.tgz", + "integrity": "sha512-kMLaI7OF5GN1Q8Doymjro1P8rVEoy7BKQALNz6fiR8IC1WKduoNyteBtJlHT7ASIL0Cx2jR6VUOBIbcB1B8pew==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -1036,13 +1004,16 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.14.tgz", - "integrity": "sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.6.tgz", + "integrity": "sha512-F/JdB7eN22txiTqHM5KhIVt0jVkzZwVYrdTR1O3Y4auBOQcXxHK4dxULf4z43QyZI5tsnQJrRBHZy7wwtL+B3A==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -1053,13 +1024,16 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.14.tgz", - "integrity": "sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.6.tgz", + "integrity": "sha512-oHXmUFEoH8Lql1xfc3QkFLiC1hGR7qedv5eKNlC185or+o4/4HiaU7vYODAH3peRCfsuLr1g6v2fK9dFFOYdyw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -1070,13 +1044,16 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.14.tgz", - "integrity": "sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.6.tgz", + "integrity": "sha512-C9s98IPDu7DYarjlZNuzJKTjVHN03RUnmHV5htvqsx6vEUXCDSJ59DNwjKVD5XYoSS4N+BYhq3RTBAL8X6svEg==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -1087,9 +1064,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.14.tgz", - "integrity": "sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.6.tgz", + "integrity": "sha512-xzThn87Pf3YrOGTEODFGONmqXpTwUNxovQb72iaUOdcw8sBSY3+3WD8Hm9IhMYLnPi0n32s3L3NWU6+eSjfqFg==", "cpu": [ "arm64" ], @@ -1104,9 +1081,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.14.tgz", - "integrity": "sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.6.tgz", + "integrity": "sha512-7++XhnsPlr1HDbor5amovPjOH6vsrFOCdp93iKXhFn6bcMUI6soodj3WWKfgEO6JosKU1W5n3uky3WW9RlRjTg==", "cpu": [ "x64" ], @@ -1120,18 +1097,136 @@ "node": ">=14.21.3" } }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.2.tgz", + "integrity": "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==", + "dev": true, + "license": "MIT OR Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.15.0.tgz", + "integrity": "sha512-EGYmJaGZKWl+X8tXxcnx4v2bOZSjQeNI5dWFeXivgX9+YCT69AkzHHwlNbVpqtEUTbew8eQurpyOpeN8fg00nw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": "1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20260310.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260310.1.tgz", + "integrity": "sha512-hF2VpoWaMb1fiGCQJqCY6M8I+2QQqjkyY4LiDYdTL5D/w6C1l5v1zhc0/jrjdD1DXfpJtpcSMSmEPjHse4p9Ig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20260310.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260310.1.tgz", + "integrity": "sha512-h/Vl3XrYYPI6yFDE27XO1QPq/1G1lKIM8tzZGIWYpntK3IN5XtH3Ee/sLaegpJ49aIJoqhF2mVAZ6Yw+Vk2gJw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20260310.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260310.1.tgz", + "integrity": "sha512-XzQ0GZ8G5P4d74bQYOIP2Su4CLdNPpYidrInaSOuSxMw+HamsHaFrjVsrV2mPy/yk2hi6SY2yMbgKFK9YjA7vw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20260310.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260310.1.tgz", + "integrity": "sha512-sxv4CxnN4ZR0uQGTFVGa0V4KTqwdej/czpIc5tYS86G8FQQoGIBiAIs2VvU7b8EROPcandxYHDBPTb+D9HIMPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20260310.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260310.1.tgz", + "integrity": "sha512-+1ZTViWKJypLfgH/luAHCqkent0DEBjAjvO40iAhOMHRLYP/SPphLvr4Jpi6lb+sIocS8Q1QZL4uM5Etg1Wskg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20260312.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260312.1.tgz", + "integrity": "sha512-ySoTKc2ZKpwHll4H6byPWkxI/vmCc86B4h+hKo077zSTmBqIcxvbFozmOcEY7dhudMMDBnCgwZ9FknRrJxyqiQ==", + "dev": true, + "license": "MIT OR Apache-2.0" + }, "node_modules/@commitlint/cli": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.4.1.tgz", - "integrity": "sha512-uuFKKpc7OtQM+6SRqT+a4kV818o1pS+uvv/gsRhyX7g4x495jg+Q7P0+O9VNGyLXBYP0syksS7gMRDJKcekr6A==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.4.4.tgz", + "integrity": "sha512-GLMNQHYGcn0ohL2HMlAnXcD1PS2vqBBGbYKlhrRPOYsWiRoLWtrewsR3uKRb9v/IdS+qOS0vqJQ64n1g8VPKFw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/format": "^20.4.0", - "@commitlint/lint": "^20.4.1", - "@commitlint/load": "^20.4.0", - "@commitlint/read": "^20.4.0", - "@commitlint/types": "^20.4.0", + "@commitlint/format": "^20.4.4", + "@commitlint/lint": "^20.4.4", + "@commitlint/load": "^20.4.4", + "@commitlint/read": "^20.4.4", + "@commitlint/types": "^20.4.4", "tinyexec": "^1.0.0", "yargs": "^17.0.0" }, @@ -1143,27 +1238,27 @@ } }, "node_modules/@commitlint/config-conventional": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.4.1.tgz", - "integrity": "sha512-0YUvIeBtpi86XriqrR+TCULVFiyYTIOEPjK7tTRMxjcBm1qlzb+kz7IF2WxL6Fq5DaundG8VO37BNgMkMTBwqA==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.4.4.tgz", + "integrity": "sha512-Usg+XXbPNG2GtFWTgRURNWCge1iH1y6jQIvvklOdAbyn2t8ajfVwZCnf5t5X4gUsy17BOiY+myszGsSMIvhOVA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.4.0", - "conventional-changelog-conventionalcommits": "^9.1.0" + "@commitlint/types": "^20.4.4", + "conventional-changelog-conventionalcommits": "^9.2.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/config-validator": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.4.0.tgz", - "integrity": "sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.4.4.tgz", + "integrity": "sha512-K8hMS9PTLl7EYe5vWtSFQ/sgsV2PHUOtEnosg8k3ZQxCyfKD34I4C7FxWEfRTR54rFKeUYmM3pmRQqBNQeLdlw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.4.0", + "@commitlint/types": "^20.4.4", "ajv": "^8.11.0" }, "engines": { @@ -1171,13 +1266,13 @@ } }, "node_modules/@commitlint/ensure": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.4.1.tgz", - "integrity": "sha512-WLQqaFx1pBooiVvBrA1YfJNFqZF8wS/YGOtr5RzApDbV9tQ52qT5VkTsY65hFTnXhW8PcDfZLaknfJTmPejmlw==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.4.4.tgz", + "integrity": "sha512-QivV0M1MGL867XCaF+jJkbVXEPKBALhUUXdjae66hes95aY1p3vBJdrcl3x8jDv2pdKWvIYIz+7DFRV/v0dRkA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.4.0", + "@commitlint/types": "^20.4.4", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -1199,13 +1294,13 @@ } }, "node_modules/@commitlint/format": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.4.0.tgz", - "integrity": "sha512-i3ki3WR0rgolFVX6r64poBHXM1t8qlFel1G1eCBvVgntE3fCJitmzSvH5JD/KVJN/snz6TfaX2CLdON7+s4WVQ==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.4.4.tgz", + "integrity": "sha512-jLi/JBA4GEQxc5135VYCnkShcm1/rarbXMn2Tlt3Si7DHiiNKHm4TaiJCLnGbZ1r8UfwDRk+qrzZ80kwh08Aow==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.4.0", + "@commitlint/types": "^20.4.4", "picocolors": "^1.1.1" }, "engines": { @@ -1213,13 +1308,13 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.4.1.tgz", - "integrity": "sha512-In5EO4JR1lNsAv1oOBBO24V9ND1IqdAJDKZiEpdfjDl2HMasAcT7oA+5BKONv1pRoLG380DGPE2W2RIcUwdgLA==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.4.4.tgz", + "integrity": "sha512-y76rT8yq02x+pMDBI2vY4y/ByAwmJTkta/pASbgo8tldBiKLduX8/2NCRTSCjb3SumE5FBeopERKx3oMIm8RTQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.4.0", + "@commitlint/types": "^20.4.4", "semver": "^7.6.0" }, "engines": { @@ -1227,33 +1322,33 @@ } }, "node_modules/@commitlint/lint": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.4.1.tgz", - "integrity": "sha512-g94LrGl/c6UhuhDQqNqU232aslLEN2vzc7MPfQTHzwzM4GHNnEAwVWWnh0zX8S5YXecuLXDwbCsoGwmpAgPWKA==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.4.4.tgz", + "integrity": "sha512-svOEW+RptcNpXKE7UllcAsV0HDIdOck9reC2TP1QA6K5Fo0xxQV+QPjV8Zqx9g6X/hQBkF2S9ZQZ78Xrv1Eiog==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/is-ignored": "^20.4.1", - "@commitlint/parse": "^20.4.1", - "@commitlint/rules": "^20.4.1", - "@commitlint/types": "^20.4.0" + "@commitlint/is-ignored": "^20.4.4", + "@commitlint/parse": "^20.4.4", + "@commitlint/rules": "^20.4.4", + "@commitlint/types": "^20.4.4" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/load": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.4.0.tgz", - "integrity": "sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.4.4.tgz", + "integrity": "sha512-kvFrzvoIACa/fMjXEP0LNEJB1joaH3q3oeMJsLajXE5IXjYrNGVcW1ZFojXUruVJ7odTZbC3LdE/6+ONW4f2Dg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^20.4.0", + "@commitlint/config-validator": "^20.4.4", "@commitlint/execute-rule": "^20.0.0", - "@commitlint/resolve-extends": "^20.4.0", - "@commitlint/types": "^20.4.0", - "cosmiconfig": "^9.0.0", + "@commitlint/resolve-extends": "^20.4.4", + "@commitlint/types": "^20.4.4", + "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", "is-plain-obj": "^4.1.0", "lodash.mergewith": "^4.6.2", @@ -1264,9 +1359,9 @@ } }, "node_modules/@commitlint/message": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.0.tgz", - "integrity": "sha512-B5lGtvHgiLAIsK5nLINzVW0bN5hXv+EW35sKhYHE8F7V9Uz1fR4tx3wt7mobA5UNhZKUNgB/+ldVMQE6IHZRyA==", + "version": "20.4.3", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.3.tgz", + "integrity": "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==", "dev": true, "license": "MIT", "engines": { @@ -1274,30 +1369,30 @@ } }, "node_modules/@commitlint/parse": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.4.1.tgz", - "integrity": "sha512-XNtZjeRcFuAfUnhYrCY02+mpxwY4OmnvD3ETbVPs25xJFFz1nRo/25nHj+5eM+zTeRFvWFwD4GXWU2JEtoK1/w==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.4.4.tgz", + "integrity": "sha512-AjfgOgrjEozeQNzhFu1KL5N0nDx4JZmswVJKNfOTLTUGp6xODhZHCHqb//QUHKOzx36If5DQ7tci2o7szYxu1A==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.4.0", - "conventional-changelog-angular": "^8.1.0", - "conventional-commits-parser": "^6.2.1" + "@commitlint/types": "^20.4.4", + "conventional-changelog-angular": "^8.2.0", + "conventional-commits-parser": "^6.3.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/read": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.4.0.tgz", - "integrity": "sha512-QfpFn6/I240ySEGv7YWqho4vxqtPpx40FS7kZZDjUJ+eHxu3azfhy7fFb5XzfTqVNp1hNoI3tEmiEPbDB44+cg==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.4.4.tgz", + "integrity": "sha512-jvgdAQDdEY6L8kCxOo21IWoiAyNFzvrZb121wU2eBxI1DzWAUZgAq+a8LlJRbT0Qsj9INhIPVWgdaBbEzlF0dQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/top-level": "^20.4.0", - "@commitlint/types": "^20.4.0", - "git-raw-commits": "^4.0.0", + "@commitlint/top-level": "^20.4.3", + "@commitlint/types": "^20.4.4", + "git-raw-commits": "^5.0.0", "minimist": "^1.2.8", "tinyexec": "^1.0.0" }, @@ -1306,14 +1401,14 @@ } }, "node_modules/@commitlint/resolve-extends": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.4.0.tgz", - "integrity": "sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.4.4.tgz", + "integrity": "sha512-pyOf+yX3c3m/IWAn2Jop+7s0YGKPQ8YvQaxt9IQxnLIM3yZAlBdkKiQCT14TnrmZTkVGTXiLtckcnFTXYwlY0A==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^20.4.0", - "@commitlint/types": "^20.4.0", + "@commitlint/config-validator": "^20.4.4", + "@commitlint/types": "^20.4.4", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", @@ -1324,16 +1419,16 @@ } }, "node_modules/@commitlint/rules": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.4.1.tgz", - "integrity": "sha512-WtqypKEPbQEuJwJS4aKs0OoJRBKz1HXPBC9wRtzVNH68FLhPWzxXlF09hpUXM9zdYTpm4vAdoTGkWiBgQ/vL0g==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.4.4.tgz", + "integrity": "sha512-PmUp8QPLICn9w05dAx5r1rdOYoTk7SkfusJJh5tP3TqHwo2mlQ9jsOm8F0HSXU9kuLfgTEGNrunAx/dlK/RyPQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/ensure": "^20.4.1", - "@commitlint/message": "^20.4.0", + "@commitlint/ensure": "^20.4.4", + "@commitlint/message": "^20.4.3", "@commitlint/to-lines": "^20.0.0", - "@commitlint/types": "^20.4.0" + "@commitlint/types": "^20.4.4" }, "engines": { "node": ">=v18" @@ -1350,9 +1445,9 @@ } }, "node_modules/@commitlint/top-level": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.0.tgz", - "integrity": "sha512-NDzq8Q6jmFaIIBC/GG6n1OQEaHdmaAAYdrZRlMgW6glYWGZ+IeuXmiymDvQNXPc82mVxq2KiE3RVpcs+1OeDeA==", + "version": "20.4.3", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.3.tgz", + "integrity": "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1363,1515 +1458,5707 @@ } }, "node_modules/@commitlint/types": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.4.0.tgz", - "integrity": "sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==", + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.4.4.tgz", + "integrity": "sha512-dwTGzyAblFXHJNBOgrTuO5Ee48ioXpS5XPRLLatxhQu149DFAHUcB3f0Q5eea3RM4USSsP1+WVT2dBtLVod4fg==", "dev": true, "license": "MIT", "dependencies": { - "conventional-commits-parser": "^6.2.1", + "conventional-commits-parser": "^6.3.0", "picocolors": "^1.1.1" }, "engines": { "node": ">=v18" } }, - "node_modules/@hexagon/base64": { - "version": "1.1.28", - "resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz", - "integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==", - "license": "MIT" - }, - "node_modules/@levischuck/tiny-cbor": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.2.11.tgz", - "integrity": "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==", - "license": "MIT" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@conventional-changelog/git-client": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.6.0.tgz", + "integrity": "sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@simple-libs/child-process-utils": "^1.0.0", + "@simple-libs/stream-utils": "^1.2.0", + "semver": "^7.5.2" }, "engines": { - "node": ">= 8" + "node": ">=18" + }, + "peerDependencies": { + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.3.0" + }, + "peerDependenciesMeta": { + "conventional-commits-filter": { + "optional": true + }, + "conventional-commits-parser": { + "optional": true + } } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, "engines": { - "node": ">= 8" + "node": ">=12" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@peculiar/asn1-android": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.6.0.tgz", - "integrity": "sha512-cBRCKtYPF7vJGN76/yG8VbxRcHLPF3HnkoHhKOZeHpoVtbMYfY9ROKtH3DtYUY9m8uI1Mh47PRhHf2hSK3xcSQ==", + "node_modules/@emnapi/runtime": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", + "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", + "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "tslib": "^2.4.0" } }, - "node_modules/@peculiar/asn1-cms": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.0.tgz", - "integrity": "sha512-2uZqP+ggSncESeUF/9Su8rWqGclEfEiz1SyU02WX5fUONFfkjzS2Z/F1Li0ofSmf4JqYXIOdCAZqIXAIBAT1OA==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "cpu": [ + "ppc64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "@peculiar/asn1-x509-attr": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@peculiar/asn1-csr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.0.tgz", - "integrity": "sha512-BeWIu5VpTIhfRysfEp73SGbwjjoLL/JWXhJ/9mo4vXnz3tRGm+NGm3KNcRzQ9VMVqwYS2RHlolz21svzRXIHPQ==", + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "cpu": [ + "arm" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@peculiar/asn1-ecc": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.0.tgz", - "integrity": "sha512-FF3LMGq6SfAOwUG2sKpPXblibn6XnEIKa+SryvUl5Pik+WR9rmRA3OCiwz8R3lVXnYnyRkSZsSLdml8H3UiOcw==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@peculiar/asn1-pfx": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.0.tgz", - "integrity": "sha512-rtUvtf+tyKGgokHHmZzeUojRZJYPxoD/jaN1+VAB4kKR7tXrnDCA/RAWXAIhMJJC+7W27IIRGe9djvxKgsldCQ==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-cms": "^2.6.0", - "@peculiar/asn1-pkcs8": "^2.6.0", - "@peculiar/asn1-rsa": "^2.6.0", - "@peculiar/asn1-schema": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@peculiar/asn1-pkcs8": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.0.tgz", - "integrity": "sha512-KyQ4D8G/NrS7Fw3XCJrngxmjwO/3htnA0lL9gDICvEQ+GJ+EPFqldcJQTwPIdvx98Tua+WjkdKHSC0/Km7T+lA==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@peculiar/asn1-pkcs9": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.0.tgz", - "integrity": "sha512-b78OQ6OciW0aqZxdzliXGYHASeCvvw5caqidbpQRYW2mBtXIX2WhofNXTEe7NyxTb0P6J62kAAWLwn0HuMF1Fw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@hexagon/base64": { + "version": "1.1.28", + "resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz", + "integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==", + "license": "MIT" + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@levischuck/tiny-cbor": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.2.11.tgz", + "integrity": "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==", + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "license": "MIT" + }, + "node_modules/@peculiar/asn1-android": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.6.0.tgz", + "integrity": "sha512-cBRCKtYPF7vJGN76/yG8VbxRcHLPF3HnkoHhKOZeHpoVtbMYfY9ROKtH3DtYUY9m8uI1Mh47PRhHf2hSK3xcSQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz", + "integrity": "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/asn1-x509-attr": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz", + "integrity": "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz", + "integrity": "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz", + "integrity": "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.1", + "@peculiar/asn1-pkcs8": "^2.6.1", + "@peculiar/asn1-rsa": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz", + "integrity": "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz", + "integrity": "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.1", + "@peculiar/asn1-pfx": "^2.6.1", + "@peculiar/asn1-pkcs8": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/asn1-x509-attr": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz", + "integrity": "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", + "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", + "license": "MIT", + "dependencies": { + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz", + "integrity": "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz", + "integrity": "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@poppinss/colors": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", + "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", + "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/dumper/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", + "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@simple-libs/child-process-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz", + "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" + } + }, + "node_modules/@simple-libs/stream-utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", + "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" + } + }, + "node_modules/@simplewebauthn/browser": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.2.2.tgz", + "integrity": "sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==", + "license": "MIT" + }, + "node_modules/@simplewebauthn/server": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.3.0.tgz", + "integrity": "sha512-MLHYFrYG8/wK2i+86XMhiecK72nMaHKKt4bo+7Q1TbuG9iGjlSdfkPWKO5ZFE/BX+ygCJ7pr8H/AJeyAj1EaTQ==", + "license": "MIT", + "dependencies": { + "@hexagon/base64": "^1.1.27", + "@levischuck/tiny-cbor": "^0.2.2", + "@peculiar/asn1-android": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.1", + "@peculiar/asn1-rsa": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/x509": "^1.14.3" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@sindresorhus/is": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", + "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", + "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.12.tgz", + "integrity": "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.11.tgz", + "integrity": "sha512-YxFiiG4YDAtX7WMN7RuhHZLeTmRRAOyCbr+zB8e3AQzHPnUhS8zXjB1+cniPVQI3xbWsQPM0X2aaIkO/ME0ymw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/node-config-provider": "^4.3.12", + "@smithy/types": "^4.13.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-endpoints": "^3.3.3", + "@smithy/util-middleware": "^4.2.12", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.23.10", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.10.tgz", + "integrity": "sha512-pn0HaJpxmdeCLdbAm79SUjX8IPiej9ANHNHec4K4u5Bkf5BqYCbAgK3c8NTCVf44DnlWJK7W1mimlgBPUQ3IlA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-stream": "^4.5.18", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.12.tgz", + "integrity": "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/node-config-provider": "^4.3.12", + "@smithy/property-provider": "^4.2.12", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.14.tgz", + "integrity": "sha512-Aswg1yMsujkikRVv+JIDw2ybTgx0cnTnv7pMee46OX6lTMwk/QpH1lbx3vN3feMwyNrFcSUbYBtbgwHXXn3CIA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/protocol-http": "^5.3.12", + "@smithy/querystring-builder": "^4.2.12", + "@smithy/types": "^4.13.1", + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.12.tgz", + "integrity": "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.12.tgz", + "integrity": "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.12.tgz", + "integrity": "sha512-W/oIpHCpWU2+iAkfZYyGWE+qkpuf3vEXHLxQQDx9FPNZTTdnul0dZ2d/gUFrtQ5je1G2kp4cjG0/24YueG2LbQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.12.tgz", + "integrity": "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.4.24", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.24.tgz", + "integrity": "sha512-k7SZG+7IbS4fVAI47p+QixmcjqliCoZ7T5ZtAJMHyViiv7AhMC9aXtgxvNQ8TQmbUe7kotsvW2XeEEqnTmdOXg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/core": "^3.23.10", + "@smithy/middleware-serde": "^4.2.13", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/shared-ini-file-loader": "^4.4.7", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-middleware": "^4.2.12", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.4.41", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.41.tgz", + "integrity": "sha512-qjeS0KGftfz2CL4/IziPmQurzemKRPh6sekt3IFbj1519nkj+JM+RcdjVrC1AQFFZhmW3zz7KqwOgN+qJZeVlQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/node-config-provider": "^4.3.12", + "@smithy/protocol-http": "^5.3.12", + "@smithy/service-error-classification": "^4.2.12", + "@smithy/smithy-client": "^4.12.4", + "@smithy/types": "^4.13.1", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-retry": "^4.2.12", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.13.tgz", + "integrity": "sha512-appEschlOmriCVGLYTTjKdbnXIZ55XT9TsV+aGuj5Jiw988gmEZwJwPkYqlZdwajMKgfxt5epjFTGriyYf4Kiw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/core": "^3.23.10", + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.12.tgz", + "integrity": "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.12", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.12.tgz", + "integrity": "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/property-provider": "^4.2.12", + "@smithy/shared-ini-file-loader": "^4.4.7", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.15.tgz", + "integrity": "sha512-2z3Z7Qfts2Eui5Oy+MLJjwKx1LT0Hm/b6W0XJXkUIFHP1W9D4BhdvxWW2W5xPP92CoXO+B4C/zSH67uIxMkWoA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/abort-controller": "^4.2.12", + "@smithy/protocol-http": "^5.3.12", + "@smithy/querystring-builder": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.12.tgz", + "integrity": "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.12", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.12.tgz", + "integrity": "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.12.tgz", + "integrity": "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "@smithy/util-uri-escape": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.12.tgz", + "integrity": "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.12.tgz", + "integrity": "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.7", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.7.tgz", + "integrity": "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.12", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.12.tgz", + "integrity": "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.12.4", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.4.tgz", + "integrity": "sha512-kbFGh3QrUj7Z9zYHCip+dGVyRGiFo6JK0A+9InOwmU4ZCkJs3HKhjLL/ABe5I8kp9uScqrftcWrDh7YxlWmmZA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/core": "^3.23.10", + "@smithy/middleware-endpoint": "^4.4.24", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "@smithy/util-stream": "^4.5.18", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.1.tgz", + "integrity": "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.12.tgz", + "integrity": "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/querystring-parser": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.40", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.40.tgz", + "integrity": "sha512-TB++dVe/aHkhCw8+fVUiGEEyz70Drftze6uk5VGBDJAjEj2mqNFftkeY7Jyit3uui346NkZxzLMGM0yzD/S8og==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/property-provider": "^4.2.12", + "@smithy/smithy-client": "^4.12.4", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.43", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.43.tgz", + "integrity": "sha512-cHmr8Q1BJstJC8ahvYrcyqjSIwrgLbpphOYmfMvF+EVsKUU52b3DDLb0SyiAzR16o7FR1r2IVUFfWWu7ADh1iw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/config-resolver": "^4.4.11", + "@smithy/credential-provider-imds": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/property-provider": "^4.2.12", + "@smithy/smithy-client": "^4.12.4", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.3.tgz", + "integrity": "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/node-config-provider": "^4.3.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.12.tgz", + "integrity": "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.12.tgz", + "integrity": "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/service-error-classification": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.18", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.18.tgz", + "integrity": "sha512-o0hxsNp2rC7Kz93RNER/mv5G60kntYPPjV9e9Zoa3Mm455bCGHlFW6TywziCQRlLzvrQj/mmWJimAvJWF/wfjg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.14", + "@smithy/node-http-handler": "^4.4.15", + "@smithy/types": "^4.13.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.2.13", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.13.tgz", + "integrity": "sha512-2zdZ9DTHngRtcYxJK1GUDxruNr53kv5W2Lupe0LMU+Imr6ohQg8M2T14MNkj1Y0wS3FFwpgpGQyvuaMF7CiTmQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@smithy/abort-controller": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.14.tgz", + "integrity": "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz", + "integrity": "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-cloudflare": { + "version": "7.2.8", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-7.2.8.tgz", + "integrity": "sha512-bIdhY/Fi4AQmqiBdQVKnafH1h9Gw+xbCvHyUu4EouC8rJOU02zwhi14k/FDhQ0mJF1iblIu3m8UNQ8GpGIvIOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cloudflare/workers-types": "^4.20250507.0", + "worktop": "0.8.0-next.18" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0", + "wrangler": "^4.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.54.0", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.54.0.tgz", + "integrity": "sha512-WDJApQ1ipZLbaC4YjqJjwYR9y7QQgTqVwEObgNZ8Mu/eVQJqn4Qzw9a+n7mr5xnBYiAYz9UdJOOl+aqVbfGXcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.14.1", + "cookie": "^0.6.0", + "devalue": "^5.6.4", + "esm-env": "^1.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "set-cookie-parser": "^3.0.0", + "sirv": "^3.0.0" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": "^5.3.3", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.4.tgz", + "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", + "deepmerge": "^4.3.1", + "magic-string": "^0.30.21", + "obug": "^2.1.0", + "vitefu": "^1.1.1" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.2.tgz", + "integrity": "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "obug": "^2.1.0" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/sinon": { + "version": "17.0.4", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", + "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz", + "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/custom-elements": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/custom-elements/-/custom-elements-1.3.0.tgz", + "integrity": "sha512-f4q/s76+8nOy+fhrNHyetuoPDR01lmlZB5czfCG+OOnBw/Wf+x48DcCDPmMQY7oL8xYFL8qfenMoiS8DUkKBUw==", + "license": "ISC" + }, + "node_modules/@willfarrell-ds/cli": { + "version": "0.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@willfarrell-ds/cli/-/cli-0.0.0-alpha.4.tgz", + "integrity": "sha512-HipRSG/nDEu+LsJYpaOcyRebC5HTLXZtagZJZTT6Ex4jhgphANT2EKC46xhQsPWpan5mV0oRYgThRMcV+0gUsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "3.1.3", + "commander": "10.0.1", + "mathjs": "15.1.1" + }, + "bin": { + "ds": "index.js" + } + }, + "node_modules/@willfarrell-ds/cli/node_modules/color-convert": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz", + "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=14.6" + } + }, + "node_modules/@willfarrell-ds/cli/node_modules/color-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", + "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@willfarrell-ds/svelte": { + "version": "0.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@willfarrell-ds/svelte/-/svelte-0.0.0-alpha.4.tgz", + "integrity": "sha512-qp+xJpEPwa3vXaCYJbtRnfadoeTm0kx2Rm+4ajDM07++e69hMx3qd1/JK8McWgFDoKOK8IhGpNlVjXvl1r0/4g==", + "license": "MIT", + "dependencies": { + "@willfarrell-ds/vanilla": "0.0.0-alpha.4", + "pretty": "2.0.0", + "prismjs": "1.30.0", + "tinykeys": "3.0.0" + }, + "peerDependencies": { + "svelte": "^5.0.0" + } + }, + "node_modules/@willfarrell-ds/vanilla": { + "version": "0.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@willfarrell-ds/vanilla/-/vanilla-0.0.0-alpha.4.tgz", + "integrity": "sha512-G2rOFUccvSlBBwhIYXFhMg9i2wLE4ey+om8kgFSkVo+qOm0coVZimtG/ML19EN+mI2xWeU2/wOOawVm+7RyeEw==", + "license": "MIT", + "dependencies": { + "@simplewebauthn/browser": "13.2.2", + "@ungap/custom-elements": "1.3.0", + "accessible-autocomplete": "3.0.1" + } + }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.3.tgz", + "integrity": "sha512-mQZgUSgFurUtA07ceMjxrWkYz8QtDuYkvPlu0ZqncgjopQ0t6CNEo/OSealkmnagSUx8ZD5ewvezUwUuMqutQg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/1auth.js.org": { + "resolved": "websites/1auth.js.org", + "link": true + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/accessible-autocomplete": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/accessible-autocomplete/-/accessible-autocomplete-3.0.1.tgz", + "integrity": "sha512-xMshgc2LT5addvvfCTGzIkRrvhbOFeylFSnSMfS/PdjvvvElZkakCwxO3/yJYBWyi1hi3tZloqOJQ5kqqJtH4g==", + "license": "MIT", + "peerDependencies": { + "preact": "^8.0.0" + }, + "peerDependenciesMeta": { + "preact": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1js": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", + "integrity": "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/aws-sdk-client-mock": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/aws-sdk-client-mock/-/aws-sdk-client-mock-4.1.0.tgz", + "integrity": "sha512-h/tOYTkXEsAcV3//6C1/7U4ifSpKyJvb6auveAepqqNJl6TdZaPFEtKjBQNf8UxQdDP850knB2i/whq4zlsxJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinon": "^17.0.3", + "sinon": "^18.0.1", + "tslib": "^2.1.0" + } + }, + "node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT", + "peer": true + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/complex.js": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.3.tgz", + "integrity": "sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/condense-newlines": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz", + "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/conventional-changelog-angular": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.0.tgz", + "integrity": "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.0.tgz", + "integrity": "sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-commits-parser": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.3.0.tgz", + "integrity": "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0", + "meow": "^13.0.0" + }, + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", + "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^2.6.1" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.4.tgz", + "integrity": "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==", + "license": "MIT" + }, + "node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/editorconfig": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz", + "integrity": "sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==", + "license": "MIT", + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "^9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/editorconfig/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/editorconfig/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, "license": "MIT", "dependencies": { - "@peculiar/asn1-cms": "^2.6.0", - "@peculiar/asn1-pfx": "^2.6.0", - "@peculiar/asn1-pkcs8": "^2.6.0", - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "@peculiar/asn1-x509-attr": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "is-arrayish": "^0.2.1" } }, - "node_modules/@peculiar/asn1-rsa": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.0.tgz", - "integrity": "sha512-Nu4C19tsrTsCp9fDrH+sdcOKoVfdfoQQ7S3VqjJU6vedR7tY3RLkQ5oguOIB3zFW33USDUuYZnPEQYySlgha4w==", + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@peculiar/asn1-schema": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", - "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, "license": "MIT", "dependencies": { - "asn1js": "^3.0.6", - "pvtsutils": "^1.3.6", - "tslib": "^2.8.1" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@peculiar/asn1-x509": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.0.tgz", - "integrity": "sha512-uzYbPEpoQiBoTq0/+jZtpM6Gq6zADBx+JNFP3yqRgziWBxQ/Dt/HcuvRfm9zJTPdRcBqPNdaRHTVwpyiq6iNMA==", + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT" + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrap": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.3.tgz", + "integrity": "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "asn1js": "^3.0.6", - "pvtsutils": "^1.3.6", - "tslib": "^2.8.1" + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^8.0.0" + }, + "engines": { + "node": ">=12.17.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-builder": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.2.tgz", + "integrity": "sha512-NJAmiuVaJEjVa7TjLZKlYd7RqmzOC91EtPFXHvlTcqBVo50Qh7XV5IwvXi1c7NRz2Q/majGX9YLcwJtWgHjtkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "path-expression-matcher": "^1.1.3" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "fast-xml-builder": "^1.0.0", + "strnum": "^2.1.2" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@peculiar/asn1-x509-attr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.0.tgz", - "integrity": "sha512-MuIAXFX3/dc8gmoZBkwJWxUWOSvG4MMDntXhrOZpJVMkYX+MYc/rUAU2uJOved9iJEoiUx7//3D8oG83a78UJA==", + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/@peculiar/x509": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", - "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-cms": "^2.6.0", - "@peculiar/asn1-csr": "^2.6.0", - "@peculiar/asn1-ecc": "^2.6.0", - "@peculiar/asn1-pkcs9": "^2.6.0", - "@peculiar/asn1-rsa": "^2.6.0", - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "pvtsutils": "^1.3.6", - "reflect-metadata": "^0.2.2", - "tslib": "^2.8.1", - "tsyringe": "^4.10.0" - }, "engines": { - "node": ">=20.0.0" + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" } }, - "node_modules/@simplewebauthn/server": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.2.2.tgz", - "integrity": "sha512-HcWLW28yTMGXpwE9VLx9J+N2KEUaELadLrkPEEI9tpI5la70xNEVEsu/C+m3u7uoq4FulLqZQhgBCzR9IZhFpA==", + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, "license": "MIT", "dependencies": { - "@hexagon/base64": "^1.1.27", - "@levischuck/tiny-cbor": "^0.2.2", - "@peculiar/asn1-android": "^2.3.10", - "@peculiar/asn1-ecc": "^2.3.8", - "@peculiar/asn1-rsa": "^2.3.8", - "@peculiar/asn1-schema": "^2.3.8", - "@peculiar/asn1-x509": "^2.3.8", - "@peculiar/x509": "^1.13.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=6 <7 || >=8" } }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", - "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1", - "type-detect": "^4.1.0" + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/@sinonjs/samsam/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", - "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, - "license": "(Unlicense OR Apache-2.0)" - }, - "node_modules/@smithy/abort-controller": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", - "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", - "license": "Apache-2.0", - "peer": true, + "license": "MIT", "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">= 0.4" } }, - "node_modules/@smithy/config-resolver": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", - "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", - "license": "Apache-2.0", - "peer": true, + "node_modules/git-raw-commits": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz", + "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "tslib": "^2.6.2" + "@conventional-changelog/git-client": "^2.6.0", + "meow": "^13.0.0" + }, + "bin": { + "git-raw-commits": "src/cli.js" }, "engines": { - "node": ">=18.0.0" + "node": ">=18" } }, - "node_modules/@smithy/core": { - "version": "3.22.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.22.1.tgz", - "integrity": "sha512-x3ie6Crr58MWrm4viHqqy2Du2rHYZjwu8BekasrQx4ca+Y24dzVAwq3yErdqIbc2G3I0kLQA13PQ+/rde+u65g==", - "license": "Apache-2.0", - "peer": true, + "node_modules/gitignore-to-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", + "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.4 <5 || >=6.9" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", "dependencies": { - "@smithy/middleware-serde": "^4.2.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.11", - "@smithy/util-utf8": "^4.2.0", - "@smithy/uuid": "^1.1.0", - "tslib": "^2.6.2" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=18.0.0" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", - "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", - "license": "Apache-2.0", - "peer": true, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "tslib": "^2.6.2" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=18.0.0" + "node": ">= 6" } }, - "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", - "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", - "license": "Apache-2.0", - "peer": true, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "tslib": "^2.6.2" + "ini": "4.1.1" }, "engines": { - "node": ">=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@smithy/hash-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.8.tgz", - "integrity": "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==", - "license": "Apache-2.0", - "peer": true, + "node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", - "tslib": "^2.6.2" + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=8" } }, - "node_modules/@smithy/invalid-dependency": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.8.tgz", - "integrity": "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=8" } }, - "node_modules/@smithy/is-array-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", - "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", - "license": "Apache-2.0", - "peer": true, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=18.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@smithy/md5-js": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.8.tgz", - "integrity": "sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==", - "license": "Apache-2.0", - "peer": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-utf8": "^4.2.0", - "tslib": "^2.6.2" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=18.0.0" + "node": ">= 0.4" } }, - "node_modules/@smithy/middleware-content-length": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.8.tgz", - "integrity": "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==", - "license": "Apache-2.0", - "peer": true, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "@types/hast": "^3.0.0" }, - "engines": { - "node": ">=18.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/@smithy/middleware-endpoint": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.13.tgz", - "integrity": "sha512-x6vn0PjYmGdNuKh/juUJJewZh7MoQ46jYaJ2mvekF4EesMuFfrl4LaW/k97Zjf8PTCPQmPgMvwewg7eNoH9n5w==", - "license": "Apache-2.0", - "peer": true, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", "dependencies": { - "@smithy/core": "^3.22.1", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-middleware": "^4.2.8", - "tslib": "^2.6.2" - }, + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=18.0.0" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/@smithy/middleware-retry": { - "version": "4.4.30", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.30.tgz", - "integrity": "sha512-CBGyFvN0f8hlnqKH/jckRDz78Snrp345+PVk8Ux7pnkUCW97Iinse59lY78hBt04h1GZ6hjBN94BRwZy1xC8Bg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/service-error-classification": "^4.2.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/uuid": "^1.1.0", - "tslib": "^2.6.2" + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" }, "engines": { - "node": ">=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" } }, - "node_modules/@smithy/middleware-serde": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", - "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", - "license": "Apache-2.0", - "peer": true, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@smithy/middleware-stack": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", - "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">= 4" } }, - "node_modules/@smithy/node-config-provider": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", - "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", - "license": "Apache-2.0", - "peer": true, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@smithy/node-http-handler": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.9.tgz", - "integrity": "sha512-KX5Wml5mF+luxm1szW4QDz32e3NObgJ4Fyw+irhph4I/2geXwUy4jkIMUs5ZPGflRBeR6BUkC2wqIab4Llgm3w==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=4" } }, - "node_modules/@smithy/property-provider": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", - "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", - "license": "Apache-2.0", - "peer": true, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", "engines": { - "node": ">=18.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@smithy/protocol-http": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", - "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@smithy/querystring-builder": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", - "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-uri-escape": "^4.2.0", - "tslib": "^2.6.2" - }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@smithy/querystring-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", - "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=8" } }, - "node_modules/@smithy/service-error-classification": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", - "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", - "license": "Apache-2.0", - "peer": true, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/types": "^4.12.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", - "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=0.12.0" } }, - "node_modules/@smithy/signature-v4": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.8.tgz", - "integrity": "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-uri-escape": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", - "tslib": "^2.6.2" - }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@smithy/smithy-client": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.11.2.tgz", - "integrity": "sha512-SCkGmFak/xC1n7hKRsUr6wOnBTJ3L22Qd4e8H1fQIuKTAjntwgU8lrdMe7uHdiT2mJAOWA/60qaW9tiMu69n1A==", - "license": "Apache-2.0", - "peer": true, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", "dependencies": { - "@smithy/core": "^3.22.1", - "@smithy/middleware-endpoint": "^4.4.13", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.11", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "@types/estree": "^1.0.6" } }, - "node_modules/@smithy/types": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", - "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "tslib": "^2.6.2" - }, + "node_modules/is-whitespace": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz", + "integrity": "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==", + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@smithy/url-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", - "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", - "license": "Apache-2.0", - "peer": true, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", "dependencies": { - "@smithy/querystring-parser": "^4.2.8", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=18.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/@smithy/util-base64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", - "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/@smithy/util-body-length-browser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", - "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", - "license": "Apache-2.0", - "peer": true, + "node_modules/js-beautify": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz", + "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==", + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" + "config-chain": "^1.1.13", + "editorconfig": "^1.0.4", + "glob": "^10.4.2", + "js-cookie": "^3.0.5", + "nopt": "^7.2.1" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" }, "engines": { - "node": ">=18.0.0" + "node": ">=14" } }, - "node_modules/@smithy/util-body-length-node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", - "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", - "license": "Apache-2.0", - "peer": true, + "node_modules/js-beautify/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/js-beautify/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "balanced-match": "^1.0.0" } }, - "node_modules/@smithy/util-buffer-from": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", - "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", - "license": "Apache-2.0", - "peer": true, + "node_modules/js-beautify/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", - "tslib": "^2.6.2" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">=18.0.0" + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@smithy/util-config-provider": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", - "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", - "license": "Apache-2.0", - "peer": true, + "node_modules/js-beautify/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", "dependencies": { - "tslib": "^2.6.2" + "brace-expansion": "^2.0.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.29", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.29.tgz", - "integrity": "sha512-nIGy3DNRmOjaYaaKcQDzmWsro9uxlaqUOhZDHQed9MW/GmkBZPtnU70Pu1+GT9IBmUXwRdDuiyaeiy9Xtpn3+Q==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=14" } }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.32", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.32.tgz", - "integrity": "sha512-7dtFff6pu5fsjqrVve0YMhrnzJtccCWDacNKOkiZjJ++fmjGExmmSu341x+WU6Oc1IccL7lDuaUj7SfrHpWc5Q==", - "license": "Apache-2.0", - "peer": true, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/config-resolver": "^4.4.6", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.11.2", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "argparse": "^2.0.1" }, - "engines": { - "node": ">=18.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@smithy/util-endpoints": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", - "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", - "license": "Apache-2.0", - "peer": true, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "license": "MIT", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "is-buffer": "^1.1.5" }, "engines": { - "node": ">=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@smithy/util-hex-encoding": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", - "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "tslib": "^2.6.2" - }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=6" } }, - "node_modules/@smithy/util-middleware": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", - "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", + "node_modules/license-check-and-add": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/license-check-and-add/-/license-check-and-add-4.0.5.tgz", + "integrity": "sha512-FySnMi3Kf/vO5jka8tcbVF1FhDFb8PWsQ8pg5Y7U/zkQgta+fIrJGcGHO58WFjfKlgvhneG1uQ00Fpxzhau3QA==", + "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "fs-extra": "^8.1.0", + "gitignore-to-glob": "^0.3.0", + "globby": "^10.0.1", + "ignore": "^5.1.2", + "yargs": "^13.3.0" }, + "bin": { + "license-check-and-add": "dist/src/cli.js" + } + }, + "node_modules/license-check-and-add/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=6" } }, - "node_modules/@smithy/util-retry": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", - "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", - "license": "Apache-2.0", - "peer": true, + "node_modules/license-check-and-add/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/service-error-classification": "^4.2.8", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=4" } }, - "node_modules/@smithy/util-stream": { - "version": "4.5.11", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.11.tgz", - "integrity": "sha512-lKmZ0S/3Qj2OF5H1+VzvDLb6kRxGzZHq6f3rAsoSu5cTLGsn3v3VQBA8czkNNXlLjoFEtVu3OQT2jEeOtOE2CA==", - "license": "Apache-2.0", - "peer": true, + "node_modules/license-check-and-add/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "license": "ISC", "dependencies": { - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.9", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, - "node_modules/@smithy/util-uri-escape": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", - "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", - "license": "Apache-2.0", - "peer": true, + "node_modules/license-check-and-add/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "color-name": "1.1.3" } }, - "node_modules/@smithy/util-utf8": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", - "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", - "tslib": "^2.6.2" - }, + "node_modules/license-check-and-add/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/license-check-and-add/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "license": "MIT" + }, + "node_modules/license-check-and-add/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=4" } }, - "node_modules/@smithy/util-waiter": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.8.tgz", - "integrity": "sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==", - "license": "Apache-2.0", - "peer": true, + "node_modules/license-check-and-add/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "license": "MIT", "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=6" } }, - "node_modules/@smithy/uuid": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", - "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", - "license": "Apache-2.0", - "peer": true, + "node_modules/license-check-and-add/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" + "ansi-regex": "^4.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=6" } }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "node_modules/license-check-and-add/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "license": "MIT", "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "node_modules/license-check-and-add/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/@types/node": { - "version": "25.2.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.2.tgz", - "integrity": "sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ==", + "node_modules/license-check-and-add/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, - "node_modules/@types/sinon": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", - "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==", + "node_modules/license-check-and-add/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@types/sinonjs__fake-timers": "*" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz", - "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, "license": "MIT" }, - "node_modules/@yarnpkg/parsers": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.3.tgz", - "integrity": "sha512-mQZgUSgFurUtA07ceMjxrWkYz8QtDuYkvPlu0ZqncgjopQ0t6CNEo/OSealkmnagSUx8ZD5ewvezUwUuMqutQg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "js-yaml": "^3.10.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=18.12.0" - } + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" }, - "node_modules/@yarnpkg/parsers/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "license": "MIT", "dependencies": { - "sprintf-js": "~1.0.2" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "node_modules/lockfile-lint": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/lockfile-lint/-/lockfile-lint-5.0.0.tgz", + "integrity": "sha512-QcVIVITLZAhWYHU2wbNSOMgwc6EN4Y2sy6mjgS5aikYyRzgDIfotXUsCrm38En+3fZpc58Yu7DF9dNeT/goi1A==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "cosmiconfig": "^9.0.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "lockfile-lint-api": "^5.9.2", + "yargs": "^17.7.2" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "lockfile-lint": "bin/lockfile-lint.js" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "node_modules/lockfile-lint-api": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/lockfile-lint-api/-/lockfile-lint-api-5.9.2.tgz", + "integrity": "sha512-3QhxWxl3jT9GcMxuCnTsU8Tz5U6U1lKBlKBu2zOYOz/x3ONUoojEtky3uzoaaDgExcLqIX0Aqv2I7TZXE383CQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "@yarnpkg/parsers": "^3.0.0-rc.48.1", + "debug": "^4.3.4", + "object-hash": "^3.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/ansi-styles": { + "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } + "license": "MIT" }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", "dev": true, - "license": "Python-2.0" + "license": "MIT" }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true, "license": "MIT" }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/asn1js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", - "integrity": "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==", - "license": "BSD-3-Clause", + "node_modules/mathjs": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.1.1.tgz", + "integrity": "sha512-rM668DTtpSzMVoh/cKAllyQVEbBApM5g//IMGD8vD7YlrIz9ITRr3SrdhjaDxcBNTdyETWwPebj2unZyHD7ZdA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "pvtsutils": "^1.3.6", - "pvutils": "^1.1.3", - "tslib": "^2.8.1" + "@babel/runtime": "^7.26.10", + "complex.js": "^2.2.5", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "^5.2.1", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.2.1" + }, + "bin": { + "mathjs": "bin/cli.js" }, "engines": { - "node": ">=12.0.0" + "node": ">= 18" } }, - "node_modules/aws-sdk-client-mock": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/aws-sdk-client-mock/-/aws-sdk-client-mock-4.1.0.tgz", - "integrity": "sha512-h/tOYTkXEsAcV3//6C1/7U4ifSpKyJvb6auveAepqqNJl6TdZaPFEtKjBQNf8UxQdDP850knB2i/whq4zlsxJw==", + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mdsvex": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.12.7.tgz", + "integrity": "sha512-gx4bReLCUvq+MPErHXYeyX+TEq1hsS2KfiZtEOMNTcbibSouFy8AHc5h04KbGCl+g5tLuo4/lbgRVYRnc7bJZw==", "dev": true, "license": "MIT", "dependencies": { - "@types/sinon": "^17.0.3", - "sinon": "^18.0.1", - "tslib": "^2.1.0" + "@types/mdast": "^4.0.4", + "@types/unist": "^2.0.3", + "prism-svelte": "^0.4.7", + "prismjs": "^1.17.1", + "unist-util-visit": "^2.0.1", + "vfile-message": "^2.0.4" + }, + "peerDependencies": { + "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/mdsvex/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "dev": true, "license": "MIT" }, - "node_modules/bowser": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", - "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, "license": "MIT", - "peer": true + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">= 8" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { - "fill-range": "^7.1.1" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/miniflare": { + "version": "4.20260310.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260310.0.tgz", + "integrity": "sha512-uC5vNPenFpDSj5aUU3wGSABG6UUqMr+Xs1m4AkCrTHo37F4Z6xcQw5BXqViTfPDVT/zcYH1UgTVoXhr1l6ZMXw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "@cspotcode/source-map-support": "0.8.1", + "sharp": "^0.34.5", + "undici": "7.18.2", + "workerd": "1.20260310.1", + "ws": "8.18.0", + "youch": "4.1.0-beta.10" + }, + "bin": { + "miniflare": "bootstrap.js" }, "engines": { - "node": ">=12" + "node": ">=18.0.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/miniflare/node_modules/undici": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.18.2.tgz", + "integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==", "dev": true, "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "color-name": "~1.1.4" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=7.0.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "license": "MIT" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mnemonist": { + "version": "0.38.3", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", + "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==", "license": "MIT", + "peer": true, "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" + "obliterator": "^1.6.1" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=10" + } }, - "node_modules/conventional-changelog-angular": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.1.0.tgz", - "integrity": "sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==", + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0" + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz", + "integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" }, "engines": { - "node": ">=18" + "node": "^18 || >=20" } }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.1.0.tgz", - "integrity": "sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA==", + "node_modules/nise": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.3.tgz", + "integrity": "sha512-OsVxbEhidvxS5gq0KQh1jivMsQC+86Tu3Hnwx2DWANu/iytRhhJkG66aYCI2L4JyozJa/69V/lQT1ofOA+qKqQ==", "dev": true, - "license": "ISC", + "license": "BSD-3-Clause", "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=18" + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^15.1.1", + "just-extend": "^6.2.0", + "path-to-regexp": "^8.3.0" } }, - "node_modules/conventional-commits-parser": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.2.1.tgz", - "integrity": "sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==", + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "meow": "^13.0.0" - }, - "bin": { - "conventional-commits-parser": "dist/cli/index.js" - }, - "engines": { - "node": ">=18" + "@sinonjs/commons": "^3.0.1" } }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "license": "MIT", "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" + "node": "4.x || >=6.0.0" }, "peerDependencies": { - "typescript": ">=4.9.5" + "encoding": "^0.1.0" }, "peerDependenciesMeta": { - "typescript": { + "encoding": { "optional": true } } }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", - "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", - "dev": true, - "license": "MIT", + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "license": "ISC", "dependencies": { - "jiti": "^2.6.1" + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" }, "engines": { - "node": ">=v18" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=9", - "typescript": ">=5" + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/obliterator": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", + "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==", + "license": "MIT", + "peer": true + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" } }, - "node_modules/dargs": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", - "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=12" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "p-limit": "^2.0.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/diff": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", - "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { - "path-type": "^4.0.0" + "callsites": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "license": "MIT", "dependencies": { - "is-obj": "^2.0.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "dev": true, "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "dev": true, "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, "engines": { - "node": ">=4" - } - }, - "node_modules/fast-check": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.5.3.tgz", - "integrity": "sha512-IE9csY7lnhxBnA8g/WI5eg/hygA6MGWJMSNfFRrBlXUciADEhS1EDB0SIsMSvzubzIlOBbVITSsypCsW717poA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT", - "dependencies": { - "pure-rand": "^7.0.0" + "node": ">=0.12" }, - "engines": { - "node": ">=12.17.0" + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, "engines": { - "node": ">=8.6.0" + "node": ">=4" } }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fast-xml-parser": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.4.tgz", - "integrity": "sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==", + "node_modules/path-expression-matcher": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.1.3.tgz", + "integrity": "sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==", "funding": [ { "type": "github", @@ -2880,1505 +7167,1991 @@ ], "license": "MIT", "peer": true, - "dependencies": { - "strnum": "^2.1.0" - }, - "bin": { - "fxparser": "src/cli/cli.js" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, "engines": { "node": ">=8" } }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "license": "MIT", + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", "dependencies": { - "locate-path": "^3.0.0" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=8" } }, - "node_modules/git-raw-commits": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", - "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pg": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", "dev": true, "license": "MIT", "dependencies": { - "dargs": "^8.0.0", - "meow": "^12.0.1", - "split2": "^4.0.0" - }, - "bin": { - "git-raw-commits": "cli.mjs" + "pg-connection-string": "^2.12.0", + "pg-pool": "^3.13.0", + "pg-protocol": "^1.13.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" }, "engines": { - "node": ">=16" + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } } }, - "node_modules/git-raw-commits/node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "node_modules/pg-cloudflare": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", "dev": true, "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", + "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "dev": true, + "license": "ISC", "engines": { - "node": ">=16.10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4.0.0" } }, - "node_modules/gitignore-to-glob": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", - "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==", + "node_modules/pg-pool": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", + "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=4.4 <5 || >=6.9" + "peerDependencies": { + "pg": ">=8.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "node_modules/pg-protocol": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", "dev": true, - "license": "ISC", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=4" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "split2": "^4.1.0" } }, - "node_modules/global-directory": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", - "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "dependencies": { - "ini": "4.1.1" - }, "engines": { - "node": ">=18" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, - "license": "ISC" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", "dev": true, "license": "MIT", - "bin": { - "husky": "bin.js" - }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" + "node": ">=0.10.0" } }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", "dev": true, "license": "MIT", "engines": { - "node": ">= 4" + "node": ">=0.10.0" } }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "dev": true, "license": "MIT", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "xtend": "^4.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, + "node_modules/pretty": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz", + "integrity": "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==", "license": "MIT", + "dependencies": { + "condense-newlines": "^0.2.1", + "extend-shallow": "^2.0.1", + "js-beautify": "^1.6.12" + }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/import-meta-resolve": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", - "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "node_modules/prism-svelte": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz", + "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==", "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "license": "MIT" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "license": "ISC" }, - "node_modules/ini": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true, - "license": "ISC", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "node_modules/pure-rand": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.0.0.tgz", + "integrity": "sha512-7rgWlxG2gAvFPIQfUreo1XYlNvrQ9VnQPFWdncPkdl3icucLK0InOxsaafbvxGTnI6Bk/Rxmslg0lQlRCuzOXw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], "license": "MIT" }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", + "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, - "node_modules/is-fullwidth-code-point": { + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" + }, + "node_modules/regexparam": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-3.0.0.tgz", + "integrity": "sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">=0.10.0" } }, - "node_modules/is-obj": { + "node_modules/require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, "bin": { - "jiti": "lib/jiti-cli.mjs" + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "queue-microtask": "^1.2.2" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "license": "MIT" }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", "dev": true, - "license": "MIT" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/just-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-cookie-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.0.1.tgz", + "integrity": "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==", "dev": true, "license": "MIT" }, - "node_modules/license-check-and-add": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/license-check-and-add/-/license-check-and-add-4.0.5.tgz", - "integrity": "sha512-FySnMi3Kf/vO5jka8tcbVF1FhDFb8PWsQ8pg5Y7U/zkQgta+fIrJGcGHO58WFjfKlgvhneG1uQ00Fpxzhau3QA==", + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "dev": true, + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "fs-extra": "^8.1.0", - "gitignore-to-glob": "^0.3.0", - "globby": "^10.0.1", - "ignore": "^5.1.2", - "yargs": "^13.3.0" + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" }, - "bin": { - "license-check-and-add": "dist/src/cli.js" + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/license-check-and-add/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/sinon": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz", + "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" } }, - "node_modules/license-check-and-add/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/license-check-and-add/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/license-check-and-add/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/license-check-and-add/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, - "license": "MIT" + "license": "ISC", + "engines": { + "node": ">= 10.x" + } }, - "node_modules/license-check-and-add/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause" }, - "node_modules/license-check-and-add/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/license-check-and-add/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/license-check-and-add/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/license-check-and-add/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/license-check-and-add/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/license-check-and-add/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, + "node_modules/strnum": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz", + "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT", - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } + "peer": true }, - "node_modules/license-check-and-add/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, + "node_modules/svelte": { + "version": "5.53.11", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.53.11.tgz", + "integrity": "sha512-GYmqRjRhJYLQBonfdfGAt28gkfWEShrtXKGXcFGneXi502aBE+I1dJcs/YQriByvP6xqXRz/OdBGC6tfvUQHyQ==", "license": "MIT", "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", + "acorn": "^8.12.1", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.6.3", + "esm-env": "^1.2.1", + "esrap": "^2.2.2", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" }, "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/lockfile-lint": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/lockfile-lint/-/lockfile-lint-5.0.0.tgz", - "integrity": "sha512-QcVIVITLZAhWYHU2wbNSOMgwc6EN4Y2sy6mjgS5aikYyRzgDIfotXUsCrm38En+3fZpc58Yu7DF9dNeT/goi1A==", + "node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "cosmiconfig": "^9.0.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "lockfile-lint-api": "^5.9.2", - "yargs": "^17.7.2" + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" }, "bin": { - "lockfile-lint": "bin/lockfile-lint.js" + "svgo": "bin/svgo.js" }, "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/lockfile-lint-api": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/lockfile-lint-api/-/lockfile-lint-api-5.9.2.tgz", - "integrity": "sha512-3QhxWxl3jT9GcMxuCnTsU8Tz5U6U1lKBlKBu2zOYOz/x3ONUoojEtky3uzoaaDgExcLqIX0Aqv2I7TZXE383CQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@yarnpkg/parsers": "^3.0.0-rc.48.1", - "debug": "^4.3.4", - "object-hash": "^3.0.0" + "node": ">=16" }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true, - "license": "MIT" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "node_modules/svgo/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=16" + } }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", "dev": true, "license": "MIT" }, - "node_modules/lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "node_modules/tinybench": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.0.0.tgz", + "integrity": "sha512-BWlWpVbbZXaYjRV0twGLNQO00Zj4HA/sjLOQP2IvzQqGwRGp+2kh7UU3ijyJ3ywFRogYDRbiHDMrUOfaMnN56g==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } }, - "node_modules/meow": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, "license": "MIT", "engines": { "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, "engines": { - "node": ">=8.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/tinykeys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinykeys/-/tinykeys-3.0.0.tgz", + "integrity": "sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "is-number": "^7.0.0" }, "engines": { - "node": "*" + "node": ">=8.0" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6" } }, - "node_modules/mnemonist": { - "version": "0.38.3", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", - "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==", + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", "license": "MIT", - "peer": true, "dependencies": { - "obliterator": "^1.6.1" + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, - "node_modules/nanoid": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz", - "integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.js" + "dependencies": { + "tslib": "^1.9.3" }, "engines": { - "node": "^18 || >=20" + "node": ">= 6.0.0" } }, - "node_modules/nise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", - "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^13.0.1", - "@sinonjs/text-encoding": "^0.7.3", - "just-extend": "^6.2.0", - "path-to-regexp": "^8.1.0" + "license": "MIT", + "engines": { + "node": ">=4" } }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "node_modules/typed-function": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.2.tgz", + "integrity": "sha512-VwaXim9Gp1bngi/q3do8hgttYn2uC3MoT/gfuMWylnj1IeZBUAyPddHZlo1K05BDoj8DYPpMdiHqH1dDYdJf2A==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" + "license": "MIT", + "engines": { + "node": ">= 18" } }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">= 6" + "node": ">=14.17" } }, - "node_modules/obliterator": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", - "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==", + "node_modules/undici": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.23.0.tgz", + "integrity": "sha512-HVMxHKZKi+eL2mrUZDzDkKW3XvCjynhbtpSq20xQp4ePDFeSFuAfnvM0GIwZIv8fiKHjXFQ5WjxhCt15KRNj+g==", + "dev": true, "license": "MIT", - "peer": true + "engines": { + "node": ">=20.18.1" + } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, - "license": "ISC", + "license": "MIT" + }, + "node_modules/unenv": { + "version": "2.0.0-rc.24", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", + "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", + "dev": true, + "license": "MIT", "dependencies": { - "wrappy": "1" + "pathe": "^2.0.3" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", "dev": true, "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.0.0" + "@types/unist": "^2.0.2" }, - "engines": { - "node": ">=6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/unist-util-stringify-position/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dev": true, "license": "MIT", "dependencies": { - "callsites": "^3.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" }, - "engines": { - "node": ">=6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "node_modules/unist-util-visit-parents/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-visit/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 4.0.0" } }, - "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dev": true, "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://opencollective.com/unified" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/vfile-message/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/pg": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.18.0.tgz", - "integrity": "sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==", + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", "dependencies": { - "pg-connection-string": "^2.11.0", - "pg-pool": "^3.11.0", - "pg-protocol": "^1.11.0", - "pg-types": "2.2.0", - "pgpass": "1.0.5" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">= 16.0.0" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "pg-cloudflare": "^1.3.0" + "fsevents": "~2.3.3" }, "peerDependencies": { - "pg-native": ">=3.0.1" + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { - "pg-native": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { "optional": true } } }, - "node_modules/pg-cloudflare": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", - "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "node_modules/vite-plugin-mkcert": { + "version": "1.17.10", + "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-1.17.10.tgz", + "integrity": "sha512-703hecAoGZYgNrkY76OIbo0M9j0tfGIIM6n7c0sYvhaczQMPwD0nFi+bS44d8kwdbCtV7885FYBWnTzhsaC7QQ==", "dev": true, "license": "MIT", - "optional": true + "dependencies": { + "axios": "^1.13.5", + "debug": "^4.4.3", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=v16.7.0" + }, + "peerDependencies": { + "vite": ">=3" + } }, - "node_modules/pg-connection-string": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", - "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", - "dev": true, - "license": "MIT" + "node_modules/vite-plugin-sitemap": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/vite-plugin-sitemap/-/vite-plugin-sitemap-0.8.2.tgz", + "integrity": "sha512-bqIw6NVOXg6je81lzX8Lm0vjf8/QSAp8di8fYQzZ3ZdVicOm8+6idBGALJiy1R1FiXNIK8rgORO6HBqXyHW+iQ==", + "dev": true }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "node_modules/vite-plugin-sri": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/vite-plugin-sri/-/vite-plugin-sri-0.0.2.tgz", + "integrity": "sha512-oTpYWvS9xmwee3kK39cr8p2KbQ+/HzOG0bxo0dzMogJ4lR11favOzrapwb2eASVt5rX3LEzG25bEqoSY4CUniA==", "dev": true, "license": "ISC", - "engines": { - "node": ">=4.0.0" + "dependencies": { + "cheerio": "^1.0.0-rc.5", + "node-fetch": "^2.6.1" } }, - "node_modules/pg-pool": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz", - "integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==", + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { - "pg": ">=8.0" + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/pg-protocol": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", - "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", - "dev": true, - "license": "MIT" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "node_modules/vitefu": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.2.tgz", + "integrity": "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==", "dev": true, "license": "MIT", - "dependencies": { - "split2": "^4.1.0" + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true, - "license": "ISC" + "license": "BSD-2-Clause" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", - "engines": { - "node": ">=8.6" + "dependencies": { + "iconv-lite": "0.6.3" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "engines": { + "node": ">=18" } }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/postgres-bytea": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", - "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/whatwg-url/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true, - "license": "MIT", + "license": "ISC" + }, + "node_modules/workerd": { + "version": "1.20260310.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260310.1.tgz", + "integrity": "sha512-yawXhypXXHtArikJj15HOMknNGikpBbSg2ZDe6lddUbqZnJXuCVSkgc/0ArUeVMG1jbbGvpst+REFtKwILvRTQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, "engines": { - "node": ">=0.10.0" + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20260310.1", + "@cloudflare/workerd-darwin-arm64": "1.20260310.1", + "@cloudflare/workerd-linux-64": "1.20260310.1", + "@cloudflare/workerd-linux-arm64": "1.20260310.1", + "@cloudflare/workerd-windows-64": "1.20260310.1" } }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "node_modules/worktop": { + "version": "0.8.0-next.18", + "resolved": "https://registry.npmjs.org/worktop/-/worktop-0.8.0-next.18.tgz", + "integrity": "sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==", "dev": true, "license": "MIT", "dependencies": { - "xtend": "^4.0.0" + "mrmime": "^2.0.0", + "regexparam": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", + "node_modules/wrangler": { + "version": "4.72.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.72.0.tgz", + "integrity": "sha512-bKkb8150JGzJZJWiNB2nu/33smVfawmfYiecA6rW4XH7xS23/jqMbgpdelM34W/7a1IhR66qeQGVqTRXROtAZg==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.4.2", + "@cloudflare/unenv-preset": "2.15.0", + "blake3-wasm": "2.1.5", + "esbuild": "0.27.3", + "miniflare": "4.20260310.0", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.24", + "workerd": "1.20260310.1" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, "engines": { - "node": ">=6" + "node": ">=20.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20260310.1" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } } }, - "node_modules/pure-rand": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", - "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "node_modules/wrangler/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } + "license": "MIT", + "optional": true, + "os": [ + "aix" ], - "license": "MIT" + "engines": { + "node": ">=18" + } }, - "node_modules/pvtsutils": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", - "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "node_modules/wrangler/node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, "license": "MIT", - "dependencies": { - "tslib": "^2.8.1" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/pvutils": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", - "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", + "node_modules/wrangler/node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=16.0.0" + "node": ">=18" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "node_modules/wrangler/node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } + "license": "MIT", + "optional": true, + "os": [ + "android" ], - "license": "MIT" - }, - "node_modules/reflect-metadata": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", - "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", - "license": "Apache-2.0" + "engines": { + "node": ">=18" + } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "node_modules/wrangler/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/wrangler/node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/wrangler/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "node_modules/wrangler/node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } + "node_modules/wrangler/node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" ], + "dev": true, "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "node_modules/wrangler/node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "node_modules/wrangler/node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "ISC" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/sinon": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz", - "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==", + "node_modules/wrangler/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.2.0", - "nise": "^6.0.0", - "supports-color": "^7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/wrangler/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "node_modules/wrangler/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "ISC", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 10.x" + "node": ">=18" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "node_modules/wrangler/node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "BSD-3-Clause" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/wrangler/node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/wrangler/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } + "node_modules/wrangler/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" ], + "dev": true, "license": "MIT", - "peer": true + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/wrangler/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/tinybench": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.0.0.tgz", - "integrity": "sha512-BWlWpVbbZXaYjRV0twGLNQO00Zj4HA/sjLOQP2IvzQqGwRGp+2kh7UU3ijyJ3ywFRogYDRbiHDMrUOfaMnN56g==", + "node_modules/wrangler/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=20.0.0" + "node": ">=18" } }, - "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "node_modules/wrangler/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { "node": ">=18" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/wrangler/node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=8.0" + "node": ">=18" } }, - "node_modules/tr46": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", - "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "node_modules/wrangler/node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=20" + "node": ">=18" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/tsyringe": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", - "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "node_modules/wrangler/node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, "license": "MIT", - "dependencies": { - "tslib": "^1.9.3" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 6.0.0" + "node": ">=18" } }, - "node_modules/tsyringe/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/wrangler/node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "node_modules/wrangler/node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", "dev": true, - "license": "Apache-2.0", - "peer": true, + "hasInstallScript": true, + "license": "MIT", "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/wrangler/node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true, "license": "MIT" }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">= 4.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/wrap-ansi": { + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -4399,6 +9172,28 @@ "dev": true, "license": "ISC" }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -4448,12 +9243,57 @@ "node": ">=12" } }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + }, + "node_modules/youch/node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "license": "MIT" + }, "packages/account": { "name": "@1auth/account", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/crypto": "0.0.0-beta.2" }, "engines": { "node": ">=24" @@ -4465,10 +9305,11 @@ }, "packages/account-username": { "name": "@1auth/account-username", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/account": "0.0.0-beta.1" + "@1auth/account": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" }, "engines": { "node": ">=24" @@ -4480,10 +9321,10 @@ }, "packages/authn": { "name": "@1auth/authn", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/crypto": "0.0.0-beta.2" }, "engines": { "node": ">=24" @@ -4495,11 +9336,11 @@ }, "packages/authn-access-token": { "name": "@1auth/authn-access-token", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" }, "engines": { "node": ">=24" @@ -4511,11 +9352,11 @@ }, "packages/authn-recovery-codes": { "name": "@1auth/authn-recovery-codes", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" }, "engines": { "node": ">=24" @@ -4527,10 +9368,13 @@ }, "packages/authn-webauthn": { "name": "@1auth/authn-webauthn", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@simplewebauthn/server": "13.2.2" + "@1auth/account": "0.0.0-beta.2", + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2", + "@simplewebauthn/server": "13.3.0" }, "engines": { "node": ">=24" @@ -4542,7 +9386,7 @@ }, "packages/crypto": { "name": "@1auth/crypto", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { "nanoid": "5.1.6" @@ -4557,11 +9401,11 @@ }, "packages/messenger": { "name": "@1auth/messenger", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" }, "engines": { "node": ">=24" @@ -4573,12 +9417,12 @@ }, "packages/messenger-email-address": { "name": "@1auth/messenger-email-address", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1", - "@1auth/messenger": "0.0.0-beta.1", + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2", + "@1auth/messenger": "0.0.0-beta.2", "tr46": "6.0.0" }, "engines": { @@ -4591,7 +9435,7 @@ }, "packages/notify": { "name": "@1auth/notify", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "engines": { "node": ">=24" @@ -4603,7 +9447,7 @@ }, "packages/notify-sqs": { "name": "@1auth/notify-sqs", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "engines": { "node": ">=24" @@ -4618,12 +9462,24 @@ }, "packages/session": { "name": "@1auth/session", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" + }, + "engines": { + "node": ">=24" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/willfarrell" + } + }, + "packages/store-d1": { + "name": "@1auth/store-d1", + "version": "0.0.0-beta.2", + "license": "MIT", "engines": { "node": ">=24" }, @@ -4634,7 +9490,7 @@ }, "packages/store-dynamodb": { "name": "@1auth/store-dynamodb", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "engines": { "node": ">=24" @@ -4650,10 +9506,10 @@ }, "packages/store-postgres": { "name": "@1auth/store-postgres", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "devDependencies": { - "pg": "8.18.0" + "pg": "8.20.0" }, "engines": { "node": ">=24" @@ -4665,7 +9521,7 @@ }, "packages/store-sqlite": { "name": "@1auth/store-sqlite", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "license": "MIT", "engines": { "node": ">=24" @@ -4674,6 +9530,30 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" } + }, + "websites/1auth.js.org": { + "version": "0.0.0-beta.2", + "dependencies": { + "@willfarrell-ds/svelte": "0.0.0-alpha.4", + "@willfarrell-ds/vanilla": "0.0.0-alpha.4", + "hast-util-to-string": "3.0.1", + "mdast-util-to-string": "4.0.0" + }, + "devDependencies": { + "@sveltejs/adapter-cloudflare": "^7.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^6.0.0", + "@willfarrell-ds/cli": "0.0.0-alpha.4", + "esbuild": "^0.27.0", + "mdsvex": "^0.12.0", + "svelte": "^5.0.0", + "svgo": "^4.0.0", + "vite": "^7.0.0", + "vite-plugin-mkcert": "^1.0.0", + "vite-plugin-sitemap": "^0.8.0", + "vite-plugin-sri": "^0.0.2", + "wrangler": "^4.0.0" + } } } } diff --git a/package.json b/package.json index 986830f..ea361fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@1auth/monorepo", - "version": "0.0.0-beta.1", + "version": "0.0.0-beta.2", "description": "", "private": true, "type": "module", @@ -10,21 +10,21 @@ "engineStrict": true, "scripts": { "prepare": "husky", - "preinstall": "npm link --workspaces", "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": "biome check --staged --no-errors-on-unmatched --files-ignore-unknown=true", "git:test-staged": "which node", "lint": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true", - "test": "npm run test:lint && npm run test:unit && npm run test:sast && npm run test:perf && npm run test:dast", + "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 --write --no-errors-on-unmatched --files-ignore-unknown=true", - "test:unit": "node --test --experimental-test-coverage --test-coverage-lines=98 --test-coverage-branches=95 --test-coverage-functions=97 --test-coverage-exclude=**/mock.js --test-coverage-exclude=**/*.test.js --test-coverage-exclude=**/table/*", - "test:sast": "npm run test:sast:license && npm run test:sast:lockfile && npm run test:sast:sandworm && npm run test:sast:semgrep && npm run test:sast:trufflehog", + "test:unit": "node --test --test-concurrency 1 --experimental-test-coverage --test-coverage-lines=98 --test-coverage-branches=95 --test-coverage-functions=97 --test-coverage-exclude=**/mock.js --test-coverage-exclude=**/*.test.js --test-coverage-exclude=**/table/*", + "test:sast": "npm run test:sast:license && npm run test:sast:lockfile && npm run test:sast:trivy && npm run test:sast:semgrep && npm run test:sast:trufflehog", "test:sast:license": "license-check-and-add check -f license.json", "test:sast:lockfile": "lockfile-lint --path package-lock.json --type npm --allowed-hosts npm --validate-https", "test:sast:semgrep": "semgrep scan --config auto", "test:sast:trivy": "trivy fs --scanners vuln,license --include-dev-deps --ignored-licenses 0BSD,Apache-2.0,BSD-1-Clause,BSD-2-Clause,BSD-3-Clause,CC0-1.0,CC-BY-4.0,ISC,MIT --exit-code 1 --disable-telemetry .", "test:sast:trufflehog": "trufflehog filesystem --only-verified --log-level=-1 ./", + "test:types": "which tstyche > /dev/null 2>&1 && tstyche || echo 'tstyche not found, skipping type tests'", "test:perf": "node --test ./**/*.perf.js", "test:dast": "npm run test:dast:fuzz && npm run test:dast:zap", "test:dast:fuzz": "node --test ./**/*.fuzz.js", @@ -34,14 +34,14 @@ "test:postgres:update": "docker pull postgres", "test:postgres": "docker run -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres", "rm": "npm run rm:node_modules && npm run rm:lock", - "rm:lock": "find . -name 'pacakge-lock.json' -type d -prune -exec rm -rf '{}' +", + "rm:lock": "find . -name 'package-lock.json' -type f -prune -exec rm -rf '{}' +", "rm:node_modules": "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +", "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:sync": "npm version $npm_package_version --workspaces && find ./packages -name \"package.json\" -exec sed -i '' -E \"s|\\\"@1auth/(.*)\\\": ([^,]*)|\\\"@1auth/\\1\\\": $(npm pkg get version)|g\" {} \\; && npm run rm:node_modules && npm link --workspaces && npm install", + "release:sync": "npm version $npm_package_version --workspaces && find ./packages -name \"package.json\" -exec sed -i '' -E \"s|\\\"@1auth/(.*)\\\": ([^,]*)|\\\"@1auth/\\1\\\": $(npm pkg get version)|g\" {} \\; && npm run rm && npm install", "release:tag": "git tag $npm_package_version && git push --tags" }, "repository": { @@ -75,9 +75,17 @@ "aws-sdk-client-mock": "^4.0.0", "fast-check": "^4.0.0", "husky": "^9.0.0", - "license-check-and-add": "4.0.5", + "license-check-and-add": "^4.0.0", "tinybench": "^6.0.0" }, + "overrides": { + "@sveltejs/kit": { + "cookie": "0.7.2" + }, + "license-check-and-add": { + "minimatch": "^10.2.4" + } + }, "devEngines": { "runtime": { "name": "node", @@ -90,6 +98,7 @@ }, "workspaces": [ "packages/*", + "websites/*", ".github" ] } diff --git a/packages/account-username/README.md b/packages/account-username/README.md new file mode 100644 index 0000000..a5ff021 --- /dev/null +++ b/packages/account-username/README.md @@ -0,0 +1,44 @@ +

+

@1auth/account-username

+ +

Username validation and management for account authentication

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/account-username +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/account-username/index.js b/packages/account-username/index.js index 7252934..70d3778 100644 --- a/packages/account-username/index.js +++ b/packages/account-username/index.js @@ -9,7 +9,7 @@ import { import { createSeasonedDigest, symmetricDecryptFields } from "@1auth/crypto"; // Only allow characters that are safe to encode -// not allowed because it can be used to declare and extension +// not allowed because it can be used to declare an extension let usernameBlacklistRegExp; const options = { id: "username", @@ -18,8 +18,8 @@ const options = { minLength: 1, maxLength: 32, }; -export default (params) => { - Object.assign(options, accountOptions(), params); +export default (opt = {}) => { + Object.assign(options, accountOptions(), opt); if (options.usernameBlacklist.length) { usernameBlacklistRegExp = new RegExp( `(${options.usernameBlacklist.map((value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})`, @@ -30,7 +30,7 @@ export default (params) => { export const exists = async (username) => { const usernameSanitized = sanitize(username); const usernameDigest = createSeasonedDigest(usernameSanitized); - return options.store.exists(options.table, { + return await options.store.exists(options.table, { digest: usernameDigest, }); }; @@ -115,7 +115,7 @@ export const validateLength = (value) => { }; export const validateAllowedChar = (value) => { - // TODO URL encode compare + // allowedCharRegExp only permits URL-safe chars, no encoding needed if (!options.allowedCharRegExp.test(value)) { return "400 Bad Request"; } diff --git a/packages/account-username/index.test.js b/packages/account-username/index.test.js index 98641dd..9e59cd1 100644 --- a/packages/account-username/index.test.js +++ b/packages/account-username/index.test.js @@ -195,7 +195,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[0].arguments[0], { id: "account-username-change", sub, - data: undefined, + data: {}, options: {}, }); }); diff --git a/packages/account-username/package.json b/packages/account-username/package.json index 0981e70..60c4eff 100644 --- a/packages/account-username/package.json +++ b/packages/account-username/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/account-username", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Username validation and management for account authentication", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "account", + "username", + "identity" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,6 +53,7 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/account": "0.0.0-beta.1" + "@1auth/account": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" } } diff --git a/packages/account/README.md b/packages/account/README.md new file mode 100644 index 0000000..768a58e --- /dev/null +++ b/packages/account/README.md @@ -0,0 +1,44 @@ +
+

@1auth/account

+ +

User account management with encrypted storage and lifecycle operations

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/account +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/account/index.fuzz.js b/packages/account/index.fuzz.js index 974106c..65f97ea 100644 --- a/packages/account/index.fuzz.js +++ b/packages/account/index.fuzz.js @@ -115,22 +115,6 @@ test("fuzz accountLookup w/ sub", async () => { ); }); -// test("fuzz accountCreate w/ values", async () => { -// await fc.assert( -// fc.asyncProperty(fc.anything(), async (values) => { -// try { -// await accountCreate(values); -// } catch (e) { -// catchError(values, e); -// } -// }), -// { -// numRuns: 100_000, -// verbose: 2, -// examples: [], -// }, -// ); -// }); test("fuzz accountCreate w/ values", async () => { await fc.assert( fc.asyncProperty(fc.string(), async (values) => { @@ -164,22 +148,6 @@ test("fuzz accountUpdate w/ sub", async () => { }, ); }); -// test("fuzz accountUpdate w/ values", async () => { -// await fc.assert( -// fc.asyncProperty(fc.anything(), async (values) => { -// try { -// await accountUpdate(sub, values); -// } catch (e) { -// catchError(values, e); -// } -// }), -// { -// numRuns: 100_000, -// verbose: 2, -// examples: [], -// }, -// ); -// }); test("fuzz accountUpdate w/ values", async () => { await fc.assert( fc.asyncProperty(fc.string(), async (values) => { diff --git a/packages/account/index.js b/packages/account/index.js index 381e62f..5383ead 100644 --- a/packages/account/index.js +++ b/packages/account/index.js @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MIT import { makeRandomConfigObject, + nowInSeconds, symmetricDecryptFields, symmetricEncryptFields, symmetricGenerateEncryptionKey, @@ -34,8 +35,8 @@ const defaults = { encryptedFields: [], }; const options = {}; -export default (params) => { - Object.assign(options, defaults, params); +export default (opt = {}) => { + Object.assign(options, defaults, opt); }; export const getOptions = () => options; @@ -43,7 +44,7 @@ export const exists = async (sub) => { if (!sub || typeof sub !== "string") { throw new Error("404 Not Found", { cause: { sub } }); } - return options.store.exists(options.table, { sub }); + return await options.store.exists(options.table, { sub }); }; export const lookup = async (sub) => { @@ -65,7 +66,7 @@ export const lookup = async (sub) => { }; export const create = async (values = {}) => { - const sub = await options.randomSubject.create(options.subPrefix); + const sub = await options.randomSubject.create(); const { encryptionKey, encryptedKey } = symmetricGenerateEncryptionKey(sub); const encryptedValues = symmetricEncryptFields( @@ -83,11 +84,11 @@ export const create = async (values = {}) => { update: now, }; if (options.idGenerate) { - params.id = await options.randomId.create(options.idPrefix); + params.id = await options.randomId.create(); } await options.store.insert(options.table, params); - // TODO update guest session, attach sub + // If caller has a guest session, use session.rotate(guestSub, guestSessionId, sub, deviceMeta) to transition it. return sub; }; @@ -139,23 +140,3 @@ export const remove = async (sub) => { // Should trigger removal of credentials and messengers await options.store.remove(options.table, { sub }); }; - -/* export const expire = async (sub) => { - const expire = nowInSeconds() + 90 * 24 * 60 * 60 - await options.store.update(options.table, { sub }, { expire }) - await options.notify.trigger('account-expire', sub) - // TODO clear sessions -} - -export const recover = async (sub) => { - await options.store.update(options.table, { sub }, { expire: null }) - await options.notify.trigger('account-recover', sub) -} */ - -// TODO manage onboard state - -// TODO save notification settings - -// TODO authorize management? - -const nowInSeconds = () => Math.floor(Date.now() / 1000); diff --git a/packages/account/package.json b/packages/account/package.json index 69c5fab..57c39c3 100644 --- a/packages/account/package.json +++ b/packages/account/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/account", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "User account management with encrypted storage and lifecycle operations", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,18 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" } }, - "types": "index.d.ts", "files": [ "index.js", - "index.d.ts" + "table" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +34,13 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "account", + "identity" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,6 +56,6 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/crypto": "0.0.0-beta.2" } } diff --git a/packages/authn-access-token/README.md b/packages/authn-access-token/README.md new file mode 100644 index 0000000..15297ae --- /dev/null +++ b/packages/authn-access-token/README.md @@ -0,0 +1,44 @@ +
+

@1auth/authn-access-token

+ +

Access token authentication for API and service-to-service communication

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/authn-access-token +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/authn-access-token/index.fuzz.js b/packages/authn-access-token/index.fuzz.js index 590a809..2e8cef9 100644 --- a/packages/authn-access-token/index.fuzz.js +++ b/packages/authn-access-token/index.fuzz.js @@ -37,9 +37,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -138,7 +138,7 @@ test("fuzz accessTokenAuthenticate w/ secret", async () => { } }), { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, @@ -256,28 +256,12 @@ test("fuzz accessTokenCreate w/ sub", async () => { } }), { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, ); }); -// test("fuzz accessTokenCreate w/ values", async () => { -// await fc.assert( -// fc.asyncProperty(fc.anything(), async (values) => { -// try { -// await accessTokenCreate(sub, values); -// } catch (e) { -// catchError(values, e); -// } -// }), -// { -// numRuns: 100_000, -// verbose: 2, -// examples: [], -// }, -// ); -// }); test("fuzz accessTokenCreate w/ values", async () => { await fc.assert( fc.asyncProperty(fc.string(), async (values) => { @@ -288,7 +272,7 @@ test("fuzz accessTokenCreate w/ values", async () => { } }), { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, diff --git a/packages/authn-access-token/index.js b/packages/authn-access-token/index.js index 3025e1f..3fba7d1 100644 --- a/packages/authn-access-token/index.js +++ b/packages/authn-access-token/index.js @@ -14,6 +14,7 @@ import { createDigest, createSecretHash, makeRandomConfigObject, + nowInSeconds, verifySecretHash, } from "@1auth/crypto"; @@ -77,10 +78,13 @@ export const exists = async (username) => { throw new Error("404 Not Found", { cause: { username } }); } const digest = createDigest(username); - return options.store.exists(options.table, { digest }); + return await options.store.exists(options.table, { digest }); }; export const count = async (sub) => { + if (!sub || typeof sub !== "string") { + throw new Error("401 Unauthorized", { cause: { sub } }); + } return await authnCount(options.secret, sub); }; @@ -92,7 +96,7 @@ export const lookup = async (username) => { const authn = await options.store.select(options.table, { digest }); if (authn) { const now = nowInSeconds(); - if (authn.expire < now) { + if (authn.expire && authn.expire < now) { return; } return authn; @@ -135,5 +139,3 @@ export const remove = async (sub, id) => { await authnRemove(options.secret, sub, id); await options.notify.trigger("authn-access-token-remove", sub); }; - -const nowInSeconds = () => Math.floor(Date.now() / 1000); diff --git a/packages/authn-access-token/index.test.js b/packages/authn-access-token/index.test.js index 94ac134..14a7e22 100644 --- a/packages/authn-access-token/index.test.js +++ b/packages/authn-access-token/index.test.js @@ -4,14 +4,14 @@ import account, { create as accountCreate, remove as accountRemove, } from "../account/index.js"; -// import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; +import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; import * as mockAccountSQLTable from "../account/table/sql.js"; import accountUsername, { create as accountUsernameCreate, exists as accountUsernameExists, } from "../account-username/index.js"; import authn, { getOptions as authnGetOptions } from "../authn/index.js"; -// import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; +import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; import * as mockAuthnSQLTable from "../authn/table/sql.js"; import accessToken, { authenticate as accessTokenAuthenticate, @@ -34,9 +34,9 @@ import crypto, { import * as notify from "../notify/index.js"; import * as mockNotify from "../notify/mock.js"; import * as storeDynamoDB from "../store-dynamodb/index.js"; +import * as mockDynamoDB from "../store-dynamodb/mock.js"; import * as storePostgres from "../store-postgres/index.js"; import * as storeSQLite from "../store-sqlite/index.js"; -// import * as mockDynamoDB from "../store-dynamodb/mock.js"; // import * as mockPostgres from "../store-postgres/mock.js"; import * as mockSQLite from "../store-sqlite/mock.js"; @@ -45,9 +45,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -93,16 +93,19 @@ const mockStores = { storeAuthn: mockAuthnSQLTable, }, }, - // TODO - // dynamodb: { - // store: storeDynamoDB, - // mocks :{ - // ...mockNotify, - // ...mockDynamoDB, - // storeAccount: mockAccountDynamoDBTable, - // storeAuthn: mockAuthnDynamoDBTable, - // } - // }, + ...(mockDynamoDB.isReady() + ? { + dynamodb: { + store: storeDynamoDB, + mocks: { + ...mockNotify, + ...mockDynamoDB, + storeAccount: mockAccountDynamoDBTable, + storeAuthn: mockAuthnDynamoDBTable, + }, + }, + } + : {}), }; account(); @@ -183,6 +186,17 @@ const tests = (config) => { }); }); + describe("`count`", () => { + it("Will throw with ({sub:undefined})", async () => { + try { + await accessTokenCount(undefined); + ok(false); + } catch (e) { + equal(e.message, "401 Unauthorized"); + } + }); + }); + describe("`remove`", () => { it("Will throw with ({sub:undefined})", async () => { try { @@ -231,7 +245,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[1].arguments[0], { id: "authn-access-token-remove", sub, - data: undefined, + data: {}, options: {}, }); @@ -275,7 +289,7 @@ const tests = (config) => { equal(row, undefined); }); it("Can select an access token with { id } (exists)", async () => { - const { id } = await accessTokenCreate(sub); // TODO id is undefined + const { id } = await accessTokenCreate(sub); const row = await accessTokenSelect(sub, id); ok(row); }); @@ -294,7 +308,7 @@ const tests = (config) => { equal(row.length, 0); }); }; -describe("authn-access-token", () => { +describe("authn-access-token", { concurrency: 1 }, () => { for (const storeKey of Object.keys(mockStores)) { describe(`using store-${storeKey}`, () => { tests(mockStores[storeKey]); diff --git a/packages/authn-access-token/package.json b/packages/authn-access-token/package.json index fb3de84..db8a547 100644 --- a/packages/authn-access-token/package.json +++ b/packages/authn-access-token/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/authn-access-token", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Access token authentication for API and service-to-service communication", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "authentication", + "access-token", + "API" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,7 +53,7 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" } } diff --git a/packages/authn-recovery-codes/README.md b/packages/authn-recovery-codes/README.md new file mode 100644 index 0000000..dbad952 --- /dev/null +++ b/packages/authn-recovery-codes/README.md @@ -0,0 +1,44 @@ +
+

@1auth/authn-recovery-codes

+ +

One-time recovery code generation and verification for account recovery

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/authn-recovery-codes +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/authn-recovery-codes/index.fuzz.js b/packages/authn-recovery-codes/index.fuzz.js index c58ec65..5c4e16a 100644 --- a/packages/authn-recovery-codes/index.fuzz.js +++ b/packages/authn-recovery-codes/index.fuzz.js @@ -34,9 +34,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -135,7 +135,7 @@ test("fuzz recoveryCodesAuthenticate w/ secret", async () => { } }), { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, @@ -186,14 +186,14 @@ test("fuzz recoveryCodesCreate w/ sub", async () => { } }), { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, ); }); -test("fuzz recoveryCodesUpate w/ sub", async () => { +test("fuzz recoveryCodesUpdate w/ sub", async () => { await fc.assert( fc.asyncProperty(fc.anything(), async (sub) => { try { @@ -203,7 +203,7 @@ test("fuzz recoveryCodesUpate w/ sub", async () => { } }), { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, diff --git a/packages/authn-recovery-codes/index.js b/packages/authn-recovery-codes/index.js index f519f1c..bbf6b56 100644 --- a/packages/authn-recovery-codes/index.js +++ b/packages/authn-recovery-codes/index.js @@ -3,10 +3,8 @@ import { authenticate as authnAuthenticate, count as authnCount, - // create as authnCreate, createList as authnCreateList, getOptions as authnGetOptions, - //select as authnSelect, list as authnList, remove as authnRemove, removeList as authnRemoveList, @@ -14,6 +12,7 @@ import { import { createSecretHash, makeRandomConfigObject, + nowInSeconds, verifySecretHash, } from "@1auth/crypto"; @@ -55,13 +54,12 @@ export const authenticate = async (username, secret) => { }; export const count = async (sub) => { + if (!sub || typeof sub !== "string") { + throw new Error("401 Unauthorized", { cause: { sub } }); + } return await authnCount(options.secret, sub); }; -// export const select = async (sub, id) => { -// return await authnSelect(options.secret, sub, id); -// }; - export const list = async (sub) => { return await authnList(options.secret, sub); }; @@ -99,7 +97,7 @@ export const remove = async (sub, id) => { const ids = await options.store .selectList(options.table, { sub, - type: `${options.id}-${options.secret.type}`, + type: `${options.secret.id}-${options.secret.type}`, }) .then((res) => res.map((item) => item.id)); await authnRemoveList(options.secret, sub, ids); @@ -121,5 +119,3 @@ const createSecrets = async (sub, count = options.count) => { await authnCreateList(options.secret, sub, secrets); return secrets; }; - -const nowInSeconds = () => Math.floor(Date.now() / 1000); diff --git a/packages/authn-recovery-codes/index.test.js b/packages/authn-recovery-codes/index.test.js index c3065e0..fa13cf7 100644 --- a/packages/authn-recovery-codes/index.test.js +++ b/packages/authn-recovery-codes/index.test.js @@ -4,14 +4,14 @@ import account, { create as accountCreate, remove as accountRemove, } from "../account/index.js"; -// import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; +import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; import * as mockAccountSQLTable from "../account/table/sql.js"; import accountUsername, { create as accountUsernameCreate, exists as accountUsernameExists, } from "../account-username/index.js"; import authn, { getOptions as authnGetOptions } from "../authn/index.js"; -// import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; +import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; import * as mockAuthnSQLTable from "../authn/table/sql.js"; import recoveryCodes, { authenticate as recoveryCodesAuthenticate, @@ -34,9 +34,9 @@ import crypto, { import * as notify from "../notify/index.js"; import * as mockNotify from "../notify/mock.js"; import * as storeDynamoDB from "../store-dynamodb/index.js"; +import * as mockDynamoDB from "../store-dynamodb/mock.js"; import * as storePostgres from "../store-postgres/index.js"; import * as storeSQLite from "../store-sqlite/index.js"; -// import * as mockDynamoDB from "../store-dynamodb/mock.js"; // import * as mockPostgres from "../store-postgres/mock.js"; import * as mockSQLite from "../store-sqlite/mock.js"; @@ -45,9 +45,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -93,16 +93,19 @@ const mockStores = { storeAuthn: mockAuthnSQLTable, }, }, - // TODO - // dynamodb: { - // store: storeDynamoDB, - // mocks :{ - // ...mockNotify, - // ...mockDynamoDB, - // storeAccount: mockAccountDynamoDBTable, - // storeAuthn: mockAuthnDynamoDBTable, - // } - // }, + ...(mockDynamoDB.isReady() + ? { + dynamodb: { + store: storeDynamoDB, + mocks: { + ...mockNotify, + ...mockDynamoDB, + storeAccount: mockAccountDynamoDBTable, + storeAuthn: mockAuthnDynamoDBTable, + }, + }, + } + : {}), }; account(); @@ -243,7 +246,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[0].arguments[0], { id: "authn-recovery-codes-create", sub, - data: undefined, + data: {}, options: {}, }); const userSub = await recoveryCodesAuthenticate(username, secrets[0].value); @@ -268,7 +271,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[1].arguments[0], { id: "authn-recovery-codes-update", sub, - data: undefined, + data: {}, options: {}, }); authnDB = await store.selectList(authnGetOptions().table, { sub }); @@ -285,7 +288,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[1].arguments[0], { id: "authn-recovery-codes-remove", sub, - data: undefined, + data: {}, options: {}, }); @@ -307,7 +310,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[1].arguments[0], { id: "authn-recovery-codes-remove", sub, - data: undefined, + data: {}, options: {}, }); @@ -367,7 +370,7 @@ const tests = (config) => { equal(row.length, 0); }); }; -describe("authn-recovery-codes", () => { +describe("authn-recovery-codes", { concurrency: 1 }, () => { for (const storeKey of Object.keys(mockStores)) { describe(`using store-${storeKey}`, () => { tests(mockStores[storeKey]); diff --git a/packages/authn-recovery-codes/package.json b/packages/authn-recovery-codes/package.json index 71b2975..8a402eb 100644 --- a/packages/authn-recovery-codes/package.json +++ b/packages/authn-recovery-codes/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/authn-recovery-codes", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "One-time recovery code generation and verification for account recovery", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "authentication", + "recovery-codes", + "2FA" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,7 +53,7 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" } } diff --git a/packages/authn-webauthn/README.md b/packages/authn-webauthn/README.md new file mode 100644 index 0000000..9bc6bf8 --- /dev/null +++ b/packages/authn-webauthn/README.md @@ -0,0 +1,44 @@ +
+

@1auth/authn-webauthn

+ +

WebAuthn/FIDO2 authentication implementation for passwordless login

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/authn-webauthn +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/authn-webauthn/index.fuzz.js b/packages/authn-webauthn/index.fuzz.js index 3d50d72..7f3dee5 100644 --- a/packages/authn-webauthn/index.fuzz.js +++ b/packages/authn-webauthn/index.fuzz.js @@ -14,8 +14,7 @@ import webauthn, { create as webauthnCreate, list as webauthnList, remove as webauthnRemove, - update as webauthnUpdate, -} from "../authn-recovery-codes/index.js"; +} from "../authn-webauthn/index.js"; import crypto, { randomChecksumPepper, @@ -34,9 +33,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -56,7 +55,6 @@ const mocks = { }; let sub; -let testSecret; const username = "username"; test.before(async () => { @@ -75,13 +73,15 @@ test.before(async () => { encryptedFields: ["value", "name"], authenticationDuration: 0, }); + webauthn({ + origin: "https://localhost", + name: "Test", + }); }); test.beforeEach(async () => { sub = await accountCreate(); await accountUsernameCreate(sub, username); - webauthn({ count: 1 }); - testSecret = await webauthnCreate(sub).then((res) => res[0]); }); test.afterEach(async () => { @@ -113,7 +113,7 @@ test("fuzz webauthnAuthenticate w/ username", async () => { await fc.assert( fc.asyncProperty(fc.anything(), async (username) => { try { - await webauthnAuthenticate(username, testSecret.value); + await webauthnAuthenticate(username, "secret"); } catch (e) { catchError(username, e); } @@ -135,7 +135,7 @@ test("fuzz webauthnAuthenticate w/ secret", async () => { } }), { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, @@ -186,24 +186,7 @@ test("fuzz webauthnCreate w/ sub", async () => { } }), { - numRuns: 100_000, - verbose: 2, - examples: [], - }, - ); -}); - -test("fuzz webauthnUpate w/ sub", async () => { - await fc.assert( - fc.asyncProperty(fc.anything(), async (sub) => { - try { - await webauthnUpdate(sub); - } catch (e) { - catchError(sub, e); - } - }), - { - numRuns: 100_000, + numRuns: 1_000, verbose: 2, examples: [], }, @@ -214,7 +197,7 @@ test("fuzz webauthnRemove w/ sub", async () => { await fc.assert( fc.asyncProperty(fc.anything(), async (sub) => { try { - await webauthnRemove(sub, testSecret.id); + await webauthnRemove(sub, "id"); } catch (e) { catchError(sub, e); } diff --git a/packages/authn-webauthn/index.js b/packages/authn-webauthn/index.js index 7fb9793..aa0a972 100644 --- a/packages/authn-webauthn/index.js +++ b/packages/authn-webauthn/index.js @@ -14,7 +14,7 @@ import { update as authnUpdate, verify as authnVerify, } from "@1auth/authn"; -import { makeRandomConfigObject } from "@1auth/crypto"; +import { makeRandomConfigObject, nowInSeconds } from "@1auth/crypto"; import { generateAuthenticationOptions, @@ -38,7 +38,10 @@ export const token = ({ ...value, response, }); - if (!verified) throw new Error("Failed verifyRegistrationResponse"); + if (!verified) + throw new Error("Failed verifyRegistrationResponse", { + cause: { response }, + }); return { registrationInfo: jsonEncodeSecret(registrationInfo) }; }, ...params @@ -82,7 +85,6 @@ export const challenge = ({ type = "challenge", otp = true, expire = 10 * 60, - // create: () => randomAlphaNumeric(challenge.minLength), encode = (value) => { value.authenticator = jsonEncodeSecret(value.authenticator); const encodedValue = JSON.stringify(value); @@ -101,9 +103,11 @@ export const challenge = ({ response, }, ); - if (!verified) throw new Error("Failed verifyAuthenticationResponse"); + if (!verified) + throw new Error("Failed verifyAuthenticationResponse", { + cause: { response }, + }); value.authenticator.credential.counter = authenticationInfo.newCounter; - // value.authenticator = jsonEncodeSecret(value.authenticator) return true; }, cleanup = async (sub, value, { sourceId } = {}) => { @@ -150,8 +154,8 @@ const defaults = { challenge: challenge(), }; const options = {}; -export default (params) => { - Object.assign(options, authnGetOptions(), defaults, params); +export default (opt = {}) => { + Object.assign(options, authnGetOptions(), defaults, opt); }; export const getOptions = () => options; @@ -189,7 +193,7 @@ export const verify = async ( }); if (notify) { - await options.notify.trigger("authn-webauthn-create", sub); // TODO add in user.name + await options.notify.trigger("authn-webauthn-create", sub, { name }); } return { id, secret: value }; }; @@ -222,22 +226,6 @@ const createToken = async (sub) => { residentKey: options.residentKey, userVerification: options.userVerification, }, - // extras? - // timeout - // pubKeyCredParams: [ - // { - // type: 'public-key', - // alg: -8 // EdDSA - // }, - // { - // type: 'public-key', - // alg: -7 // ES256 - // }, - // { - // type: 'public-key', - // alg: -257 // RS256 - // } - // ] }; const secret = await generateRegistrationOptions(registrationOptions); const value = { @@ -261,8 +249,17 @@ const verifyToken = async (sub, credential) => { }; export const createChallenge = async (sub) => { - // TODO remove previous challenges - // const challenge = options.challenge.create(); + // Remove previous challenges for this user + const previousChallenges = await authnList( + options.challenge, + sub, + undefined, + ["id"], + ); + for (const prev of previousChallenges) { + await authnRemove(options.challenge, sub, prev.id); + } + const now = nowInSeconds(); const credentials = await authnList(options.secret, sub, undefined, [ @@ -282,7 +279,7 @@ export const createChallenge = async (sub) => { if (!allowCredentials.length) { if (options.log) { - options.log("@1auth/auth-webauthn allowCredentials is empty"); + options.log("@1auth/authn-webauthn allowCredentials is empty"); } return {}; } @@ -328,14 +325,12 @@ export const remove = async (sub, id) => { const jsonEncodeSecret = (value) => { if (!value) return value; - // value.credential.id = credentialNormalize(value.credential.id); value.credential.publicKey = credentialNormalize(value.credential.publicKey); value.attestationObject = credentialNormalize(value.attestationObject); return value; }; const jsonParseSecret = (value) => { - // value.credential.id = credentialBuffer(value.credential.id); value.credential.publicKey = credentialBuffer(value.credential.publicKey); value.attestationObject = credentialBuffer(value.attestationObject); return value; @@ -352,5 +347,3 @@ const credentialNormalize = (value) => { const credentialBuffer = (value) => { return Buffer.from(credentialNormalize(value)); }; - -const nowInSeconds = () => Math.floor(Date.now() / 1000); diff --git a/packages/authn-webauthn/index.test.js b/packages/authn-webauthn/index.test.js index 3317c49..3ac0673 100644 --- a/packages/authn-webauthn/index.test.js +++ b/packages/authn-webauthn/index.test.js @@ -4,14 +4,14 @@ import account, { create as accountCreate, remove as accountRemove, } from "../account/index.js"; -// import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; +import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; import * as mockAccountSQLTable from "../account/table/sql.js"; import accountUsername, { create as accountUsernameCreate, exists as accountUsernameExists, } from "../account-username/index.js"; import authn, { getOptions as authnGetOptions } from "../authn/index.js"; -// import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; +import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; import * as mockAuthnSQLTable from "../authn/table/sql.js"; import webauthn, { authenticate as webauthnAuthenticate, @@ -37,9 +37,9 @@ import crypto, { import * as notify from "../notify/index.js"; import * as mockNotify from "../notify/mock.js"; import * as storeDynamoDB from "../store-dynamodb/index.js"; +import * as mockDynamoDB from "../store-dynamodb/mock.js"; import * as storePostgres from "../store-postgres/index.js"; import * as storeSQLite from "../store-sqlite/index.js"; -// import * as mockDynamoDB from "../store-dynamodb/mock.js"; // import * as mockPostgres from "../store-postgres/mock.js"; import * as mockSQLite from "../store-sqlite/mock.js"; @@ -48,9 +48,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -96,16 +96,19 @@ const mockStores = { storeAuthn: mockAuthnSQLTable, }, }, - // TODO - // dynamodb: { - // store: storeDynamoDB, - // mocks :{ - // ...mockNotify, - // ...mockDynamoDB, - // storeAccount: mockAccountDynamoDBTable, - // storeAuthn: mockAuthnDynamoDBTable, - // } - // }, + ...(mockDynamoDB.isReady() + ? { + dynamodb: { + store: storeDynamoDB, + mocks: { + ...mockNotify, + ...mockDynamoDB, + storeAccount: mockAccountDynamoDBTable, + storeAuthn: mockAuthnDynamoDBTable, + }, + }, + } + : {}), }; account(); @@ -241,7 +244,7 @@ const tests = (config) => { } }); it("Can select an WebAuthn with { id } (exists)", async () => { - await webauthnCreate(sub); // TODO id is undefined + await webauthnCreate(sub); const [token] = await store.selectList(authnGetOptions().table, { sub }); await overrideCreateChallenge(sub, token); const { id } = await webauthnVerify( @@ -378,7 +381,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[0].arguments[0], { id: "authn-webauthn-create", sub, - data: undefined, + data: { name: "PassKey" }, options: {}, }); @@ -388,7 +391,7 @@ const tests = (config) => { equal(secret.type, "WebAuthn-secret"); equal(secret.otp, false); equal(secret.value.length, 1741); - equal(secret.expire, null); + ok(!secret.expire); count = await webauthnCount(sub); equal(count, 1); @@ -434,14 +437,16 @@ const tests = (config) => { await overrideCreateChallenge(sub, db0[0]); await webauthnVerify(sub, registrationResponse, { name: "PassKey" }); - // TODO finish - // await webauthnCreate(sub); - // const [token] = await store.selectList(authnGetOptions().table, { sub }); - // await overrideCreateChallenge(sub, token); - // await webauthnVerify(sub, registrationResponse, { name: "Yubikey" }); + await webauthnCreate(sub); + const [token] = await store.selectList(authnGetOptions().table, { + sub, + type: "WebAuthn-token", + }); + await overrideCreateChallenge(sub, token); + await webauthnVerify(sub, registrationResponse, { name: "Yubikey" }, false); - // let count = await webauthnCount(sub); - // equal(count, 2); + const count = await webauthnCount(sub); + equal(count, 2); }); it("Can remove WebAuthn on an account", async () => { await webauthnCreate(sub); @@ -459,7 +464,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[1].arguments[0], { id: "authn-webauthn-remove", sub, - data: undefined, + data: {}, options: {}, }); @@ -583,7 +588,7 @@ const tests = (config) => { ); }; }; -describe("authn-webauthn", () => { +describe("authn-webauthn", { concurrency: 1 }, () => { for (const storeKey of Object.keys(mockStores)) { describe(`using store-${storeKey}`, () => { tests(mockStores[storeKey]); diff --git a/packages/authn-webauthn/package.json b/packages/authn-webauthn/package.json index 5e62786..616f280 100644 --- a/packages/authn-webauthn/package.json +++ b/packages/authn-webauthn/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/authn-webauthn", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "WebAuthn/FIDO2 authentication implementation for passwordless login", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,15 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "authentication", + "WebAuthn", + "passkey", + "FIDO2" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,6 +54,9 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@simplewebauthn/server": "13.2.2" + "@1auth/account": "0.0.0-beta.2", + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2", + "@simplewebauthn/server": "13.3.0" } } diff --git a/packages/authn/README.md b/packages/authn/README.md new file mode 100644 index 0000000..a73c655 --- /dev/null +++ b/packages/authn/README.md @@ -0,0 +1,44 @@ +
+

@1auth/authn

+ +

Core authentication module with multi-factor authentication support

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/authn +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/authn/index.js b/packages/authn/index.js index 51788ad..3b8b217 100644 --- a/packages/authn/index.js +++ b/packages/authn/index.js @@ -3,6 +3,7 @@ import { setTimeout } from "node:timers/promises"; import { makeRandomConfigObject, + nowInSeconds, symmetricDecryptFields, symmetricEncryptFields, symmetricGenerateEncryptionKey, @@ -35,19 +36,9 @@ export default (opt = {}) => { }; export const getOptions = () => options; -// export const exists = async (credentialOptions, sub, params) => { -// const type = makeType(credentialOptions); -// const list = await options.store.selectList(options.table, { -// ...params, -// sub, -// type, -// }); -// return list.length > 1; -// }; - export const count = async (credentialOptions, sub) => { if (!sub || typeof sub !== "string") { - throw new Error("401 Unauthorized", { cause: { sub, id } }); + throw new Error("401 Unauthorized", { cause: { sub } }); } const type = makeType(credentialOptions); const credentials = await options.store.selectList( @@ -72,7 +63,7 @@ export const count = async (credentialOptions, sub) => { export const list = async (credentialOptions, sub, params, fields) => { if (!sub || typeof sub !== "string") { - throw new Error("401 Unauthorized", { cause: { sub, id } }); + throw new Error("401 Unauthorized", { cause: { sub } }); } const type = makeType(credentialOptions); const items = await options.store.selectList( @@ -84,14 +75,13 @@ export const list = async (credentialOptions, sub, params, fields) => { }, fields, ); - // const now = nowInSeconds(); + const now = nowInSeconds(); const list = []; for (let i = items.length; i--; ) { const item = items[i]; - // TODO need filter for expire - // if (credential.expire < now) { - // continue; - // } + if (item.expire && item.expire < now) { + continue; + } const { encryptionKey: encryptedKey } = item; item.encryptionKey = undefined; const decryptedItem = symmetricDecryptFields( @@ -167,11 +157,7 @@ export const update = async ( credentialOptions, { id, sub, encryptionKey, encryptedKey, value, ...values }, ) => { - // if (!sub || typeof sub !== "string") { - // throw new Error("401 Unauthorized", { cause: { sub } }); - // } const now = nowInSeconds(); - // const type = makeType(credentialOptions); const encodedValue = await credentialOptions.encode(value); @@ -181,7 +167,7 @@ export const update = async ( options.encryptedFields, ); - return options.store.update( + return await options.store.update( options.table, { sub, id }, { @@ -192,7 +178,7 @@ export const update = async ( }; export const subject = async (username) => { - return Promise.all( + return await Promise.all( options.usernameExists.map((exists) => { return exists(username); }), @@ -256,7 +242,6 @@ export const authenticate = async (credentialOptions, username, secret) => { if (otp) { await expire(credentialOptions, sub, id, { lastused: now }); } else { - const now = nowInSeconds(); await options.store.update( options.table, { id, sub }, @@ -292,7 +277,6 @@ export const verifySecret = async (_credentialOptions, sub, id) => { if (!id || typeof id !== "string") { throw new Error("404 Not Found", { cause: { sub, id } }); } - // const type = makeType(credentialOptions); const now = nowInSeconds(); await options.store.update( options.table, @@ -301,7 +285,6 @@ export const verifySecret = async (_credentialOptions, sub, id) => { ); }; -// TODO add in sourceId as filter for messengers export const verify = async (credentialOptions, sub, input) => { const timeout = setTimeout(options.authenticationDuration); if (!sub || typeof sub !== "string") { @@ -315,11 +298,12 @@ export const verify = async (credentialOptions, sub, input) => { } const type = makeType(credentialOptions); + const filters = { sub, type }; + if (credentialOptions.sourceId) { + filters.sourceId = credentialOptions.sourceId; + } - const credentials = await options.store.selectList(options.table, { - sub, - type, - }); + const credentials = await options.store.selectList(options.table, filters); const now = nowInSeconds(); let valid; @@ -327,7 +311,7 @@ export const verify = async (credentialOptions, sub, input) => { let skipExpiredCount = 0; for (credential of credentials) { // skip expired - if (credential.expire < now) { + if (credential.expire && credential.expire < now) { skipExpiredCount += 1; continue; } @@ -378,7 +362,6 @@ export const expire = async (_credentialOptions, sub, id, values = {}) => { if (!id || typeof id !== "string") { throw new Error("404 Not Found", { cause: { sub, id } }); } - // const type = makeType(credentialOptions); await options.store.update( options.table, { sub, id }, @@ -428,12 +411,5 @@ export const select = async (credentialOptions, sub, id) => { return decryptedItem; }; -// TODO manage onboard state - -// TODO save notification settings - -// TODO authorize management? - -const makeType = (credentialOptions) => +export const makeType = (credentialOptions) => `${credentialOptions.id}-${credentialOptions.type}`; -const nowInSeconds = () => Math.floor(Date.now() / 1000); diff --git a/packages/authn/package.json b/packages/authn/package.json index f35dbe2..6a86ac2 100644 --- a/packages/authn/package.json +++ b/packages/authn/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/authn", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Core authentication module with multi-factor authentication support", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,18 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" } }, - "types": "index.d.ts", "files": [ "index.js", - "index.d.ts" + "table" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +34,13 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "authentication", + "credentials" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,6 +56,6 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/crypto": "0.0.0-beta.2" } } diff --git a/packages/authn/table/dynamodb.js b/packages/authn/table/dynamodb.js index 33a9c15..c43c4df 100644 --- a/packages/authn/table/dynamodb.js +++ b/packages/authn/table/dynamodb.js @@ -26,6 +26,10 @@ export const create = async (client, table = name) => { AttributeName: "type", AttributeType: "S", }, + { + AttributeName: "digest", + AttributeType: "S", + }, { AttributeName: "expire", AttributeType: "N", @@ -49,15 +53,49 @@ export const create = async (client, table = name) => { AttributeName: "sub", KeyType: "HASH", }, + { + AttributeName: "type", + KeyType: "RANGE", + }, + ], + Projection: { + ProjectionType: "INCLUDE", + NonKeyAttributes: [ + "id", + "encryptionKey", + "value", + "digest", + "name", + "otp", + "sourceId", + "create", + "update", + "verify", + "expire", + "lastused", + ], + }, + }, + { + IndexName: "digest", + KeySchema: [ + { + AttributeName: "digest", + KeyType: "HASH", + }, ], Projection: { ProjectionType: "INCLUDE", NonKeyAttributes: [ "id", + "sub", "encryptionKey", "value", "name", + "otp", + "sourceId", "create", + "update", "verify", "expire", "lastused", diff --git a/packages/crypto/README.md b/packages/crypto/README.md new file mode 100644 index 0000000..3dc444d --- /dev/null +++ b/packages/crypto/README.md @@ -0,0 +1,44 @@ +
+

@1auth/crypto

+ +

Cryptographic utilities for encryption, hashing, and signing with modern algorithms

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/crypto +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/crypto/index.js b/packages/crypto/index.js index 36fa67a..92b1280 100644 --- a/packages/crypto/index.js +++ b/packages/crypto/index.js @@ -34,13 +34,17 @@ const defaults = { digestChecksumEncoding: undefined, digestChecksumSalt: undefined, // randomChecksumSalt() digestChecksumPepper: undefined, // randomChecksumPepper() + // Password hashing defaults - based on OWASP Password Storage Cheat Sheet + // https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + // OWASP minimums: 19 MiB memory, 2 iterations, 1 parallelism + // We use 32 MiB (exceeds minimum) for enhanced security secretArgon2Algorithm: "argon2id", - secretArgon2Version: 19, // argon2id - secretArgon2Parallelism: 1, // argon2id - secretArgon2MemoryCost: 15, // argon2id - secretArgon2TimeCost: 3, // argon2id - secretArgon2NonceLength: 16, // argon2id - secretArgon2HashLength: 64, // argon2id + secretArgon2Version: 19, + secretArgon2Parallelism: 1, // OWASP: 1 (matches) + secretArgon2MemoryCost: 15, // 2^15 KiB = 32 MiB (exceeds OWASP minimum of 19 MiB) + secretArgon2TimeCost: 3, // OWASP: 2 (we use 3 for better security) + secretArgon2NonceLength: 16, + secretArgon2HashLength: 64, defaultEncoding: "base64", defaultHashAlgorithm: "sha3-384", @@ -121,35 +125,12 @@ export const makeOptionsBuffer = ( export const getOptions = () => options; -// *** entropy *** // -// export const characterPoolSize = (value) => { -// const chars = value.split('') -// let min = chars[0].charCodeAt() -// let max = chars[0].charCodeAt() -// for(const char of value.split('')) { -// const code = char.charCodeAt() -// if (code < min) { -// min = code -// } else if (max < code) { -// max = code -// } -// } -// return max - min -// } - // *** Helpers *** // // Ref: https://therootcompany.com/blog/how-many-bits-of-entropy-per-character/ export const entropyToCharacterLength = (bits, characterPoolSize) => { // bits*ln(2)/ln(characterPoolSize) return Math.ceil((bits * Math.LN2) / Math.log(characterPoolSize)); }; -/* export const characterLengthToEntropy = ( - characterLength, - characterPoolSize, -) => { - // log_2(characterPoolSize^characterLength) - return Math.floor(Math.log2(characterPoolSize ** characterLength)); -}; */ // *** Random generators *** // export { randomBytes, randomInt, randomUUID } from "node:crypto"; @@ -179,7 +160,7 @@ export const randomAlphaNumeric = (characterLength) => { export const randomNumeric = (characterLength) => { let value = ""; for (let i = characterLength; i--; ) { - value += randomInt(9); + value += randomInt(0, 10); } return value; }; @@ -442,7 +423,7 @@ export const symmetricGenerateEncryptionKey = ( { encryptionKey, signatureSecret } = {}, ) => { encryptionKey ??= options.symmetricEncryptionKey; - signatureSecret ??= options.symemeticSignatureSecret; + signatureSecret ??= options.symmetricSignatureSecret; const rowEncryptionKey = symmetricRandomEncryptionKey(); const rowEncryptedKey = symmetricEncrypt(rowEncryptionKey, { @@ -539,7 +520,7 @@ export const symmetricDecryptKey = ( { sub, encryptionKey, signatureSecret } = {}, ) => { encryptionKey ??= options.symmetricEncryptionKey; - signatureSecret ??= options.symemeticSignatureSecret; + signatureSecret ??= options.symmetricSignatureSecret; return Buffer.from( symmetricDecrypt(encryptedKey, { encryptionKey, @@ -575,7 +556,9 @@ export const symmetricDecrypt = ( ); if (encryptedDataPacket === false) { - throw new Error("Signature incorrect"); + throw new Error("Signature incorrect", { + cause: { signedEncryptedDataPacket }, + }); } const iv = Buffer.from( encryptedDataPacket.substring(0, symmetricEncryptionEncodingLengths.iv), @@ -666,7 +649,10 @@ export const symmetricRotation = ( return data; }, ) => { - if (oldOptions.sub !== newOptions.sub) throw new Error("Mismatching `sub`"); + if (oldOptions.sub !== newOptions.sub) + throw new Error("Mismatching `sub`", { + cause: { sub: oldOptions.sub }, + }); const oldEncryptedValuesClone = structuredClone(oldEncryptedValues); // Don't use structuredClone, converts Buffer to Uint8Array ... @@ -754,6 +740,8 @@ export const verifyAsymmetricSignature = async ( ); }; +export const nowInSeconds = () => Math.floor(Date.now() / 1000); + export const safeEqual = (input, expected) => { const bufferInput = Buffer.from(input); const bufferExpected = Buffer.from(expected); diff --git a/packages/crypto/package.json b/packages/crypto/package.json index fc3f490..dc1cfaa 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/crypto", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Cryptographic utilities for encryption, hashing, and signing with modern algorithms", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "crypto", + "encryption", + "hashing" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" diff --git a/packages/messenger-email-address/README.md b/packages/messenger-email-address/README.md new file mode 100644 index 0000000..1d79b57 --- /dev/null +++ b/packages/messenger-email-address/README.md @@ -0,0 +1,44 @@ +
+

@1auth/messenger-email-address

+ +

Email address messenger for email verification and notifications

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/messenger-email-address +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/messenger-email-address/index.fuzz.js b/packages/messenger-email-address/index.fuzz.js index 8071716..9b8e4ad 100644 --- a/packages/messenger-email-address/index.fuzz.js +++ b/packages/messenger-email-address/index.fuzz.js @@ -35,9 +35,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -125,7 +125,7 @@ test("fuzz emailAddressExists w/ `username`", async () => { } }), { - numRuns: 10, + numRuns: 100_000, verbose: 2, examples: [], }, @@ -142,7 +142,7 @@ test("fuzz emailAddressLookup w/ `username`", async () => { } }), { - numRuns: 10, + numRuns: 100_000, verbose: 2, examples: [], }, @@ -159,7 +159,7 @@ test("fuzz emailAddressList w/ `sub`", async () => { } }), { - numRuns: 10, + numRuns: 100_000, verbose: 2, examples: [], }, @@ -176,7 +176,7 @@ test("fuzz emailAddressSelect w/ `sub`", async () => { } }), { - numRuns: 10, + numRuns: 100_000, verbose: 2, examples: [], }, @@ -193,7 +193,7 @@ test("fuzz emailAddressSelect w/ `id`", async () => { } }), { - numRuns: 10, + numRuns: 100_000, verbose: 2, examples: [], }, @@ -210,7 +210,7 @@ test("fuzz emailAddressCreate w/ `sub`", async () => { } }), { - numRuns: 10, + numRuns: 1_000, verbose: 2, examples: [], }, @@ -227,7 +227,7 @@ test("fuzz emailAddressCreate w/ `username`", async () => { } }), { - numRuns: 10, + numRuns: 1_000, verbose: 2, examples: [], }, @@ -244,30 +244,13 @@ test("fuzz emailAddressCreate w/ `emailAddress`", async () => { } }), { - numRuns: 10, + numRuns: 1_000, verbose: 2, examples: [], }, ); }); -// test("fuzz emailAddressCreate w/ `values`", async () => { -// await fc.assert( -// fc.asyncProperty(fc.anything(), async (values) => { -// try { -// await emailAddressCreate(sub, testMessenger.value, values); -// } catch (e) { -// catchError(values, e); -// } -// }), -// { -// numRuns: 10, -// verbose: 2, -// examples: [], -// }, -// ); -// }); - test("fuzz emailAddressCreate w/ `values`", async () => { await fc.assert( fc.asyncProperty(fc.anything(), async (values) => { @@ -278,7 +261,7 @@ test("fuzz emailAddressCreate w/ `values`", async () => { } }), { - numRuns: 10, + numRuns: 1_000, verbose: 2, examples: [], }, @@ -295,7 +278,7 @@ test("fuzz emailAddressRemove w/ `sub`", async () => { } }), { - numRuns: 10, + numRuns: 100_000, verbose: 2, examples: [], }, @@ -312,7 +295,7 @@ test("fuzz emailAddressRemove w/ `id`", async () => { } }), { - numRuns: 10, + numRuns: 100_000, verbose: 2, examples: [], }, diff --git a/packages/messenger-email-address/index.js b/packages/messenger-email-address/index.js index 8221edc..f7a05db 100644 --- a/packages/messenger-email-address/index.js +++ b/packages/messenger-email-address/index.js @@ -59,7 +59,10 @@ export const exists = async (value) => { }; export const count = async (sub) => { - return await messengerCount(options.secret, sub); + if (!sub || typeof sub !== "string") { + throw new Error("401 Unauthorized", { cause: { sub } }); + } + return await messengerCount(options.id, sub); }; export const lookup = async (emailAddress) => { @@ -68,7 +71,7 @@ export const lookup = async (emailAddress) => { }; export const list = async (sub) => { - return messengerList(options.id, sub); + return await messengerList(options.id, sub); }; export const select = async (sub, id) => { @@ -92,7 +95,7 @@ export const remove = async (sub, id) => { }; export const createToken = async (sub, sourceId) => { - return messengerCreateToken(options.id, sub, sourceId); + return await messengerCreateToken(options.id, sub, sourceId); }; export const verifyToken = async (sub, token, sourceId) => { @@ -108,7 +111,8 @@ export const sanitize = (value) => { // not a valid email if (!domain) return value; - username = username.trimStart().split("+")[0].toLowerCase(); // TODO puntycode? + // punycode/IDNA only applies to domains (RFC 5891), not local part (RFC 6531) + username = username.trimStart().split("+")[0].toLowerCase(); domain = toASCII(domain).trimEnd().toLowerCase(); if (optionalDotDomainsMap[domain]) { diff --git a/packages/messenger-email-address/index.test.js b/packages/messenger-email-address/index.test.js index ba0f821..e40ec6f 100644 --- a/packages/messenger-email-address/index.test.js +++ b/packages/messenger-email-address/index.test.js @@ -4,14 +4,14 @@ import account, { create as accountCreate, remove as accountRemove, } from "../account/index.js"; -// import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; +import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; import * as mockAccountSQLTable from "../account/table/sql.js"; import accountUsername, { create as accountUsernameCreate, exists as accountUsernameExists, } from "../account-username/index.js"; import authn, { getOptions as authnGetOptions } from "../authn/index.js"; -// import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; +import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; import * as mockAuthnSQLTable from "../authn/table/sql.js"; import crypto, { randomChecksumPepper, @@ -22,7 +22,7 @@ import crypto, { import messenger, { getOptions as messengerGetOptions, } from "../messenger/index.js"; -// import * as mockMessengerDynamoDBTable from "../messenger/table/dynamodb.js"; +import * as mockMessengerDynamoDBTable from "../messenger/table/dynamodb.js"; import * as mockMessengerSQLTable from "../messenger/table/sql.js"; import emailAddress, { count as emailAddressCount, @@ -31,17 +31,20 @@ import emailAddress, { exists as emailAddressExists, list as emailAddressList, lookup as emailAddressLookup, + mask as emailAddressMask, remove as emailAddressRemove, + sanitize as emailAddressSanitize, select as emailAddressSelect, + validate as emailAddressValidate, verifyToken as emailAddressVerifyToken, } from "../messenger-email-address/index.js"; // *** Setup Start *** // import * as notify from "../notify/index.js"; import * as mockNotify from "../notify/mock.js"; import * as storeDynamoDB from "../store-dynamodb/index.js"; +import * as mockDynamoDB from "../store-dynamodb/mock.js"; import * as storePostgres from "../store-postgres/index.js"; import * as storeSQLite from "../store-sqlite/index.js"; -// import * as mockDynamoDB from "../store-dynamodb/mock.js"; // import * as mockPostgres from "../store-postgres/mock.js"; import * as mockSQLite from "../store-sqlite/mock.js"; @@ -50,9 +53,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -101,15 +104,21 @@ const mockStores = { storeMessenger: mockMessengerSQLTable, }, }, - // TODO - // dynamodb: { - // store: storeDynamoDB, - // mocks :{ - // ...mockNotify, - // ...mockDynamoDB, - // storeMessenger: mockMessengerDynamoDBTable, - // } - // }, + ...(mockDynamoDB.isReady() + ? { + dynamodb: { + store: storeDynamoDB, + messenger: emailAddress, + mocks: { + ...mockNotify, + ...mockDynamoDB, + storeAccount: mockAccountDynamoDBTable, + storeAuthn: mockAuthnDynamoDBTable, + storeMessenger: mockMessengerDynamoDBTable, + }, + }, + } + : {}), }; account(); @@ -173,6 +182,15 @@ const tests = (config) => { mocks.storeClient.after?.(); }); + it("Can NOT count messengers with ({sub:undefined})", async () => { + try { + await emailAddressCount(undefined); + ok(false); + } catch (e) { + equal(e.message, "401 Unauthorized"); + } + }); + it("Can create a messenger on an account", async () => { const messengerId = await emailAddressCreate(sub, messengerValue); @@ -265,7 +283,7 @@ const tests = (config) => { // notify additional messenger const notifyCall2 = mocks.notifyClient.mock.calls[2].arguments[0]; deepEqual(notifyCall2, { - data: undefined, + data: {}, id: `messenger-${messengerType}-create`, options: { messengers: [ @@ -396,7 +414,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[1].arguments[0], { id: `messenger-${messengerType}-remove-self`, sub, - data: undefined, + data: {}, options: { messengers: [ { @@ -409,7 +427,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[2].arguments[0], { id: `messenger-${messengerType}-remove`, sub, - data: undefined, + data: {}, options: {}, }); @@ -529,7 +547,59 @@ const tests = (config) => { equal(messenger?.[0]?.value, messengerValue); // unencrypted }); - // TODO sanitize, validate testings + // sanitize + it("Can sanitize: lowercase", () => { + equal(emailAddressSanitize("User@Example.COM"), "user@example.com"); + }); + it("Can sanitize: trim leading whitespace", () => { + equal(emailAddressSanitize(" user@example.com"), "user@example.com"); + }); + it("Can sanitize: strip plus addressing", () => { + equal(emailAddressSanitize("user+tag@example.com"), "user@example.com"); + }); + it("Can sanitize: optional dots for gmail", () => { + equal(emailAddressSanitize("user.name@gmail.com"), "username@gmail.com"); + }); + it("Can sanitize: alias domains", () => { + equal(emailAddressSanitize("user@proton.me"), "user@protonmail.com"); + }); + it("Can sanitize: IDN domain to ASCII", () => { + equal(emailAddressSanitize("user@münchen.de"), "user@xn--mnchen-3ya.de"); + }); + it("Can NOT sanitize: null", () => { + try { + emailAddressSanitize(null); + } catch (e) { + equal(e.message, "400 Bad Request"); + } + }); + it("Can NOT sanitize: non-string", () => { + try { + emailAddressSanitize(123); + } catch (e) { + equal(e.message, "400 Bad Request"); + } + }); + it("Can sanitize: no domain returns as-is", () => { + equal(emailAddressSanitize("nodomain"), "nodomain"); + }); + + // validate + it("Can validate: valid email", () => { + equal(emailAddressValidate("user@example.com"), true); + }); + it("Can NOT validate: invalid format", () => { + equal(emailAddressValidate("user[at]example.com"), "400 Bad Request"); + }); + it("Can NOT validate: blacklisted username", () => { + equal(emailAddressValidate("admin@example.com"), "409 Conflict"); + }); + + // mask + it("Can mask email", () => { + equal(emailAddressMask("username@example.com"), "u...e@example.com"); + }); + it("Can create a messenger on an account w/ optionalDotDomains", async () => { await emailAddressCreate(sub, "user.name@gmail.com"); const exists = emailAddressExists("username@gmail.com"); @@ -578,7 +648,7 @@ const tests = (config) => { } }); }; -describe("messenger-email-address", () => { +describe("messenger-email-address", { concurrency: 1 }, () => { for (const storeKey of Object.keys(mockStores)) { describe(`using store-${storeKey}`, () => { tests(mockStores[storeKey]); diff --git a/packages/messenger-email-address/package.json b/packages/messenger-email-address/package.json index a57e140..1d47973 100644 --- a/packages/messenger-email-address/package.json +++ b/packages/messenger-email-address/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/messenger-email-address", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Email address messenger for email verification and notifications", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "email", + "verification", + "messenger" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,9 +53,9 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1", - "@1auth/messenger": "0.0.0-beta.1", + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2", + "@1auth/messenger": "0.0.0-beta.2", "tr46": "6.0.0" } } diff --git a/packages/messenger/README.md b/packages/messenger/README.md new file mode 100644 index 0000000..cfe842c --- /dev/null +++ b/packages/messenger/README.md @@ -0,0 +1,44 @@ +
+

@1auth/messenger

+ +

Messaging framework for sending notifications and verification codes

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/messenger +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/messenger/index.js b/packages/messenger/index.js index 7ca4848..28680e5 100644 --- a/packages/messenger/index.js +++ b/packages/messenger/index.js @@ -9,6 +9,7 @@ import { createSeasonedDigest, createSecretHash, makeRandomConfigObject, + nowInSeconds, randomNumeric, symmetricDecryptFields, symmetricEncryptFields, @@ -66,13 +67,16 @@ export const getOptions = () => options; export const exists = async (type, value) => { const valueDigest = createSeasonedDigest(value); - return options.store.exists(options.table, { + return await options.store.exists(options.table, { type, digest: valueDigest, }); }; export const count = async (type, sub) => { + if (!sub || typeof sub !== "string") { + throw new Error("401 Unauthorized", { cause: { sub } }); + } const messengers = await options.store.selectList( options.table, { sub, type }, @@ -199,7 +203,7 @@ export const create = async (type, sub, values) => { update: now, // in case new digests need to be created }; if (options.idGenerate) { - params.id = options.randomId.create(options.idPrefix); + params.id = await options.randomId.create(); } const id = await options.store.insert(options.table, params); @@ -255,7 +259,7 @@ export const verifyToken = async (type, sub, token, sourceId) => { } return messengers; }); - await authnVerify(options.token, sub, token); + await authnVerify({ ...options.token, sourceId }, sub, token); await options.store.update( options.table, { sub, id: sourceId }, @@ -282,9 +286,8 @@ export const remove = async (type, sub, id) => { ); if (!messenger) { - throw new Error("401 Unauthorized"); + throw new Error("401 Unauthorized", { cause: { sub, id } }); } - // await authnRemove(options.token, sub, id); await authnGetOptions().store.remove(authnGetOptions().table, { sub, sourceId: id, @@ -314,5 +317,3 @@ export const remove = async (type, sub, id) => { options.notify.trigger(`messenger-${type}-remove`, sub), ]); }; - -const nowInSeconds = () => Math.floor(Date.now() / 1000); diff --git a/packages/messenger/index.test.js b/packages/messenger/index.test.js index 9f951c2..c0e4735 100644 --- a/packages/messenger/index.test.js +++ b/packages/messenger/index.test.js @@ -4,14 +4,14 @@ import account, { create as accountCreate, remove as accountRemove, } from "../account/index.js"; -// import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; +import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; import * as mockAccountSQLTable from "../account/table/sql.js"; import accountUsername, { create as accountUsernameCreate, exists as accountUsernameExists, } from "../account-username/index.js"; import authn, { getOptions as authnGetOptions } from "../authn/index.js"; -// import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; +import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; import * as mockAuthnSQLTable from "../authn/table/sql.js"; import crypto, { createSeasonedDigest, @@ -36,12 +36,12 @@ import messenger, { import * as notify from "../notify/index.js"; import * as mockNotify from "../notify/mock.js"; import * as storeDynamoDB from "../store-dynamodb/index.js"; +import * as mockDynamoDB from "../store-dynamodb/mock.js"; import * as storePostgres from "../store-postgres/index.js"; import * as storeSQLite from "../store-sqlite/index.js"; -// import * as mockDynamoDB from "../store-dynamodb/mock.js"; // import * as mockPostgres from "../store-postgres/mock.js"; import * as mockSQLite from "../store-sqlite/mock.js"; -// import * as mockMessengerDynamoDBTable from "./table/dynamodb.js"; +import * as mockMessengerDynamoDBTable from "./table/dynamodb.js"; import * as mockMessengerSQLTable from "./table/sql.js"; crypto({ @@ -49,9 +49,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -99,17 +99,20 @@ const mockStores = { storeMessenger: mockMessengerSQLTable, }, }, - // TODO - // dynamodb: { - // store: storeDynamoDB, - // mocks :{ - // ...mockNotify, - // ...mockDynamoDB, - // storeAccount: mockAccountDynamoDBTable, - // storeAuthn: mockAuthnDynamoDBTable, - // storeMessenger: mockMessengerDynamoDBTable, - // } - // }, + ...(mockDynamoDB.isReady() + ? { + dynamodb: { + store: storeDynamoDB, + mocks: { + ...mockNotify, + ...mockDynamoDB, + storeAccount: mockAccountDynamoDBTable, + storeAuthn: mockAuthnDynamoDBTable, + storeMessenger: mockMessengerDynamoDBTable, + }, + }, + } + : {}), }; account(); @@ -173,6 +176,15 @@ const tests = (config) => { mocks.storeClient.after?.(); }); + it("Can NOT count messengers with ({sub:undefined})", async () => { + try { + await messengerCount(messengerType, undefined); + ok(false); + } catch (e) { + equal(e.message, "401 Unauthorized"); + } + }); + it("Can create a messenger on an account", async () => { const messengerId = await messengerCreate(messengerType, sub, { value: messengerValue, @@ -289,7 +301,7 @@ const tests = (config) => { // notify additional messenger const notifyCall2 = mocks.notifyClient.mock.calls[2].arguments[0]; deepEqual(notifyCall2, { - data: undefined, + data: {}, id: `messenger-${messengerType}-create`, options: { messengers: [ @@ -368,7 +380,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[1].arguments[0], { id: `messenger-${messengerType}-remove-self`, sub, - data: undefined, + data: {}, options: { messengers: [ { @@ -381,7 +393,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[2].arguments[0], { id: `messenger-${messengerType}-remove`, sub, - data: undefined, + data: {}, options: {}, }); @@ -489,7 +501,7 @@ const tests = (config) => { equal(messengers?.[0]?.value, messengerValue); // unencrypted }); }; -describe("messenger", () => { +describe("messenger", { concurrency: 1 }, () => { for (const storeKey of Object.keys(mockStores)) { describe(`using store-${storeKey}`, () => { tests(mockStores[storeKey]); diff --git a/packages/messenger/package.json b/packages/messenger/package.json index 338e52b..a913e00 100644 --- a/packages/messenger/package.json +++ b/packages/messenger/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/messenger", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Messaging framework for sending notifications and verification codes", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,18 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" } }, - "types": "index.d.ts", "files": [ "index.js", - "index.d.ts" + "table" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +34,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "messenger", + "notification", + "verification" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,7 +57,7 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" } } diff --git a/packages/messenger/table/dynamodb.js b/packages/messenger/table/dynamodb.js index bf00676..e3a4d95 100644 --- a/packages/messenger/table/dynamodb.js +++ b/packages/messenger/table/dynamodb.js @@ -30,6 +30,10 @@ export const create = async (client, table = name) => { AttributeName: "digest", AttributeType: "S", }, + { + AttributeName: "expire", + AttributeType: "N", + }, ], KeySchema: [ { @@ -49,6 +53,10 @@ export const create = async (client, table = name) => { AttributeName: "sub", KeyType: "HASH", }, + { + AttributeName: "type", + KeyType: "RANGE", + }, ], Projection: { ProjectionType: "INCLUDE", @@ -56,8 +64,10 @@ export const create = async (client, table = name) => { "id", "encryptionKey", "value", + "digest", "name", "create", + "update", "verify", "expire", "lastused", @@ -71,6 +81,10 @@ export const create = async (client, table = name) => { AttributeName: "digest", KeyType: "HASH", }, + { + AttributeName: "type", + KeyType: "RANGE", + }, ], Projection: { ProjectionType: "INCLUDE", @@ -81,6 +95,7 @@ export const create = async (client, table = name) => { "value", "name", "create", + "update", "verify", "expire", "lastused", diff --git a/packages/notify-sqs/README.md b/packages/notify-sqs/README.md new file mode 100644 index 0000000..a00d688 --- /dev/null +++ b/packages/notify-sqs/README.md @@ -0,0 +1,44 @@ +
+

@1auth/notify-sqs

+ +

AWS SQS notification implementation for scalable message queuing

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/notify-sqs +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/notify-sqs/index.js b/packages/notify-sqs/index.js index 0a86ffb..f437e9b 100644 --- a/packages/notify-sqs/index.js +++ b/packages/notify-sqs/index.js @@ -13,8 +13,8 @@ const options = { log: false, }; -export default (params) => { - Object.assign(options, params); +export default (opt = {}) => { + Object.assign(options, opt); // requires need for AWS access // options.queueUrl ??= options.client // .send(new GetQueueUrlCommand({ QueueName: options.queueName })) diff --git a/packages/notify-sqs/package.json b/packages/notify-sqs/package.json index 1cd6702..4ffa287 100644 --- a/packages/notify-sqs/package.json +++ b/packages/notify-sqs/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/notify-sqs", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "AWS SQS notification implementation for scalable message queuing", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "notification", + "SQS", + "AWS" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" diff --git a/packages/notify/README.md b/packages/notify/README.md new file mode 100644 index 0000000..0bcbc2b --- /dev/null +++ b/packages/notify/README.md @@ -0,0 +1,44 @@ +
+

@1auth/notify

+ +

Base notification interface for sending messages through various channels

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/notify +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/notify/index.js b/packages/notify/index.js index 264d7b8..fd6b27f 100644 --- a/packages/notify/index.js +++ b/packages/notify/index.js @@ -5,8 +5,8 @@ const options = { client: () => {}, }; -export default (params) => { - Object.assign(options, params); +export default (opt = {}) => { + Object.assign(options, opt); }; /* @@ -17,6 +17,6 @@ notifyOptions: object of how and who to send message to - messengers: array of { id } or { type, value } - types: array of allowed types to be used */ -export const trigger = (id, sub, data, notifyOptions = {}) => { - options.client({ id, sub, data, options: notifyOptions }); +export const trigger = async (id, sub, data = {}, notifyOptions = {}) => { + await options.client({ id, sub, data, options: notifyOptions }); }; diff --git a/packages/notify/package.json b/packages/notify/package.json index 936024b..6cb6a59 100644 --- a/packages/notify/package.json +++ b/packages/notify/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/notify", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Base notification interface for sending messages through various channels", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,14 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" } }, - "types": "index.d.ts", "files": [ - "index.js", - "index.d.ts" + "index.js" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +30,13 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "notification", + "events" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" diff --git a/packages/session/README.md b/packages/session/README.md new file mode 100644 index 0000000..fdb3c5b --- /dev/null +++ b/packages/session/README.md @@ -0,0 +1,44 @@ +
+

@1auth/session

+ +

Secure session management with expiration and encryption support

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/session +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/session/index.fuzz.js b/packages/session/index.fuzz.js index ab28b85..e53c8b8 100644 --- a/packages/session/index.fuzz.js +++ b/packages/session/index.fuzz.js @@ -35,9 +35,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -229,23 +229,25 @@ test("fuzz sessionCreate w/ value", async () => { }, ); }); -// TODO throws due tp missing columns .. -// test("fuzz sessionCreate w/ values", async () => { -// await fc.assert( -// fc.asyncProperty(fc.anything(), async (values) => { -// try { -// await sessionCreate(sub, testSession.value, values); -// } catch (e) { -// catchError(values, e); -// } -// }), -// { -// numRuns: 100_000, -// verbose: 2, -// examples: [], -// }, -// ); -// }); +test("fuzz sessionCreate w/ values", async () => { + await fc.assert( + fc.asyncProperty( + fc.record({ metadata: fc.anything() }, { withDeletedKeys: true }), + async (values) => { + try { + await sessionCreate(sub, testSession.value, values); + } catch (e) { + catchError(values, e); + } + }, + ), + { + numRuns: 100_000, + verbose: 2, + examples: [], + }, + ); +}); test("fuzz sessionCheck w/ sub", async () => { await fc.assert( diff --git a/packages/session/index.js b/packages/session/index.js index 2a0476b..89f559b 100644 --- a/packages/session/index.js +++ b/packages/session/index.js @@ -3,6 +3,7 @@ import { createSeasonedDigest, makeRandomConfigObject, + nowInSeconds, safeEqual, symmetricDecrypt, symmetricDecryptFields, @@ -63,7 +64,7 @@ export const lookup = async (sid, value = {}) => { const session = await options.store.select(options.table, { digest }); if (session) { const now = nowInSeconds(); - if (session.expire < now) { + if (session.expire && session.expire < now) { return; } const encodedValue = options.encode(value); @@ -184,7 +185,7 @@ export const check = async (sub, value = {}) => { return; } } - options.notify.trigger("authn-session-new-device", sub); + await options.notify.trigger("authn-session-new-device", sub); }; export const expire = async (sub, id) => { @@ -219,10 +220,3 @@ export const sign = (sid) => { export const verify = (sidWithSignature) => { return symmetricSignatureVerify(sidWithSignature); }; - -// guest or onboard session to authenticated -// export const rotate = async (sub, meta) => { -// await remove() -// return create() -// } -const nowInSeconds = () => Math.floor(Date.now() / 1000); diff --git a/packages/session/index.test.js b/packages/session/index.test.js index 53fb758..a550918 100644 --- a/packages/session/index.test.js +++ b/packages/session/index.test.js @@ -4,12 +4,12 @@ import account, { create as accountCreate, remove as accountRemove, } from "../account/index.js"; -// import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; +import * as mockAccountDynamoDBTable from "../account/table/dynamodb.js"; import * as mockAccountSQLTable from "../account/table/sql.js"; import accountUsername, { create as accountUsernameCreate, } from "../account-username/index.js"; -// import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; +import * as mockAuthnDynamoDBTable from "../authn/table/dynamodb.js"; import * as mockAuthnSQLTable from "../authn/table/sql.js"; import crypto, { randomChecksumPepper, @@ -32,12 +32,12 @@ import session, { verify as sessionVerify, } from "../session/index.js"; import * as storeDynamoDB from "../store-dynamodb/index.js"; +import * as mockDynamoDB from "../store-dynamodb/mock.js"; import * as storePostgres from "../store-postgres/index.js"; import * as storeSQLite from "../store-sqlite/index.js"; -// import * as mockDynamoDB from "../store-dynamodb/mock.js"; // import * as mockPostgres from "../store-postgres/mock.js"; import * as mockSQLite from "../store-sqlite/mock.js"; -// import * as mockSessionDynamoDBTable from "./table/dynamodb.js"; +import * as mockSessionDynamoDBTable from "./table/dynamodb.js"; import * as mockSessionSQLTable from "./table/sql.js"; crypto({ @@ -45,9 +45,9 @@ crypto({ symmetricSignatureSecret: symmetricRandomSignatureSecret(), digestChecksumSalt: randomChecksumSalt(), digestChecksumPepper: randomChecksumPepper(), - secretTimeCost: 1, - secretMemoryCost: 2 ** 3, - secretParallelism: 1, + secretArgon2TimeCost: 1, + secretArgon2MemoryCost: 2 ** 3, + secretArgon2Parallelism: 1, }); notify.default({ client: (...args) => mocks.notifyClient(...args), @@ -95,17 +95,20 @@ const mockStores = { storeSession: mockSessionSQLTable, }, }, - // TODO - // dynamodb: { - // store: storeDynamoDB, - // mocks :{ - // ...mockNotify, - // ...mockDynamoDB, - // storeAccount: mockAccountDynamoDBTable, - // storeAuthn: mockAuthnDynamoDBTable, - // storeSession: mockSessionDynamoDBTable, // is working - // } - // }, + ...(mockDynamoDB.isReady() + ? { + dynamodb: { + store: storeDynamoDB, + mocks: { + ...mockNotify, + ...mockDynamoDB, + storeAccount: mockAccountDynamoDBTable, + storeAuthn: mockAuthnDynamoDBTable, + storeSession: mockSessionDynamoDBTable, + }, + }, + } + : {}), }; account(); @@ -352,7 +355,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[0].arguments[0], { id: "authn-session-new-device", sub, - data: undefined, + data: {}, options: {}, }); }); @@ -379,7 +382,7 @@ const tests = (config) => { deepEqual(mocks.notifyClient.mock.calls[0].arguments[0], { id: "authn-session-new-device", sub, - data: undefined, + data: {}, options: {}, }); }); @@ -476,7 +479,7 @@ const tests = (config) => { ok(verify); }); }; -describe("session", () => { +describe("session", { concurrency: 1 }, () => { for (const storeKey of Object.keys(mockStores)) { describe(`using store-${storeKey}`, () => { tests(mockStores[storeKey]); diff --git a/packages/session/package.json b/packages/session/package.json index 3f58384..86800ab 100644 --- a/packages/session/package.json +++ b/packages/session/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/session", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "Secure session management with expiration and encryption support", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,18 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" } }, - "types": "index.d.ts", "files": [ "index.js", - "index.d.ts" + "table" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +34,13 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "session", + "session-management" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -50,7 +56,7 @@ "homepage": "https://github.com/willfarrell/1auth", "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": { - "@1auth/authn": "0.0.0-beta.1", - "@1auth/crypto": "0.0.0-beta.1" + "@1auth/authn": "0.0.0-beta.2", + "@1auth/crypto": "0.0.0-beta.2" } } diff --git a/packages/store-d1/README.md b/packages/store-d1/README.md new file mode 100644 index 0000000..04a21cb --- /dev/null +++ b/packages/store-d1/README.md @@ -0,0 +1,44 @@ +
+

@1auth/store-d1

+ +

Cloudflare D1 storage implementation for serverless SQLite persistence

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/store-d1 +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/store-d1/index.js b/packages/store-d1/index.js new file mode 100644 index 0000000..31afae7 --- /dev/null +++ b/packages/store-d1/index.js @@ -0,0 +1,262 @@ +// Copyright 2003 - 2026 will Farrell, and 1Auth contributors. +// SPDX-License-Identifier: MIT +const options = { + id: "d1", + log: false, + client: undefined, // D1 database binding (e.g. env.DB) + // number of seconds after expire before removal + // 10d chosen based on EFF DNT Policy + timeToLiveExpireOffset: 10 * 24 * 60 * 60, + timeToLiveKey: "remove", + placeholder: "?", +}; + +export default (opt = {}) => { + Object.assign(options, opt); +}; + +export const exists = async (table, filters) => { + if (options.log) { + options.log(`@1auth/store-${options.id} exists(`, table, filters, ")"); + } + const { select, where, parameters } = makeSqlParts(filters, {}, ["sub"]); + const sql = `SELECT ${select} FROM ${table} ${where} LIMIT 1`; + const res = await options.client + .prepare(sql) + .bind(...parameters) + .first(); + return res?.sub; +}; + +export const count = async (table, filters = {}) => { + if (options.log) { + options.log(`@1auth/store-${options.id} count(`, table, filters, ")"); + } + const { where, parameters } = makeSqlParts(filters, {}); + const sql = `SELECT COUNT(*) AS count FROM ${table} ${where}`; + const res = await options.client + .prepare(sql) + .bind(...parameters) + .first(); + return res.count; +}; + +export const select = async (table, filters = {}, fields = []) => { + if (options.log) { + options.log( + `@1auth/store-${options.id} select(`, + table, + filters, + fields, + ")", + ); + } + const { select, where, parameters } = makeSqlParts(filters, {}, fields); + const sql = `SELECT ${select} FROM ${table} ${where} LIMIT 1`; + const row = await options.client + .prepare(sql) + .bind(...parameters) + .first(); + if (!row) return undefined; + parseValues(row); + return row; +}; + +export const selectList = async (table, filters = {}, fields = []) => { + if (options.log) { + options.log( + `@1auth/store-${options.id} selectList(`, + table, + filters, + fields, + ")", + ); + } + const { select, where, parameters } = makeSqlParts(filters, {}, fields); + const sql = `SELECT ${select} FROM ${table} ${where}`; + const res = await options.client + .prepare(sql) + .bind(...parameters) + .all(); + return res.results.map((row) => { + parseValues(row); + return row; + }); +}; + +export const insert = async (table, inputValues = {}) => { + const values = structuredClone(inputValues); + if (options.log) { + options.log(`@1auth/store-${options.id} insert(`, table, values, ")"); + } + if (values.expire && options.timeToLiveKey) { + values[options.timeToLiveKey] = + values.expire + options.timeToLiveExpireOffset; + } + normalizeValues(values); + const { insert, parameters } = makeSqlParts({}, values); + const sql = `INSERT INTO ${table} ${insert}`; + const res = await options.client + .prepare(sql) + .bind(...parameters) + .run(); + return values.id ?? res.meta.last_row_id; +}; + +export const insertList = async (table, rows = []) => { + if (options.log) { + options.log(`@1auth/store-${options.id} insertList(`, table, rows, ")"); + } + const stmts = []; + for (let i = 0, l = rows.length; i < l; i++) { + const values = structuredClone(rows[i]); + if (values.expire && options.timeToLiveKey) { + values[options.timeToLiveKey] = + values.expire + options.timeToLiveExpireOffset; + } + normalizeValues(values); + const { insert, parameters } = makeSqlParts({}, values); + const sql = `INSERT INTO ${table} ${insert}`; + stmts.push(options.client.prepare(sql).bind(...parameters)); + } + return await options.client.batch(stmts); +}; + +export const update = async (table, filters = {}, inputValues = {}) => { + const values = structuredClone(inputValues); + if (options.log) { + options.log( + `@1auth/store-${options.id} update(`, + table, + filters, + values, + ")", + ); + } + if (values.expire && options.timeToLiveKey) { + values[options.timeToLiveKey] = + values.expire + options.timeToLiveExpireOffset; + } + normalizeValues(values); + const { update, where, parameters } = makeSqlParts(filters, values); + const sql = `UPDATE ${table} SET ${update} ${where}`; + await options.client + .prepare(sql) + .bind(...parameters) + .run(); +}; + +export const updateList = async (table, filtersList = [], values = {}) => { + if (options.log) { + options.log( + `@1auth/store-${options.id} updateList(`, + table, + filtersList, + values, + ")", + ); + } + return await Promise.allSettled( + filtersList.map((filters) => update(table, filters, values)), + ); +}; + +export const remove = async (table, filters = {}) => { + if (options.log) { + options.log(`@1auth/store-${options.id} remove(`, table, filters, ")"); + } + const { where, parameters } = makeSqlParts(filters); + const sql = `DELETE FROM ${table} ${where}`; + await options.client + .prepare(sql) + .bind(...parameters) + .run(); +}; + +export const removeList = remove; + +const normalizeValues = (values) => { + if (!values) return; + if (Object.hasOwn(values, "otp")) { + values.otp = values.otp ? 1 : 0; + } + values.create &&= new Date(values.create * 1000).toISOString(); + values.update &&= new Date(values.update * 1000).toISOString(); + values.verify &&= new Date(values.verify * 1000).toISOString(); + values.lastused &&= new Date(values.lastused * 1000).toISOString(); + values.expire &&= new Date(values.expire * 1000).toISOString(); + values.remove &&= new Date(values.remove * 1000).toISOString(); + for (const [key, v] of Object.entries(values)) { + if (v !== null && typeof v !== "string" && typeof v !== "number") { + values[key] = + v === undefined + ? null + : typeof v === "object" + ? JSON.stringify(v) + : String(v); + } + } +}; + +const parseValues = (values) => { + if (!values) return; + if (typeof values.otp === "number") { + values.otp = !!values.otp; + } + values.create &&= Date.parse(values.create) / 1000; + values.update &&= Date.parse(values.update) / 1000; + values.verify &&= Date.parse(values.verify) / 1000; + values.lastused &&= Date.parse(values.lastused) / 1000; + values.expire &&= Date.parse(values.expire) / 1000; + values.remove &&= Date.parse(values.remove) / 1000; +}; + +// export for testing +export const getPlaceholder = (idx) => { + return options.placeholder === "$" ? `$${idx}` : options.placeholder; +}; +export const makeSqlParts = ( + filters = {}, + values = {}, + fields = [], + idxStart = 1, +) => { + let idx = idxStart; + let parameters = []; + const keys = Object.keys(values); + + const select = fields.length ? `"${fields.join('", "')}"` : "*"; + + const insertParts = []; + const updateParts = []; + for (const key of keys) { + insertParts.push(getPlaceholder(idx)); + updateParts.push(`"${key}" = ${getPlaceholder(idx)}`); + idx++; + } + const insert = `("${keys.join('", "')}") VALUES (${insertParts.join(",")})`; + const update = updateParts.join(", "); + parameters = parameters.concat(Object.values(values)); + + let where = Object.keys(filters) + .map((key) => { + const value = filters[key]; + if (typeof value === "undefined") { + return null; + } + if (Array.isArray(value)) { + let sql = value.map(() => getPlaceholder(idx++)).join(","); + sql &&= `"${key}" IN (${sql})`; + parameters = parameters.concat(value); + return sql; + } + const sql = `"${key}" = ${getPlaceholder(idx++)}`; + parameters.push(value); + return sql; + }) + .filter((v) => v) + .join(" AND "); + where &&= `WHERE ${where}`; + + return { select, insert, update, where, parameters }; +}; diff --git a/packages/store-d1/index.test.js b/packages/store-d1/index.test.js new file mode 100644 index 0000000..fe1ebce --- /dev/null +++ b/packages/store-d1/index.test.js @@ -0,0 +1,634 @@ +import { + deepEqual, + deepStrictEqual, + equal, + ok, + strictEqual, +} from "node:assert/strict"; +import { describe, it, test } from "node:test"; +import tests from "../store/index.test.js"; +import * as store from "./index.js"; +import * as mockDatabase from "./mock.js"; +import * as mockDatabaseTable from "./table/d1.js"; + +store.default({ + log: (...args) => mocks.log(...args), + client: mockDatabase.storeClient, +}); + +const mocks = { + ...mockDatabase, + table: mockDatabaseTable, +}; + +const table = mockDatabaseTable.name; +const nowInSeconds = () => Math.floor(Date.now() / 1000); + +// Extended table with otp and all date fields for normalizeValues/parseValues coverage +const extTable = "test_ext"; +const createExtTable = async () => { + await mockDatabase.storeClient + .prepare( + `CREATE TABLE IF NOT EXISTS ${extTable} ( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "sub" VARCHAR(15) NOT NULL, + "value" VARCHAR(256) NOT NULL, + "otp" INTEGER DEFAULT NULL, + "create" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "update" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "verify" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "lastused" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "expire" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "remove" TIMESTAMP WITH TIME ZONE DEFAULT NULL + )`, + ) + .run(); +}; +const truncateExtTable = async () => { + await mockDatabase.storeClient.prepare(`DELETE FROM ${extTable}`).run(); +}; +const dropExtTable = async () => { + await mockDatabase.storeClient + .prepare(`DROP TABLE IF EXISTS ${extTable}`) + .run(); +}; + +describe("store-d1", () => { + tests(store, mocks); + describe("default", () => { + it("Should merge options", async () => { + store.default({ placeholder: "?" }); + const { insert } = store.makeSqlParts({}, { a: "a" }); + equal(insert, '("a") VALUES (?)'); + }); + }); + describe("getPlaceholder", () => { + it("Should return ? for default placeholder", async () => { + store.default({ placeholder: "?" }); + equal(store.getPlaceholder(1), "?"); + equal(store.getPlaceholder(5), "?"); + }); + it("Should return $N for $ placeholder", async () => { + store.default({ placeholder: "$" }); + equal(store.getPlaceholder(1), "$1"); + equal(store.getPlaceholder(3), "$3"); + store.default({ placeholder: "?" }); + }); + }); + describe("makeSqlParts", () => { + it("Should format {select} with fields", async () => { + const { select, parameters } = store.makeSqlParts({}, {}, ["a", "b"]); + equal(select, '"a", "b"'); + deepEqual(parameters, []); + }); + + it("Should format {select} to * when no fields", async () => { + const { select, parameters } = store.makeSqlParts({}, {}, []); + equal(select, "*"); + deepEqual(parameters, []); + }); + + it("Should format {insert} with ? placeholder", async () => { + store.default({ placeholder: "?" }); + const { insert, parameters } = store.makeSqlParts({}, { a: "a", b: "b" }); + equal(insert, '("a", "b") VALUES (?,?)'); + deepEqual(parameters, ["a", "b"]); + }); + + it("Should format {update} with ? placeholder", async () => { + store.default({ placeholder: "?" }); + const { update, parameters } = store.makeSqlParts({}, { a: "a", b: "b" }); + equal(update, '"a" = ?, "b" = ?'); + deepEqual(parameters, ["a", "b"]); + }); + + it("Should format {where} with ? placeholder", async () => { + store.default({ placeholder: "?" }); + const { where, parameters } = store.makeSqlParts({ + a: "a", + bc: ["b", "c"], + d: "d", + }); + equal(where, 'WHERE "a" = ? AND "bc" IN (?,?) AND "d" = ?'); + deepEqual(parameters, ["a", "b", "c", "d"]); + }); + + it("Should skip undefined filter values in {where}", async () => { + const { where, parameters } = store.makeSqlParts({ + a: "a", + b: undefined, + c: "c", + }); + equal(where, 'WHERE "a" = ? AND "c" = ?'); + deepEqual(parameters, ["a", "c"]); + }); + + it("Should return empty {where} when no filters", async () => { + const { where, parameters } = store.makeSqlParts({}); + equal(where, ""); + deepEqual(parameters, []); + }); + + it("Should respect idxStart parameter", async () => { + store.default({ placeholder: "$" }); + const { insert } = store.makeSqlParts({}, { a: "a", b: "b" }, [], 5); + equal(insert, '("a", "b") VALUES ($5,$6)'); + store.default({ placeholder: "?" }); + }); + + it("Should combine values and filters parameters", async () => { + const { update, where, parameters } = store.makeSqlParts( + { id: 1 }, + { value: "x" }, + ); + equal(update, '"value" = ?'); + equal(where, 'WHERE "id" = ?'); + deepEqual(parameters, ["x", 1]); + }); + + it("Should handle empty array filter", async () => { + const { where, parameters } = store.makeSqlParts({ id: [] }); + equal(where, ""); + deepEqual(parameters, []); + }); + + it("Should format {select} with single field", async () => { + const { select } = store.makeSqlParts({}, {}, ["id"]); + equal(select, '"id"'); + }); + }); + describe("normalizeValues/parseValues round-trip", () => { + test.before(async () => { + await createExtTable(); + }); + test.afterEach(async () => { + await truncateExtTable(); + }); + test.after(async () => { + await dropExtTable(); + }); + it("Should round-trip otp true as boolean", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_otp", + value: "v", + otp: true, + create: ts, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.otp, true); + }); + it("Should round-trip otp false as boolean", async () => { + await store.insert(extTable, { + id: 1, + sub: "sub_otp", + value: "v", + otp: false, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.otp, false); + }); + it("Should round-trip otp via update", async () => { + await store.insert(extTable, { + id: 1, + sub: "sub_otp", + value: "v", + otp: false, + }); + await store.update(extTable, { id: 1 }, { otp: true }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.otp, true); + }); + it("Should round-trip create timestamp", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_ts", + value: "v", + create: ts, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.create, ts); + }); + it("Should round-trip update timestamp", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_ts", + value: "v", + update: ts, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.update, ts); + }); + it("Should round-trip verify timestamp", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_ts", + value: "v", + verify: ts, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.verify, ts); + }); + it("Should round-trip lastused timestamp", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_ts", + value: "v", + lastused: ts, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.lastused, ts); + }); + it("Should round-trip expire timestamp", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_ts", + value: "v", + expire: ts, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.expire, ts); + }); + it("Should round-trip remove timestamp", async () => { + const ts = nowInSeconds(); + store.default({ timeToLiveKey: "" }); + await store.insert(extTable, { + id: 1, + sub: "sub_ts", + value: "v", + remove: ts, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.remove, ts); + store.default({ timeToLiveKey: "remove" }); + }); + it("Should round-trip all 6 date fields simultaneously", async () => { + const ts = nowInSeconds(); + store.default({ timeToLiveKey: "" }); + await store.insert(extTable, { + id: 1, + sub: "sub_all", + value: "v", + create: ts, + update: ts + 1, + verify: ts + 2, + lastused: ts + 3, + expire: ts + 4, + remove: ts + 5, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.create, ts); + strictEqual(result.update, ts + 1); + strictEqual(result.verify, ts + 2); + strictEqual(result.lastused, ts + 3); + strictEqual(result.expire, ts + 4); + strictEqual(result.remove, ts + 5); + store.default({ timeToLiveKey: "remove" }); + }); + it("Should preserve null date fields", async () => { + await store.insert(extTable, { + id: 1, + sub: "sub_null", + value: "v", + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.create, null); + strictEqual(result.update, null); + strictEqual(result.verify, null); + strictEqual(result.lastused, null); + strictEqual(result.expire, null); + strictEqual(result.remove, null); + }); + it("Should parse date fields in selectList", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_list", + value: "v", + create: ts, + verify: ts, + }); + await store.insert(extTable, { + id: 2, + sub: "sub_list", + value: "w", + create: ts, + lastused: ts, + }); + const results = await store.selectList(extTable, { sub: "sub_list" }); + strictEqual(results.length, 2); + strictEqual(results[0].create, ts); + strictEqual(results[0].verify, ts); + strictEqual(results[1].create, ts); + strictEqual(results[1].lastused, ts); + }); + it("Should normalize actual boolean to string via String()", async () => { + // A non-otp boolean value goes through the String(v) branch + // in normalizeValues: not null, not string, not number, + // not undefined, not object → String(true) = "true" + await store.insert(extTable, { + id: 1, + sub: "sub_bool", + value: true, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.value, "true"); + }); + it("Should normalize actual object to JSON via JSON.stringify()", async () => { + // An object value goes through JSON.stringify branch in normalizeValues + const obj = { key: "val", nested: [1, 2] }; + await store.insert(extTable, { + id: 1, + sub: "sub_obj", + value: obj, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.value, JSON.stringify(obj)); + }); + it("Should normalize otp undefined to false (via 0)", async () => { + // otp: undefined → hasOwn is true → undefined ? 1 : 0 → 0 + // parseValues: typeof 0 === "number" → !!0 → false + await store.insert(extTable, { + id: 1, + sub: "sub_undef", + value: "v", + otp: undefined, + }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.otp, false); + }); + it("Should normalize undefined non-date value to null", async () => { + // digest: undefined → not otp, not date → for loop: + // v !== null, not string, not number → v === undefined → null + await store.insert(table, { + id: 1, + sub: "sub_undef_v", + value: "v", + digest: undefined, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.digest, null); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should update date fields via update path", async () => { + const ts = nowInSeconds(); + await store.insert(extTable, { + id: 1, + sub: "sub_upd", + value: "v", + }); + await store.update(extTable, { id: 1 }, { verify: ts, lastused: ts }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.verify, ts); + strictEqual(result.lastused, ts); + }); + it("Should handle expire with TTL on update path", async () => { + const expire = nowInSeconds() + 86400; + await store.insert(extTable, { + id: 1, + sub: "sub_ttl", + value: "v", + }); + await store.update(extTable, { id: 1 }, { expire }); + const result = await store.select(extTable, { id: 1 }); + strictEqual(result.expire, expire); + ok(result.remove > expire); + }); + }); + describe("normalizeValues (via insert)", () => { + it("Should serialize object values to JSON", async () => { + const obj = { nested: true }; + const row = { id: 1, sub: "sub_json", value: JSON.stringify(obj) }; + await store.insert(table, row); + const result = await store.select(table, { id: 1 }); + equal(result.value, JSON.stringify(obj)); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should store null values", async () => { + const row = { id: 1, sub: "sub_null", value: "v", digest: null }; + await store.insert(table, row); + const result = await store.select(table, { id: 1 }); + strictEqual(result.digest, null); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + }); + describe("D1-specific behavior", () => { + it("Should return last_row_id when no id provided in insert", async () => { + const id = await store.insert(table, { sub: "sub_auto", value: "v" }); + strictEqual(typeof id, "number"); + ok(id > 0); + const result = await store.select(table, { id }); + equal(result.sub, "sub_auto"); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should return provided id when id is in insert values", async () => { + const id = await store.insert(table, { + id: 42, + sub: "sub_42", + value: "v", + }); + strictEqual(id, 42); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should fall back to last_row_id when id is undefined", async () => { + const id = await store.insert(table, { + id: undefined, + sub: "sub_undef", + value: "v", + }); + strictEqual(typeof id, "number"); + ok(id > 0); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should fall back to last_row_id when id is null", async () => { + const id = await store.insert(table, { + id: null, + sub: "sub_null_id", + value: "v", + }); + strictEqual(typeof id, "number"); + ok(id > 0); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should use batch for insertList", async () => { + const rows = [ + { id: 1, sub: "sub_batch1", value: "a" }, + { id: 2, sub: "sub_batch2", value: "b" }, + { id: 3, sub: "sub_batch3", value: "c" }, + ]; + const res = await store.insertList(table, rows); + strictEqual(res.length, 3); + const result = await store.selectList(table, { + sub: ["sub_batch1", "sub_batch2", "sub_batch3"], + }); + strictEqual(result.length, 3); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should handle insertList with empty array", async () => { + const res = await store.insertList(table, []); + strictEqual(res.length, 0); + }); + it("Should not mutate input rows in insertList", async () => { + const rows = [ + { sub: "sub_imm1", value: "a" }, + { sub: "sub_imm2", value: "b" }, + ]; + const rowsCopy = structuredClone(rows); + await store.insertList(table, rows); + deepStrictEqual(rows, rowsCopy); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should not mutate input values in update", async () => { + await store.insert(table, { id: 1, sub: "sub_upd", value: "a" }); + const values = { value: "b" }; + const valuesCopy = structuredClone(values); + await store.update(table, { id: 1 }, values); + deepStrictEqual(values, valuesCopy); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should return empty list from selectList with no matches", async () => { + const result = await store.selectList(table, { sub: "nonexistent" }); + deepStrictEqual(result, []); + }); + it("Should return all rows from selectList with no filters", async () => { + await store.insertList(table, [ + { id: 1, sub: "sub_a", value: "a" }, + { id: 2, sub: "sub_b", value: "b" }, + ]); + const result = await store.selectList(table); + strictEqual(result.length, 2); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should return 0 from count with no matches", async () => { + const result = await store.count(table); + strictEqual(result, 0); + }); + it("Should return correct count with multiple rows", async () => { + await store.insertList(table, [ + { id: 1, sub: "sub_cnt", value: "a" }, + { id: 2, sub: "sub_cnt", value: "b" }, + { id: 3, sub: "sub_other", value: "c" }, + ]); + const all = await store.count(table); + strictEqual(all, 3); + const filtered = await store.count(table, { sub: "sub_cnt" }); + strictEqual(filtered, 2); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should skip timeToLiveKey when timeToLiveKey is falsy", async () => { + store.default({ timeToLiveKey: "" }); + const expire = nowInSeconds() + 86400; + await store.insert(table, { + id: 1, + sub: "sub_nottl", + value: "v", + expire, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.remove, null); + store.default({ timeToLiveKey: "remove" }); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + it("Should return settled results from updateList", async () => { + await store.insertList(table, [ + { id: 1, sub: "sub_ul", value: "a" }, + { id: 2, sub: "sub_ul", value: "b" }, + ]); + const results = await store.updateList(table, [{ id: 1 }, { id: 2 }], { + value: "z", + }); + strictEqual(results.length, 2); + strictEqual(results[0].status, "fulfilled"); + strictEqual(results[1].status, "fulfilled"); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + }); + describe("logging", () => { + it("Should work without logging enabled", async () => { + store.default({ log: false }); + await store.insert(table, { id: 1, sub: "sub_nolog", value: "v" }); + const ex = await store.exists(table, { id: 1 }); + strictEqual(ex, "sub_nolog"); + const cnt = await store.count(table, { id: 1 }); + strictEqual(cnt, 1); + const row = await store.select(table, { id: 1 }); + strictEqual(row.value, "v"); + const list = await store.selectList(table, { id: 1 }); + strictEqual(list.length, 1); + await store.update(table, { id: 1 }, { value: "w" }); + await store.updateList(table, [{ id: 1 }], { value: "x" }); + await store.remove(table, { id: 1 }); + store.default({ log: (...args) => mocks.log(...args) }); + await mockDatabaseTable.truncate(mockDatabase.storeClient, table); + }); + }); + describe("removeList", () => { + it("Should be the same function reference as remove", async () => { + strictEqual(store.removeList, store.remove); + }); + }); + describe("table/d1.js", () => { + it("Should create emptyRow with null prototype", async () => { + const row = mockDatabaseTable.emptyRow(); + strictEqual(Object.getPrototypeOf(row), null); + }); + it("Should create emptyRow with correct default values", async () => { + const row = mockDatabaseTable.emptyRow(); + strictEqual(row.id, 0); + strictEqual(row.sub, null); + strictEqual(row.value, null); + strictEqual(row.digest, null); + strictEqual(row.expire, null); + strictEqual(row.remove, null); + }); + it("Should create independent emptyRow instances", async () => { + const row1 = mockDatabaseTable.emptyRow(); + const row2 = mockDatabaseTable.emptyRow(); + row1.id = 99; + strictEqual(row2.id, 0); + }); + it("Should have exactly 6 keys on emptyRow", async () => { + const row = mockDatabaseTable.emptyRow(); + strictEqual(Object.keys(row).length, 6); + }); + it("Should export correct table name", async () => { + strictEqual(mockDatabaseTable.name, "test"); + }); + it("Should export correct timeToLiveKey", async () => { + strictEqual(mockDatabaseTable.timeToLiveKey, "remove"); + }); + it("Should create/truncate/drop table with explicit name", async () => { + const tmpTable = "test_table_ops"; + await mockDatabaseTable.create(mockDatabase.storeClient, tmpTable); + await store.insert(tmpTable, { id: 1, sub: "s", value: "v" }); + const before = await store.count(tmpTable); + strictEqual(before, 1); + await mockDatabaseTable.truncate(mockDatabase.storeClient, tmpTable); + const after = await store.count(tmpTable); + strictEqual(after, 0); + await mockDatabaseTable.drop(mockDatabase.storeClient, tmpTable); + }); + it("Should create/truncate/drop table with default name", async () => { + // Uses the default "test" table name — the shared tests already + // created/dropped it, so CREATE IF NOT EXISTS is safe + await mockDatabaseTable.create(mockDatabase.storeClient); + await store.insert(mockDatabaseTable.name, { + id: 1, + sub: "s", + value: "v", + }); + await mockDatabaseTable.truncate(mockDatabase.storeClient); + const cnt = await store.count(mockDatabaseTable.name); + strictEqual(cnt, 0); + await mockDatabaseTable.drop(mockDatabase.storeClient); + // Recreate for any subsequent tests + await mockDatabaseTable.create(mockDatabase.storeClient); + }); + }); +}); diff --git a/packages/store-d1/mock.js b/packages/store-d1/mock.js new file mode 100644 index 0000000..eadb59a --- /dev/null +++ b/packages/store-d1/mock.js @@ -0,0 +1,57 @@ +// Copyright 2003 - 2026 will Farrell, and 1Auth contributors. +// SPDX-License-Identifier: MIT +import { DatabaseSync } from "node:sqlite"; + +const db = new DatabaseSync(":memory:", {}); +db.exec("PRAGMA journal_mode = 'wal';"); + +// Wrap node:sqlite DatabaseSync with D1-compatible async API +const createBoundStatement = (sql, params) => ({ + all() { + const results = db.prepare(sql).all(...params); + return Promise.resolve({ results }); + }, + first() { + const row = db.prepare(sql).get(...params); + return Promise.resolve(row ?? null); + }, + run() { + try { + const result = db.prepare(sql).run(...params); + return Promise.resolve({ + meta: { last_row_id: result.lastInsertRowid }, + }); + } catch (e) { + if (e.message.includes("Use run() instead")) { + db.prepare(sql).run(...params); + return Promise.resolve({ meta: { last_row_id: 0 } }); + } + throw e; + } + }, +}); + +export const log = () => {}; +export const storeClient = { + prepare(sql) { + return { + bind(...params) { + return createBoundStatement(sql, params); + }, + // No-bind shorthand (for table DDL) + all() { + return createBoundStatement(sql, []).all(); + }, + first() { + return createBoundStatement(sql, []).first(); + }, + run() { + return createBoundStatement(sql, []).run(); + }, + }; + }, + batch(stmts) { + return Promise.resolve(stmts.map((stmt) => stmt.run())); + }, + after: () => db.close(), +}; diff --git a/packages/store-d1/package.json b/packages/store-d1/package.json new file mode 100644 index 0000000..2029583 --- /dev/null +++ b/packages/store-d1/package.json @@ -0,0 +1,60 @@ +{ + "name": "@1auth/store-d1", + "version": "0.0.0-beta.2", + "description": "Cloudflare D1 storage implementation for serverless SQLite persistence", + "type": "module", + "engines": { + "node": ">=24" + }, + "engineStrict": true, + "publishConfig": { + "access": "public" + }, + "main": "./index.js", + "module": "./index.js", + "sideEffects": false, + "exports": { + ".": { + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" + } + }, + "files": [ + "index.js", + "table" + ], + "scripts": { + "test": "npm run test:unit", + "test:unit": "node --test" + }, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/willfarrell" + }, + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "cloudflare", + "d1", + "workers", + "database" + ], + "author": { + "name": "1auth contributors", + "url": "https://github.com/willfarrell/1auth/graphs/contributors" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/willfarrell/1auth.git", + "directory": "packages/store-d1" + }, + "bugs": { + "url": "https://github.com/willfarrell/1auth/issues" + }, + "homepage": "https://github.com/willfarrell/1auth", + "dependencies": {} +} diff --git a/packages/store-d1/table/d1.js b/packages/store-d1/table/d1.js new file mode 100644 index 0000000..4243f53 --- /dev/null +++ b/packages/store-d1/table/d1.js @@ -0,0 +1,37 @@ +// Copyright 2003 - 2026 will Farrell, and 1Auth contributors. +// SPDX-License-Identifier: MIT +export const name = "test"; +export const timeToLiveKey = "remove"; +export const create = async (client, table = name) => { + const sql = ` + CREATE TABLE IF NOT EXISTS ${table} + ( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "sub" VARCHAR(15) NOT NULL, + "value" VARCHAR(256) NOT NULL, + "digest" VARCHAR(256) DEFAULT NULL, + + "expire" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "${timeToLiveKey}" TIMESTAMP WITH TIME ZONE DEFAULT NULL + ) + `; + return await client.prepare(sql).run(); +}; + +export const truncate = async (client, table = name) => { + return await client.prepare(`DELETE FROM ${table}`).run(); +}; + +export const drop = async (client, table = name) => { + return await client.prepare(`DROP TABLE ${table}`).run(); +}; + +export const emptyRow = () => + Object.assign(Object.create(null), { + id: 0, + sub: null, + value: null, + digest: null, + expire: null, + remove: null, + }); diff --git a/packages/store-dynamodb/README.md b/packages/store-dynamodb/README.md new file mode 100644 index 0000000..cb133ff --- /dev/null +++ b/packages/store-dynamodb/README.md @@ -0,0 +1,44 @@ +
+

@1auth/store-dynamodb

+ +

AWS DynamoDB storage implementation for serverless persistence

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/store-dynamodb +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/store-dynamodb/index.js b/packages/store-dynamodb/index.js index 8be04c4..3ac88cf 100644 --- a/packages/store-dynamodb/index.js +++ b/packages/store-dynamodb/index.js @@ -24,8 +24,8 @@ const options = { timeToLiveKey: "remove", }; -export default (params) => { - Object.assign(options, params); +export default (opt = {}) => { + Object.assign(options, opt); }; export const exists = async (table, filters) => { @@ -40,9 +40,11 @@ export const count = async (table, filters) => { if (options.log) { options.log(`@1auth/store-${options.id} count(`, table, filters, ")"); } - // TODO refactor to use Select COUNT - const items = await queryCommand(table, filters); - return items.length; + const commandParams = buildQueryCommand(table, filters); + commandParams.Select = "COUNT"; + return await options.client + .send(new QueryCommand(commandParams)) + .then((res) => res.Count); }; export const select = async (table, filters = {}, fields = []) => { @@ -65,18 +67,22 @@ export const select = async (table, filters = {}, fields = []) => { const getItem = async (table, filters = {}, fields = []) => { let indexName; // must be length of >=3 if (filters.digest) { - indexName ??= "digest"; + indexName = "digest"; } else if (filters.sub && !filters.id) { - indexName ??= "sub"; + indexName = "sub"; } else if (filters.id && !filters.sub) { - indexName ??= "key"; + indexName = "key"; } if (indexName) { return await queryCommand(table, filters, fields).then((res) => res?.[0]); } + // Only pass table key attributes to GetItemCommand + const key = {}; + if (filters.sub !== undefined) key.sub = filters.sub; + if (filters.id !== undefined) key.id = filters.id; const commandParams = { TableName: table, - Key: marshall(filters, marshallOptions), + Key: marshall(key, marshallOptions), }; if (fields.length) { commandParams.AttributesToGet = fields; @@ -86,13 +92,6 @@ const getItem = async (table, filters = {}, fields = []) => { .send(new GetItemCommand(commandParams)) .then((res) => unmarshall(res.Item)); } catch (e) { - // if (e.message === "The provided key element does not match the schema") { - // return await queryCommand(table, filters, fields).then((res) => res[0]); - // } - // ResourceNotFoundException - // if (e.message === "Requested resource not found") { - // return; - // } if (e.message === "No value defined: {}") { return; } @@ -108,38 +107,78 @@ export const selectList = async (table, filters = {}, fields = []) => { return await queryCommand(table, filters, fields); }; -const queryCommand = async (table, filters = {}, fields = []) => { +const buildQueryCommand = (table, filters = {}) => { let indexName; // must be length of >=3 + let partitionKey; if (filters.digest) { - indexName ??= "digest"; + indexName = "digest"; + partitionKey = "digest"; } else if (filters.sub && !filters.id) { - indexName ??= "sub"; + indexName = "sub"; + partitionKey = "sub"; } else if (filters.id && !filters.sub) { - indexName ??= "key"; + indexName = "key"; + partitionKey = "id"; + } else { + partitionKey = "sub"; + } + + // Determine which attributes are key attributes for this index + const keyAttributeSet = new Set([partitionKey]); + if (indexName === "sub" || indexName === "digest") { + if (filters.type !== undefined) keyAttributeSet.add("type"); + } else if (!indexName) { + keyAttributeSet.add("id"); + } + + const expressionAttributeNames = {}; + const expressionAttributeValues = {}; + const keyConditions = []; + const filterConditions = []; + for (const key in filters) { + let value = filters[key]; + if (typeof value === "undefined") { + continue; + } + const isArray = Array.isArray(value); + if (isArray) { + value = new Set(value); + } + expressionAttributeNames[`#${key}`] = key; + expressionAttributeValues[`:${key}`] = marshall(value, marshallOptions); + const condition = isArray ? `#${key} IN (:${key})` : `#${key} = :${key}`; + if (keyAttributeSet.has(key)) { + keyConditions.push(condition); + } else { + filterConditions.push(condition); + } } - const { - ExpressionAttributeNames, - ExpressionAttributeValues, - KeyConditionExpression, - //AttributesToGet, - } = makeQueryParams(filters, fields); const commandParams = { TableName: table, IndexName: indexName, - ExpressionAttributeNames, - ExpressionAttributeValues, - KeyConditionExpression, - // return in the same order they were inserted - ScanIndexForward: false, + ExpressionAttributeNames: expressionAttributeNames, + ExpressionAttributeValues: expressionAttributeValues, + KeyConditionExpression: keyConditions.join(" and "), }; + if (filterConditions.length) { + commandParams.FilterExpression = filterConditions.join(" and "); + } + return commandParams; +}; - // DynamoDB can't support fields - // ValidationException: Can not use both expression and non-expression parameters in the same request: Non-expression parameters: {AttributesToGet} Expression parameters: {KeyConditionExpression} +const queryCommand = async (table, filters = {}, fields = []) => { + const commandParams = buildQueryCommand(table, filters); + // return in the same order they were inserted + commandParams.ScanIndexForward = false; - // Add fields to secondary indexes instead if (fields.length) { - commandParams.AttributesToGet = undefined; //AttributesToGet; + for (const field of fields) { + commandParams.ExpressionAttributeNames[`#${field}`] = field; + } + commandParams.ProjectionExpression = fields + .map((field) => `#${field}`) + .join(", "); } return await options.client @@ -147,7 +186,8 @@ const queryCommand = async (table, filters = {}, fields = []) => { .then((res) => res.Items.map(unmarshall)); }; -export const insert = async (table, values = {}) => { +export const insert = async (table, inputValues = {}) => { + const values = structuredClone(inputValues); if (options.log) { options.log(`@1auth/store-${options.id} insert(`, table, values, ")"); } @@ -194,7 +234,8 @@ export const insertList = async (table, rows = []) => { return ids; }; -export const update = async (table, filters = {}, values = {}) => { +export const update = async (table, filters = {}, inputValues = {}) => { + const values = structuredClone(inputValues); if (options.log) { options.log( `@1auth/store-${options.id} update(`, @@ -204,12 +245,6 @@ export const update = async (table, filters = {}, values = {}) => { ")", ); } - // TODO Move to updateList - for updating webauthn - // if (Array.isArray(filters.id)) { - // return Promise.allSettled( - // filters.id.map((id) => update(table, { ...filters, id }, values)), - // ); - // } if (values.expire && options.timeToLiveKey) { values[options.timeToLiveKey] = values.expire + options.timeToLiveExpireOffset; @@ -220,9 +255,13 @@ export const update = async (table, filters = {}, values = {}) => { ExpressionAttributeValues, KeyConditionExpression, } = makeQueryParams(values); + // Only pass table key attributes to UpdateItemCommand + const key = {}; + if (filters.sub !== undefined) key.sub = filters.sub; + if (filters.id !== undefined) key.id = filters.id; const commandParams = { TableName: table, - Key: marshall(filters, marshallOptions), + Key: marshall(key, marshallOptions), ExpressionAttributeNames, ExpressionAttributeValues, UpdateExpression: `SET ${KeyConditionExpression.replaceAll(" and ", ", ")}`, @@ -230,61 +269,66 @@ export const update = async (table, filters = {}, values = {}) => { await options.client.send(new UpdateItemCommand(commandParams)); }; -/* export const updateList = async (table, filters = {}, params = {}) => { - const { - ExpressionAttributeNames, - ExpressionAttributeValues, - KeyConditionExpression - } = makeQueryParams(params) - options.log('BatchWriteItemCommand', { - TableName: table, - Key: marshall(filters, marshallOptions), - ExpressionAttributeNames, - ExpressionAttributeValues, - UpdateExpression: `SET ` + KeyConditionExpression.replace(' and ', ', ') - }) - await client.send( - new BatchWriteItemCommand({ - RequestItems:{ - [table]: filters.id.map(id => ({ - PutRequest: { - Key: - } - })) - } - TableName: table, - Key: marshall(filters, marshallOptions), - ExpressionAttributeNames, - ExpressionAttributeValues, - UpdateExpression: `SET ` + KeyConditionExpression.replace(' and ', ', ') - }) - ) -} */ +export const updateList = async (table, filtersList = [], values = {}) => { + if (options.log) { + options.log( + `@1auth/store-${options.id} updateList(`, + table, + filtersList, + values, + ")", + ); + } + return await Promise.allSettled( + filtersList.map((filters) => update(table, filters, values)), + ); +}; export const remove = async (table, filters = {}) => { if (options.log) { options.log(`@1auth/store-${options.id} remove(`, table, filters, ")"); } - const commandParams = { - TableName: table, - Key: marshall(filters, marshallOptions), - }; - await options.client.send(new DeleteItemCommand(commandParams)); + const key = {}; + if (filters.sub !== undefined) key.sub = filters.sub; + if (filters.id !== undefined) key.id = filters.id; + const hasNonKeyFilters = Object.keys(filters).some( + (k) => k !== "sub" && k !== "id", + ); + if (hasNonKeyFilters) { + // Non-key attributes can't be used in DeleteItemCommand. + // Query to find matching items, then delete each by primary key. + const items = await queryCommand(table, filters); + for (const item of items) { + await options.client.send( + new DeleteItemCommand({ + TableName: table, + Key: marshall({ sub: item.sub, id: item.id }, marshallOptions), + }), + ); + } + return; + } + await options.client.send( + new DeleteItemCommand({ + TableName: table, + Key: marshall(key, marshallOptions), + }), + ); }; // Can only be used with recovery-codes for now export const removeList = async (table, filters = {}) => { if (options.log) { - options.log("@1auth/store-dynamodb removeList(", table, filters, ")"); + options.log(`@1auth/store-${options.id} removeList(`, table, filters, ")"); } const deleteRequests = []; for (let i = 0, l = filters.id.length; i < l; i++) { - const itemFilters = structuredClone(filters); - itemFilters.id = filters.id[i]; + // Only pass table key attributes to DeleteItemCommand + const key = { sub: filters.sub, id: filters.id[i] }; deleteRequests.push({ DeleteRequest: { - Key: marshall(itemFilters, marshallOptions), + Key: marshall(key, marshallOptions), }, }); } diff --git a/packages/store-dynamodb/index.test.js b/packages/store-dynamodb/index.test.js index b23efee..b9b6b63 100644 --- a/packages/store-dynamodb/index.test.js +++ b/packages/store-dynamodb/index.test.js @@ -1,18 +1,11 @@ -import { deepEqual, equal } from "node:assert/strict"; +import { deepEqual, equal, ok } from "node:assert/strict"; import { randomInt } from "node:crypto"; -import { describe, it } from "node:test"; +import { describe, it, test } from "node:test"; +import tests from "../store/index.test.js"; import * as store from "../store-dynamodb/index.js"; - import * as mockDatabase from "./mock.js"; import * as mockDatabaseTable from "./table/dynamodb.js"; -// import { -// DynamoDBClient, GetItemCommand -// } from "@aws-sdk/client-dynamodb"; -// import { mockClient } from "aws-sdk-client-mock"; - -import tests from "../store/index.test.js"; - store.default({ log: (...args) => mocks.log(...args), client: { @@ -26,19 +19,20 @@ const mocks = { table: mockDatabaseTable, }; +const table = mockDatabaseTable.name; + describe("store-dynamodb", () => { tests(store, mocks); describe("makeQueryParams", () => { it("Should format {ExpressionAttributeNames} properly", async () => { - const { ExpressionAttributeNames } = store.makeQueryParams( - { id: [1, 2], sub: "sub_000" }, - //["value"], - ); + const { ExpressionAttributeNames } = store.makeQueryParams({ + id: [1, 2], + sub: "sub_000", + }); deepEqual(ExpressionAttributeNames, { "#id": "id", "#sub": "sub", - //"#value": "value", }); }); it("Should format {ExpressionAttributeValues} properly", async () => { @@ -69,5 +63,225 @@ describe("store-dynamodb", () => { ); equal(UpdateExpression, "SET #id = :id, #sub = :sub"); }); + it("Should format {ProjectionExpression} properly", async () => { + const { ProjectionExpression, AttributesToGet } = store.makeQueryParams( + { id: [1, 2], sub: "sub_000" }, + ["value"], + ); + equal(ProjectionExpression, ":value"); + deepEqual(AttributesToGet, [":value"]); + }); + }); + + describe("makeQueryParams edge cases", () => { + it("Should skip undefined filter values", async () => { + const { ExpressionAttributeNames, KeyConditionExpression } = + store.makeQueryParams({ sub: "sub_000", id: undefined }); + deepEqual(ExpressionAttributeNames, { "#sub": "sub" }); + equal(KeyConditionExpression, "#sub = :sub"); + }); + + it("Should handle single scalar filter", async () => { + const result = store.makeQueryParams({ sub: "sub_000" }); + equal(result.KeyConditionExpression, "#sub = :sub"); + deepEqual(result.ExpressionAttributeValues, { + ":sub": { S: "sub_000" }, + }); + }); + + it("Should handle numeric filter value", async () => { + const result = store.makeQueryParams({ id: 42 }); + deepEqual(result.ExpressionAttributeValues, { + ":id": { N: "42" }, + }); + equal(result.KeyConditionExpression, "#id = :id"); + }); + + it("Should not include ProjectionExpression when no fields", async () => { + const result = store.makeQueryParams({ sub: "sub_000" }); + equal(result.ProjectionExpression, undefined); + equal(result.AttributesToGet, undefined); + }); + + it("Should handle multiple fields", async () => { + const result = store.makeQueryParams({ sub: "sub_000" }, [ + "value", + "digest", + ]); + equal(result.ProjectionExpression, ":value, :digest"); + deepEqual(result.AttributesToGet, [":value", ":digest"]); + equal(result.ExpressionAttributeNames["#value"], "value"); + equal(result.ExpressionAttributeNames["#digest"], "digest"); + }); + + it("Should deduplicate ProjectionExpression fields", async () => { + const result = store.makeQueryParams({ sub: "sub_000" }, [ + "value", + "value", + ]); + equal(result.ProjectionExpression, ":value"); + }); + + it("Should handle empty filters", async () => { + const result = store.makeQueryParams({}); + equal(result.KeyConditionExpression, ""); + equal(result.UpdateExpression, "SET "); + deepEqual(result.ExpressionAttributeNames, {}); + deepEqual(result.ExpressionAttributeValues, {}); + }); + + it("Should handle string array filter values", async () => { + const result = store.makeQueryParams({ sub: ["sub_000", "sub_001"] }); + equal(result.KeyConditionExpression, "#sub IN (:sub)"); + deepEqual(result.ExpressionAttributeValues, { + ":sub": { SS: ["sub_000", "sub_001"] }, + }); + }); + }); + + describe("integration", () => { + test.before(async () => { + await mockDatabaseTable.create(mocks.storeClient, table); + }); + test.afterEach(async () => { + await mockDatabaseTable.truncate(mocks.storeClient, table); + }); + test.after(async () => { + await mockDatabaseTable.drop(mocks.storeClient, table); + }); + + describe("select index paths", () => { + it("Should select by digest (uses digest GSI)", async () => { + const row = { + id: 1, + sub: "sub_000", + value: "a", + digest: "digest_abc", + }; + await store.insert(table, row); + const result = await store.select(table, { digest: "digest_abc" }); + equal(result.sub, "sub_000"); + equal(result.digest, "digest_abc"); + }); + + it("Should select by sub only (uses sub GSI)", async () => { + const row = { id: 1, sub: "sub_000", value: "a" }; + await store.insert(table, row); + const result = await store.select(table, { sub: "sub_000" }); + equal(result.sub, "sub_000"); + equal(result.value, "a"); + }); + + it("Should select by id only (uses key GSI)", async () => { + const row = { id: 1, sub: "sub_000", value: "a" }; + await store.insert(table, row); + const result = await store.select(table, { id: 1 }); + equal(result.id, 1); + equal(result.sub, "sub_000"); + }); + + it("Should select by sub+id (uses GetItem)", async () => { + const row = { id: 1, sub: "sub_000", value: "a" }; + await store.insert(table, row); + const result = await store.select(table, { + sub: "sub_000", + id: 1, + }); + equal(result.sub, "sub_000"); + equal(result.id, 1); + equal(result.value, "a"); + }); + }); + + describe("insert edge cases", () => { + it("Should assign randomId when no id provided", async () => { + const row = { sub: "sub_000", value: "a" }; + const id = await store.insert(table, row); + ok(id); + ok(typeof id === "number"); + const result = await store.select(table, { sub: "sub_000", id }); + equal(result.value, "a"); + }); + + it("Should not mutate the input values object on update", async () => { + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + const updateValues = { value: "b" }; + const updateCopy = structuredClone(updateValues); + await store.update(table, { sub: "sub_000", id: 1 }, updateValues); + deepEqual(updateValues, updateCopy); + }); + + it("Should insert without expire and not add timeToLiveKey", async () => { + const row = { id: 1, sub: "sub_000", value: "a" }; + await store.insert(table, row); + const result = await store.select(table, { + sub: "sub_000", + id: row.id, + }); + equal(result[mockDatabaseTable.timeToLiveKey], undefined); + }); + }); + + describe("remove edge cases", () => { + it("Should remove by sub+id (direct delete)", async () => { + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + await store.insert(table, { id: 2, sub: "sub_000", value: "b" }); + await store.remove(table, { sub: "sub_000", id: 1 }); + const result = await store.selectList(table, { sub: "sub_000" }); + equal(result.length, 1); + equal(result[0].id, 2); + }); + + it("Should remove by non-key filter (query then delete)", async () => { + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + digest: "d1", + }); + await store.insert(table, { + id: 2, + sub: "sub_000", + value: "b", + digest: "d2", + }); + await store.remove(table, { digest: "d1" }); + const result = await store.selectList(table, { sub: "sub_000" }); + equal(result.length, 1); + equal(result[0].id, 2); + }); + }); + + describe("count edge cases", () => { + it("Should count by sub", async () => { + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + await store.insert(table, { id: 2, sub: "sub_000", value: "b" }); + await store.insert(table, { id: 3, sub: "sub_001", value: "c" }); + const result = await store.count(table, { sub: "sub_000" }); + equal(result, 2); + }); + }); + + describe("selectList edge cases", () => { + it("Should return multiple items filtered by sub", async () => { + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + await store.insert(table, { id: 2, sub: "sub_000", value: "b" }); + await store.insert(table, { id: 3, sub: "sub_001", value: "c" }); + const result = await store.selectList(table, { sub: "sub_000" }); + equal(result.length, 2); + }); + + it("Should return only requested fields in selectList", async () => { + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + await store.insert(table, { id: 2, sub: "sub_000", value: "b" }); + const result = await store.selectList(table, { sub: "sub_000" }, [ + "value", + ]); + equal(result.length, 2); + for (const row of result) { + ok(row.value); + } + }); + }); }); }); diff --git a/packages/store-dynamodb/mock.js b/packages/store-dynamodb/mock.js index 2d9779f..fe1f320 100644 --- a/packages/store-dynamodb/mock.js +++ b/packages/store-dynamodb/mock.js @@ -15,15 +15,22 @@ export const storeClient = new DynamoDBClient({ }); let ready; -const waitForStart = async () => { +const maxRetries = 30; +const waitForStart = async (attempt = 0) => { if (ready) return; try { await storeClient.send(new ListTablesCommand()); ready = 1; } catch (error) { + if (attempt >= maxRetries) { + console.warn("DynamoDB local not available, skipping DynamoDB tests"); + return; + } console.info("Waiting for dynamodb to start...", error); await setTimeout(500); - return waitForStart(); + return waitForStart(attempt + 1); } }; await waitForStart(); + +export const isReady = () => !!ready; diff --git a/packages/store-dynamodb/package.json b/packages/store-dynamodb/package.json index 8b9e2f3..c663d4b 100644 --- a/packages/store-dynamodb/package.json +++ b/packages/store-dynamodb/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/store-dynamodb", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "AWS DynamoDB storage implementation for serverless persistence", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,18 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" } }, - "types": "index.d.ts", "files": [ "index.js", - "index.d.ts" + "table" ], "scripts": { "run": "docker run -p 8000:8000 amazon/dynamodb-local", @@ -35,7 +35,14 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "DynamoDB", + "AWS", + "database" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" diff --git a/packages/store-dynamodb/table/dynamodb.js b/packages/store-dynamodb/table/dynamodb.js index aeb197a..28b71c8 100644 --- a/packages/store-dynamodb/table/dynamodb.js +++ b/packages/store-dynamodb/table/dynamodb.js @@ -105,11 +105,17 @@ export const truncate = async (client, table = name) => { }; export const drop = async (client, table = name) => { - await client.send( - new DeleteTableCommand({ - TableName: table, - }), - ); + try { + await client.send( + new DeleteTableCommand({ + TableName: table, + }), + ); + } catch (e) { + if (e.name !== "ResourceNotFoundException") { + throw e; + } + } }; export const emptyRow = () => ({ diff --git a/packages/store-postgres/README.md b/packages/store-postgres/README.md new file mode 100644 index 0000000..931aca9 --- /dev/null +++ b/packages/store-postgres/README.md @@ -0,0 +1,44 @@ +
+

@1auth/store-postgres

+ +

PostgreSQL storage implementation for relational database persistence

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/store-postgres +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/store-postgres/index.js b/packages/store-postgres/index.js index e476346..cd48572 100644 --- a/packages/store-postgres/index.js +++ b/packages/store-postgres/index.js @@ -11,8 +11,8 @@ const options = { placeholder: "$", }; -export default (params) => { - Object.assign(options, params); +export default (opt = {}) => { + Object.assign(options, opt); }; export const exists = async (table, filters) => { @@ -34,7 +34,7 @@ export const count = async (table, filters = {}) => { const sql = `SELECT COUNT(*) AS count FROM ${table} ${where}`; return await options.client .query(sql, parameters) - .then((res) => res[0].count); + .then((res) => Number(res[0].count)); }; export const select = async (table, filters = {}, fields = []) => { @@ -52,7 +52,7 @@ export const select = async (table, filters = {}, fields = []) => { return await options.client .query(sql, parameters) .then((res) => res?.[0]) - // Workaround because an expire filter doesn't exists yet' + // Workaround because an expire filter doesn't exist yet .then((row) => { parseValues(row); return row; @@ -73,7 +73,7 @@ export const selectList = async (table, filters = {}, fields = []) => { const sql = `SELECT ${select} FROM ${table} ${where}`; return await options.client .query(sql, parameters) - // Workaround because an expire filter doesn't exists yet' + // Workaround because an expire filter doesn't exist yet .then((rows) => { return rows.map((row) => { parseValues(row); @@ -156,6 +156,21 @@ export const update = async (table, filters = {}, inputValues = {}) => { await options.client.query(sql, parameters); }; +export const updateList = async (table, filtersList = [], values = {}) => { + if (options.log) { + options.log( + `@1auth/store-${options.id} updateList(`, + table, + filtersList, + values, + ")", + ); + } + return await Promise.allSettled( + filtersList.map((filters) => update(table, filters, values)), + ); +}; + export const remove = async (table, filters = {}) => { if (options.log) { options.log(`@1auth/store-${options.id} remove(`, table, filters, ")"); @@ -206,8 +221,6 @@ export const makeSqlParts = ( const insertParts = []; const updateParts = []; for (const key of keys) { - // insertParts.push("$" + idx); - // updateParts.push('"' + key + '" = $' + idx); insertParts.push(getPlaceholder(idx)); updateParts.push(`"${key}" = ${getPlaceholder(idx)}`); idx++; @@ -228,7 +241,6 @@ export const makeSqlParts = ( parameters = parameters.concat(value); return sql; } - // const sql = '"' + key + '" = $' + idx++; const sql = `"${key}" = ${getPlaceholder(idx++)}`; parameters.push(value); return sql; diff --git a/packages/store-postgres/index.test.js b/packages/store-postgres/index.test.js index 8d31ab2..abf8659 100644 --- a/packages/store-postgres/index.test.js +++ b/packages/store-postgres/index.test.js @@ -84,4 +84,23 @@ describe("store-postgres", () => { deepEqual(parameters, ["a", "b", "c", "d"]); }); }); + describe("makeSqlParts with default placeholder", () => { + it("Should format {insert} with $ placeholder", async () => { + store.default({ placeholder: "$" }); + const { insert, parameters } = store.makeSqlParts({}, { a: "a", b: "b" }); + equal(insert, '("a", "b") VALUES ($1,$2)'); + deepEqual(parameters, ["a", "b"]); + }); + + it("Should format {where} with $ placeholder", async () => { + store.default({ placeholder: "$" }); + const { where, parameters } = store.makeSqlParts({ + a: "a", + bc: ["b", "c"], + d: "d", + }); + equal(where, 'WHERE "a" = $1 AND "bc" IN ($2,$3) AND "d" = $4'); + deepEqual(parameters, ["a", "b", "c", "d"]); + }); + }); }); diff --git a/packages/store-postgres/mock.js b/packages/store-postgres/mock.js index 8cb742c..a7f6bc8 100644 --- a/packages/store-postgres/mock.js +++ b/packages/store-postgres/mock.js @@ -16,31 +16,6 @@ const pgClient = new Pool({ export const log = () => {}; export const storeClient = { query: async (sql, parameters) => { - // if (sql.trim().substring(0, 6) === "CREATE") { - // console.log('|> postgres '+sql.trim().split('\n')[0]) - // } else if (sql.trim().substring(0, 6) === "DELETE" && !sql.includes('WHERE')) { - // console.log('|> postgres '+sql.trim()) - // } else if (sql.trim().substring(0, 4) === "DROP") { - // console.log('|> postgres '+sql.trim()) - // } //else { - // const query = `SELECT * FROM pg_stat_activity WHERE state = 'active'` - // const res = await pgClient.query(query).then(res => { - // return res.rows.filter(item => item.query !== query) - // }) - // console.log('|> postgres ', res.length, JSON.stringify(res)) - // } - // wait for last command to complete - // const query = `SELECT * FROM pg_stat_activity WHERE state = 'active'` - // const res = await pgClient.query(query).then(res => { - // return res.rows.filter(item => item.query !== query).map(item => item.query) - // }) - //await setTimeout(500) - // if (res.length) { - // console.log('Waiting for postgres to finish last query...') - // await setTimeout(500) - // return storeClient.query(sql, parameters) - // } - return await pgClient .query(sql, parameters) .then((res) => { @@ -55,15 +30,22 @@ export const storeClient = { }; let ready; -const waitForStart = async () => { +const maxRetries = 30; +const waitForStart = async (attempt = 0) => { if (ready) return; try { await storeClient.query("SELECT 1"); ready = 1; } catch (error) { + if (attempt >= maxRetries) { + console.warn("PostgreSQL not available, skipping PostgreSQL tests"); + return; + } console.info("Waiting for postgres to start...", error); await setTimeout(500); - return await waitForStart(); + return await waitForStart(attempt + 1); } }; await waitForStart(); + +export const isReady = () => !!ready; diff --git a/packages/store-postgres/package.json b/packages/store-postgres/package.json index 833b32b..a4a984f 100644 --- a/packages/store-postgres/package.json +++ b/packages/store-postgres/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/store-postgres", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "PostgreSQL storage implementation for relational database persistence", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,18 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" } }, - "types": "index.d.ts", "files": [ "index.js", - "index.d.ts" + "table" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +34,13 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "PostgreSQL", + "database" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -42,7 +48,7 @@ "repository": { "type": "git", "url": "git+https://github.com/willfarrell/1auth.git", - "directory": "packages/store-sqlite" + "directory": "packages/store-postgres" }, "bugs": { "url": "https://github.com/willfarrell/1auth/issues" @@ -51,6 +57,6 @@ "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431", "dependencies": {}, "devDependencies": { - "pg": "8.18.0" + "pg": "8.20.0" } } diff --git a/packages/store-sqlite/README.md b/packages/store-sqlite/README.md new file mode 100644 index 0000000..25e03de --- /dev/null +++ b/packages/store-sqlite/README.md @@ -0,0 +1,44 @@ +
+

@1auth/store-sqlite

+ +

SQLite storage implementation for lightweight embedded database persistence

+

+ GitHub Actions unit test status + GitHub Actions dast test status + GitHub Actions perf test status + GitHub Actions SAST test status + GitHub Actions lint test status +
+ npm version + npm install size + + npm weekly downloads + + npm provenance +
+ Open Source Security Foundation (OpenSSF) Scorecard + SLSA 3 + + Checked with Biome + Conventional Commits +

+

You can read the documentation at: https://1auth.js.org

+
+ +## Install + +```bash +npm install @1auth/store-sqlite +``` + +## Documentation and examples + +For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org). + +## Contributing + +Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +## License + +Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors). diff --git a/packages/store-sqlite/index.js b/packages/store-sqlite/index.js index 9f72c59..665fd1b 100644 --- a/packages/store-sqlite/index.js +++ b/packages/store-sqlite/index.js @@ -11,8 +11,8 @@ const options = { placeholder: "?", }; -export default (params) => { - Object.assign(options, params); +export default (opt = {}) => { + Object.assign(options, opt); }; export const exists = async (table, filters) => { @@ -52,7 +52,7 @@ export const select = async (table, filters = {}, fields = []) => { return await options.client .query(sql, parameters) .then((res) => res?.[0]) - // Workaround because an expire filter doesn't exists yet' + // Workaround because an expire filter doesn't exist yet .then((row) => { parseValues(row); return row; @@ -73,7 +73,7 @@ export const selectList = async (table, filters = {}, fields = []) => { const sql = `SELECT ${select} FROM ${table} ${where}`; return await options.client .query(sql, parameters) - // Workaround because an expire filter doesn't exists yet' + // Workaround because an expire filter doesn't exist yet .then((rows) => { return rows.map((row) => { parseValues(row); @@ -152,6 +152,21 @@ export const update = async (table, filters = {}, inputValues = {}) => { await options.client.query(sql, parameters); }; +export const updateList = async (table, filtersList = [], values = {}) => { + if (options.log) { + options.log( + `@1auth/store-${options.id} updateList(`, + table, + filtersList, + values, + ")", + ); + } + return await Promise.allSettled( + filtersList.map((filters) => update(table, filters, values)), + ); +}; + export const remove = async (table, filters = {}) => { if (options.log) { options.log(`@1auth/store-${options.id} remove(`, table, filters, ")"); @@ -174,6 +189,16 @@ const normalizeValues = (values) => { values.lastused &&= new Date(values.lastused * 1000).toISOString(); values.expire &&= new Date(values.expire * 1000).toISOString(); values.remove &&= new Date(values.remove * 1000).toISOString(); + for (const [key, v] of Object.entries(values)) { + if (v !== null && typeof v !== "string" && typeof v !== "number") { + values[key] = + v === undefined + ? null + : typeof v === "object" + ? JSON.stringify(v) + : String(v); + } + } }; const parseValues = (values) => { @@ -208,8 +233,6 @@ export const makeSqlParts = ( const insertParts = []; const updateParts = []; for (const key of keys) { - // insertParts.push("$" + idx); - // updateParts.push('"' + key + '" = $' + idx); insertParts.push(getPlaceholder(idx)); updateParts.push(`"${key}" = ${getPlaceholder(idx)}`); idx++; @@ -230,7 +253,6 @@ export const makeSqlParts = ( parameters = parameters.concat(value); return sql; } - // const sql = '"' + key + '" = $' + idx++; const sql = `"${key}" = ${getPlaceholder(idx++)}`; parameters.push(value); return sql; diff --git a/packages/store-sqlite/index.test.js b/packages/store-sqlite/index.test.js index d82c988..92185cc 100644 --- a/packages/store-sqlite/index.test.js +++ b/packages/store-sqlite/index.test.js @@ -1,5 +1,11 @@ -import { deepEqual, equal } from "node:assert/strict"; -import { describe, it } from "node:test"; +import { + deepEqual, + deepStrictEqual, + equal, + ok, + strictEqual, +} from "node:assert/strict"; +import { describe, it, test } from "node:test"; import tests from "../store/index.test.js"; import * as store from "./index.js"; import * as mockDatabase from "./mock.js"; @@ -17,6 +23,9 @@ const mocks = { table: mockDatabaseTable, }; +const table = mockDatabaseTable.name; +const nowInSeconds = () => Math.floor(Date.now() / 1000); + describe("store-sqlite", () => { tests(store, mocks); describe("makeSqlParts", () => { @@ -52,6 +61,12 @@ describe("store-sqlite", () => { deepEqual(parameters, []); }); + it("Should format {select} with single field", async () => { + store.default({ placeholder: "$" }); + const { select } = store.makeSqlParts({}, {}, ["id"]); + equal(select, '"id"'); + }); + it("Should format {insert} properly", async () => { const filters = {}; const values = { a: "a", b: "b" }; @@ -84,4 +99,529 @@ describe("store-sqlite", () => { deepEqual(parameters, ["a", "b", "c", "d"]); }); }); + describe("makeSqlParts with default placeholder", () => { + it("Should format {insert} with ? placeholder", async () => { + store.default({ placeholder: "?" }); + const { insert, parameters } = store.makeSqlParts({}, { a: "a", b: "b" }); + equal(insert, '("a", "b") VALUES (?,?)'); + deepEqual(parameters, ["a", "b"]); + }); + + it("Should format {where} with ? placeholder", async () => { + store.default({ placeholder: "?" }); + const { where, parameters } = store.makeSqlParts({ + a: "a", + bc: ["b", "c"], + d: "d", + }); + equal(where, 'WHERE "a" = ? AND "bc" IN (?,?) AND "d" = ?'); + deepEqual(parameters, ["a", "b", "c", "d"]); + }); + }); + + describe("makeSqlParts edge cases", () => { + it("Should handle combined filters and values for UPDATE", async () => { + store.default({ placeholder: "$" }); + const { update, where, parameters } = store.makeSqlParts( + { id: 1, sub: "sub_000" }, + { value: "b" }, + ); + equal(update, '"value" = $1'); + equal(where, 'WHERE "id" = $2 AND "sub" = $3'); + deepEqual(parameters, ["b", 1, "sub_000"]); + }); + + it("Should handle idxStart parameter", async () => { + store.default({ placeholder: "$" }); + const { insert, parameters } = store.makeSqlParts( + {}, + { a: "a", b: "b" }, + [], + 5, + ); + equal(insert, '("a", "b") VALUES ($5,$6)'); + deepEqual(parameters, ["a", "b"]); + }); + + it("Should return empty where when no filters", async () => { + store.default({ placeholder: "$" }); + const { where, parameters } = store.makeSqlParts({}); + equal(where, ""); + deepEqual(parameters, []); + }); + + it("Should skip undefined filter values", async () => { + store.default({ placeholder: "$" }); + const { where, parameters } = store.makeSqlParts({ + a: "a", + b: undefined, + c: "c", + }); + equal(where, 'WHERE "a" = $1 AND "c" = $2'); + deepEqual(parameters, ["a", "c"]); + }); + + it("Should handle empty array filter value", async () => { + store.default({ placeholder: "$" }); + const { where, parameters } = store.makeSqlParts({ + a: [], + }); + equal(where, ""); + deepEqual(parameters, []); + }); + }); + + describe("getPlaceholder", () => { + it("Should return $N for $ placeholder", async () => { + store.default({ placeholder: "$" }); + equal(store.getPlaceholder(1), "$1"); + equal(store.getPlaceholder(5), "$5"); + }); + + it("Should return ? for ? placeholder", async () => { + store.default({ placeholder: "?" }); + equal(store.getPlaceholder(1), "?"); + equal(store.getPlaceholder(5), "?"); + }); + }); + + describe("integration", () => { + test.before(async () => { + await mockDatabaseTable.create(mocks.storeClient, table); + }); + test.afterEach(async () => { + await mockDatabaseTable.truncate(mocks.storeClient, table); + }); + + describe("normalizeValues / parseValues round-trip", () => { + it("Should round-trip otp boolean values", async () => { + store.default({ placeholder: "?" }); + const row = { id: 1, sub: "sub_000", value: "a" }; + + // otp = true + await store.insert(table, { ...row, otp: true }); + let result = await store.select(table, { id: row.id }); + equal(result.otp, true); + await mocks.table.truncate(mocks.storeClient, table); + + // otp = false + await store.insert(table, { ...row, otp: false }); + result = await store.select(table, { id: row.id }); + equal(result.otp, false); + }); + + it("Should round-trip otp via update", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + otp: false, + }); + await store.update(table, { id: 1 }, { otp: true }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.otp, true); + }); + + it("Should normalize otp undefined to false (via 0)", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + otp: undefined, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.otp, false); + }); + + it("Should round-trip date fields (create, update, verify, lastused)", async () => { + store.default({ placeholder: "?" }); + const now = nowInSeconds(); + const row = { + id: 1, + sub: "sub_000", + value: "a", + create: now, + update: now + 100, + verify: now + 200, + lastused: now + 300, + }; + await store.insert(table, row); + const result = await store.select(table, { id: row.id }); + equal(result.create, now); + equal(result.update, now + 100); + equal(result.verify, now + 200); + equal(result.lastused, now + 300); + }); + + it("Should round-trip expire timestamp", async () => { + store.default({ placeholder: "?" }); + const ts = nowInSeconds(); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + expire: ts, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.expire, ts); + }); + + it("Should round-trip remove timestamp independently", async () => { + store.default({ placeholder: "?", timeToLiveKey: "" }); + const ts = nowInSeconds(); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + remove: ts, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.remove, ts); + store.default({ timeToLiveKey: "remove" }); + }); + + it("Should round-trip all 6 date fields simultaneously", async () => { + store.default({ placeholder: "?", timeToLiveKey: "" }); + const ts = nowInSeconds(); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + create: ts, + update: ts + 1, + verify: ts + 2, + lastused: ts + 3, + expire: ts + 4, + remove: ts + 5, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.create, ts); + strictEqual(result.update, ts + 1); + strictEqual(result.verify, ts + 2); + strictEqual(result.lastused, ts + 3); + strictEqual(result.expire, ts + 4); + strictEqual(result.remove, ts + 5); + store.default({ timeToLiveKey: "remove" }); + }); + + it("Should preserve null date fields", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.create, null); + strictEqual(result.update, null); + strictEqual(result.verify, null); + strictEqual(result.lastused, null); + strictEqual(result.expire, null); + strictEqual(result.remove, null); + }); + + it("Should normalize actual boolean to string via String()", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: true, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.value, "true"); + }); + + it("Should normalize actual object to JSON via JSON.stringify()", async () => { + store.default({ placeholder: "?" }); + const obj = { key: "val", nested: [1, 2] }; + await store.insert(table, { + id: 1, + sub: "sub_000", + value: obj, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.value, JSON.stringify(obj)); + }); + + it("Should handle pre-stringified object values", async () => { + store.default({ placeholder: "?" }); + const obj = { key: "val", nested: [1, 2] }; + const row = { id: 1, sub: "sub_000", value: JSON.stringify(obj) }; + await store.insert(table, row); + const result = await store.select(table, { id: row.id }); + equal(result.value, JSON.stringify(obj)); + }); + + it("Should normalize undefined non-date value to null", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "v", + digest: undefined, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.digest, null); + }); + + it("Should store null values", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "v", + digest: null, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.digest, null); + }); + + it("Should not mutate the input values object on update", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + const updateValues = { value: "b" }; + const updateCopy = structuredClone(updateValues); + await store.update(table, { id: 1 }, updateValues); + deepEqual(updateValues, updateCopy); + }); + + it("Should insert without expire and not add timeToLiveKey", async () => { + store.default({ placeholder: "?" }); + const row = { id: 1, sub: "sub_000", value: "a" }; + await store.insert(table, row); + const result = await store.select(table, { id: row.id }); + equal(result[mocks.table.timeToLiveKey], null); + }); + + it("Should update date fields via update path", async () => { + store.default({ placeholder: "?" }); + const ts = nowInSeconds(); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "v", + }); + await store.update(table, { id: 1 }, { verify: ts, lastused: ts }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.verify, ts); + strictEqual(result.lastused, ts); + }); + + it("Should handle expire with TTL on update path", async () => { + store.default({ placeholder: "?" }); + const expire = nowInSeconds() + 86400; + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "v", + }); + await store.update(table, { id: 1 }, { expire }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.expire, expire); + ok(result.remove > expire); + }); + }); + + describe("count edge cases", () => { + it("Should count all rows with empty filters", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + await store.insert(table, { id: 2, sub: "sub_001", value: "b" }); + const result = await store.count(table); + equal(result, 2); + }); + + it("Should return correct filtered count", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + }); + await store.insert(table, { + id: 2, + sub: "sub_000", + value: "b", + }); + await store.insert(table, { + id: 3, + sub: "sub_001", + value: "c", + }); + const all = await store.count(table); + strictEqual(all, 3); + const filtered = await store.count(table, { sub: "sub_000" }); + strictEqual(filtered, 2); + }); + }); + + describe("selectList edge cases", () => { + it("Should return all rows with empty filters", async () => { + store.default({ placeholder: "?" }); + await store.insert(table, { id: 1, sub: "sub_000", value: "a" }); + await store.insert(table, { id: 2, sub: "sub_001", value: "b" }); + const result = await store.selectList(table); + equal(result.length, 2); + }); + + it("Should parse date fields in selectList results", async () => { + store.default({ placeholder: "?" }); + const now = nowInSeconds(); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "a", + expire: now + 1000, + }); + await store.insert(table, { + id: 2, + sub: "sub_000", + value: "b", + expire: now + 2000, + }); + const result = await store.selectList(table, { sub: "sub_000" }); + equal(result[0].expire, now + 1000); + equal(result[1].expire, now + 2000); + }); + }); + + describe("insertList edge cases", () => { + it("Should not mutate input rows", async () => { + store.default({ placeholder: "?" }); + const rows = [ + { sub: "sub_000", value: "a" }, + { sub: "sub_001", value: "b" }, + ]; + const rowsCopy = structuredClone(rows); + await store.insertList(table, rows); + deepStrictEqual(rows, rowsCopy); + }); + }); + + describe("updateList edge cases", () => { + it("Should return settled results from updateList", async () => { + store.default({ placeholder: "?" }); + await store.insertList(table, [ + { id: 1, sub: "sub_000", value: "a" }, + { id: 2, sub: "sub_000", value: "b" }, + ]); + const results = await store.updateList(table, [{ id: 1 }, { id: 2 }], { + value: "z", + }); + strictEqual(results.length, 2); + strictEqual(results[0].status, "fulfilled"); + strictEqual(results[1].status, "fulfilled"); + }); + }); + + describe("timeToLiveKey edge cases", () => { + it("Should skip timeToLiveKey when falsy", async () => { + store.default({ placeholder: "?", timeToLiveKey: "" }); + const expire = nowInSeconds() + 86400; + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "v", + expire, + }); + const result = await store.select(table, { id: 1 }); + strictEqual(result.remove, null); + store.default({ timeToLiveKey: "remove" }); + }); + }); + + describe("logging", () => { + it("Should work without logging enabled", async () => { + store.default({ placeholder: "?", log: false }); + await store.insert(table, { + id: 1, + sub: "sub_000", + value: "v", + }); + const ex = await store.exists(table, { id: 1 }); + strictEqual(ex, "sub_000"); + const cnt = await store.count(table, { id: 1 }); + strictEqual(cnt, 1); + const row = await store.select(table, { id: 1 }); + strictEqual(row.value, "v"); + const list = await store.selectList(table, { id: 1 }); + strictEqual(list.length, 1); + await store.update(table, { id: 1 }, { value: "w" }); + await store.updateList(table, [{ id: 1 }], { value: "x" }); + await store.remove(table, { id: 1 }); + store.default({ + log: (...args) => mocks.log(...args), + }); + }); + }); + }); + + describe("removeList", () => { + it("Should be the same function reference as remove", async () => { + strictEqual(store.removeList, store.remove); + }); + }); + + describe("table/sqlite.js", () => { + it("Should create emptyRow with null prototype", async () => { + const row = mockDatabaseTable.emptyRow(); + strictEqual(Object.getPrototypeOf(row), null); + }); + it("Should create emptyRow with correct default values", async () => { + const row = mockDatabaseTable.emptyRow(); + strictEqual(row.id, 0); + strictEqual(row.sub, null); + strictEqual(row.value, null); + strictEqual(row.digest, null); + strictEqual(row.otp, null); + strictEqual(row.create, null); + strictEqual(row.update, null); + strictEqual(row.verify, null); + strictEqual(row.lastused, null); + strictEqual(row.expire, null); + strictEqual(row.remove, null); + }); + it("Should create independent emptyRow instances", async () => { + const row1 = mockDatabaseTable.emptyRow(); + const row2 = mockDatabaseTable.emptyRow(); + row1.id = 99; + strictEqual(row2.id, 0); + }); + it("Should have exactly 11 keys on emptyRow", async () => { + const row = mockDatabaseTable.emptyRow(); + strictEqual(Object.keys(row).length, 11); + }); + it("Should export correct table name", async () => { + strictEqual(mockDatabaseTable.name, "test"); + }); + it("Should export correct timeToLiveKey", async () => { + strictEqual(mockDatabaseTable.timeToLiveKey, "remove"); + }); + it("Should create/truncate/drop table with explicit name", async () => { + const tmpTable = "test_table_ops"; + await mockDatabaseTable.create(mocks.storeClient, tmpTable); + await store.insert(tmpTable, { id: 1, sub: "s", value: "v" }); + const before = await store.count(tmpTable); + strictEqual(before, 1); + await mockDatabaseTable.truncate(mocks.storeClient, tmpTable); + const after = await store.count(tmpTable); + strictEqual(after, 0); + await mockDatabaseTable.drop(mocks.storeClient, tmpTable); + }); + it("Should create/truncate/drop table with default name", async () => { + await mockDatabaseTable.create(mocks.storeClient); + await store.insert(mockDatabaseTable.name, { + id: 1, + sub: "s", + value: "v", + }); + await mockDatabaseTable.truncate(mocks.storeClient); + const cnt = await store.count(mockDatabaseTable.name); + strictEqual(cnt, 0); + await mockDatabaseTable.drop(mocks.storeClient); + await mockDatabaseTable.create(mocks.storeClient); + }); + }); }); diff --git a/packages/store-sqlite/package.json b/packages/store-sqlite/package.json index 7c2f9d7..11067b3 100644 --- a/packages/store-sqlite/package.json +++ b/packages/store-sqlite/package.json @@ -1,7 +1,7 @@ { "name": "@1auth/store-sqlite", - "version": "0.0.0-beta.1", - "description": "", + "version": "0.0.0-beta.2", + "description": "SQLite storage implementation for lightweight embedded database persistence", "type": "module", "engines": { "node": ">=24" @@ -12,18 +12,18 @@ }, "main": "./index.js", "module": "./index.js", + "sideEffects": false, "exports": { ".": { - "import": { - "types": "./index.d.ts", - "default": "./index.js" - } + "import": "./index.js" + }, + "./table/*": { + "import": "./table/*" } }, - "types": "index.d.ts", "files": [ "index.js", - "index.d.ts" + "table" ], "scripts": { "test": "npm run test:unit", @@ -34,7 +34,13 @@ "type": "github", "url": "https://github.com/sponsors/willfarrell" }, - "keywords": [], + "keywords": [ + "1auth", + "OWASP", + "ASVS", + "SQLite", + "database" + ], "author": { "name": "1auth contributors", "url": "https://github.com/willfarrell/1auth/graphs/contributors" @@ -42,7 +48,7 @@ "repository": { "type": "git", "url": "git+https://github.com/willfarrell/1auth.git", - "directory": "packages/store-postgres" + "directory": "packages/store-sqlite" }, "bugs": { "url": "https://github.com/willfarrell/1auth/issues" diff --git a/packages/store-sqlite/table/sqlite.js b/packages/store-sqlite/table/sqlite.js index 85dee5f..cabb1c7 100644 --- a/packages/store-sqlite/table/sqlite.js +++ b/packages/store-sqlite/table/sqlite.js @@ -10,7 +10,12 @@ export const create = async (client, table = name) => { "sub" VARCHAR(15) NOT NULL, "value" VARCHAR(256) NOT NULL, "digest" VARCHAR(256) DEFAULT NULL, + "otp" INTEGER DEFAULT NULL, + "create" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "update" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "verify" TIMESTAMP WITH TIME ZONE DEFAULT NULL, + "lastused" TIMESTAMP WITH TIME ZONE DEFAULT NULL, "expire" TIMESTAMP WITH TIME ZONE DEFAULT NULL, "${timeToLiveKey}" TIMESTAMP WITH TIME ZONE DEFAULT NULL ) @@ -27,16 +32,22 @@ export const truncate = async (client, table = name) => { export const drop = async (client, table = name) => { const sql = ` - DROP TABLE ${table}; + DROP TABLE IF EXISTS ${table}; `; return await client.query(sql); }; -export const emptyRow = () => ({ - id: 0, - sub: null, - value: null, - digest: null, - expire: null, - remove: null, -}); +export const emptyRow = () => + Object.assign(Object.create(null), { + id: 0, + sub: null, + value: null, + digest: null, + otp: null, + create: null, + update: null, + verify: null, + lastused: null, + expire: null, + remove: null, + }); diff --git a/packages/store/index.test.js b/packages/store/index.test.js index 931d309..8925b2f 100644 --- a/packages/store/index.test.js +++ b/packages/store/index.test.js @@ -1,4 +1,4 @@ -import { deepEqual, equal, ok } from "node:assert"; +import { deepStrictEqual, ok, strictEqual } from "node:assert/strict"; import { describe, it, test } from "node:test"; const nowInSeconds = () => Math.floor(Date.now() / 1000); @@ -6,6 +6,11 @@ const nowInSeconds = () => Math.floor(Date.now() / 1000); const tests = (store, mocks) => { const table = mocks.table.name; const emptyRow = mocks.table.emptyRow; + // Build expected row matching the store's object prototype (e.g. null-prototype for SQLite) + const expectedRow = (...sources) => { + const proto = Object.getPrototypeOf(emptyRow()); + return Object.assign(Object.create(proto), ...sources); + }; test.before(async () => { await mocks.table.create(mocks.storeClient, table); @@ -29,79 +34,79 @@ const tests = (store, mocks) => { it("Should return undefined when nothing found", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; const result = await store.exists(table, { id: row.id, sub: row.sub }); - equal(result, undefined); - equal(mocks.log.mock.calls.length, 1); + strictEqual(result, undefined); + strictEqual(mocks.log.mock.calls.length, 1); }); it("Should return sub when something found {id, sub}", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; await store.insert(table, row); const result = await store.exists(table, { id: row.id, sub: row.sub }); - equal(result, row.sub); - equal(mocks.log.mock.calls.length, 2); + strictEqual(result, row.sub); + strictEqual(mocks.log.mock.calls.length, 2); }); it("Should return sub when something found {id}", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; await store.insert(table, row); const result = await store.exists(table, { id: row.id }); - equal(result, row.sub); - equal(mocks.log.mock.calls.length, 2); + strictEqual(result, row.sub); + strictEqual(mocks.log.mock.calls.length, 2); }); it("Should return sub when something found {sub}", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; await store.insert(table, row); const result = await store.exists(table, { sub: row.sub }); - equal(result, row.sub); - equal(mocks.log.mock.calls.length, 2); + strictEqual(result, row.sub); + strictEqual(mocks.log.mock.calls.length, 2); }); it("Should return sub when something found {sub, id:undefined}", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; await store.insert(table, row); const result = await store.exists(table, { sub: row.sub, id: undefined }); - equal(result, row.sub); - equal(mocks.log.mock.calls.length, 2); + strictEqual(result, row.sub); + strictEqual(mocks.log.mock.calls.length, 2); }); it("Should return sub when something found {digest}", async () => { const row = { id: 1, sub: "sub_000", value: "a", digest: "d" }; await store.insert(table, row); const result = await store.exists(table, { digest: row.digest }); - equal(result, row.sub); - equal(mocks.log.mock.calls.length, 2); + strictEqual(result, row.sub); + strictEqual(mocks.log.mock.calls.length, 2); }); }); describe("count", () => { it("Should return 0 when nothing found", async () => { const result = await store.count(table, { id: 1 }); - equal(result, 0); - equal(mocks.log.mock.calls.length, 1); + strictEqual(result, 0); + strictEqual(mocks.log.mock.calls.length, 1); }); it("Should return # when something found", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; await store.insert(table, row); const result = await store.count(table, { id: row.id }); - equal(result, 1); - equal(mocks.log.mock.calls.length, 2); + strictEqual(result, 1); + strictEqual(mocks.log.mock.calls.length, 2); }); }); describe("select", () => { it("Should return undefined when nothing found", async () => { const result = await store.select(table, { id: 1 }); - equal(result, undefined); - equal(mocks.log.mock.calls.length, 1); + strictEqual(result, undefined); + strictEqual(mocks.log.mock.calls.length, 1); }); it("Should return item when something found {id, sub}", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; await store.insert(table, row); const result = await store.exists(table, { id: row.id, sub: row.sub }); - equal(result, row.sub); - equal(mocks.log.mock.calls.length, 2); + strictEqual(result, row.sub); + strictEqual(mocks.log.mock.calls.length, 2); }); }); describe("insert/update", () => { it("Should return object when something found", async () => { const row = { id: 1, sub: "sub_000", value: "a" }; const id = await store.insert(table, row); - equal(id, row.id); - equal(mocks.log.mock.calls.length, 1); + strictEqual(id, row.id); + strictEqual(mocks.log.mock.calls.length, 1); row.value = "b"; await store.update( @@ -109,18 +114,18 @@ const tests = (store, mocks) => { { sub: "sub_000", id: row.id }, { value: row.value }, ); - equal(mocks.log.mock.calls.length, 2); + strictEqual(mocks.log.mock.calls.length, 2); // returns all fields let result = await store.select(table, { id: row.id }); - deepEqual(result, { ...emptyRow(), ...row }); - equal(mocks.log.mock.calls.length, 3); + deepStrictEqual(result, Object.assign(emptyRow(), row)); + strictEqual(mocks.log.mock.calls.length, 3); // returns fields result = await store.select(table, { sub: "sub_000", id: row.id }, [ "value", ]); - deepEqual(result, { value: row.value }); - equal(mocks.log.mock.calls.length, 4); + deepStrictEqual(result, expectedRow({ value: row.value })); + strictEqual(mocks.log.mock.calls.length, 4); }); it("Should return object with random id when something found", async () => { const row = { sub: "sub_000", value: "a" }; @@ -128,15 +133,15 @@ const tests = (store, mocks) => { ok(id); row.value = "b"; await store.update(table, { sub: "sub_000", id }, { value: row.value }); - equal(mocks.log.mock.calls.length, 2); + strictEqual(mocks.log.mock.calls.length, 2); // returns all fields let result = await store.select(table, { id }); - deepEqual(result, { ...emptyRow(), id, ...row }); - equal(mocks.log.mock.calls.length, 3); + deepStrictEqual(result, Object.assign(emptyRow(), { id }, row)); + strictEqual(mocks.log.mock.calls.length, 3); // returns fields result = await store.select(table, { sub: "sub_000", id }, ["value"]); - deepEqual(result, { value: row.value }); - equal(mocks.log.mock.calls.length, 4); + deepStrictEqual(result, expectedRow({ value: row.value })); + strictEqual(mocks.log.mock.calls.length, 4); }); it("Should add in `timeToLiveKey` when `expire` is inserted", async () => { const expire = nowInSeconds() + 86400; @@ -145,6 +150,12 @@ const tests = (store, mocks) => { const result = await store.select(table, { sub: "sub_000", id: row.id }); ok(expire < result[mocks.table.timeToLiveKey]); }); + it("Should not mutate the input values object on insert", async () => { + const row = { sub: "sub_000", value: "x" }; + const rowCopy = structuredClone(row); + await store.insert(table, row); + deepStrictEqual(row, rowCopy); + }); it("Should add in `timeToLiveKey` when `expire` is updated", async () => { const expire = nowInSeconds() + 86400; const row = { id: 1, sub: "sub_000", value: "a" }; @@ -157,8 +168,8 @@ const tests = (store, mocks) => { describe("selectList", () => { it("Should return [] when nothing found", async () => { const result = await store.selectList(table, { id: 1 }); - deepEqual(result, []); - equal(mocks.log.mock.calls.length, 1); + deepStrictEqual(result, []); + strictEqual(mocks.log.mock.calls.length, 1); }); it("Should return object[] when filtered by `id`", async () => { const rows = [ @@ -167,8 +178,23 @@ const tests = (store, mocks) => { ]; await store.insertList(table, rows); const result = await store.selectList(table, { id: rows[0].id }); - deepEqual(result, [{ ...emptyRow(), ...rows[0] }]); - equal(mocks.log.mock.calls.length, 2); + deepStrictEqual(result, [Object.assign(emptyRow(), rows[0])]); + strictEqual(mocks.log.mock.calls.length, 2); + }); + it("Should return only requested fields", async () => { + const rows = [ + { id: 1, sub: "sub_000", value: "a" }, + { id: 2, sub: "sub_000", value: "b" }, + ]; + await store.insertList(table, rows); + const result = await store.selectList(table, { sub: "sub_000" }, [ + "value", + ]); + strictEqual(result.length, 2); + for (const row of result) { + ok(row.value); + strictEqual(row.id, undefined); + } }); }); describe("insertList", () => { @@ -178,11 +204,11 @@ const tests = (store, mocks) => { { id: 2, sub: "sub_000", value: "b" }, ]; await store.insertList(table, rows); - equal(mocks.log.mock.calls.length, 1); + strictEqual(mocks.log.mock.calls.length, 1); const result = await store.selectList(table, { sub: "sub_000" }); - deepEqual( + deepStrictEqual( result, - rows.map((row) => ({ ...emptyRow(), ...row })), + rows.map((row) => Object.assign(emptyRow(), row)), ); }); it("Should add in `timeToLiveKey` when `expire` is inserted", async () => { @@ -205,8 +231,8 @@ const tests = (store, mocks) => { await store.insertList(table, rows); await store.remove(table, { sub: "sub_000", id: rows[0].id }); const result = await store.selectList(table, { sub: rows[0].sub }); - deepEqual(result, [{ ...emptyRow(), ...rows[1] }]); - equal(mocks.log.mock.calls.length, 3); + deepStrictEqual(result, [Object.assign(emptyRow(), rows[1])]); + strictEqual(mocks.log.mock.calls.length, 3); }); it("Should remove row in store using {id:'', sub:''}", async () => { const rows = [ @@ -216,11 +242,31 @@ const tests = (store, mocks) => { await store.insertList(table, rows); await store.remove(table, { sub: rows[0].sub, id: rows[0].id }); const result = await store.selectList(table, { sub: rows[0].sub }); - deepEqual(result, [{ ...emptyRow(), ...rows[1] }]); - equal(mocks.log.mock.calls.length, 3); + deepStrictEqual(result, [Object.assign(emptyRow(), rows[1])]); + strictEqual(mocks.log.mock.calls.length, 3); }); }); - describe("remove", () => { + describe("updateList", () => { + it("Should update multiple rows in store", async () => { + const rows = [ + { id: 1, sub: "sub_000", value: "a" }, + { id: 2, sub: "sub_000", value: "b" }, + ]; + await store.insertList(table, rows); + await store.updateList( + table, + [ + { sub: "sub_000", id: rows[0].id }, + { sub: "sub_000", id: rows[1].id }, + ], + { value: "z" }, + ); + const result = await store.selectList(table, { sub: "sub_000" }); + strictEqual(result[0].value, "z"); + strictEqual(result[1].value, "z"); + }); + }); + describe("removeList", () => { it("Should remove rows in store using {id:[], sub:''}", async () => { const rows = [ { id: 1, sub: "sub_000", value: "a" }, @@ -233,8 +279,8 @@ const tests = (store, mocks) => { id: [rows[0].id, rows[1].id], }); const result = await store.selectList(table, { sub: rows[0].sub }); - equal(mocks.log.mock.calls.length, 3); - deepEqual(result, [{ ...emptyRow(), ...rows[2] }]); + strictEqual(mocks.log.mock.calls.length, 3); + deepStrictEqual(result, [Object.assign(emptyRow(), rows[2])]); }); }); }; diff --git a/websites/1auth.js.org/.gitignore b/websites/1auth.js.org/.gitignore new file mode 100644 index 0000000..573dde9 --- /dev/null +++ b/websites/1auth.js.org/.gitignore @@ -0,0 +1,25 @@ +test-results +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +.svelte-kit +build +src/styles/app.css + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/websites/1auth.js.org/package.json b/websites/1auth.js.org/package.json new file mode 100644 index 0000000..5403df7 --- /dev/null +++ b/websites/1auth.js.org/package.json @@ -0,0 +1,45 @@ +{ + "name": "1auth.js.org", + "description": "SvelteKit SSR", + "private": true, + "version": "0.0.0-beta.2", + "type": "module", + "scripts": { + "start": "vite dev", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "build": "npm run build:svelte && npm run build:styles:extract && npm run build:styles:optimize && npm run build:svg", + "build:svelte": "vite build", + "build:styles:extract": "ds extract --input-dir ./.svelte-kit --theme ./src/styles/theme.css --output-dir src/styles/", + "build:styles:optimize": "ds optimize-styles ./.svelte-kit", + "build:svg": "npx svgo --multipass --recursive ./.svelte-kit/ -o ./.svelte-kit/", + "release:login": "wrangler login --browser false", + "release:deploy": "wrangler pages deploy" + }, + "dependencies": { + "@willfarrell-ds/svelte": "0.0.0-alpha.4", + "@willfarrell-ds/vanilla": "0.0.0-alpha.4", + "hast-util-to-string": "3.0.1", + "mdast-util-to-string": "4.0.0" + }, + "devDependencies": { + "@sveltejs/adapter-cloudflare": "^7.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^6.0.0", + "@willfarrell-ds/cli": "0.0.0-alpha.4", + "esbuild": "^0.27.0", + "mdsvex": "^0.12.0", + "svelte": "^5.0.0", + "svgo": "^4.0.0", + "vite": "^7.0.0", + "vite-plugin-mkcert": "^1.0.0", + "vite-plugin-sitemap": "^0.8.0", + "vite-plugin-sri": "^0.0.2", + "wrangler": "^4.0.0" + }, + "overrides": { + "@sveltejs/kit": { + "cookie": "0.7.2" + } + } +} diff --git a/websites/1auth.js.org/src/app.html b/websites/1auth.js.org/src/app.html new file mode 100644 index 0000000..962e1fb --- /dev/null +++ b/websites/1auth.js.org/src/app.html @@ -0,0 +1,20 @@ + + + + + + %sveltekit.head% + + + + + + + + + + + + %sveltekit.body% + + diff --git a/websites/1auth.js.org/src/components/BodyFooter.svelte b/websites/1auth.js.org/src/components/BodyFooter.svelte new file mode 100644 index 0000000..f6ce489 --- /dev/null +++ b/websites/1auth.js.org/src/components/BodyFooter.svelte @@ -0,0 +1,39 @@ + + + + {#snippet logo()} + + 1auth logo, to the homepage + + {/snippet} + diff --git a/websites/1auth.js.org/src/components/BodyHeader.svelte b/websites/1auth.js.org/src/components/BodyHeader.svelte new file mode 100644 index 0000000..990d927 --- /dev/null +++ b/websites/1auth.js.org/src/components/BodyHeader.svelte @@ -0,0 +1,58 @@ + + + + + + + + {#snippet start()} + + 1auth logo, to the homepage + + {/snippet} + {#snippet end()} + +
+
+ + +
+
+ {/snippet} +
diff --git a/websites/1auth.js.org/src/components/BodyMain.svelte b/websites/1auth.js.org/src/components/BodyMain.svelte new file mode 100644 index 0000000..50904ca --- /dev/null +++ b/websites/1auth.js.org/src/components/BodyMain.svelte @@ -0,0 +1,9 @@ + + + + {@render children?.()} + diff --git a/websites/1auth.js.org/src/components/docs/AsideNav.svelte b/websites/1auth.js.org/src/components/docs/AsideNav.svelte new file mode 100644 index 0000000..70e84eb --- /dev/null +++ b/websites/1auth.js.org/src/components/docs/AsideNav.svelte @@ -0,0 +1,50 @@ + + + diff --git a/websites/1auth.js.org/src/components/docs/mdsvex-layout.svelte b/websites/1auth.js.org/src/components/docs/mdsvex-layout.svelte new file mode 100644 index 0000000..909e24d --- /dev/null +++ b/websites/1auth.js.org/src/components/docs/mdsvex-layout.svelte @@ -0,0 +1,47 @@ + + + {title} | 1auth + {#if description}{/if} + + + {#snippet aside()} + + {/snippet} + + {#snippet header()} +
+

{title}

+
+ {/snippet} + {#snippet aside()} + +
+

On this page

+
    + {#if headings.length > 0} + {#each headings as heading} +
  1. {heading.text}
  2. + {/each} + {/if} +
+
+
+ {/snippet} + {@render children?.()} +
+
diff --git a/websites/1auth.js.org/src/error.html b/websites/1auth.js.org/src/error.html new file mode 100644 index 0000000..962e1fb --- /dev/null +++ b/websites/1auth.js.org/src/error.html @@ -0,0 +1,20 @@ + + + + + + %sveltekit.head% + + + + + + + + + + + + %sveltekit.body% + + diff --git a/websites/1auth.js.org/src/hooks.js b/websites/1auth.js.org/src/hooks.js new file mode 100644 index 0000000..f620c68 --- /dev/null +++ b/websites/1auth.js.org/src/hooks.js @@ -0,0 +1,7 @@ +// Used for passing scan results to SSR +export const transport = { + Error: { + encode: (value) => value instanceof Error && value.message, + decode: (message) => new Error(message), + }, +}; diff --git a/websites/1auth.js.org/src/hooks.server.js b/websites/1auth.js.org/src/hooks.server.js new file mode 100644 index 0000000..c60d49d --- /dev/null +++ b/websites/1auth.js.org/src/hooks.server.js @@ -0,0 +1,16 @@ +import applyCacheControlMiddleware from "@design-system/hooks/applyCacheControlMiddleware.js"; +import removeCommentsMiddleware from "@design-system/hooks/removeCommentsMiddleware.js"; +import removeDuplicateImportMiddleware from "@design-system/hooks/removeDuplicateImportMiddleware.js"; +import removeOnEventsMiddleware from "@design-system/hooks/removeOnEventsMiddleware.js"; +import tardisecMiddleware from "@hooks/tardisecMiddleware.js"; +import { sequence } from "@sveltejs/kit/hooks"; + +export { handleError } from "@hooks/handleError.js"; + +export const handle = sequence( + applyCacheControlMiddleware, + tardisecMiddleware, + removeCommentsMiddleware, + removeOnEventsMiddleware, + removeDuplicateImportMiddleware, +); diff --git a/websites/1auth.js.org/src/hooks/handleError.js b/websites/1auth.js.org/src/hooks/handleError.js new file mode 100644 index 0000000..efe5f48 --- /dev/null +++ b/websites/1auth.js.org/src/hooks/handleError.js @@ -0,0 +1,17 @@ +//import { stderr } from "node:process"; // CloudFlare doesn't support +// import { NIL as uuidNil } from "uuid"; + +const uuidNil = "00000000-0000-0000-0000-000000000000"; +export async function handleError({ error, event }) { + console.error( + `${JSON.stringify({ + log_level: "ERROR", + message: error.message, + stack: error.stack, + cause: error.cause, + status_code: error.statusCode ?? null, + request_id: uuidNil, + event, // TODO need to remove sensitive data before logging (ip, user agent, ) + })}\n`, + ); +} diff --git a/websites/1auth.js.org/src/hooks/tardisecMiddleware.js b/websites/1auth.js.org/src/hooks/tardisecMiddleware.js new file mode 100644 index 0000000..fb0ae02 --- /dev/null +++ b/websites/1auth.js.org/src/hooks/tardisecMiddleware.js @@ -0,0 +1,26 @@ +// TODO convert into adapter +// import * as env from '$env/static/private'; +// import { redirect } from "@utils/sveltekit.js"; +//import { recommendHttpHeader } from "@utils/recommend.js"; +import tardisec from "../../tardisec.json" with { type: "json" }; + +const tardisecMiddleware = async ({ event, resolve }) => { + // const { url, params, cookies } = event; + + const response = await resolve(event); + + const keys = Object.keys(tardisec.raw); + for (let i = keys.length; i--; ) { + const headerKey = keys[i]; + const headerValue = tardisec.raw[headerKey]; + if (headerValue && !response.headers.has(headerKey)) { + response.headers.set(headerKey, headerValue); + } + } + + response.headers.delete("X-Sveltekit-Page"); + + return response; +}; + +export default tardisecMiddleware; diff --git a/websites/1auth.js.org/src/lib/rehype-add-heading-ids.js b/websites/1auth.js.org/src/lib/rehype-add-heading-ids.js new file mode 100644 index 0000000..e49306a --- /dev/null +++ b/websites/1auth.js.org/src/lib/rehype-add-heading-ids.js @@ -0,0 +1,27 @@ +import { toString as nodetoString } from "hast-util-to-string"; +import visit from "unist-util-visit"; + +/** + * Rehype plugin to add IDs to H2 headings + */ +export function rehypeAddHeadingIds() { + return (tree) => { + visit(tree, "element", (node) => { + // Only process H2 elements + if (node.tagName === "h2") { + const text = nodetoString(node); + // Create slug from heading text + const id = text + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/^-|-$/g, ""); + + // Add id to properties + if (!node.properties) { + node.properties = {}; + } + node.properties.id = id; + } + }); + }; +} diff --git a/websites/1auth.js.org/src/lib/remark-extract-headings.js b/websites/1auth.js.org/src/lib/remark-extract-headings.js new file mode 100644 index 0000000..ac23864 --- /dev/null +++ b/websites/1auth.js.org/src/lib/remark-extract-headings.js @@ -0,0 +1,31 @@ +import { toString as nodetoString } from "mdast-util-to-string"; +import visit from "unist-util-visit"; + +/** + * Remark plugin to extract H2 headings and add them to frontmatter + */ +export function remarkExtractHeadings() { + return (tree, file) => { + const headings = []; + + visit(tree, "heading", (node) => { + // Only extract H2 headings + if (node.depth === 2) { + const text = nodetoString(node); + // Create slug from heading text + const id = text + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/^-|-$/g, ""); + + headings.push({ id, text }); + } + }); + + // Add headings to frontmatter + if (!file.data.fm) { + file.data.fm = {}; + } + file.data.fm.headings = headings; + }; +} diff --git a/websites/1auth.js.org/src/routes/+error.svelte b/websites/1auth.js.org/src/routes/+error.svelte new file mode 100644 index 0000000..e23a41e --- /dev/null +++ b/websites/1auth.js.org/src/routes/+error.svelte @@ -0,0 +1,50 @@ + + + + {page.status} | 1auth + + +
+
+

{page.status}

+ {#if page.status === 500} +

+ {import.meta.env.AWS_REQUEST_ID ?? + "00000000-0000-0000-0000-000000000000"} +

+ {/if} +
+
+ + diff --git a/websites/1auth.js.org/src/routes/+layout.server.js b/websites/1auth.js.org/src/routes/+layout.server.js new file mode 100644 index 0000000..4f31814 --- /dev/null +++ b/websites/1auth.js.org/src/routes/+layout.server.js @@ -0,0 +1,11 @@ +import pkg from "../../package.json" with { type: "json" }; + +export const prerender = false; +export const ssr = true; +export const csr = false; + +export async function load() { + return { + version: pkg.version, + }; +} diff --git a/websites/1auth.js.org/src/routes/+layout.svelte b/websites/1auth.js.org/src/routes/+layout.svelte new file mode 100644 index 0000000..0ac3c65 --- /dev/null +++ b/websites/1auth.js.org/src/routes/+layout.svelte @@ -0,0 +1,21 @@ + + + + + + + + + +{@render children?.()} + diff --git a/websites/1auth.js.org/src/routes/+page.svelte b/websites/1auth.js.org/src/routes/+page.svelte new file mode 100644 index 0000000..fc180e8 --- /dev/null +++ b/websites/1auth.js.org/src/routes/+page.svelte @@ -0,0 +1,187 @@ + + + + 1auth + + + +
+
+ 1auth logo +

Secure authentication & session management for Node.js

+ +

ORM-like modules for accounts, authentication, messengers, and + sessions. Consistent APIs with encryption by default and + industry-standard cryptographic algorithms.

+ +

Project highlights

+
    +
  • +

    + OWASP

    +

    ASVS v5.0 Level 3

    +
  • +
  • +

    + 96%

    +

    Code coverage

    +
  • +
  • +

    + SLSA 3

    +

    Supply chain security

    +
  • +
+
+
+
+
+

Everything you need for secure auth

+
+
    +
  • +

    Secure by default

    +

    ChaCha20-Poly1305 encryption, Argon2id password hashing, + HMAC-signed sessions, and timing-safe authentication out of + the box.

    +
  • +
  • +

    Consistent APIs

    +

    ORM-like interface for accounts, credentials, messengers, + and sessions. Encryption and decryption applied + transparently.

    +
  • +
  • +

    Multi-factor auth

    +

    WebAuthn/FIDO2, recovery codes, and access tokens. Pluggable + credential types with a unified authentication flow.

    +
  • +
  • +

    Multiple backends

    +

    DynamoDB, PostgreSQL, SQLite, and Cloudflare D1. Swap storage + backends without changing your application code.

    +
  • +
  • +

    Per-record encryption

    +

    Every sensitive field is encrypted before storage with + per-user derived keys. Digests are used for lookups instead + of plaintext.

    +
  • +
  • +

    Battle-tested security

    +

    SAST, DAST, SCA, fuzzing, and performance benchmarks run on + every commit. OpenSSF Scorecard and SLSA 3 compliant.

    +
  • +
+
+
+
+

Core packages

+

Modular packages that work together or standalone.

+
+
    + +

    account

    +

    User account management with encrypted storage.

    +
    + +

    authn

    +

    Core authentication with multi-factor support.

    +
    + +

    session

    +

    HMAC-signed session management.

    +
    + +

    messenger

    +

    Messaging framework for email verification.

    +
    + +

    crypto

    +

    Cryptographic utilities for encryption and hashing.

    +
    + +

    store

    +

    Pluggable storage backends for persistence.

    +
    +
+
+
+
+

Ready to get started?

+ Install 1auth and start building secure authentication today. +

+ Read the docs + + +
+
+
+ +
+
diff --git a/websites/1auth.js.org/src/routes/docs/+layout.css b/websites/1auth.js.org/src/routes/docs/+layout.css new file mode 100644 index 0000000..3d16ab7 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/+layout.css @@ -0,0 +1,97 @@ +code { + --hex-neutral: #000000; + --hex-red: #c52f21; + --hex-cerise-red: #d81b60; + --hex-cinnabar: #e53935; + --hex-pomegranate: #f4511e; + --hex-pizazz: #fb8c00; + --hex-selective-yellow: #ffb300; + --hex-bright-yellow: #fdd835; + --hex-key-lime-pie: #c0ca33; + --hex-sushi: #7cb342; + --hex-apple: #43a047; + --hex-elf-green: #00897b; + --hex-pelorous: #00acc1; + --hex-curious-blue: #039be5; + --hex-cornflower-blue: #1e88e5; + --hex-cobalt: #3949ab; + --hex-daisy-bush: #5e35b1; + --hex-violet-eggplant: #8e24aa; + + --lightness-code: var(--lightness-main-bold); + + --code-comment: light-dark( + oklch(from #000 0.6 c h), + oklch(from #000 0.5 c h) + ); + --code-punctuation: oklch(from var(--hex-neutral) var(--lightness-code) c h); + --code-deleted: oklch(from var(--hex-red) var(--lightness-code) c h); + --code-inserted: oklch( + from var(--hex-key-lime-pie) var(--lightness-code) c h + ); + --code-operator: oklch(from var(--hex-cobalt) var(--lightness-code) c h); + --code-keyword: oklch(from var(--hex-pelorous) var(--lightness-code) c h); + --code-function: oklch(from var(--hex-cinnabar) var(--lightness-code) c h); + --code-variable: oklch(from var(--hex-pizazz) var(--lightness-code) c h); + + /* prismjs */ + .comment, + .prolog, + .doctype, + .cdata { + color: var(--code-comment, --color-text); + } + .punctuation { + color: var(--code-punctuation, --color-text); + } + .namespace { + opacity: 0.7; + } + .property, + .tag, + .boolean, + .number, + .constant, + .symbol, + .deleted { + color: var(--code-deleted, --color-del, --color-text); + } + .selector, + .attr-name, + .string, + .char, + .builtin, + .inserted { + color: var(--code-inserted, --color-ins, --color-text); + } + .operator, + .entity, + .url, + .style .string { + color: var(--code-operator, --color-text); + background: hsla(0, 0, 100%, 0.5); + } + .atrule, + .attr-value, + .keyword { + color: var(--code-keyword, --color-text); + } + .function { + color: var(--code-function, --color-text); + } + .regex, + .important, + .variable { + color: var(--code-variable, --color-text); + } + .important, + .bold { + font-weight: bold; + } + .italic { + font-style: italic; + } + .entity { + cursor: help; + } +} diff --git a/websites/1auth.js.org/src/routes/docs/+layout.svelte b/websites/1auth.js.org/src/routes/docs/+layout.svelte new file mode 100644 index 0000000..617b774 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/+layout.svelte @@ -0,0 +1,10 @@ + + +{@render children?.()} + + diff --git a/websites/1auth.js.org/src/routes/docs/+page.md b/websites/1auth.js.org/src/routes/docs/+page.md new file mode 100644 index 0000000..2a68c51 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/+page.md @@ -0,0 +1,28 @@ +--- +title: Introduction +description: Secure authentication and session management modules for Node.js with encryption by default and consistent APIs. +slug: / +--- + +## What is 1auth + +1auth is a collection of modules to assist in **user authentication** and **session management** for **Node.js** applications. + +It works like an ORM for `accounts`, `authentications`, `messengers`, and `sessions` — providing a consistent API while ensuring that encoding, decoding, encryption, and decryption are applied transparently. All while enforcing industry defaults for cryptographic algorithms with an easy method to keep them up to date. + +## Key features + +- **Secure by default** — ChaCha20-Poly1305 encryption, Argon2id password hashing, HMAC-signed sessions +- **Consistent API** — All modules follow the same initialization and CRUD patterns +- **Per-record encryption** — Every sensitive field is encrypted before storage with per-user derived keys +- **Multi-factor authentication** — WebAuthn/FIDO2, recovery codes, and access tokens +- **Multiple storage backends** — DynamoDB, PostgreSQL, SQLite, Cloudflare D1 +- **Security-first** — OWASP ASVS v5.0 Level 3 compliance, OpenSSF Scorecard, SLSA 3 + +## Security standards + +1auth aims to meet [OWASP ASVS v5.0 Level 3](https://github.com/OWASP/ASVS/tree/master/5.0/en) using automated scans (Linting, Unit tests, SAST, SCA, DAST, Perf) and manual self-audits. + +## License + +Licensed under [MIT License](https://github.com/willfarrell/1auth/blob/main/LICENSE). diff --git a/websites/1auth.js.org/src/routes/docs/intro/architecture/+page.md b/websites/1auth.js.org/src/routes/docs/intro/architecture/+page.md new file mode 100644 index 0000000..a6c26b1 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/intro/architecture/+page.md @@ -0,0 +1,66 @@ +--- +title: Architecture +description: Overview of 1auth's modular architecture, package responsibilities, and how components communicate through shared interfaces. +--- + +## Overview + +1auth is designed as a modular system where each package handles a specific concern. Packages communicate through a shared `store` and `notify` interface, while `@1auth/crypto` provides the cryptographic primitives used throughout. + +![Architecture diagram](/img/architecture.png) + +## Module layers + +### Crypto layer + +`@1auth/crypto` is the foundation. It must be initialized before any other module. It provides: + +- Symmetric encryption (ChaCha20-Poly1305 / AES-256-GCM) +- Password hashing (Argon2id) +- HMAC signing +- Digest computation +- Random ID generation + +### Storage layer + +Store modules implement a common interface for database operations: + +- `@1auth/store-dynamodb` — AWS DynamoDB +- `@1auth/store-postgres` — PostgreSQL +- `@1auth/store-sqlite` — SQLite +- `@1auth/store-d1` — Cloudflare D1 + +All stores provide: `exists`, `count`, `select`, `selectList`, `insert`, `update`, `remove` + +### Notification layer + +- `@1auth/notify` — Base notification interface +- `@1auth/notify-sqs` — AWS SQS implementation + +Notifications are decoupled from business logic. Events like "verification token created" are sent to a queue for processing by a separate service. + +### Application layer + +- `@1auth/account` — User account CRUD with encrypted storage +- `@1auth/account-username` — Username validation and lookup +- `@1auth/authn` — Core authentication framework +- `@1auth/authn-webauthn` — WebAuthn/FIDO2 credential support +- `@1auth/authn-recovery-codes` — Backup recovery codes +- `@1auth/authn-access-token` — API access tokens (PATs) +- `@1auth/messenger` — Messaging framework for contact verification +- `@1auth/messenger-email-address` — Email address verification +- `@1auth/session` — Session creation, signing, and management + +## Data flow + +1. **User input** enters through the application layer +2. **Authentication** validates credentials using timing-safe comparisons +3. **Encryption** is applied transparently before storage +4. **Storage** persists encrypted data to the configured backend +5. **Notifications** are sent asynchronously through SQS or similar + +## Trust boundaries + +- **Client to Application Server** — All user inputs validated at entry +- **Application Server to Database** — Sensitive fields encrypted before storage; digests used for lookups +- **Application Server to Notification Service** — Tokens sent through notification channels, never returned in API responses diff --git a/websites/1auth.js.org/src/routes/docs/intro/contributing/+page.md b/websites/1auth.js.org/src/routes/docs/intro/contributing/+page.md new file mode 100644 index 0000000..78e8301 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/intro/contributing/+page.md @@ -0,0 +1,77 @@ +--- +title: Contributing +description: How to contribute to 1auth, including development setup, coding standards, and pull request guidelines. +--- + +In the spirit of Open Source Software, everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls). + +Before contributing, make sure to have a look at our [Code of Conduct](https://github.com/willfarrell/1auth/blob/main/docs/CODE_OF_CONDUCT.md). + +## Fork + +Ensure git history is pulled from the `develop` branch. + +## Setup + +```bash +npm i -g nmq +npm i -g lockfile-lint +npm i -g @sandworm/audit +brew install semgrep +brew install trufflehog +``` + +## Implementation + +When necessary ensure changes follow secure design principles. See the [Threat Model](/docs/security/threat-model) for details. + +## Testing + +```bash +npm test +``` + +Ensure tests are updated and pass. All tests are automatically enforced using GitHub Actions on Pull-Requests. + +### Formatting / Linting + +We use `biome` with recommended configurations plus a few correctness additions. + +### Unit tests + +We use `node --test` with a minimum test coverage of: + +- lines: >=90% +- branches: >=80% +- functions: >=90% + +Bug fixes should always start with a failing unit test. +New features should have acceptance and rejection tests. + +### SAST + +We use `CodeQL` & `semgrep` to ensure code is written in a secure way. + +### SCA + +We use `DependaBot` & `sandworm` to ensure dependencies are free of known vulnerabilities. + +### DAST + +We use `fast-check` to run fuzzing on user inputs. It is expected that user inputs are pre-validated and/or sanitized before reaching package inputs. + +### Performance benchmarks + +We use `tinybench` to ensure there are no performance regressions. + +## Committing + +Ensure git commits meet the following FLOSS Best Practices: + +- Message follows [Conventional Commits](https://www.conventionalcommits.org/) pattern. Enforced using `@commitlint/cli`. +- Message includes sign off for [Developer Certificate of Origin (DCO)](https://developercertificate.org/) compliance. Enforced via GitHub Actions. +- Commit is cryptographically signed and can be verified. + +## Pull Request + +Submit a PR to the `develop` branch. Keep PR in draft mode until all automated tests pass. At least 2 maintainers will review the PR. diff --git a/websites/1auth.js.org/src/routes/docs/intro/generate-secrets/+page.md b/websites/1auth.js.org/src/routes/docs/intro/generate-secrets/+page.md new file mode 100644 index 0000000..1ef44fd --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/intro/generate-secrets/+page.md @@ -0,0 +1,58 @@ +--- +title: Generate Secrets +description: Generate the cryptographic secrets required to configure 1auth. +--- + +## Generate secrets + +1auth requires four cryptographic secrets for encryption, signing, and digest operations. Use the following script to generate them: + +```javascript +import { + randomChecksumPepper, + randomChecksumSalt, + symmetricRandomEncryptionKey, + symmetricRandomSignatureSecret, +} from "@1auth/crypto"; + +const secrets = { + symmetricEncryptionKey: symmetricRandomEncryptionKey().toString("base64"), + symmetricSignatureSecret: symmetricRandomSignatureSecret().toString("base64"), + digestChecksumSalt: randomChecksumSalt().toString("base64"), + digestChecksumPepper: randomChecksumPepper().toString("base64"), +}; +console.log(secrets); +``` + +## Run + +```bash +node -e " +import { + randomChecksumPepper, + randomChecksumSalt, + symmetricRandomEncryptionKey, + symmetricRandomSignatureSecret, +} from '@1auth/crypto'; + +console.log({ + symmetricEncryptionKey: symmetricRandomEncryptionKey().toString('base64'), + symmetricSignatureSecret: symmetricRandomSignatureSecret().toString('base64'), + digestChecksumSalt: randomChecksumSalt().toString('base64'), + digestChecksumPepper: randomChecksumPepper().toString('base64'), +}); +" +``` + +## Usage + +Store the generated values as environment variables: + +| Variable | Secret | +|----------|--------| +| `SYMMETRIC_ENCRYPTION_KEY` | `symmetricEncryptionKey` | +| `SYMMETRIC_SIGNATURE_SECRET` | `symmetricSignatureSecret` | +| `DIGEST_CHECKSUM_SALT` | `digestChecksumSalt` | +| `DIGEST_CHECKSUM_PEPPER` | `digestChecksumPepper` | + +These are passed to `@1auth/crypto` during initialization. See [Quick Start](/docs/intro/quick-start) for the full setup example. diff --git a/websites/1auth.js.org/src/routes/docs/intro/quick-start/+page.md b/websites/1auth.js.org/src/routes/docs/intro/quick-start/+page.md new file mode 100644 index 0000000..739d36d --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/intro/quick-start/+page.md @@ -0,0 +1,112 @@ +--- +title: Quick Start +description: Install and configure 1auth packages to add secure authentication to your Node.js application. +--- + +## Install + +```bash +npm i @1auth/store-dynamodb @1auth/notify-sqs @1auth/crypto @1auth/account-username @1auth/account @1auth/messenger @1auth/messenger-email-address @1auth/authn @1auth/authn-webauthn @1auth/authn-recovery-codes @1auth/authn-access-token @1auth/session +``` + +## Example + +```javascript +import * as store from '@1auth/store-dynamodb' +import * as notify from '@1auth/notify-sqs' +import crypto from '@1auth/crypto' + +import account from '@1auth/account' +import accountUsername, { + exists as usernameExists +} from '@1auth/account-username' + +import messenger from '@1auth/messenger' +import messengerEmailAddress from '@1auth/messenger-email-address' + +import authn from '@1auth/authn' +import webauthn from '@1auth/authn-webauthn' +import recoveryCodes from '@1auth/authn-recovery-codes' +import accessToken from '@1auth/authn-access-token' + +import session from '@1auth/session' + +// 12h chosen based on OWASP ASVS +const sessionExpire = 12 * 60 * 60 +// 10d chosen based on EFF DNT Policy +const ttlExpire = 10 * 24 * 60 * 60 + +store.default({ + timeToLiveExpireOffset: ttlExpire - sessionExpire +}) +notify.default({ + queueName: process.env.QUEUE_NAME ?? 'notify-queue' +}) + +// Passed in via ENV for example only +crypto({ + symmetricEncryptionKey: process.env.SYMMETRIC_ENCRYPTION_KEY ?? '', + symmetricSignatureSecret: process.env.SYMMETRIC_SIGNATURE_SECRET ?? '', + digestChecksumSalt: process.env.DIGEST_CHECKSUM_SALT ?? '', + digestChecksumPepper: process.env.DIGEST_CHECKSUM_PEPPER ?? '' +}) + +account({ + store, + notify, + encryptedFields: ['value','name', 'locale'] +}) +accountUsername({ + usernameBlacklist: ['root', 'admin', 'sa'] +}) + +messenger({ + store, + notify, + encryptedFields: ['value'] +}) +messengerEmailAddress() + +authn({ + store, + notify, + usernameExists: [usernameExists], + encryptedFields: ['value', 'name'] +}) +webauthn({ + origin: process.env.ORIGIN, + name: 'Organization Name', + userVerification: 'preferred' +}) +recoveryCodes() +accessToken() + +session({ + store, + notify, + expire: sessionExpire +}) +``` + +## Initialization pattern + +Every 1auth module follows the same pattern: + +1. Import the module's default export (configuration function) +2. Call it with an options object containing `store`, `notify`, and module-specific settings +3. Use the returned functions for CRUD operations + +All modules require `@1auth/crypto` to be initialized first, as it provides the encryption primitives used throughout. + +## Environment variables + +The following environment variables are typically needed: + +| Variable | Description | +|----------|-------------| +| `SYMMETRIC_ENCRYPTION_KEY` | Key for ChaCha20-Poly1305 encryption | +| `SYMMETRIC_SIGNATURE_SECRET` | Secret for HMAC signing | +| `DIGEST_CHECKSUM_SALT` | Salt for digest computation | +| `DIGEST_CHECKSUM_PEPPER` | Pepper for additional digest security | +| `ORIGIN` | Application origin for WebAuthn | +| `QUEUE_NAME` | SQS queue name for notifications | diff --git a/websites/1auth.js.org/src/routes/docs/intro/roadmap/+page.md b/websites/1auth.js.org/src/routes/docs/intro/roadmap/+page.md new file mode 100644 index 0000000..6db0dfc --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/intro/roadmap/+page.md @@ -0,0 +1,49 @@ +--- +title: Roadmap +description: Planned features, improvements, and upcoming milestones for 1auth. +--- + +## Documentation + +- Add options, inputs, outputs for each package +- Threat modelling +- Document item count enforcement +- Document DB permissions for stores +- Document SQS permissions for notify +- Document how to update `lastused` on accounts after login + +## Features + +- `authn-recovery-code` +- Update sqlite — move mock logic into lib +- Add dedicated stores: + - `store-rdsdataapi` + - `store-cloudfront-kv` + - `store-cloudflare-kv` + - `store-redis` +- DynamoDB update count to use `Scan({Select})` +- `session-cookie` — move sign/verify from `session` +- `session-peseto` — access-token exchange for PESETO token (single use, 15min expire) +- Add option to replace secret after config change (applies to `authn-access-token`) +- Add support for Secure Remote Password (SRP) protocol into `crypto` + +## Testing + +- Session fuzz `{values}` needs key enforcement +- Fix DynamoDB tests on all packages +- Fix `npm test` race condition with `store-postgres` +- Fix `npm test` race condition with `store-dynamodb` +- Improve unit tests 96% to 100% +- Add more perf tests (crypto) +- Demo + DAST (ZAP) + +## Planned updates + +- Node.js support for Argon2id (2025-04+) +- ASVS v5.0 (2025-05+) +- Update to support quantum-safe algorithms (ML-KEM-1024, ML-DSA-87, SLH-DSA-SHA2-256) + +## Schedule + +Repository will be reviewed annually after each Node.js major LTS release. Deprecate support for old Node.js versions. +Security review should be conducted for every major version release, or every 5 years, whichever comes first. diff --git a/websites/1auth.js.org/src/routes/docs/intro/upgrade/+page.md b/websites/1auth.js.org/src/routes/docs/intro/upgrade/+page.md new file mode 100644 index 0000000..1207e77 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/intro/upgrade/+page.md @@ -0,0 +1,8 @@ +--- +title: Upgrade Guide +description: Migration guide for upgrading between 1auth major versions with breaking changes and required steps. +--- + +## v0.0.0 => v1.0.0 + +Details about breaking changes and details on how to migrate will be documented here when v1.0.0 is released. diff --git a/websites/1auth.js.org/src/routes/docs/packages/account-username/+page.md b/websites/1auth.js.org/src/routes/docs/packages/account-username/+page.md new file mode 100644 index 0000000..f5d68f8 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/account-username/+page.md @@ -0,0 +1,83 @@ +--- +title: "@1auth/account-username" +description: Username validation, sanitization, and account lookup by username. +--- + +Username validation, sanitization, and account lookup by username. + +## Install + +```bash +npm i @1auth/account-username +``` + +## Usage + +```javascript +import accountUsername, { + exists as usernameExists +} from '@1auth/account-username' + +accountUsername({ + usernameBlacklist: ['root', 'admin', 'sa'] +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `minLength` | `number` | `1` | Minimum username length | +| `maxLength` | `number` | `32` | Maximum username length | +| `allowedCharRegExp` | `RegExp` | — | Allowed characters pattern | +| `usernameBlacklist` | `string[]` | `[]` | Blocked usernames | + +## API + +### `exists(username)` + +Check if a username is already taken. + +**Returns:** `boolean` + +### `lookup(username)` + +Find an account by username. Sanitizes and digests the input before lookup. + +**Returns:** Account object or `undefined` + +### `create(sub, username)` + +Create a username for an account. + +### `update(sub, username)` + +Update an account's username. + +### `recover(sub)` + +Trigger a username recovery notification. + +### `sanitize(value)` + +Normalize a username: lowercase, trim whitespace, remove diacritics. + +**Returns:** Sanitized string + +### `validate(value)` + +Validate a username against all rules (length, characters, blacklist). + +**Returns:** `boolean` + +### `validateLength(value)` + +Check username length constraints. + +### `validateAllowedChar(value)` + +Check username contains only allowed characters. + +### `validateBlacklist(value)` + +Check username is not blacklisted. diff --git a/websites/1auth.js.org/src/routes/docs/packages/account/+page.md b/websites/1auth.js.org/src/routes/docs/packages/account/+page.md new file mode 100644 index 0000000..212bd33 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/account/+page.md @@ -0,0 +1,80 @@ +--- +title: "@1auth/account" +description: User account management with encrypted storage and lifecycle operations. +--- + +User account management with encrypted storage and lifecycle operations. + +## Install + +```bash +npm i @1auth/account +``` + +## Usage + +```javascript +import account from '@1auth/account' + +account({ + store, + notify, + encryptedFields: ['value', 'name', 'locale'] +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `store` | `object` | **required** | Storage backend module | +| `notify` | `object` | **required** | Notification module | +| `table` | `object` | — | Table schema definition | +| `encryptedFields` | `string[]` | `[]` | Fields to encrypt before storage | +| `idGenerate` | `object` | — | ID generation config | +| `randomId` | `object` | — | Random ID options (prefix: `user_`) | +| `randomSubject` | `object` | — | Random subject options (prefix: `sub_`) | + +## API + +### `randomId(options)` + +Generate a random account ID. + +### `randomSubject(options)` + +Generate a random subject identifier. + +### `exists(sub)` + +Check if an account exists by subject. + +**Returns:** `boolean` + +### `lookup(sub)` + +Retrieve and decrypt an account by subject. + +**Returns:** Decrypted account object or `undefined` + +### `create(values)` + +Create a new account. Generates a subject ID, encrypts configured fields, and stores the record. + +**Returns:** Created account with `sub` and `id` + +### `update(sub, values)` + +Update account metadata. Re-encrypts modified fields. + +### `expire(sub)` + +Mark an account as expired. + +### `remove(sub)` + +Delete an account record. + +### `getOptions()` + +Get current module configuration. diff --git a/websites/1auth.js.org/src/routes/docs/packages/authn-access-token/+page.md b/websites/1auth.js.org/src/routes/docs/packages/authn-access-token/+page.md new file mode 100644 index 0000000..fb1aa0d --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/authn-access-token/+page.md @@ -0,0 +1,76 @@ +--- +title: "@1auth/authn-access-token" +description: API access tokens (Personal Access Tokens) for programmatic authentication. +--- + +API access tokens (Personal Access Tokens) for programmatic authentication. + +## Install + +```bash +npm i @1auth/authn-access-token +``` + +## Usage + +```javascript +import accessToken from '@1auth/authn-access-token' + +accessToken() +``` + +## Configuration + +Access tokens use these defaults: + +- **Username prefix:** `pat-` +- **Entropy:** 112 bits +- **Expiry:** 30 days + +## API + +### `username(options)` + +Access token username configuration (the public identifier). + +### `secret(options)` + +Access token secret configuration. + +### `authenticate(username, secret)` + +Verify an access token. + +### `exists(username)` + +Check if a token username exists. + +### `count(sub)` + +Count access tokens for a subject. + +### `lookup(username)` + +Find a token by its public username. + +### `select(sub, id)` + +Get a specific access token. + +### `list(sub)` + +List all access tokens for a subject. + +### `create(sub, values)` + +Create a new access token. + +**Returns:** Object with `username` and `secret` (the secret is only returned once at creation) + +### `expire(sub, id)` + +Expire an access token. + +### `remove(sub, id)` + +Delete an access token. diff --git a/websites/1auth.js.org/src/routes/docs/packages/authn-recovery-codes/+page.md b/websites/1auth.js.org/src/routes/docs/packages/authn-recovery-codes/+page.md new file mode 100644 index 0000000..a747ba3 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/authn-recovery-codes/+page.md @@ -0,0 +1,60 @@ +--- +title: "@1auth/authn-recovery-codes" +description: Backup recovery codes for account access when primary credentials are unavailable. +--- + +Backup recovery codes for account access when primary credentials are unavailable. + +## Install + +```bash +npm i @1auth/authn-recovery-codes +``` + +## Usage + +```javascript +import recoveryCodes from '@1auth/authn-recovery-codes' + +recoveryCodes() +``` + +## Configuration + +Recovery codes use sensible defaults: + +- **Entropy:** 112 bits per code +- **Count:** 5 codes per account +- **OTP:** Single-use (removed after use) + +## API + +### `secret(options)` + +Recovery code secret configuration. + +### `authenticate(username, secret)` + +Verify a recovery code. The code is consumed (removed) after successful use. + +### `count(sub)` + +Count remaining recovery codes for a subject. + +### `list(sub)` + +List all recovery codes. + +### `create(sub)` + +Generate a new set of recovery codes. + +**Returns:** Array of plaintext recovery codes (store/display to user immediately — they cannot be retrieved later) + +### `update(sub)` + +Replace all recovery codes with a new set. + +### `remove(sub, id)` + +Remove a specific recovery code or all codes. diff --git a/websites/1auth.js.org/src/routes/docs/packages/authn-webauthn/+page.md b/websites/1auth.js.org/src/routes/docs/packages/authn-webauthn/+page.md new file mode 100644 index 0000000..f0ff213 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/authn-webauthn/+page.md @@ -0,0 +1,84 @@ +--- +title: "@1auth/authn-webauthn" +description: WebAuthn/FIDO2 credential support for passwordless authentication. +--- + +WebAuthn/FIDO2 credential support for passwordless authentication. + +## Install + +```bash +npm i @1auth/authn-webauthn +``` + +## Usage + +```javascript +import webauthn from '@1auth/authn-webauthn' + +webauthn({ + origin: process.env.ORIGIN, + name: 'Organization Name', + userVerification: 'preferred' +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `origin` | `string` | **required** | Application origin URL | +| `name` | `string` | **required** | Relying party name | +| `residentKey` | `string` | — | Resident key requirement | +| `userVerification` | `string` | `'preferred'` | User verification level | +| `preferredAuthenticatorType` | `string` | — | Preferred authenticator type | + +## API + +### `token(options)` + +Token configuration for registration. + +### `secret(options)` + +Secret storage configuration for credentials. + +### `challenge(options)` + +Authentication challenge configuration. + +### `count(sub)` + +Count WebAuthn credentials for a subject. + +### `list(sub)` + +List all WebAuthn credentials. + +### `select(sub, id)` + +Get a specific WebAuthn credential. + +### `authenticate(username, input)` + +Authenticate a user with a WebAuthn assertion. + +### `create(sub)` + +Start the WebAuthn registration process. Returns registration options. + +### `verify(sub, response, {name}, notify)` + +Verify a WebAuthn registration response and store the credential. + +### `createChallenge(sub)` + +Generate an authentication challenge for an existing credential. + +### `expire(sub, id)` + +Expire a WebAuthn credential. + +### `remove(sub, id)` + +Delete a WebAuthn credential. diff --git a/websites/1auth.js.org/src/routes/docs/packages/authn/+page.md b/websites/1auth.js.org/src/routes/docs/packages/authn/+page.md new file mode 100644 index 0000000..9927de7 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/authn/+page.md @@ -0,0 +1,96 @@ +--- +title: "@1auth/authn" +description: Core authentication module with multi-factor authentication support. +--- + +Core authentication module with multi-factor authentication support. + +## Install + +```bash +npm i @1auth/authn +``` + +## Usage + +```javascript +import authn from '@1auth/authn' + +authn({ + store, + notify, + usernameExists: [usernameExists], + encryptedFields: ['value', 'name'] +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `store` | `object` | **required** | Storage backend module | +| `notify` | `object` | **required** | Notification module | +| `table` | `object` | — | Table schema definition | +| `encryptedFields` | `string[]` | `["value"]` | Fields to encrypt | +| `authenticationDuration` | `number` | `100` | Minimum auth duration (ms) for timing safety | +| `usernameExists` | `function[]` | `[]` | Username existence check callbacks | +| `idGenerate` | `object` | — | ID generation config | +| `randomId` | `object` | — | Random ID options (prefix: `authn_`) | + +## API + +### `randomId(options)` + +Generate a random credential ID. + +### `count(credentialOptions, sub)` + +Count valid credentials of a given type for a subject. + +### `list(credentialOptions, sub, params, fields)` + +List credentials with automatic decryption. + +### `create(credentialOptions, sub, values)` + +Create a single credential. + +### `createList(credentialOptions, sub, list)` + +Create multiple credentials at once (e.g., recovery codes). + +### `subject(username)` + +Look up a subject by username using registered `usernameExists` callbacks. + +### `authenticate(credentialOptions, username, secret)` + +Authenticate a user with timing-safe comparison. Uses `setTimeout` to ensure constant-time responses. + +### `verifySecret(credentialOptions, sub, id)` + +Mark a credential as verified. + +### `verify(credentialOptions, sub, input)` + +Verify a credential value. + +### `expire(credentialOptions, sub, id)` + +Expire a credential. + +### `remove(credentialOptions, sub, id)` + +Delete a credential. + +### `removeList(credentialOptions, sub, id)` + +Delete multiple credentials. + +### `select(credentialOptions, sub, id)` + +Get a single credential by ID. + +### `makeType(credentialOptions)` + +Create a type identifier for a credential type. diff --git a/websites/1auth.js.org/src/routes/docs/packages/crypto/+page.md b/websites/1auth.js.org/src/routes/docs/packages/crypto/+page.md new file mode 100644 index 0000000..2f8145d --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/crypto/+page.md @@ -0,0 +1,86 @@ +--- +title: "@1auth/crypto" +description: Cryptographic utilities for encryption, hashing, and signing with modern algorithms. +--- + +Cryptographic utilities for encryption, hashing, and signing with modern algorithms. + +## Install + +```bash +npm i @1auth/crypto +``` + +## Usage + +```javascript +import crypto from '@1auth/crypto' + +crypto({ + symmetricEncryptionKey: process.env.SYMMETRIC_ENCRYPTION_KEY, + symmetricSignatureSecret: process.env.SYMMETRIC_SIGNATURE_SECRET, + digestChecksumSalt: process.env.DIGEST_CHECKSUM_SALT, + digestChecksumPepper: process.env.DIGEST_CHECKSUM_PEPPER +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `symmetricEncryptionKey` | `string` | **required** | Key for symmetric encryption | +| `symmetricSignatureSecret` | `string` | — | Secret for HMAC signing | +| `digestChecksumSalt` | `string` | — | Salt for digest computation | +| `digestChecksumPepper` | `string` | — | Pepper for additional digest security | +| `symmetricEncryptionAlgorithm` | `string` | `chacha20-poly1305` | Encryption algorithm | +| `digestAlgorithm` | `string` | `sha3-384` | Digest algorithm | +| `asymmetricEncryptionCurve` | `string` | `P-384` | Asymmetric key curve | + +## API + +### Random generation + +- `randomBytes(length)` — Generate random bytes +- `randomInt(min, max)` — Generate random integer +- `randomCharacters(options)` — Generate random string from character set +- `randomAlphaNumeric(options)` — Generate alphanumeric string +- `randomNumeric(options)` — Generate numeric string + +### Digests + +- `createChecksum(value)` — Create a checksum digest +- `createDigest(value)` — Create a digest +- `createSeasonedDigest(value)` — Create a seasoned digest +- `createSaltedDigest(value)` — Create a salted digest +- `createPepperedDigest(value)` — Create a peppered digest + +### Secret hashing + +- `createSecretHash(secret)` — Hash a secret with Argon2id +- `verifySecretHash(secret, hash)` — Verify a secret against its hash + +### Symmetric encryption + +- `symmetricGenerateEncryptionKey()` — Generate a new encryption key +- `symmetricEncrypt(value, key)` — Encrypt a value +- `symmetricDecrypt(encrypted, key)` — Decrypt a value +- `symmetricEncryptFields(fields, values, key)` — Encrypt specific fields in an object +- `symmetricDecryptFields(fields, values, key)` — Decrypt specific fields in an object +- `symmetricRotation(encrypted, oldKey, newKey)` — Re-encrypt with a new key + +### Symmetric signatures + +- `symmetricSignatureSign(value)` — Sign a value with HMAC +- `symmetricSignatureVerify(value, signature)` — Verify an HMAC signature + +### Asymmetric keys + +- `makeAsymmetricKeys()` — Generate asymmetric key pair +- `makeAsymmetricSignature(data, privateKey)` — Sign data with private key +- `verifyAsymmetricSignature(data, signature, publicKey)` — Verify signature + +### Utilities + +- `nowInSeconds()` — Current timestamp in seconds +- `safeEqual(a, b)` — Timing-safe string comparison +- `getOptions()` — Get current configuration diff --git a/websites/1auth.js.org/src/routes/docs/packages/messenger-email-address/+page.md b/websites/1auth.js.org/src/routes/docs/packages/messenger-email-address/+page.md new file mode 100644 index 0000000..e447f9e --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/messenger-email-address/+page.md @@ -0,0 +1,82 @@ +--- +title: "@1auth/messenger-email-address" +description: Email address verification with sanitization, validation, and IDNA support. +--- + +Email address verification with sanitization, validation, and IDNA support. + +## Install + +```bash +npm i @1auth/messenger-email-address +``` + +## Usage + +```javascript +import messengerEmailAddress from '@1auth/messenger-email-address' + +messengerEmailAddress() +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `optionalDotDomains` | `string[]` | Gmail domains | Domains where dots are optional | +| `aliasDomains` | `object` | — | Domain alias mapping | +| `usernameBlacklist` | `string[]` | `[]` | Blocked email usernames | + +## API + +### `token(options)` + +Email-specific token configuration. + +### `exists(value)` + +Check if an email address is already registered. + +### `count(sub)` + +Count verified email addresses for a subject. + +### `lookup(emailAddress)` + +Find an account by email address. + +### `list(sub)` + +List all email addresses for a subject. + +### `select(sub, id)` + +Get a specific email messenger. + +### `create(sub, value, values)` + +Create an email messenger and send a verification token. + +### `remove(sub, id)` + +Delete an email messenger. + +### `createToken(sub, sourceId)` + +Generate a new verification token. + +### `verifyToken(sub, token, sourceId)` + +Verify the token and mark the email as verified. + +### `sanitize(value)` + +Normalize an email address: lowercase, IDNA encoding, optional dot handling, alias domain resolution. + +### `validate(value)` + +Validate email address format. + +### `mask(value)` + +Obfuscate an email for display (e.g., `u***@example.com`). diff --git a/websites/1auth.js.org/src/routes/docs/packages/messenger/+page.md b/websites/1auth.js.org/src/routes/docs/packages/messenger/+page.md new file mode 100644 index 0000000..bca86c8 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/messenger/+page.md @@ -0,0 +1,81 @@ +--- +title: "@1auth/messenger" +description: Messaging framework for contact method verification (email, phone, etc.). +--- + +Messaging framework for contact method verification (email, phone, etc.). + +## Install + +```bash +npm i @1auth/messenger +``` + +## Usage + +```javascript +import messenger from '@1auth/messenger' + +messenger({ + store, + notify, + encryptedFields: ['value'] +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `store` | `object` | **required** | Storage backend module | +| `notify` | `object` | **required** | Notification module | +| `table` | `object` | — | Table schema definition | +| `encryptedFields` | `string[]` | `["value"]` | Fields to encrypt | +| `idGenerate` | `object` | — | ID generation config | +| `randomId` | `object` | — | Random ID options (prefix: `messenger_`) | + +## API + +### `randomId(options)` + +Generate a random messenger ID. + +### `token(options)` + +Token configuration — 6-digit numeric OTP with 10 minute expiry by default. + +### `exists(type, value)` + +Check if a messenger of the given type and value exists. + +### `count(type, sub)` + +Count verified messengers of a type for a subject. + +### `lookup(type, value)` + +Find a messenger by type and value. + +### `list(type, sub)` + +List all messengers of a type for a subject. + +### `select(type, sub, id)` + +Get a specific messenger. + +### `create(type, sub, values)` + +Create a new messenger with a verification token. Triggers a notification with the token. + +### `createToken(type, sub, sourceId)` + +Generate a new verification token for an existing messenger. + +### `verifyToken(type, sub, token, sourceId)` + +Verify a token and mark the messenger as verified. + +### `remove(type, sub, id)` + +Delete a messenger. diff --git a/websites/1auth.js.org/src/routes/docs/packages/notify-sqs/+page.md b/websites/1auth.js.org/src/routes/docs/packages/notify-sqs/+page.md new file mode 100644 index 0000000..a3e24d8 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/notify-sqs/+page.md @@ -0,0 +1,66 @@ +--- +title: "@1auth/notify-sqs" +description: AWS SQS notification implementation for asynchronous message delivery. +--- + +AWS SQS notification implementation for asynchronous message delivery. + +## Install + +```bash +npm i @1auth/notify-sqs +``` + +## Peer dependencies + +```bash +npm i @aws-sdk/client-sqs +``` + +## Usage + +```javascript +import * as notify from '@1auth/notify-sqs' + +notify.default({ + queueName: process.env.QUEUE_NAME ?? 'notify-queue' +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `client` | `SQSClient` | — | Custom SQS client instance | +| `queueName` | `string` | — | SQS queue name | +| `queueUrl` | `string` | — | Full SQS queue URL (alternative to queueName) | +| `log` | `function` | — | Logging function | + +## API + +### `trigger(id, sub, data, notifyOptions)` + +Send a notification to the configured SQS queue. + +The message body is a JSON-stringified object containing: + +```json +{ + "id": "template-id", + "sub": "user-subject", + "data": { "token": "123456" }, + "options": { "messengers": [{ "type": "email" }] } +} +``` + +## IAM permissions + +The Lambda execution role needs the following SQS permissions: + +```json +{ + "Effect": "Allow", + "Action": ["sqs:SendMessage"], + "Resource": "arn:aws:sqs:*:*:notify-queue" +} +``` diff --git a/websites/1auth.js.org/src/routes/docs/packages/notify/+page.md b/websites/1auth.js.org/src/routes/docs/packages/notify/+page.md new file mode 100644 index 0000000..974a419 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/notify/+page.md @@ -0,0 +1,42 @@ +--- +title: "@1auth/notify" +description: Base notification interface for sending events through configured channels. +--- + +Base notification interface for sending events through configured channels. + +## Install + +```bash +npm i @1auth/notify +``` + +## Usage + +```javascript +import * as notify from '@1auth/notify' + +notify.default({ + client: (message) => { /* handle notification */ } +}) +``` + +## API + +### `trigger(id, sub, data, notifyOptions)` + +Emit a notification event. + +| Parameter | Type | Description | +|-----------|------|-------------| +| `id` | `string` | Template identifier (e.g., `email-verify`) | +| `sub` | `string` | Subject/user ID | +| `data` | `object` | Template variables | +| `notifyOptions` | `object` | Delivery options | + +The `notifyOptions` object can include: + +- `messengers` — Array of `{id}` or `{type, value}` targets +- `types` — Array of messenger types to target + +The notification service is responsible for rendering templates and delivering messages through the appropriate channel. diff --git a/websites/1auth.js.org/src/routes/docs/packages/session/+page.md b/websites/1auth.js.org/src/routes/docs/packages/session/+page.md new file mode 100644 index 0000000..0957c25 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/session/+page.md @@ -0,0 +1,92 @@ +--- +title: "@1auth/session" +description: Session creation, signing, verification, and management with encrypted storage. +--- + +Session creation, signing, verification, and management with encrypted storage. + +## Install + +```bash +npm i @1auth/session +``` + +## Usage + +```javascript +import session from '@1auth/session' + +session({ + store, + notify, + expire: 12 * 60 * 60 // 12 hours (OWASP ASVS) +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `store` | `object` | **required** | Storage backend module | +| `notify` | `object` | **required** | Notification module | +| `table` | `object` | — | Table schema definition | +| `encryptedFields` | `string[]` | `["value"]` | Fields to encrypt | +| `expire` | `number` | `900` (15min) | Session expiry in seconds | +| `idGenerate` | `object` | — | ID generation config | +| `randomId` | `object` | — | Random ID options (prefix: `session_`) | +| `randomSessionId` | `object` | — | Session token options (prefix: `sid_`, entropy: 128) | +| `encode` | `function` | — | Custom session encoding | +| `decode` | `function` | — | Custom session decoding | +| `checkMetadata` | `function` | — | Device metadata check function | + +## API + +### `randomId(options)` + +Generate a random session record ID. + +### `randomSessionId(options)` + +Generate a random session token (the value stored in the cookie). + +### `lookup(sid, value)` + +Find a session by its signed token. + +### `select(sub, id)` + +Get a specific session by subject and record ID. + +### `list(sub)` + +List all sessions for a subject. + +### `create(sub, value, values)` + +Create a new session. Generates a session token, encrypts metadata, and stores the record. + +**Returns:** Object with `id`, `sid` (signed session token), and metadata + +### `check(sub, value)` + +Check if the device is new before session creation (for "new device" notifications). + +### `expire(sub, id)` + +Expire a session. + +### `remove(sub, id)` + +Delete a session. + +### `sign(sid)` + +Sign a session token with HMAC. + +**Returns:** `sid.signature` + +### `verify(sidWithSignature)` + +Verify a signed session token. + +**Returns:** Original `sid` if valid, `undefined` otherwise diff --git a/websites/1auth.js.org/src/routes/docs/packages/store-d1/+page.md b/websites/1auth.js.org/src/routes/docs/packages/store-d1/+page.md new file mode 100644 index 0000000..5e2967b --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/store-d1/+page.md @@ -0,0 +1,34 @@ +--- +title: "@1auth/store-d1" +description: Cloudflare D1 storage implementation for edge serverless. +--- + +Cloudflare D1 storage implementation for edge serverless. + +## Install + +```bash +npm i @1auth/store-d1 +``` + +## Usage + +```javascript +import * as store from '@1auth/store-d1' + +store.default({ + client: env.DB // D1 database binding +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `client` | `D1Database` | **required** | Cloudflare D1 database binding | +| `timeToLiveExpireOffset` | `number` | `864000` | TTL offset in seconds | +| `timeToLiveKey` | `string` | `"remove"` | Column name for TTL | + +## API + +Implements the [store interface](/docs/packages/store) using D1's `prepare().bind().first/all/run()` API with `?` placeholders. diff --git a/websites/1auth.js.org/src/routes/docs/packages/store-dynamodb/+page.md b/websites/1auth.js.org/src/routes/docs/packages/store-dynamodb/+page.md new file mode 100644 index 0000000..276d5b7 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/store-dynamodb/+page.md @@ -0,0 +1,66 @@ +--- +title: "@1auth/store-dynamodb" +description: AWS DynamoDB storage implementation for serverless persistence. +--- + +AWS DynamoDB storage implementation for serverless persistence. + +## Install + +```bash +npm i @1auth/store-dynamodb +``` + +## Peer dependencies + +```bash +npm i @aws-sdk/client-dynamodb @aws-sdk/util-dynamodb +``` + +## Usage + +```javascript +import * as store from '@1auth/store-dynamodb' + +store.default({ + timeToLiveExpireOffset: 10 * 24 * 60 * 60 // 10 days +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `client` | `DynamoDBClient` | auto-created | Custom DynamoDB client | +| `timeToLiveExpireOffset` | `number` | `864000` | TTL offset in seconds | +| `timeToLiveKey` | `string` | `"remove"` | DynamoDB TTL attribute name | +| `randomId` | `object` | — | ID generation options | + +## API + +Implements the [store interface](/docs/packages/store) using DynamoDB operations: + +- `exists` — `GetItem` with projection +- `count` — `Query` with `Select: 'COUNT'` +- `select` — `GetItem` or `Query` +- `selectList` — `Query` +- `insert` — `PutItem` +- `update` — `UpdateItem` +- `remove` — `DeleteItem` + +## IAM permissions + +```json +{ + "Effect": "Allow", + "Action": [ + "dynamodb:GetItem", + "dynamodb:PutItem", + "dynamodb:UpdateItem", + "dynamodb:DeleteItem", + "dynamodb:Query", + "dynamodb:BatchWriteItem" + ], + "Resource": "arn:aws:dynamodb:*:*:table/1auth-*" +} +``` diff --git a/websites/1auth.js.org/src/routes/docs/packages/store-postgres/+page.md b/websites/1auth.js.org/src/routes/docs/packages/store-postgres/+page.md new file mode 100644 index 0000000..8b44da2 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/store-postgres/+page.md @@ -0,0 +1,42 @@ +--- +title: "@1auth/store-postgres" +description: PostgreSQL storage implementation for 1auth. +--- + +PostgreSQL storage implementation. + +## Install + +```bash +npm i @1auth/store-postgres +``` + +## Peer dependencies + +```bash +npm i pg +``` + +## Usage + +```javascript +import * as store from '@1auth/store-postgres' + +store.default({ + client: pgPool +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `client` | `object` | **required** | PostgreSQL client with `query` method | +| `timeToLiveExpireOffset` | `number` | `864000` | TTL offset in seconds | +| `timeToLiveKey` | `string` | `"remove"` | Column name for TTL | + +## API + +Implements the [store interface](/docs/packages/store) using parameterized SQL queries with `$` placeholders. + +All queries use parameterized statements to prevent SQL injection. diff --git a/websites/1auth.js.org/src/routes/docs/packages/store-sqlite/+page.md b/websites/1auth.js.org/src/routes/docs/packages/store-sqlite/+page.md new file mode 100644 index 0000000..5daadec --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/store-sqlite/+page.md @@ -0,0 +1,34 @@ +--- +title: "@1auth/store-sqlite" +description: SQLite storage implementation for embedded and local development use. +--- + +SQLite storage implementation for embedded and local development use. + +## Install + +```bash +npm i @1auth/store-sqlite +``` + +## Usage + +```javascript +import * as store from '@1auth/store-sqlite' + +store.default({ + client: sqliteDb +}) +``` + +## Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `client` | `object` | **required** | SQLite client with `query` method | +| `timeToLiveExpireOffset` | `number` | `864000` | TTL offset in seconds | +| `timeToLiveKey` | `string` | `"remove"` | Column name for TTL | + +## API + +Implements the [store interface](/docs/packages/store) using parameterized SQL queries with `?` placeholders. diff --git a/websites/1auth.js.org/src/routes/docs/packages/store/+page.md b/websites/1auth.js.org/src/routes/docs/packages/store/+page.md new file mode 100644 index 0000000..f5183d3 --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/packages/store/+page.md @@ -0,0 +1,69 @@ +--- +title: "@1auth/store" +description: Base storage interface that all store implementations follow. +--- + +Base storage interface that all store implementations follow. + +## Overview + +Store modules provide a common interface for database operations. All 1auth modules that persist data accept a `store` option pointing to any compatible implementation. + +## Available implementations + +| Package | Backend | Notes | +|---------|---------|-------| +| [`@1auth/store-dynamodb`](/docs/packages/store-dynamodb) | AWS DynamoDB | Serverless, pay-per-request | +| [`@1auth/store-postgres`](/docs/packages/store-postgres) | PostgreSQL | Relational, self-hosted | +| [`@1auth/store-sqlite`](/docs/packages/store-sqlite) | SQLite | Embedded, local development | +| [`@1auth/store-d1`](/docs/packages/store-d1) | Cloudflare D1 | Edge, serverless SQLite | + +## Common interface + +All store implementations provide these methods: + +### `exists(table, filters)` + +Check if a record exists matching the filters. + +**Returns:** `boolean` + +### `count(table, filters)` + +Count records matching the filters. + +**Returns:** `number` + +### `select(table, filters, fields)` + +Retrieve a single record. + +**Returns:** Record object or `undefined` + +### `selectList(table, filters, fields)` + +Retrieve multiple records. + +**Returns:** Array of record objects + +### `insert(table, values)` + +Insert a new record. + +### `update(table, filters, values)` + +Update an existing record. + +### `remove(table, filters)` + +Delete a record. + +## Configuration + +All stores share common options: + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `client` | `object` | — | Database client instance | +| `timeToLiveExpireOffset` | `number` | `864000` (10 days) | TTL offset in seconds | +| `timeToLiveKey` | `string` | `"remove"` | Column/attribute name for TTL | diff --git a/websites/1auth.js.org/src/routes/docs/security/algorithms/+page.md b/websites/1auth.js.org/src/routes/docs/security/algorithms/+page.md new file mode 100644 index 0000000..586966f --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/security/algorithms/+page.md @@ -0,0 +1,65 @@ +--- +title: Algorithms +description: Default cryptographic algorithms used by 1auth, including encryption, hashing, and signing choices. +--- + +## Default algorithms + +1auth enforces modern cryptographic algorithms by default. These can be configured per-module where noted. + +| Purpose | Algorithm | Alternatives | +|---------|-----------|-------------| +| Symmetric encryption | ChaCha20-Poly1305 | AES-256-GCM | +| Symmetric signature | HMAC | — | +| Asymmetric encryption | ECDSA | — | +| Asymmetric key | ECC P-384 | ECC P-512 | +| Asymmetric signature | Ed25519 (future) | — | +| Digest | SHA3-384 | SHA2-512, SHA3-512 | +| Secret hash | Argon2id | — | +| Encoding | base64 | — | + +## FIPS compliance + +FIPS 140-3 Level 4 can be achieved by using `aes-256-gcm` as the symmetric encryption algorithm instead of the default `chacha20-poly1305`. + +## Argon2id parameters + +Password hashing uses [OWASP-recommended Argon2id parameters](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id): + +| Parameter | Value | +|-----------|-------| +| `timeCost` | 3 | +| `memoryCost` | 2^15 (32 MiB) | +| `saltLength` | 16 bytes | +| `outputLen` | 64 bytes | + +## Rationale + +### ChaCha20-Poly1305 + +Default symmetric cipher because it provides: +- Consistent performance across hardware (no AES-NI dependency) +- AEAD construction (authenticated encryption with associated data) +- Wide adoption in TLS 1.3 and modern protocols + +### SHA3-384 + +Default digest algorithm because: +- SHA-3 family provides defense-in-depth against SHA-2 vulnerabilities +- 384-bit output balances security margin with performance +- Supported natively in Node.js `crypto` module + +### Argon2id + +Default password hashing because: +- Recommended by OWASP for password storage +- Resistant to both GPU and ASIC attacks (memory-hard) +- Combines Argon2i (side-channel resistant) and Argon2d (GPU-resistant) + +## Future: quantum-safe algorithms + +The roadmap includes migration to quantum-safe algorithms: + +- **ML-KEM-1024** — Key encapsulation +- **ML-DSA-87** — Digital signatures +- **SLH-DSA-SHA2-256** — Stateless hash-based signatures diff --git a/websites/1auth.js.org/src/routes/docs/security/threat-model/+page.md b/websites/1auth.js.org/src/routes/docs/security/threat-model/+page.md new file mode 100644 index 0000000..545a40b --- /dev/null +++ b/websites/1auth.js.org/src/routes/docs/security/threat-model/+page.md @@ -0,0 +1,70 @@ +--- +title: Threat Model +description: 1auth's security goals, threat model, and OWASP ASVS v5.0 Level 3 compliance approach. +--- + +## Security goals + +1auth aims to comply with [OWASP ASVS v5.0 Level 3](https://github.com/OWASP/ASVS/tree/master/5.0/en) using automated and manual security audits. + +## Secure design principles + +- **Secure by default** — Safe configurations out of the box +- **Use white lists** — Explicit allow lists over deny lists +- **No backdoors** — No debug modes or hidden access +- **Follow least privilege** — Minimal permissions required +- **Keep it simple** — Reduced attack surface through simplicity + +## Primary threats + +### Credential stuffing / brute force + +**Mitigation:** Timing-safe authentication with minimum duration (`setTimeout`), Argon2id password hashing with configurable cost parameters. + +All authentication responses take a constant minimum time regardless of whether the username exists or the password is correct. + +### Session hijacking + +**Mitigation:** HMAC-signed session IDs, encrypted session storage, per-session encryption keys. + +Session tokens are signed with HMAC to prevent tampering. Session data is encrypted at rest with per-session keys. + +### Credential theft at rest + +**Mitigation:** Per-record ChaCha20-Poly1305 encryption with per-user derived keys. + +Every sensitive field is encrypted before storage. Database compromise does not expose plaintext credentials. + +### Account enumeration + +**Mitigation:** Constant-time authentication responses via `setTimeout` to prevent timing side-channels. + +Whether a username exists or not, the response time is identical, preventing attackers from determining valid usernames. + +### Token replay + +**Mitigation:** OTP tokens are expired/removed after single use. + +Verification tokens (email, recovery codes) are consumed on use and cannot be replayed. + +## Trust boundaries + +### Client to Application Server + +All user inputs (credentials, tokens, session IDs) are validated at entry. No user-supplied data is trusted without validation. + +### Application Server to Database + +All sensitive fields are encrypted before storage. Digests are used for lookups instead of plaintext values. The database never sees plaintext credentials. + +### Application Server to Notification Service + +Tokens are sent through notification channels (email, SMS), never returned in API responses directly. This ensures tokens are delivered through a verified communication channel. + +## Vulnerability reporting + +Report security vulnerabilities by emailing: `willfarrell@proton.me` (PGP supported). + +- **Acknowledgment:** Within 14 days +- **Detailed response:** Within 48 hours of acknowledgment +- **Fix target:** Within 60 days diff --git a/websites/1auth.js.org/src/routes/llms.txt/+server.js b/websites/1auth.js.org/src/routes/llms.txt/+server.js new file mode 100644 index 0000000..797493c --- /dev/null +++ b/websites/1auth.js.org/src/routes/llms.txt/+server.js @@ -0,0 +1,30 @@ +const modules = import.meta.glob("/src/routes/docs/**/+page.md", { + query: "?raw", + import: "default", + eager: true, +}); + +export const prerender = true; + +export const GET = async () => { + const contents = []; + + const paths = Object.keys(modules).sort(); + + for (const path of paths) { + const relativePath = path + .replace("/src/routes/docs/", "") + .replace(/\+page\.md$/, "") + .replace(/^\//, ""); + + contents.push(`\n\n// File: ${relativePath}\n\n`); + contents.push(modules[path]); + } + + return new Response(contents.join(""), { + headers: { + "Content-Type": "text/plain; charset=utf-8", + "Cache-Control": "public, max-age=3600", + }, + }); +}; diff --git a/websites/1auth.js.org/src/routes/search/+page.server.js b/websites/1auth.js.org/src/routes/search/+page.server.js new file mode 100644 index 0000000..575d8a5 --- /dev/null +++ b/websites/1auth.js.org/src/routes/search/+page.server.js @@ -0,0 +1,142 @@ +const modules = import.meta.glob("/src/routes/docs/**/+page.md", { + query: "?raw", + import: "default", + eager: true, +}); + +function getFiles() { + const files = []; + for (const [path, content] of Object.entries(modules)) { + const filePath = path + .replace("/src/routes/docs/", "") + .replace(/\+page\.md$/, "") + .replace(/^\//, ""); + files.push({ filePath, content }); + } + return files; +} + +function extractTitle(content) { + // Try to extract title from frontmatter + const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---/); + if (frontmatterMatch) { + const titleMatch = frontmatterMatch[1].match(/title:\s*(.+)/); + if (titleMatch) { + return titleMatch[1].trim(); + } + } + + // Fallback to first # heading + const headingMatch = content.match(/^#\s+(.+)$/m); + if (headingMatch) { + return headingMatch[1].trim(); + } + + return "Untitled"; +} + +function cleanContentForSearch(content) { + // Remove frontmatter + const withoutFrontmatter = content.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, ""); + + // Remove markdown syntax for cleaner search + return withoutFrontmatter + .replace(/```[\s\S]*?```/g, "") // Remove code blocks + .replace(/`[^`]+`/g, "") // Remove inline code + .replace(/^\s*#{1,6}\s+/gm, "") // Remove headings + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") // Convert links to text + .replace(/[*_]{1,2}([^*_]+)[*_]{1,2}/g, "$1") // Remove bold/italic + .replace(/^\s*[-*+]\s+/gm, "") // Remove list markers + .replace(/\n\s*\n/g, " ") // Collapse multiple newlines + .replace(/\s+/g, " ") // Normalize whitespace + .trim(); +} + +function searchContent(content, query) { + const cleanContent = cleanContentForSearch(content); + const lowerContent = cleanContent.toLowerCase(); + const lowerQuery = query.toLowerCase(); + + return lowerContent.includes(lowerQuery); +} + +function extractDescription(content, query, maxLength = 150) { + // Validate query to prevent ReDoS attacks + if (!query || query.length > 100 || query.length < 1) { + return null; + } + + // Reject queries with excessive repetition (potential ReDoS pattern) + if (/(.)\1{20,}/.test(query)) { + return null; + } + + const cleanContent = cleanContentForSearch(content); + + const lowerCleanContent = cleanContent.toLowerCase(); + const lowerQuery = query.toLowerCase(); + const queryIndex = lowerCleanContent.indexOf(lowerQuery); + + if (queryIndex === -1) { + return null; + } + + const snippetStart = Math.max(0, queryIndex - Math.floor(maxLength / 2)); + const snippetEnd = Math.min(cleanContent.length, snippetStart + maxLength); + + let snippet = cleanContent.substring(snippetStart, snippetEnd); + + if (snippetStart > 0) snippet = `...${snippet}`; + if (snippetEnd < cleanContent.length) snippet = `${snippet}...`; + + // Bold the query match (case-insensitive) with safe regex handling + try { + const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + // SAST: Query is validated (max length, no excessive repetition) and properly escaped + // nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp + const regex = new RegExp(`(${escapedQuery})`, "gi"); + snippet = snippet.replace(regex, "$1"); + } catch (e) { + console.warn("Search highlighting failed:", e.message); + } + + return snippet; +} + +export function load({ url }) { + const query = url.searchParams.get("q"); + + if (!query || query.trim() === "") { + return { + results: [], + query: "", + }; + } + + const files = getFiles(); + const results = []; + const maxResults = 10; + + for (const { filePath, content } of files) { + if (results.length >= maxResults) break; + + if (searchContent(content, query)) { + const href = `/docs/${filePath}`; + const title = extractTitle(content); + const description = extractDescription(content, query); + const id = filePath.replace(/\//g, "-") || "home"; + + results.push({ + id, + href, + title, + description, + }); + } + } + + return { + results, + query: query.trim(), + }; +} diff --git a/websites/1auth.js.org/src/routes/search/+page.svelte b/websites/1auth.js.org/src/routes/search/+page.svelte new file mode 100644 index 0000000..0bd6ead --- /dev/null +++ b/websites/1auth.js.org/src/routes/search/+page.svelte @@ -0,0 +1,47 @@ + + + + Search | 1auth + + + +
+

Search results

+ {#if results.length} +
    + {#each results as card} + +

    {card.title}

    + {#if card.description} +

    {@html card.description}

    + {/if} + {#if card.button} + + {/if} +
    + {/each} +
+ {:else} +

No pages found.

+ {/if} +
+
diff --git a/websites/1auth.js.org/src/scripts/bootstrap.js b/websites/1auth.js.org/src/scripts/bootstrap.js new file mode 100644 index 0000000..b59cbd5 --- /dev/null +++ b/websites/1auth.js.org/src/scripts/bootstrap.js @@ -0,0 +1,3 @@ +/* eslint-env browser */ +import "@willfarrell-ds/vanilla/bootstrap/webcomponents.js"; +// import '@willfarrell-ds/vanilla/bootstrap/trustedtypes.js'; diff --git a/websites/1auth.js.org/src/styles/above.css b/websites/1auth.js.org/src/styles/above.css new file mode 100644 index 0000000..325fa27 --- /dev/null +++ b/websites/1auth.js.org/src/styles/above.css @@ -0,0 +1,20 @@ +/* generated by @willfarrell-ds/cli */ +@import "@willfarrell-ds/vanilla/layers/base.css"; +@import "@willfarrell-ds/vanilla/layers/media.css"; +@import "@willfarrell-ds/vanilla/elements/a.css"; +@import "@willfarrell-ds/vanilla/elements/button.css"; +@import "@willfarrell-ds/vanilla/elements/h1.css"; +@import "@willfarrell-ds/vanilla/elements/hgroup.css"; +@import "@willfarrell-ds/vanilla/elements/li.css"; +@import "@willfarrell-ds/vanilla/elements/nav.css"; +@import "@willfarrell-ds/vanilla/elements/ul.css"; +@import "@willfarrell-ds/vanilla/classes/a.button.css"; +@import "@willfarrell-ds/vanilla/classes/details.chevron.css"; +@import "@willfarrell-ds/vanilla/classes/.container.css"; +@import "@willfarrell-ds/vanilla/classes/.container-aside.css"; +@import "@willfarrell-ds/vanilla/classes/.container-slices.css"; +@import "@willfarrell-ds/vanilla/classes/.container-toc.css"; +@import "@willfarrell-ds/vanilla/classes/a.skip.css"; +@import "@willfarrell-ds/vanilla/classes/.visually-hidden.css"; +@import "@willfarrell-ds/vanilla/theme.css"; +@import "./theme.css"; diff --git a/websites/1auth.js.org/src/styles/below.css b/websites/1auth.js.org/src/styles/below.css new file mode 100644 index 0000000..e53a869 --- /dev/null +++ b/websites/1auth.js.org/src/styles/below.css @@ -0,0 +1,21 @@ +@import "@willfarrell-ds/vanilla/elements/code.css"; +@import "@willfarrell-ds/vanilla/elements/details.css"; +@import "@willfarrell-ds/vanilla/elements/form.css"; +@import "@willfarrell-ds/vanilla/elements/h2.css"; +@import "@willfarrell-ds/vanilla/elements/h3.css"; +@import "@willfarrell-ds/vanilla/elements/hr.css"; +@import "@willfarrell-ds/vanilla/elements/input.css"; +@import "@willfarrell-ds/vanilla/elements/label.css"; +@import "@willfarrell-ds/vanilla/elements/ol.css"; +@import "@willfarrell-ds/vanilla/elements/p.css"; +@import "@willfarrell-ds/vanilla/elements/picture.css"; +@import "@willfarrell-ds/vanilla/elements/pre.css"; +@import "@willfarrell-ds/vanilla/elements/s.css"; +@import "@willfarrell-ds/vanilla/elements/select.css"; +@import "@willfarrell-ds/vanilla/elements/table.css"; +@import "@willfarrell-ds/vanilla/classes/li.card.css"; +@import "@willfarrell-ds/vanilla/classes/select.chevron.css"; +@import "@willfarrell-ds/vanilla/classes/.grid.css"; +@import "@willfarrell-ds/vanilla/classes/.icon.css"; +@import "@willfarrell-ds/vanilla/components/ds-card.css"; +@import "@willfarrell-ds/vanilla/components/ds-input-focus.css"; diff --git a/websites/1auth.js.org/src/styles/print.css b/websites/1auth.js.org/src/styles/print.css new file mode 100644 index 0000000..bf2d68b --- /dev/null +++ b/websites/1auth.js.org/src/styles/print.css @@ -0,0 +1 @@ +@import "@willfarrell-ds/vanilla/print.css"; diff --git a/websites/1auth.js.org/src/styles/theme.css b/websites/1auth.js.org/src/styles/theme.css new file mode 100644 index 0000000..1cb3efa --- /dev/null +++ b/websites/1auth.js.org/src/styles/theme.css @@ -0,0 +1,111 @@ +:root { + --hex-main: #0d7377; +} + +header input { + --border-color: var(--color-main-bold); +} +.grid:has(.stat) { + --grid-min-width: 15ch; + grid-template-columns: repeat(auto-fit, var(--grid-min-width)); + list-style-type: none; + padding-inline-start: 0; + justify-content: center; +} +.grid > .stat { + --border-width: 0; + + & h3 { + display: inline-flex; + align-items: center; + } + & p { + margin-block: 0; + } +} +section.grid:has(.feature) { + padding: var(--block-padding) var(--page-gap); +} +.grid:has(.feature) { + max-width: 110ch; + margin: auto; +} +.grid > .feature { + --border-width: 0; + --border-radius: 2em; + padding: var(--border-radius); +} + +.grid > .package { + --border-width: 1px; + --border-color: var(--color-l5); + filter: unset; + & > p { + margin: 0; + } +} + +/* round buttons, cards */ +:root { + --border-radius: 0.25rem; +} +[is="ds-card"] { + background-color: var(--color-l1); + --border-radius: 0.5rem; +} + +/* Safari bug workaround */ +/* Use filter: https://angel-rs.github.io/css-color-filter-generator/ */ +[src="/img/logo.svg"] { + /* #1f1f1f */ + filter: brightness(0) saturate(100%) invert(6%) sepia(56%) saturate(12%) + hue-rotate(102deg) brightness(95%) contrast(88%); +} +@media (prefers-color-scheme: dark) { + [src="/img/logo.svg"] { + /* #fafafa */ + filter: brightness(0) saturate(100%) invert(100%) sepia(4%) saturate(0%) + hue-rotate(259deg) brightness(104%) contrast(96%); + } +} + +/* Hero shader background */ +.hero { + position: relative; + overflow: clip; +} + +.hero::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: -25%; + z-index: -1; + background: + radial-gradient(circle at 40% 40%, var(--hex-main) 0%, transparent 25%), + radial-gradient(circle at 50% 60%, var(--hex-main) 0%, transparent 25%), + radial-gradient(circle at 30% 50%, var(--hex-main) 0%, transparent 25%); + filter: blur(25px); + @media (prefers-reduced-motion: no-preference) { + animation: hero-shader 20s ease-in-out infinite; + } + opacity: 0.6; + @media (prefers-color-scheme: dark) { + opacity: 0.4; + } +} + +@keyframes hero-shader { + 0%, + 100% { + transform: translate(15%, -15%) scale(1); + } + 33% { + transform: translate(20%, -20%) scale(1.05); + } + 66% { + transform: translate(-5%, 5%) scale(0.95); + } +} diff --git a/websites/1auth.js.org/static/.well-known/manifest.webmanifest b/websites/1auth.js.org/static/.well-known/manifest.webmanifest new file mode 100644 index 0000000..98330a1 --- /dev/null +++ b/websites/1auth.js.org/static/.well-known/manifest.webmanifest @@ -0,0 +1,16 @@ +{ + "name": "1auth", + "short_name": "1auth", + "icons": [ + { + "src": "/favicon.svg", + "sizes": "any", + "type": "image/svg+xml" + } + ], + "theme_color": "#0d7377", + "background_color": "#000000", + "display": "standalone", + "start_url": "/", + "prefer_related_applications": false +} diff --git a/websites/1auth.js.org/static/apple-touch-icon.png b/websites/1auth.js.org/static/apple-touch-icon.png new file mode 100644 index 0000000..0dd1608 --- /dev/null +++ b/websites/1auth.js.org/static/apple-touch-icon.png @@ -0,0 +1,2 @@ +PNG + diff --git a/websites/1auth.js.org/static/favicon.ico b/websites/1auth.js.org/static/favicon.ico new file mode 100644 index 0000000..49bbb85 Binary files /dev/null and b/websites/1auth.js.org/static/favicon.ico differ diff --git a/websites/1auth.js.org/static/favicon.svg b/websites/1auth.js.org/static/favicon.svg new file mode 100644 index 0000000..9f1f7e1 --- /dev/null +++ b/websites/1auth.js.org/static/favicon.svg @@ -0,0 +1 @@ +🔐 diff --git a/websites/1auth.js.org/static/img/architecture.png b/websites/1auth.js.org/static/img/architecture.png new file mode 100644 index 0000000..1947a78 Binary files /dev/null and b/websites/1auth.js.org/static/img/architecture.png differ diff --git a/websites/1auth.js.org/static/img/icons.svg b/websites/1auth.js.org/static/img/icons.svg new file mode 100644 index 0000000..d7c642d --- /dev/null +++ b/websites/1auth.js.org/static/img/icons.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/websites/1auth.js.org/static/img/logo.svg b/websites/1auth.js.org/static/img/logo.svg new file mode 100644 index 0000000..7986f2a --- /dev/null +++ b/websites/1auth.js.org/static/img/logo.svg @@ -0,0 +1 @@ +Untitled \ No newline at end of file diff --git a/websites/1auth.js.org/static/robots.txt b/websites/1auth.js.org/static/robots.txt new file mode 100644 index 0000000..74ec0e7 --- /dev/null +++ b/websites/1auth.js.org/static/robots.txt @@ -0,0 +1,4 @@ +sitemap: https://1auth.js.org/sitemap.xml + +User-agent: * +Disallow: diff --git a/websites/1auth.js.org/svelte.config.js b/websites/1auth.js.org/svelte.config.js new file mode 100644 index 0000000..c69dc7c --- /dev/null +++ b/websites/1auth.js.org/svelte.config.js @@ -0,0 +1,74 @@ +import { resolve } from "node:path"; +import adapter from "@sveltejs/adapter-cloudflare"; +import { mdsvex } from "mdsvex"; +import { rehypeAddHeadingIds } from "./src/lib/rehype-add-heading-ids.js"; +import { remarkExtractHeadings } from "./src/lib/remark-extract-headings.js"; +import tardisec from "./tardisec.json" with { type: "json" }; + +const domain = process.env.ORIGIN ?? "1auth.js.org"; +const origin = domain; +const config = { + kit: { + adapter: adapter({}), + alias: { + "@design-system": resolve("../../node_modules/@willfarrell-ds/svelte"), + "@components": resolve("./src/components"), + "@hooks": resolve("./src/hooks"), + "@scripts": resolve("./src/scripts"), + "@styles": resolve("./src/styles"), + }, + appDir: "_", + csp: { + ...tardisec["svelte.config.js"]["Content-Security-Policy"], + mode: "hash", + directives: { + "default-src": ["none"], + "base-uri": ["none"], + "connect-src": ["self"], + "form-action": ["self"], + "frame-ancestors": ["none"], + "img-src": ["self"], + "manifest-src": ["self"], + "script-src": ["self"], + "script-src-attr": ["report-sample"], + "style-src": ["self"], + "style-src-attr": ["report-sample"], + "upgrade-insecure-requests": true, + "worker-src": ["self"], + "report-to": ["default"], + }, + }, + csrf: { + trustedOrigins: [origin], + }, + }, + preprocess: [ + mdsvex({ + extensions: [".md"], + layout: { + _: resolve("./src/components/docs/mdsvex-layout.svelte"), + }, + remarkPlugins: [remarkExtractHeadings], + rehypePlugins: [rehypeAddHeadingIds], + }), + ], + extensions: [".svelte", ".md"], + prerender: { + concurrency: 5, + crawl: true, + entries: ["/", "/sitemap.xml", "/llms.txt"], + handleHttpError: "warn", + handleMissingId: "warn", + handleEntryGeneratorMismatch: "warn", + origin: `https://${origin}`, + }, + onwarn(warning, defaultHandler) { + if (warning.code === "attribute_avoid_is") return; + if (warning.code === "non_reactive_update") return; + + warning.message = `[${warning.code}] ${warning.message}`; + defaultHandler(warning); + }, +}; + +export default config; diff --git a/websites/1auth.js.org/svgo.config.mjs b/websites/1auth.js.org/svgo.config.mjs new file mode 100644 index 0000000..4ac8a94 --- /dev/null +++ b/websites/1auth.js.org/svgo.config.mjs @@ -0,0 +1,14 @@ +export default { + plugins: [ + // 1. Minify the path data (the "d" attribute) + "convertPathData", + // 2. Remove comments + "removeComments", + // 3. Remove metadata/editors junk + "removeMetadata", + "removeEditorsNSData", + // 4. Clean up attributes but DO NOT touch IDs or Symbols + "removeUnknownsAndDefaults", + "removeUnusedNS", + ], +}; diff --git a/websites/1auth.js.org/tardisec.json b/websites/1auth.js.org/tardisec.json new file mode 100644 index 0000000..a2d21e7 --- /dev/null +++ b/websites/1auth.js.org/tardisec.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://schema.tardisec.com/0.0.0-alpha.0", + "raw": { + "Content-Security-Policy": null, + "Content-Security-Policy-Report-Only": "base-uri 'none';default-src 'report-sample' 'report-sha256';form-action 'none';frame-ancestors 'none';report-to default;report-uri https://1auth.js.org.report-to.org;require-trusted-types-for 'script'", + "Cross-Origin-Embedder-Policy": "require-corp;report-to=default", + "Cross-Origin-Embedder-Policy-Report-Only": null, + "Cross-Origin-Opener-Policy": "same-origin;report-to=default", + "Cross-Origin-Opener-Policy-Report-Only": null, + "Cross-Origin-Resource-Policy": "same-origin", + "Document-Isolation-Policy": "isolate-and-require-corp;report-to=default", + "Document-Policy": null, + "Document-Policy-Report-Only": "*;report-to=default", + "Integrity-Policy": "blocked-destinations=(),endpoints=(default)", + "Integrity-Policy-Report-Only": "blocked-destinations=(script style),endpoints=(default)", + "NEL": "{\"failure_fraction\":1,\"include_subdomains\":true,\"max_age\":31536000,\"report_to\":\"default\",\"success_fraction\":0}", + "Origin-Agent-Cluster": "?1", + "Permissions-Policy": null, + "Permissions-Policy-Report-Only": "accelerometer=(),all-screens-capture=(),ambient-light-sensor=(),aria-notify=(),attribution-reporting=(),autoplay=(),battery=(),bluetooth=(),browsing-topics=(),camera=(),captured-surface-control=(),ch-ua=(),ch-ua-arch=(),ch-ua-bitness=(),ch-ua-full-version=(),ch-ua-full-version-list=(),ch-ua-high-entropy-values=(),ch-ua-mobile=(),ch-ua-model=(),ch-ua-platform=(),ch-ua-platform-version=(),compute-pressure=(),cross-origin-isolated=(),digital-credentials-create=(),digital-credentials-get=(),direct-sockets=(),display-capture=(),encrypted-media=(),execution-while-not-rendered=(),execution-while-out-of-viewport=(),focus-without-user-activation=(),fullscreen=(),gamepad=(),geolocation=(),gyroscope=(),hid=(),identity-credentials-get=(),idle-detection=(),interest-cohort=(),join-ad-interest-group=(),keyboard-map=(),language-detector=(),local-fonts=(),magnetometer=(),mediasession=(),microphone=(),midi=(),monetization=(),navigation-override=(),on-device-speech-recognition=(),otp-credentials=(),payment=(),picture-in-picture=(),private-state-token-issuance=(),private-state-token-redemption=(),publickey-credentials-create=(),publickey-credentials-get=(),run-ad-auction=(),screen-wake-lock=(),serial=(),smart-card=(),speaker-selection=(),storage-access=(),summarizer=(),sync-script=(),sync-xhr=(),translator=(),trust-token-redemption=(),unload=(),usb=(),vertical-scroll=(),web-share=(),window-management=(),xr-spatial-tracking=()", + "Referrer-Policy": "no-referrer", + "Report-To": "{\"endpoints\":[{\"url\":\"https://1auth.js.org.report-to.org\"}],\"group\":\"default\",\"include_subdomains\":true,\"max_age\":31536000}", + "Reporting-Endpoints": "default=\"https://1auth.js.org.report-to.org\"", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", + "X-Content-Type-Options": "nosniff", + "X-Download-Options": "noopen", + "X-Frame-Options": "DENY", + "X-Permitted-Cross-Domain-Policies": "none" + }, + "svelte.config.js": { + "Content-Security-Policy": { + "mode": "hash", + "directives": { + "default-src": ["none"], + "base-uri": ["none"], + "connect-src": ["self"], + "form-action": ["self"], + "frame-ancestors": ["none"], + "img-src": ["self"], + "manifest-src": ["self"], + "script-src": ["self"], + "script-src-attr": ["report-sample"], + "style-src": ["self"], + "style-src-attr": ["report-sample"], + "upgrade-insecure-requests": true, + "worker-src": ["self"], + "report-to": ["default"] + } + } + } +} diff --git a/websites/1auth.js.org/vite.config.js b/websites/1auth.js.org/vite.config.js new file mode 100644 index 0000000..418d0c5 --- /dev/null +++ b/websites/1auth.js.org/vite.config.js @@ -0,0 +1,29 @@ +import { sveltekit } from "@sveltejs/kit/vite"; +import { createLogger, defineConfig } from "vite"; +import mkcert from "vite-plugin-mkcert"; +import sitemap from "vite-plugin-sitemap"; +import sriPrerendered from "vite-plugin-sri"; + +// TODO remove after vite 8 — https://github.com/vitejs/vite/issues/19498 +const logger = createLogger(); +const originalWarn = logger.warn.bind(logger); +logger.warn = (msg, options) => { + if (msg.includes("node:async_hooks")) return; + originalWarn(msg, options); +}; + +export default defineConfig({ + plugins: [ + sveltekit(), + mkcert({ mkcertPath: "/opt/homebrew/bin/mkcert" }), + sriPrerendered(), + sitemap({ hostname: "https://1auth.js.org", outDir: "build/assets/" }), + ], + build: { + assetsInlineLimit: 0, + }, + customLogger: logger, + ssr: { + noExternal: ["prismjs"], + }, +}); diff --git a/websites/1auth.js.org/wrangler.jsonc b/websites/1auth.js.org/wrangler.jsonc new file mode 100644 index 0000000..d9cf3be --- /dev/null +++ b/websites/1auth.js.org/wrangler.jsonc @@ -0,0 +1,7 @@ +{ + "$schema": "node_modules/wrangler/config-schema.json", + "name": "1auth", + "compatibility_date": "2026-03-10", + "compatibility_flags": ["nodejs_compat"], + "pages_build_output_dir": ".svelte-kit/cloudflare/" +}