From 56d53e1090be404286ea95d70589c2d19f735bd8 Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 20:18:55 +0000 Subject: [PATCH 01/17] refactor: move to bun Having serious problems with the release process and deno. --- .devcontainer/devcontainer.json | 17 - .dvmrc | 1 - .github/actions/test/action.yml | 8 +- .github/workflows/dependencies.yml | 24 - .github/workflows/get-deno-version.yml | 22 - .github/workflows/pull-request.yml | 8 +- .github/workflows/release.yml | 15 +- .github/workflows/test.yml | 18 - .gitignore | 2 - bun.lock | 706 ++++++ deno.json | 26 - deno.lock | 2175 ----------------- lint-staged.config.js | 3 +- oxfmt.config.ts | 6 + oxlint.config.ts | 8 + package.json | 33 + packages/api/deno.json | 35 - packages/api/jsr.json | 8 + packages/api/package.json | 27 + packages/api/test/Data.test.ts | 306 +-- .../api/test/__snapshots__/Data.test.ts.snap | 354 ++- packages/api/test/parsers/switch.test.ts | 37 +- packages/api/test/tsconfig.json | 7 + packages/api/test/utils.test.ts | 42 +- packages/api/tsconfig.json | 7 + packages/client/deno.json | 35 - packages/client/jsr.json | 8 + packages/client/package.json | 30 + .../test/__snapshots__/index.test.ts.snap | 42 +- packages/client/test/index.test.ts | 65 +- .../test/queryToURLSearchParams.test.ts | 41 +- packages/client/test/tsconfig.json | 7 + packages/client/tsconfig.json | 7 + packages/date-range/deno.json | 34 - packages/date-range/jsr.json | 8 + packages/date-range/package.json | 27 + packages/date-range/test/index.test.ts | 34 +- packages/date-range/test/tsconfig.json | 7 + packages/date-range/tsconfig.json | 7 + packages/explode/deno.json | 36 - packages/explode/jsr.json | 8 + packages/explode/package.json | 29 + packages/explode/test/explode.test.ts | 33 +- packages/explode/test/tsconfig.json | 7 + packages/explode/tsconfig.json | 7 + packages/fs/deno.json | 38 - packages/fs/jsr.json | 8 + packages/fs/package.json | 31 + packages/fs/src/watch.ts | 30 +- packages/fs/test/load.test.ts | 13 +- packages/fs/test/tsconfig.json | 7 + packages/fs/test/watch.test.ts | 55 +- packages/fs/tsconfig.json | 7 + packages/json-schema/deno.json | 40 - packages/json-schema/jsr.json | 11 + packages/json-schema/package.json | 33 + packages/json-schema/src/index.ts | 9 +- .../test/__snapshots__/index.test.ts.snap | 607 ++--- packages/json-schema/test/index.test.ts | 9 +- packages/json-schema/test/tsconfig.json | 7 + packages/json-schema/tsconfig.json | 7 + packages/server/deno.json | 41 - packages/server/jsr.json | 8 + packages/server/package.json | 38 + .../test/__snapshots__/index.test.ts.snap | 92 +- packages/server/test/index.test.ts | 93 +- packages/server/test/tsconfig.json | 7 + packages/server/tsconfig.json | 7 + release-please-config.json | 60 +- targetd.code-workspace | 34 +- tsconfig.json | 25 + 71 files changed, 2040 insertions(+), 3644 deletions(-) delete mode 100644 .devcontainer/devcontainer.json delete mode 100644 .dvmrc delete mode 100644 .github/workflows/dependencies.yml delete mode 100644 .github/workflows/get-deno-version.yml delete mode 100644 .github/workflows/test.yml create mode 100644 bun.lock delete mode 100644 deno.json delete mode 100644 deno.lock create mode 100644 oxfmt.config.ts create mode 100644 oxlint.config.ts create mode 100644 package.json delete mode 100644 packages/api/deno.json create mode 100644 packages/api/jsr.json create mode 100644 packages/api/package.json create mode 100644 packages/api/test/tsconfig.json create mode 100644 packages/api/tsconfig.json delete mode 100644 packages/client/deno.json create mode 100644 packages/client/jsr.json create mode 100644 packages/client/package.json create mode 100644 packages/client/test/tsconfig.json create mode 100644 packages/client/tsconfig.json delete mode 100644 packages/date-range/deno.json create mode 100644 packages/date-range/jsr.json create mode 100644 packages/date-range/package.json create mode 100644 packages/date-range/test/tsconfig.json create mode 100644 packages/date-range/tsconfig.json delete mode 100644 packages/explode/deno.json create mode 100644 packages/explode/jsr.json create mode 100644 packages/explode/package.json create mode 100644 packages/explode/test/tsconfig.json create mode 100644 packages/explode/tsconfig.json delete mode 100644 packages/fs/deno.json create mode 100644 packages/fs/jsr.json create mode 100644 packages/fs/package.json create mode 100644 packages/fs/test/tsconfig.json create mode 100644 packages/fs/tsconfig.json delete mode 100644 packages/json-schema/deno.json create mode 100644 packages/json-schema/jsr.json create mode 100644 packages/json-schema/package.json create mode 100644 packages/json-schema/test/tsconfig.json create mode 100644 packages/json-schema/tsconfig.json delete mode 100644 packages/server/deno.json create mode 100644 packages/server/jsr.json create mode 100644 packages/server/package.json create mode 100644 packages/server/test/tsconfig.json create mode 100644 packages/server/tsconfig.json create mode 100644 tsconfig.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 7e597967b..000000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "Targetd", - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", - "features": { - "ghcr.io/devcontainers-community/features/deno:1": {}, - "ghcr.io/devcontainers/features/github-cli:1": {} - }, - "customizations": { - "vscode": { - "extensions": [ - "denoland.vscode-deno", - "github.vscode-github-actions" - ] - } - }, - "postStartCommand": "sudo deno upgrade && deno install" -} diff --git a/.dvmrc b/.dvmrc deleted file mode 100644 index a603bb50a..000000000 --- a/.dvmrc +++ /dev/null @@ -1 +0,0 @@ -2.7.5 diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 27c95b6ed..5fe2d2df5 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -6,8 +6,10 @@ runs: using: composite steps: - shell: bash - run: deno check --frozen + run: bun install - shell: bash - run: deno lint + run: bun run check - shell: bash - run: deno task test + run: bun run lint + - shell: bash + run: bun test diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml deleted file mode 100644 index 801ea78ff..000000000 --- a/.github/workflows/dependencies.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Deno Dependency Updates - -on: - schedule: - - cron: '0 0 * * 1' # Weekly on Mondays - workflow_dispatch: - -jobs: - update-dependencies: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - uses: actions/checkout@v6 - - uses: denoland/setup-deno@v2 - with: - deno-version-file: .dvmrc - - uses: johngeorgewright/workflows/actions/deno-update@main - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - pr-labels: dependencies - recursive: 'true' - version-policy: latest diff --git a/.github/workflows/get-deno-version.yml b/.github/workflows/get-deno-version.yml deleted file mode 100644 index e9be618a1..000000000 --- a/.github/workflows/get-deno-version.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Get Deno Version - -on: - workflow_call: - outputs: - version: - description: The Deno version from .dvmrc - value: ${{ jobs.get-deno-version.outputs.version }} - -jobs: - get-deno-version: - name: Get Deno Version - runs-on: ubuntu-latest - outputs: - version: ${{ steps.deno-version.outputs.version }} - steps: - - uses: actions/checkout@v6 - with: - sparse-checkout: .dvmrc - sparse-checkout-cone-mode: false - - id: deno-version - run: echo "version=$(cat .dvmrc)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index c8abc401c..16d3dcc94 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -9,4 +9,10 @@ concurrency: jobs: test: - uses: ./.github/workflows/test.yml + name: Test + runs-on: ubuntu-latest + container: + image: oven/bun:1 + steps: + - uses: actions/checkout@v6 + - uses: ./.github/actions/test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 912c8bde7..afdd94847 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,14 +31,17 @@ jobs: matrix: path_released: ${{ fromJson(needs.release-github.outputs.paths_released) }} name: Publish ${{ matrix.path_released }} to JSR + container: + image: oven/bun:1 permissions: contents: read id-token: write steps: - uses: actions/checkout@v6 - - uses: denoland/setup-deno@v2 - with: - deno-version-file: .dvmrc - - uses: ./.github/actions/test - - working-directory: ${{ matrix.path_released }} - run: if [ "$(cat deno.json | jq -r '.private // false')" != "true" ]; then deno publish; fi + - id: package + run: echo "private=$(cat package.json | jq -r '.private // false')" >> $GITHUB_OUTPUT + - if: steps.package.outputs.private != 'true' + uses: ./.github/actions/test + - if: steps.package.outputs.private != 'true' + working-directory: ${{ matrix.path_released }} + run: bunx jsr publish diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 52099fe51..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Test - -on: - workflow_call: - -jobs: - get-deno-version: - uses: ./.github/workflows/get-deno-version.yml - - test: - name: Test - runs-on: ubuntu-latest - needs: get-deno-version - container: - image: denoland/deno:${{ needs.get-deno-version.outputs.version }} - steps: - - uses: actions/checkout@v6 - - uses: ./.github/actions/test diff --git a/.gitignore b/.gitignore index c3f603aa3..08b57f41d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ dist *.log node_modules -package.json -package-lock.json *.validator.ts diff --git a/bun.lock b/bun.lock new file mode 100644 index 000000000..7afd36a8a --- /dev/null +++ b/bun.lock @@ -0,0 +1,706 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "@targetd/monorepo", + "devDependencies": { + "@commitlint/cli": "^20.4.3", + "@commitlint/config-conventional": "^20.4.3", + "@types/bun": "catalog:", + "lint-staged": "^16.3.1", + "oxlint": "^1.56.0", + "typescript": "catalog:", + }, + }, + "packages/api": { + "name": "@targetd/api", + "version": "8.1.1", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "ts-toolbelt": "catalog:", + }, + "devDependencies": { + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:", + }, + "peerDependencies": { + "zod": "catalog:", + }, + }, + "packages/client": { + "name": "@targetd/client", + "version": "7.0.2", + "dependencies": { + "ts-toolbelt": "catalog:", + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@targetd/date-range": "workspace:*", + "@targetd/server": "workspace:*", + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:", + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:", + }, + }, + "packages/date-range": { + "name": "@targetd/date-range", + "version": "6.0.2", + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "@types/sinon": "catalog:", + "sinon": "catalog:", + "typescript": "catalog:", + "zod": "catalog:", + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:", + }, + }, + "packages/explode": { + "name": "@targetd/explode", + "version": "4.0.2", + "dependencies": { + "flat": "^6.0.1", + "ts-toolbelt": "catalog:", + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:", + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:", + }, + }, + "packages/fs": { + "name": "@targetd/fs", + "version": "7.1.0", + "dependencies": { + "@johngw/fs": "^3.0.1", + "es-toolkit": "catalog:", + "ts-toolbelt": "catalog:", + "yaml": "^2.8.2", + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:", + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:", + }, + }, + "packages/json-schema": { + "name": "@targetd/json-schema", + "version": "5.2.0", + "dependencies": { + "es-toolkit": "catalog:", + "yargs": "^18.0.0", + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "@types/yargs": "^17.0.35", + "typescript": "catalog:", + "zod": "catalog:", + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:", + }, + }, + "packages/server": { + "name": "@targetd/server", + "version": "8.1.2", + "dependencies": { + "@johngw/error": "^2.2.2", + "cors": "^2.8.6", + "express": "^5.2.1", + "express-query-boolean": "^2.0.0", + "qs": "^6.15.0", + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@targetd/date-range": "workspace:*", + "@types/bun": "catalog:", + "@types/express": "^5.0.6", + "@types/qs": "^6.15.0", + "@types/supertest": "latest", + "lodash": "latest", + "supertest": "latest", + "typescript": "catalog:", + "zod": "catalog:", + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:", + }, + }, + }, + "catalog": { + "@types/bun": "^1.3.10", + "@types/sinon": "^21.0.0", + "es-toolkit": "^1.45.1", + "sinon": "^21.0.3", + "ts-toolbelt": "^9.6.0", + "typescript": "^5.9.3", + "zod": "^4.3.6", + }, + "packages": { + "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@commitlint/cli": ["@commitlint/cli@20.5.0", "", { "dependencies": { "@commitlint/format": "^20.5.0", "@commitlint/lint": "^20.5.0", "@commitlint/load": "^20.5.0", "@commitlint/read": "^20.5.0", "@commitlint/types": "^20.5.0", "tinyexec": "^1.0.0", "yargs": "^17.0.0" }, "bin": { "commitlint": "./cli.js" } }, "sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ=="], + + "@commitlint/config-conventional": ["@commitlint/config-conventional@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-conventionalcommits": "^9.2.0" } }, "sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA=="], + + "@commitlint/config-validator": ["@commitlint/config-validator@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "ajv": "^8.11.0" } }, "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw=="], + + "@commitlint/ensure": ["@commitlint/ensure@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", "lodash.startcase": "^4.4.0", "lodash.upperfirst": "^4.3.1" } }, "sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw=="], + + "@commitlint/execute-rule": ["@commitlint/execute-rule@20.0.0", "", {}, "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw=="], + + "@commitlint/format": ["@commitlint/format@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "picocolors": "^1.1.1" } }, "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q=="], + + "@commitlint/is-ignored": ["@commitlint/is-ignored@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "semver": "^7.6.0" } }, "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg=="], + + "@commitlint/lint": ["@commitlint/lint@20.5.0", "", { "dependencies": { "@commitlint/is-ignored": "^20.5.0", "@commitlint/parse": "^20.5.0", "@commitlint/rules": "^20.5.0", "@commitlint/types": "^20.5.0" } }, "sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA=="], + + "@commitlint/load": ["@commitlint/load@20.5.0", "", { "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/execute-rule": "^20.0.0", "@commitlint/resolve-extends": "^20.5.0", "@commitlint/types": "^20.5.0", "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", "is-plain-obj": "^4.1.0", "lodash.mergewith": "^4.6.2", "picocolors": "^1.1.1" } }, "sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw=="], + + "@commitlint/message": ["@commitlint/message@20.4.3", "", {}, "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ=="], + + "@commitlint/parse": ["@commitlint/parse@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-angular": "^8.2.0", "conventional-commits-parser": "^6.3.0" } }, "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA=="], + + "@commitlint/read": ["@commitlint/read@20.5.0", "", { "dependencies": { "@commitlint/top-level": "^20.4.3", "@commitlint/types": "^20.5.0", "git-raw-commits": "^5.0.0", "minimist": "^1.2.8", "tinyexec": "^1.0.0" } }, "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w=="], + + "@commitlint/resolve-extends": ["@commitlint/resolve-extends@20.5.0", "", { "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/types": "^20.5.0", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0" } }, "sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg=="], + + "@commitlint/rules": ["@commitlint/rules@20.5.0", "", { "dependencies": { "@commitlint/ensure": "^20.5.0", "@commitlint/message": "^20.4.3", "@commitlint/to-lines": "^20.0.0", "@commitlint/types": "^20.5.0" } }, "sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ=="], + + "@commitlint/to-lines": ["@commitlint/to-lines@20.0.0", "", {}, "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw=="], + + "@commitlint/top-level": ["@commitlint/top-level@20.4.3", "", { "dependencies": { "escalade": "^3.2.0" } }, "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ=="], + + "@commitlint/types": ["@commitlint/types@20.5.0", "", { "dependencies": { "conventional-commits-parser": "^6.3.0", "picocolors": "^1.1.1" } }, "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA=="], + + "@conventional-changelog/git-client": ["@conventional-changelog/git-client@2.6.0", "", { "dependencies": { "@simple-libs/child-process-utils": "^1.0.0", "@simple-libs/stream-utils": "^1.2.0", "semver": "^7.5.2" }, "peerDependencies": { "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.3.0" }, "optionalPeers": ["conventional-commits-filter", "conventional-commits-parser"] }, "sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg=="], + + "@johngw/error": ["@johngw/error@2.2.2", "", { "dependencies": { "tslib": "2.5.2" } }, "sha512-V/QA3NZNhDwjfhDjfF1IYP/AohSwzkdDQzPEc8BVC7P7cYLKG6JtDIcDqE1WRJbcvl512CrKolZZTCOezWnBpA=="], + + "@johngw/fs": ["@johngw/fs@3.0.1", "", { "dependencies": { "tslib": "2.5.2" } }, "sha512-VPA521hX03kADhzUbYvO2iTvaLENElEpZ1pVDBkEr38v+Jy01V2w0/5tZ9mjCuTGCKVrv33cFnKgeXajeLG7Kg=="], + + "@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.56.0", "", { "os": "android", "cpu": "arm" }, "sha512-IyfYPthZyiSKwAv/dLjeO18SaK8MxLI9Yss2JrRDyweQAkuL3LhEy7pwIwI7uA3KQc1Vdn20kdmj3q0oUIQL6A=="], + + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.56.0", "", { "os": "android", "cpu": "arm64" }, "sha512-Ga5zYrzH6vc/VFxhn6MmyUnYEfy9vRpwTIks99mY3j6Nz30yYpIkWryI0QKPCgvGUtDSXVLEaMum5nA+WrNOSg=="], + + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.56.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ogmbdJysnw/D4bDcpf1sPLpFThZ48lYp4aKYm10Z/6Nh1SON6NtnNhTNOlhEY296tDFItsZUz+2tgcSYqh8Eyw=="], + + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.56.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-x8QE1h+RAtQ2g+3KPsP6Fk/tdz6zJQUv5c7fTrJxXV3GHOo+Ry5p/PsogU4U+iUZg0rj6hS+E4xi+mnwwlDCWQ=="], + + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.56.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-6G+WMZvwJpMvY7my+/SHEjb7BTk/PFbePqLpmVmUJRIsJMy/UlyYqjpuh0RCgYYkPLcnXm1rUM04kbTk8yS1Yg=="], + + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-YYHBsk/sl7fYwQOok+6W5lBPeUEvisznV/HZD2IfZmF3Bns6cPC3Z0vCtSEOaAWTjYWN3jVsdu55jMxKlsdlhg=="], + + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-+AZK8rOUr78y8WT6XkDb04IbMRqauNV+vgT6f8ZLOH8wnpQ9i7Nol0XLxAu+Cq7Sb+J9wC0j6Km5hG8rj47/yQ=="], + + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-urse2SnugwJRojUkGSSeH2LPMaje5Q50yQtvtL9HFckiyeqXzoFwOAZqD5TR29R2lq7UHidfFDM9EGcchcbb8A=="], + + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-rkTZkBfJ4TYLjansjSzL6mgZOdN5IvUnSq3oNJSLwBcNvy3dlgQtpHPrRxrCEbbcp7oQ6If0tkNaqfOsphYZ9g=="], + + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.56.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-uqL1kMH3u69/e1CH2EJhP3CP28jw2ExLsku4o8RVAZ7fySo9zOyI2fy9pVlTAp4voBLVgzndXi3SgtdyCTa2aA=="], + + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-j0CcMBOgV6KsRaBdsebIeiy7hCjEvq2KdEsiULf2LZqAq0v1M1lWjelhCV57LxsqaIGChXFuFJ0RiFrSRHPhSg=="], + + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-7VDOiL8cDG3DQ/CY3yKjbV1c4YPvc4vH8qW09Vv+5ukq3l/Kcyr6XGCd5NvxUmxqDb2vjMpM+eW/4JrEEsUetA=="], + + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.56.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-JGRpX0M+ikD3WpwJ7vKcHKV6Kg0dT52BW2Eu2BupXotYeqGXBrbY+QPkAyKO6MNgKozyTNaRh3r7g+VWgyAQYQ=="], + + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-dNaICPvtmuxFP/VbqdofrLqdS3bM/AKJN3LMJD52si44ea7Be1cBk6NpfIahaysG9Uo+L98QKddU9CD5L8UHnQ=="], + + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pF1vOtM+GuXmbklM1hV8WMsn6tCNPvkUzklj/Ej98JhlanbmA2RB1BILgOpwSuCTRTIYx2MXssmEyQQ90QF5aA=="], + + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.56.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bp8NQ4RE6fDIFLa4bdBiOA+TAvkNkg+rslR+AvvjlLTYXLy9/uKAYLQudaQouWihLD/hgkrXIKKzXi5IXOewwg=="], + + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.56.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-PxT4OJDfMOQBzo3OlzFb9gkoSD+n8qSBxyVq2wQSZIHFQYGEqIRTo9M0ZStvZm5fdhMqaVYpOnJvH2hUMEDk/g=="], + + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.56.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-PTRy6sIEPqy2x8PTP1baBNReN/BNEFmde0L+mYeHmjXE1Vlcc9+I5nsqENsB2yAm5wLkzPoTNCMY/7AnabT4/A=="], + + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.56.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ZHa0clocjLmIDr+1LwoWtxRcoYniAvERotvwKUYKhH41NVfl0Y4LNbyQkwMZzwDvKklKGvGZ5+DAG58/Ik47tQ=="], + + "@paralleldrive/cuid2": ["@paralleldrive/cuid2@2.3.1", "", { "dependencies": { "@noble/hashes": "^1.1.5" } }, "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw=="], + + "@simple-libs/child-process-utils": ["@simple-libs/child-process-utils@1.0.2", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0" } }, "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw=="], + + "@simple-libs/stream-utils": ["@simple-libs/stream-utils@1.2.0", "", {}, "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA=="], + + "@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="], + + "@sinonjs/fake-timers": ["@sinonjs/fake-timers@15.1.1", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw=="], + + "@sinonjs/samsam": ["@sinonjs/samsam@9.0.3", "", { "dependencies": { "@sinonjs/commons": "^3.0.1", "type-detect": "^4.1.0" } }, "sha512-ZgYY7Dc2RW+OUdnZ1DEHg00lhRt+9BjymPKHog4PRFzr1U3MbK57+djmscWyKxzO1qfunHqs4N45WWyKIFKpiQ=="], + + "@targetd/api": ["@targetd/api@workspace:packages/api"], + + "@targetd/client": ["@targetd/client@workspace:packages/client"], + + "@targetd/date-range": ["@targetd/date-range@workspace:packages/date-range"], + + "@targetd/explode": ["@targetd/explode@workspace:packages/explode"], + + "@targetd/fs": ["@targetd/fs@workspace:packages/fs"], + + "@targetd/json-schema": ["@targetd/json-schema@workspace:packages/json-schema"], + + "@targetd/server": ["@targetd/server@workspace:packages/server"], + + "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], + + "@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="], + + "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], + + "@types/cookiejar": ["@types/cookiejar@2.1.5", "", {}, "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q=="], + + "@types/express": ["@types/express@5.0.6", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", "@types/serve-static": "^2" } }, "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA=="], + + "@types/express-serve-static-core": ["@types/express-serve-static-core@5.1.1", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A=="], + + "@types/http-errors": ["@types/http-errors@2.0.5", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="], + + "@types/methods": ["@types/methods@1.1.4", "", {}, "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ=="], + + "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], + + "@types/qs": ["@types/qs@6.15.0", "", {}, "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow=="], + + "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="], + + "@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="], + + "@types/serve-static": ["@types/serve-static@2.2.0", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*" } }, "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ=="], + + "@types/sinon": ["@types/sinon@21.0.0", "", { "dependencies": { "@types/sinonjs__fake-timers": "*" } }, "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw=="], + + "@types/sinonjs__fake-timers": ["@types/sinonjs__fake-timers@15.0.1", "", {}, "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w=="], + + "@types/superagent": ["@types/superagent@8.1.9", "", { "dependencies": { "@types/cookiejar": "^2.1.5", "@types/methods": "^1.1.4", "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ=="], + + "@types/supertest": ["@types/supertest@7.2.0", "", { "dependencies": { "@types/methods": "^1.1.4", "@types/superagent": "^8.1.0" } }, "sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw=="], + + "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="], + + "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "ajv": ["ajv@8.18.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" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + + "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], + + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "array-ify": ["array-ify@1.0.0", "", {}, "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng=="], + + "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="], + + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], + + "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], + + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], + + "cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="], + + "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], + + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + + "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], + + "component-emitter": ["component-emitter@1.3.1", "", {}, "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ=="], + + "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], + + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], + + "conventional-changelog-angular": ["conventional-changelog-angular@8.3.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA=="], + + "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@9.3.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA=="], + + "conventional-commits-parser": ["conventional-commits-parser@6.3.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg=="], + + "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], + + "cookiejar": ["cookiejar@2.1.4", "", {}, "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="], + + "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + + "cosmiconfig": ["cosmiconfig@9.0.1", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ=="], + + "cosmiconfig-typescript-loader": ["cosmiconfig-typescript-loader@6.2.0", "", { "dependencies": { "jiti": "^2.6.1" }, "peerDependencies": { "@types/node": "*", "cosmiconfig": ">=9", "typescript": ">=5" } }, "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "dezalgo": ["dezalgo@1.0.4", "", { "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig=="], + + "diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], + + "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + + "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + + "es-toolkit": ["es-toolkit@1.45.1", "", {}, "sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + + "express-query-boolean": ["express-query-boolean@2.0.0", "", {}, "sha512-4dU/1HPm8lkTPR12+HFUXqCarcsC19OKOkb4otLOuADfPYrQMaugPJkSmxNsqwmWYjozvT6vdTiqkgeBHkzOow=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="], + + "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + + "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], + + "flat": ["flat@6.0.1", "", { "bin": { "flat": "cli.js" } }, "sha512-/3FfIa8mbrg3xE7+wAhWeV+bd7L2Mof+xtZb5dRDKZ+wDvYJK4WDYeIOuOhre5Yv5aQObZrlbRmk3RTSiuQBtw=="], + + "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], + + "formidable": ["formidable@3.5.4", "", { "dependencies": { "@paralleldrive/cuid2": "^2.2.2", "dezalgo": "^1.0.4", "once": "^1.4.0" } }, "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug=="], + + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], + + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "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" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "git-raw-commits": ["git-raw-commits@5.0.1", "", { "dependencies": { "@conventional-changelog/git-client": "^2.6.0", "meow": "^13.0.0" }, "bin": { "git-raw-commits": "src/cli.js" } }, "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ=="], + + "global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="], + + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], + + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + + "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "lint-staged": ["lint-staged@16.4.0", "", { "dependencies": { "commander": "^14.0.3", "listr2": "^9.0.5", "picomatch": "^4.0.3", "string-argv": "^0.3.2", "tinyexec": "^1.0.4", "yaml": "^2.8.2" }, "bin": { "lint-staged": "bin/lint-staged.js" } }, "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw=="], + + "listr2": ["listr2@9.0.5", "", { "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g=="], + + "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], + + "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="], + + "lodash.kebabcase": ["lodash.kebabcase@4.1.1", "", {}, "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="], + + "lodash.mergewith": ["lodash.mergewith@4.6.2", "", {}, "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="], + + "lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="], + + "lodash.startcase": ["lodash.startcase@4.4.0", "", {}, "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg=="], + + "lodash.upperfirst": ["lodash.upperfirst@4.3.1", "", {}, "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg=="], + + "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + + "meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], + + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], + + "methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="], + + "mime": ["mime@2.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], + + "oxlint": ["oxlint@1.56.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.56.0", "@oxlint/binding-android-arm64": "1.56.0", "@oxlint/binding-darwin-arm64": "1.56.0", "@oxlint/binding-darwin-x64": "1.56.0", "@oxlint/binding-freebsd-x64": "1.56.0", "@oxlint/binding-linux-arm-gnueabihf": "1.56.0", "@oxlint/binding-linux-arm-musleabihf": "1.56.0", "@oxlint/binding-linux-arm64-gnu": "1.56.0", "@oxlint/binding-linux-arm64-musl": "1.56.0", "@oxlint/binding-linux-ppc64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-musl": "1.56.0", "@oxlint/binding-linux-s390x-gnu": "1.56.0", "@oxlint/binding-linux-x64-gnu": "1.56.0", "@oxlint/binding-linux-x64-musl": "1.56.0", "@oxlint/binding-openharmony-arm64": "1.56.0", "@oxlint/binding-win32-arm64-msvc": "1.56.0", "@oxlint/binding-win32-ia32-msvc": "1.56.0", "@oxlint/binding-win32-x64-msvc": "1.56.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.15.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g=="], + + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "parse-json": ["parse-json@5.2.0", "", { "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" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], + + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + + "qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="], + + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], + + "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], + + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], + + "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], + + "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "sinon": ["sinon@21.0.3", "", { "dependencies": { "@sinonjs/commons": "^3.0.1", "@sinonjs/fake-timers": "^15.1.1", "@sinonjs/samsam": "^9.0.3", "diff": "^8.0.3", "supports-color": "^7.2.0" } }, "sha512-0x8TQFr8EjADhSME01u1ZK31yv2+bd6Z5NrBCHVM+n4qL1wFqbxftmeyi3bwlr49FbbzRfrqSFOpyHCOh/YmYA=="], + + "slice-ansi": ["slice-ansi@8.0.0", "", { "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" } }, "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg=="], + + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + + "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], + + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "superagent": ["superagent@10.3.0", "", { "dependencies": { "component-emitter": "^1.3.1", "cookiejar": "^2.1.4", "debug": "^4.3.7", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.5", "formidable": "^3.5.4", "methods": "^1.1.2", "mime": "2.6.0", "qs": "^6.14.1" } }, "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ=="], + + "supertest": ["supertest@7.2.2", "", { "dependencies": { "cookie-signature": "^1.2.2", "methods": "^1.1.2", "superagent": "^10.3.0" } }, "sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], + + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "ts-toolbelt": ["ts-toolbelt@9.6.0", "", {}, "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w=="], + + "tslib": ["tslib@2.5.2", "", {}, "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA=="], + + "type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="], + + "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], + + "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], + + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], + + "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], + + "@commitlint/cli/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "@sinonjs/samsam/type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="], + + "cli-truncate/string-width": ["string-width@8.2.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw=="], + + "form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "log-update/slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="], + + "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "@commitlint/cli/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "@commitlint/cli/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "@commitlint/cli/yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "@commitlint/cli/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "@commitlint/cli/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "@commitlint/cli/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "@commitlint/cli/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "@commitlint/cli/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "@commitlint/cli/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "@commitlint/cli/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + } +} diff --git a/deno.json b/deno.json deleted file mode 100644 index ae0efd533..000000000 --- a/deno.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "lint": { - "rules": { - "exclude": ["no-explicit-any", "ban-types"] - } - }, - "tasks": { - "check": "deno check --frozen packages/**/src", - "commitlint": "deno run --allow-read --allow-env --allow-sys @commitlint/cli", - "hook": "deno run --allow-read --allow-run --allow-write https://deno.land/x/deno_hooks@0.1.1/mod.ts", - "test": "deno test --frozen --allow-all packages/**/test", - "test:dev": "deno test --allow-all packages/**/test" - }, - "workspace": [ - "./packages/*" - ], - "imports": { - "@commitlint/cli": "npm:@commitlint/cli@^20.4.3", - "@commitlint/config-conventional": "npm:@commitlint/config-conventional@^20.4.3", - "lint-staged": "npm:lint-staged@^16.3.1" - } -} diff --git a/deno.lock b/deno.lock deleted file mode 100644 index 521fcff84..000000000 --- a/deno.lock +++ /dev/null @@ -1,2175 +0,0 @@ -{ - "version": "5", - "specifiers": { - "jsr:@es-toolkit/es-toolkit@^1.45.1": "1.45.1", - "jsr:@std/assert@*": "1.0.14", - "jsr:@std/assert@^1.0.13": "1.0.14", - "jsr:@std/async@^1.0.13": "1.0.14", - "jsr:@std/data-structures@^1.0.9": "1.0.9", - "jsr:@std/fs@*": "1.0.19", - "jsr:@std/fs@^1.0.19": "1.0.19", - "jsr:@std/internal@^1.0.10": "1.0.10", - "jsr:@std/internal@^1.0.9": "1.0.10", - "jsr:@std/path@^1.1.1": "1.1.2", - "jsr:@std/testing@*": "1.0.15", - "npm:@commitlint/cli@^20.4.3": "20.4.4_@types+node@25.5.0_typescript@5.9.3", - "npm:@commitlint/config-conventional@^20.4.3": "20.4.4", - "npm:@johngw/error@^2.2.2": "2.2.2", - "npm:@johngw/fs@^3.0.1": "3.0.1", - "npm:@types/express@^5.0.6": "5.0.6", - "npm:@types/qs@^6.15.0": "6.15.0", - "npm:@types/supertest@*": "6.0.3", - "npm:@types/yargs@^17.0.35": "17.0.35", - "npm:cors@^2.8.6": "2.8.6", - "npm:express-query-boolean@2": "2.0.0", - "npm:express@^5.2.1": "5.2.1", - "npm:fast-deep-equal@^3.1.3": "3.1.3", - "npm:flat@^6.0.1": "6.0.1", - "npm:lint-staged@^16.3.1": "16.3.3", - "npm:lodash@*": "4.17.23", - "npm:qs@^6.15.0": "6.15.0", - "npm:release-please@*": "17.3.0", - "npm:supertest@*": "7.2.2", - "npm:ts-toolbelt@^9.6.0": "9.6.0", - "npm:yaml@^2.8.2": "2.8.2", - "npm:yargs@18": "18.0.0", - "npm:zod@^4.3.6": "4.3.6" - }, - "jsr": { - "@es-toolkit/es-toolkit@1.45.1": { - "integrity": "fcfce61ab4ac4db2fd45841ac86f6101b271d4e3a094dc7edbb14fd41289471b" - }, - "@std/assert@1.0.14": { - "integrity": "68d0d4a43b365abc927f45a9b85c639ea18a9fab96ad92281e493e4ed84abaa4", - "dependencies": [ - "jsr:@std/internal@^1.0.10" - ] - }, - "@std/async@1.0.14": { - "integrity": "62e954a418652c704d37563a3e54a37d4cf0268a9dcaeac1660cc652880b5326" - }, - "@std/data-structures@1.0.9": { - "integrity": "033d6e17e64bf1f84a614e647c1b015fa2576ae3312305821e1a4cb20674bb4d" - }, - "@std/fs@1.0.19": { - "integrity": "051968c2b1eae4d2ea9f79a08a3845740ef6af10356aff43d3e2ef11ed09fb06", - "dependencies": [ - "jsr:@std/internal@^1.0.9", - "jsr:@std/path" - ] - }, - "@std/internal@1.0.10": { - "integrity": "e3be62ce42cab0e177c27698e5d9800122f67b766a0bea6ca4867886cbde8cf7" - }, - "@std/path@1.1.2": { - "integrity": "c0b13b97dfe06546d5e16bf3966b1cadf92e1cc83e56ba5476ad8b498d9e3038", - "dependencies": [ - "jsr:@std/internal@^1.0.10" - ] - }, - "@std/testing@1.0.15": { - "integrity": "a490169f5ccb0f3ae9c94fbc69d2cd43603f2cffb41713a85f99bbb0e3087cbc", - "dependencies": [ - "jsr:@std/assert@^1.0.13", - "jsr:@std/async", - "jsr:@std/data-structures", - "jsr:@std/fs@^1.0.19", - "jsr:@std/internal@^1.0.10", - "jsr:@std/path" - ] - } - }, - "npm": { - "@babel/code-frame@7.29.0": { - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dependencies": [ - "@babel/helper-validator-identifier", - "js-tokens", - "picocolors" - ] - }, - "@babel/helper-validator-identifier@7.28.5": { - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==" - }, - "@commitlint/cli@20.4.4_@types+node@25.5.0_typescript@5.9.3": { - "integrity": "sha512-GLMNQHYGcn0ohL2HMlAnXcD1PS2vqBBGbYKlhrRPOYsWiRoLWtrewsR3uKRb9v/IdS+qOS0vqJQ64n1g8VPKFw==", - "dependencies": [ - "@commitlint/format", - "@commitlint/lint", - "@commitlint/load", - "@commitlint/read", - "@commitlint/types", - "tinyexec", - "yargs@17.7.2" - ], - "bin": true - }, - "@commitlint/config-conventional@20.4.4": { - "integrity": "sha512-Usg+XXbPNG2GtFWTgRURNWCge1iH1y6jQIvvklOdAbyn2t8ajfVwZCnf5t5X4gUsy17BOiY+myszGsSMIvhOVA==", - "dependencies": [ - "@commitlint/types", - "conventional-changelog-conventionalcommits@9.3.0" - ] - }, - "@commitlint/config-validator@20.4.4": { - "integrity": "sha512-K8hMS9PTLl7EYe5vWtSFQ/sgsV2PHUOtEnosg8k3ZQxCyfKD34I4C7FxWEfRTR54rFKeUYmM3pmRQqBNQeLdlw==", - "dependencies": [ - "@commitlint/types", - "ajv" - ] - }, - "@commitlint/ensure@20.4.4": { - "integrity": "sha512-QivV0M1MGL867XCaF+jJkbVXEPKBALhUUXdjae66hes95aY1p3vBJdrcl3x8jDv2pdKWvIYIz+7DFRV/v0dRkA==", - "dependencies": [ - "@commitlint/types", - "lodash.camelcase", - "lodash.kebabcase", - "lodash.snakecase", - "lodash.startcase", - "lodash.upperfirst" - ] - }, - "@commitlint/execute-rule@20.0.0": { - "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==" - }, - "@commitlint/format@20.4.4": { - "integrity": "sha512-jLi/JBA4GEQxc5135VYCnkShcm1/rarbXMn2Tlt3Si7DHiiNKHm4TaiJCLnGbZ1r8UfwDRk+qrzZ80kwh08Aow==", - "dependencies": [ - "@commitlint/types", - "picocolors" - ] - }, - "@commitlint/is-ignored@20.4.4": { - "integrity": "sha512-y76rT8yq02x+pMDBI2vY4y/ByAwmJTkta/pASbgo8tldBiKLduX8/2NCRTSCjb3SumE5FBeopERKx3oMIm8RTQ==", - "dependencies": [ - "@commitlint/types", - "semver@7.7.4" - ] - }, - "@commitlint/lint@20.4.4": { - "integrity": "sha512-svOEW+RptcNpXKE7UllcAsV0HDIdOck9reC2TP1QA6K5Fo0xxQV+QPjV8Zqx9g6X/hQBkF2S9ZQZ78Xrv1Eiog==", - "dependencies": [ - "@commitlint/is-ignored", - "@commitlint/parse", - "@commitlint/rules", - "@commitlint/types" - ] - }, - "@commitlint/load@20.4.4_@types+node@25.5.0_typescript@5.9.3": { - "integrity": "sha512-kvFrzvoIACa/fMjXEP0LNEJB1joaH3q3oeMJsLajXE5IXjYrNGVcW1ZFojXUruVJ7odTZbC3LdE/6+ONW4f2Dg==", - "dependencies": [ - "@commitlint/config-validator", - "@commitlint/execute-rule", - "@commitlint/resolve-extends", - "@commitlint/types", - "cosmiconfig", - "cosmiconfig-typescript-loader", - "is-plain-obj@4.1.0", - "lodash.mergewith", - "picocolors" - ] - }, - "@commitlint/message@20.4.3": { - "integrity": "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==" - }, - "@commitlint/parse@20.4.4": { - "integrity": "sha512-AjfgOgrjEozeQNzhFu1KL5N0nDx4JZmswVJKNfOTLTUGp6xODhZHCHqb//QUHKOzx36If5DQ7tci2o7szYxu1A==", - "dependencies": [ - "@commitlint/types", - "conventional-changelog-angular", - "conventional-commits-parser" - ] - }, - "@commitlint/read@20.4.4": { - "integrity": "sha512-jvgdAQDdEY6L8kCxOo21IWoiAyNFzvrZb121wU2eBxI1DzWAUZgAq+a8LlJRbT0Qsj9INhIPVWgdaBbEzlF0dQ==", - "dependencies": [ - "@commitlint/top-level", - "@commitlint/types", - "git-raw-commits", - "minimist", - "tinyexec" - ] - }, - "@commitlint/resolve-extends@20.4.4": { - "integrity": "sha512-pyOf+yX3c3m/IWAn2Jop+7s0YGKPQ8YvQaxt9IQxnLIM3yZAlBdkKiQCT14TnrmZTkVGTXiLtckcnFTXYwlY0A==", - "dependencies": [ - "@commitlint/config-validator", - "@commitlint/types", - "global-directory", - "import-meta-resolve", - "lodash.mergewith", - "resolve-from@5.0.0" - ] - }, - "@commitlint/rules@20.4.4": { - "integrity": "sha512-PmUp8QPLICn9w05dAx5r1rdOYoTk7SkfusJJh5tP3TqHwo2mlQ9jsOm8F0HSXU9kuLfgTEGNrunAx/dlK/RyPQ==", - "dependencies": [ - "@commitlint/ensure", - "@commitlint/message", - "@commitlint/to-lines", - "@commitlint/types" - ] - }, - "@commitlint/to-lines@20.0.0": { - "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==" - }, - "@commitlint/top-level@20.4.3": { - "integrity": "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==", - "dependencies": [ - "escalade" - ] - }, - "@commitlint/types@20.4.4": { - "integrity": "sha512-dwTGzyAblFXHJNBOgrTuO5Ee48ioXpS5XPRLLatxhQu149DFAHUcB3f0Q5eea3RM4USSsP1+WVT2dBtLVod4fg==", - "dependencies": [ - "conventional-commits-parser", - "picocolors" - ] - }, - "@conventional-changelog/git-client@2.6.0": { - "integrity": "sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==", - "dependencies": [ - "@simple-libs/child-process-utils", - "@simple-libs/stream-utils", - "semver@7.7.4" - ] - }, - "@conventional-commits/parser@0.4.1": { - "integrity": "sha512-H2ZmUVt6q+KBccXfMBhbBF14NlANeqHTXL4qCL6QGbMzrc4HDXyzWuxPxPNbz71f/5UkR5DrycP5VO9u7crahg==", - "dependencies": [ - "unist-util-visit", - "unist-util-visit-parents" - ] - }, - "@google-automations/git-file-utils@3.0.0": { - "integrity": "sha512-e+WLoKR0TchIhKsSDOnd/su171eXKAAdLpP2tS825UAloTgfYus53kW8uKoVj9MAsMjXGXsJ2s1ASgjq81xVdA==", - "dependencies": [ - "@octokit/rest", - "@octokit/types", - "minimatch@5.1.9" - ] - }, - "@iarna/toml@3.0.0": { - "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==" - }, - "@johngw/error@2.2.2": { - "integrity": "sha512-V/QA3NZNhDwjfhDjfF1IYP/AohSwzkdDQzPEc8BVC7P7cYLKG6JtDIcDqE1WRJbcvl512CrKolZZTCOezWnBpA==", - "dependencies": [ - "tslib" - ] - }, - "@johngw/fs@3.0.1": { - "integrity": "sha512-VPA521hX03kADhzUbYvO2iTvaLENElEpZ1pVDBkEr38v+Jy01V2w0/5tZ9mjCuTGCKVrv33cFnKgeXajeLG7Kg==", - "dependencies": [ - "tslib" - ] - }, - "@jsep-plugin/assignment@1.3.0_jsep@1.4.0": { - "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", - "dependencies": [ - "jsep" - ] - }, - "@jsep-plugin/regex@1.0.4_jsep@1.4.0": { - "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", - "dependencies": [ - "jsep" - ] - }, - "@noble/hashes@1.8.0": { - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==" - }, - "@octokit/auth-token@4.0.0": { - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==" - }, - "@octokit/core@5.2.2": { - "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", - "dependencies": [ - "@octokit/auth-token", - "@octokit/graphql", - "@octokit/request", - "@octokit/request-error", - "@octokit/types", - "before-after-hook", - "universal-user-agent" - ] - }, - "@octokit/endpoint@9.0.6": { - "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", - "dependencies": [ - "@octokit/types", - "universal-user-agent" - ] - }, - "@octokit/graphql@7.1.1": { - "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", - "dependencies": [ - "@octokit/request", - "@octokit/types", - "universal-user-agent" - ] - }, - "@octokit/openapi-types@24.2.0": { - "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==" - }, - "@octokit/plugin-paginate-rest@11.4.4-cjs.2_@octokit+core@5.2.2": { - "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", - "dependencies": [ - "@octokit/core", - "@octokit/types" - ] - }, - "@octokit/plugin-request-log@4.0.1_@octokit+core@5.2.2": { - "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", - "dependencies": [ - "@octokit/core" - ] - }, - "@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1_@octokit+core@5.2.2": { - "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", - "dependencies": [ - "@octokit/core", - "@octokit/types" - ] - }, - "@octokit/request-error@5.1.1": { - "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", - "dependencies": [ - "@octokit/types", - "deprecation", - "once" - ] - }, - "@octokit/request@8.4.1": { - "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", - "dependencies": [ - "@octokit/endpoint", - "@octokit/request-error", - "@octokit/types", - "universal-user-agent" - ] - }, - "@octokit/rest@20.1.2": { - "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", - "dependencies": [ - "@octokit/core", - "@octokit/plugin-paginate-rest", - "@octokit/plugin-request-log", - "@octokit/plugin-rest-endpoint-methods" - ] - }, - "@octokit/types@13.10.0": { - "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", - "dependencies": [ - "@octokit/openapi-types" - ] - }, - "@paralleldrive/cuid2@2.3.1": { - "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", - "dependencies": [ - "@noble/hashes" - ] - }, - "@simple-libs/child-process-utils@1.0.2": { - "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", - "dependencies": [ - "@simple-libs/stream-utils" - ] - }, - "@simple-libs/stream-utils@1.2.0": { - "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==" - }, - "@types/body-parser@1.19.6": { - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dependencies": [ - "@types/connect", - "@types/node" - ] - }, - "@types/connect@3.4.38": { - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": [ - "@types/node" - ] - }, - "@types/cookiejar@2.1.5": { - "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==" - }, - "@types/express-serve-static-core@5.1.1": { - "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", - "dependencies": [ - "@types/node", - "@types/qs", - "@types/range-parser", - "@types/send" - ] - }, - "@types/express@5.0.6": { - "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", - "dependencies": [ - "@types/body-parser", - "@types/express-serve-static-core", - "@types/serve-static" - ] - }, - "@types/http-errors@2.0.5": { - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==" - }, - "@types/methods@1.1.4": { - "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==" - }, - "@types/minimist@1.2.5": { - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==" - }, - "@types/node@25.5.0": { - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", - "dependencies": [ - "undici-types" - ] - }, - "@types/normalize-package-data@2.4.4": { - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==" - }, - "@types/npm-package-arg@6.1.4": { - "integrity": "sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==" - }, - "@types/qs@6.15.0": { - "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==" - }, - "@types/range-parser@1.2.7": { - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "@types/send@1.2.1": { - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "dependencies": [ - "@types/node" - ] - }, - "@types/serve-static@2.2.0": { - "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", - "dependencies": [ - "@types/http-errors", - "@types/node" - ] - }, - "@types/superagent@8.1.9": { - "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==", - "dependencies": [ - "@types/cookiejar", - "@types/methods", - "@types/node", - "form-data" - ] - }, - "@types/supertest@6.0.3": { - "integrity": "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==", - "dependencies": [ - "@types/methods", - "@types/superagent" - ] - }, - "@types/unist@2.0.11": { - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" - }, - "@types/yargs-parser@21.0.3": { - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "@types/yargs@16.0.11": { - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": [ - "@types/yargs-parser" - ] - }, - "@types/yargs@17.0.35": { - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "dependencies": [ - "@types/yargs-parser" - ] - }, - "@xmldom/xmldom@0.8.11": { - "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==" - }, - "accepts@2.0.0": { - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "dependencies": [ - "mime-types@3.0.2", - "negotiator" - ] - }, - "agent-base@7.1.4": { - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==" - }, - "ajv@8.18.0": { - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "dependencies": [ - "fast-deep-equal", - "fast-uri", - "json-schema-traverse", - "require-from-string" - ] - }, - "ansi-escapes@7.3.0": { - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", - "dependencies": [ - "environment" - ] - }, - "ansi-regex@5.0.1": { - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-regex@6.2.2": { - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" - }, - "ansi-styles@4.3.0": { - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": [ - "color-convert" - ] - }, - "ansi-styles@6.2.3": { - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" - }, - "argparse@2.0.1": { - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "array-ify@1.0.0": { - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==" - }, - "arrify@1.0.1": { - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" - }, - "asap@2.0.6": { - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "async-retry@1.3.3": { - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "dependencies": [ - "retry" - ] - }, - "asynckit@0.4.0": { - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "balanced-match@1.0.2": { - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "before-after-hook@2.2.3": { - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" - }, - "body-parser@2.2.2": { - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", - "dependencies": [ - "bytes", - "content-type", - "debug", - "http-errors", - "iconv-lite", - "on-finished", - "qs", - "raw-body", - "type-is" - ] - }, - "boolbase@1.0.0": { - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "brace-expansion@1.1.12": { - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dependencies": [ - "balanced-match", - "concat-map" - ] - }, - "brace-expansion@2.0.2": { - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dependencies": [ - "balanced-match" - ] - }, - "braces@3.0.3": { - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": [ - "fill-range" - ] - }, - "bytes@3.1.2": { - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "call-bind-apply-helpers@1.0.2": { - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dependencies": [ - "es-errors", - "function-bind" - ] - }, - "call-bound@1.0.4": { - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dependencies": [ - "call-bind-apply-helpers", - "get-intrinsic" - ] - }, - "callsites@3.1.0": { - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase-keys@6.2.2": { - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dependencies": [ - "camelcase", - "map-obj@4.3.0", - "quick-lru" - ] - }, - "camelcase@5.3.1": { - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chalk@4.1.2": { - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": [ - "ansi-styles@4.3.0", - "supports-color" - ] - }, - "cli-cursor@5.0.0": { - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dependencies": [ - "restore-cursor" - ] - }, - "cli-truncate@5.2.0": { - "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", - "dependencies": [ - "slice-ansi@8.0.0", - "string-width@8.2.0" - ] - }, - "cliui@7.0.4": { - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": [ - "string-width@4.2.3", - "strip-ansi@6.0.1", - "wrap-ansi@7.0.0" - ] - }, - "cliui@8.0.1": { - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": [ - "string-width@4.2.3", - "strip-ansi@6.0.1", - "wrap-ansi@7.0.0" - ] - }, - "cliui@9.0.1": { - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", - "dependencies": [ - "string-width@7.2.0", - "strip-ansi@7.2.0", - "wrap-ansi@9.0.2" - ] - }, - "code-suggester@5.0.1": { - "integrity": "sha512-8qJiiSCfkbPNWvjEFzdG1UW3axL+Bs0ldV1/TdlBKmF9I/a/WooSQZQCi9M44HoXbVTQesn/IQr6+nIWNnVIWA==", - "dependencies": [ - "@octokit/rest", - "@types/yargs@16.0.11", - "async-retry", - "diff", - "glob", - "parse-diff", - "yargs@16.2.0" - ], - "bin": true - }, - "color-convert@2.0.1": { - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": [ - "color-name" - ] - }, - "color-name@1.1.4": { - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colorette@2.0.20": { - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "combined-stream@1.0.8": { - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": [ - "delayed-stream" - ] - }, - "commander@14.0.3": { - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==" - }, - "compare-func@2.0.0": { - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dependencies": [ - "array-ify", - "dot-prop" - ] - }, - "component-emitter@1.3.1": { - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==" - }, - "concat-map@0.0.1": { - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "content-disposition@1.0.1": { - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==" - }, - "content-type@1.0.5": { - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "conventional-changelog-angular@8.3.0": { - "integrity": "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==", - "dependencies": [ - "compare-func" - ] - }, - "conventional-changelog-conventionalcommits@6.1.0": { - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", - "dependencies": [ - "compare-func" - ] - }, - "conventional-changelog-conventionalcommits@9.3.0": { - "integrity": "sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==", - "dependencies": [ - "compare-func" - ] - }, - "conventional-changelog-writer@6.0.1": { - "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", - "dependencies": [ - "conventional-commits-filter", - "dateformat", - "handlebars", - "json-stringify-safe", - "meow@8.1.2", - "semver@7.7.4", - "split" - ], - "bin": true - }, - "conventional-commits-filter@3.0.0": { - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", - "dependencies": [ - "lodash.ismatch", - "modify-values" - ] - }, - "conventional-commits-parser@6.3.0": { - "integrity": "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==", - "dependencies": [ - "@simple-libs/stream-utils", - "meow@13.2.0" - ], - "bin": true - }, - "cookie-signature@1.2.2": { - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==" - }, - "cookie@0.7.2": { - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==" - }, - "cookiejar@2.1.4": { - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" - }, - "cors@2.8.6": { - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "dependencies": [ - "object-assign", - "vary" - ] - }, - "cosmiconfig-typescript-loader@6.2.0_@types+node@25.5.0_cosmiconfig@9.0.1__typescript@5.9.3_typescript@5.9.3": { - "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", - "dependencies": [ - "@types/node", - "cosmiconfig", - "jiti", - "typescript@5.9.3" - ] - }, - "cosmiconfig@9.0.1_typescript@5.9.3": { - "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", - "dependencies": [ - "env-paths", - "import-fresh", - "js-yaml", - "parse-json", - "typescript@5.9.3" - ], - "optionalPeers": [ - "typescript@5.9.3" - ] - }, - "css-select@5.2.2": { - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "dependencies": [ - "boolbase", - "css-what", - "domhandler", - "domutils", - "nth-check" - ] - }, - "css-what@6.2.2": { - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==" - }, - "dateformat@3.0.3": { - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==" - }, - "debug@4.4.3": { - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dependencies": [ - "ms" - ] - }, - "decamelize-keys@1.1.1": { - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dependencies": [ - "decamelize", - "map-obj@1.0.1" - ] - }, - "decamelize@1.2.0": { - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" - }, - "delayed-stream@1.0.0": { - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "depd@2.0.0": { - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "deprecation@2.3.1": { - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - }, - "detect-indent@6.1.0": { - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==" - }, - "dezalgo@1.0.4": { - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", - "dependencies": [ - "asap", - "wrappy" - ] - }, - "diff@8.0.3": { - "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==" - }, - "dom-serializer@2.0.0": { - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dependencies": [ - "domelementtype", - "domhandler", - "entities" - ] - }, - "domelementtype@2.3.0": { - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" - }, - "domhandler@5.0.3": { - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dependencies": [ - "domelementtype" - ] - }, - "domutils@3.2.2": { - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "dependencies": [ - "dom-serializer", - "domelementtype", - "domhandler" - ] - }, - "dot-prop@5.3.0": { - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dependencies": [ - "is-obj" - ] - }, - "dunder-proto@1.0.1": { - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dependencies": [ - "call-bind-apply-helpers", - "es-errors", - "gopd" - ] - }, - "ee-first@1.1.1": { - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "emoji-regex@10.6.0": { - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" - }, - "emoji-regex@8.0.0": { - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "encodeurl@2.0.0": { - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - }, - "entities@4.5.0": { - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - }, - "env-paths@2.2.1": { - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" - }, - "environment@1.1.0": { - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==" - }, - "error-ex@1.3.4": { - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dependencies": [ - "is-arrayish" - ] - }, - "es-define-property@1.0.1": { - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" - }, - "es-errors@1.3.0": { - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "es-object-atoms@1.1.1": { - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dependencies": [ - "es-errors" - ] - }, - "es-set-tostringtag@2.1.0": { - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dependencies": [ - "es-errors", - "get-intrinsic", - "has-tostringtag", - "hasown" - ] - }, - "escalade@3.2.0": { - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" - }, - "escape-html@1.0.3": { - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp@1.0.5": { - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" - }, - "etag@1.8.1": { - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "eventemitter3@5.0.4": { - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==" - }, - "express-query-boolean@2.0.0": { - "integrity": "sha512-4dU/1HPm8lkTPR12+HFUXqCarcsC19OKOkb4otLOuADfPYrQMaugPJkSmxNsqwmWYjozvT6vdTiqkgeBHkzOow==" - }, - "express@5.2.1": { - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "dependencies": [ - "accepts", - "body-parser", - "content-disposition", - "content-type", - "cookie", - "cookie-signature", - "debug", - "depd", - "encodeurl", - "escape-html", - "etag", - "finalhandler", - "fresh", - "http-errors", - "merge-descriptors", - "mime-types@3.0.2", - "on-finished", - "once", - "parseurl", - "proxy-addr", - "qs", - "range-parser", - "router", - "send", - "serve-static", - "statuses", - "type-is", - "vary" - ] - }, - "fast-deep-equal@3.1.3": { - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-safe-stringify@2.1.1": { - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "fast-uri@3.1.0": { - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==" - }, - "figures@3.2.0": { - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dependencies": [ - "escape-string-regexp" - ] - }, - "fill-range@7.1.1": { - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": [ - "to-regex-range" - ] - }, - "finalhandler@2.1.1": { - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "dependencies": [ - "debug", - "encodeurl", - "escape-html", - "on-finished", - "parseurl", - "statuses" - ] - }, - "find-up@4.1.0": { - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": [ - "locate-path", - "path-exists" - ] - }, - "flat@6.0.1": { - "integrity": "sha512-/3FfIa8mbrg3xE7+wAhWeV+bd7L2Mof+xtZb5dRDKZ+wDvYJK4WDYeIOuOhre5Yv5aQObZrlbRmk3RTSiuQBtw==", - "bin": true - }, - "form-data@4.0.5": { - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "dependencies": [ - "asynckit", - "combined-stream", - "es-set-tostringtag", - "hasown", - "mime-types@2.1.35" - ] - }, - "formidable@3.5.4": { - "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", - "dependencies": [ - "@paralleldrive/cuid2", - "dezalgo", - "once" - ] - }, - "forwarded@0.2.0": { - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh@2.0.0": { - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==" - }, - "fs.realpath@1.0.0": { - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "function-bind@1.1.2": { - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "get-caller-file@2.0.5": { - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-east-asian-width@1.5.0": { - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==" - }, - "get-intrinsic@1.3.0": { - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dependencies": [ - "call-bind-apply-helpers", - "es-define-property", - "es-errors", - "es-object-atoms", - "function-bind", - "get-proto", - "gopd", - "has-symbols", - "hasown", - "math-intrinsics" - ] - }, - "get-proto@1.0.1": { - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dependencies": [ - "dunder-proto", - "es-object-atoms" - ] - }, - "git-raw-commits@5.0.1": { - "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", - "dependencies": [ - "@conventional-changelog/git-client", - "meow@13.2.0" - ], - "bin": true - }, - "glob@7.2.3": { - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": [ - "fs.realpath", - "inflight", - "inherits", - "minimatch@3.1.5", - "once", - "path-is-absolute" - ], - "deprecated": true - }, - "global-directory@4.0.1": { - "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", - "dependencies": [ - "ini" - ] - }, - "gopd@1.2.0": { - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" - }, - "handlebars@4.7.8": { - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dependencies": [ - "minimist", - "neo-async", - "source-map", - "wordwrap" - ], - "optionalDependencies": [ - "uglify-js" - ], - "bin": true - }, - "hard-rejection@2.1.0": { - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==" - }, - "has-flag@4.0.0": { - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-symbols@1.1.0": { - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" - }, - "has-tostringtag@1.0.2": { - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": [ - "has-symbols" - ] - }, - "hasown@2.0.2": { - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": [ - "function-bind" - ] - }, - "he@1.2.0": { - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": true - }, - "hosted-git-info@2.8.9": { - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" - }, - "hosted-git-info@4.1.0": { - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dependencies": [ - "lru-cache" - ] - }, - "http-errors@2.0.1": { - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dependencies": [ - "depd", - "inherits", - "setprototypeof", - "statuses", - "toidentifier" - ] - }, - "http-proxy-agent@7.0.2": { - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dependencies": [ - "agent-base", - "debug" - ] - }, - "https-proxy-agent@7.0.6": { - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dependencies": [ - "agent-base", - "debug" - ] - }, - "iconv-lite@0.7.2": { - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "dependencies": [ - "safer-buffer" - ] - }, - "import-fresh@3.3.1": { - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dependencies": [ - "parent-module", - "resolve-from@4.0.0" - ] - }, - "import-meta-resolve@4.2.0": { - "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==" - }, - "indent-string@4.0.0": { - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "inflight@1.0.6": { - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": [ - "once", - "wrappy" - ], - "deprecated": true - }, - "inherits@2.0.4": { - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini@4.1.1": { - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==" - }, - "ipaddr.js@1.9.1": { - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arrayish@0.2.1": { - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "is-core-module@2.16.1": { - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dependencies": [ - "hasown" - ] - }, - "is-fullwidth-code-point@3.0.0": { - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-fullwidth-code-point@5.1.0": { - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "dependencies": [ - "get-east-asian-width" - ] - }, - "is-number@7.0.0": { - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-obj@2.0.0": { - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - }, - "is-plain-obj@1.1.0": { - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==" - }, - "is-plain-obj@4.1.0": { - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" - }, - "is-promise@4.0.0": { - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" - }, - "jiti@2.6.1": { - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "bin": true - }, - "js-tokens@4.0.0": { - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml@4.1.1": { - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dependencies": [ - "argparse" - ], - "bin": true - }, - "jsep@1.4.0": { - "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==" - }, - "json-parse-even-better-errors@2.3.1": { - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json-schema-traverse@1.0.0": { - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "json-stringify-safe@5.0.1": { - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "jsonpath-plus@10.4.0": { - "integrity": "sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==", - "dependencies": [ - "@jsep-plugin/assignment", - "@jsep-plugin/regex", - "jsep" - ], - "bin": true - }, - "kind-of@6.0.3": { - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "lines-and-columns@1.2.4": { - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "lint-staged@16.3.3": { - "integrity": "sha512-RLq2koZ5fGWrx7tcqx2tSTMQj4lRkfNJaebO/li/uunhCJbtZqwTuwPHpgIimAHHi/2nZIiGrkCHDCOeR1onxA==", - "dependencies": [ - "commander", - "listr2", - "micromatch", - "string-argv", - "tinyexec", - "yaml" - ], - "bin": true - }, - "listr2@9.0.5": { - "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", - "dependencies": [ - "cli-truncate", - "colorette", - "eventemitter3", - "log-update", - "rfdc", - "wrap-ansi@9.0.2" - ] - }, - "locate-path@5.0.0": { - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": [ - "p-locate" - ] - }, - "lodash.camelcase@4.3.0": { - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "lodash.ismatch@4.4.0": { - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==" - }, - "lodash.kebabcase@4.1.1": { - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==" - }, - "lodash.mergewith@4.6.2": { - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" - }, - "lodash.snakecase@4.1.1": { - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" - }, - "lodash.startcase@4.4.0": { - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==" - }, - "lodash.upperfirst@4.3.1": { - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==" - }, - "lodash@4.17.23": { - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==" - }, - "log-update@6.1.0": { - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", - "dependencies": [ - "ansi-escapes", - "cli-cursor", - "slice-ansi@7.1.2", - "strip-ansi@7.2.0", - "wrap-ansi@9.0.2" - ] - }, - "lru-cache@6.0.0": { - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": [ - "yallist" - ] - }, - "map-obj@1.0.1": { - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==" - }, - "map-obj@4.3.0": { - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==" - }, - "math-intrinsics@1.1.0": { - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" - }, - "media-typer@1.1.0": { - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==" - }, - "meow@13.2.0": { - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==" - }, - "meow@8.1.2": { - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dependencies": [ - "@types/minimist", - "camelcase-keys", - "decamelize-keys", - "hard-rejection", - "minimist-options", - "normalize-package-data@3.0.3", - "read-pkg-up", - "redent", - "trim-newlines", - "type-fest@0.18.1", - "yargs-parser@20.2.9" - ] - }, - "merge-descriptors@2.0.0": { - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==" - }, - "methods@1.1.2": { - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "micromatch@4.0.8": { - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": [ - "braces", - "picomatch" - ] - }, - "mime-db@1.52.0": { - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-db@1.54.0": { - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==" - }, - "mime-types@2.1.35": { - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": [ - "mime-db@1.52.0" - ] - }, - "mime-types@3.0.2": { - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "dependencies": [ - "mime-db@1.54.0" - ] - }, - "mime@2.6.0": { - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": true - }, - "mimic-function@5.0.1": { - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==" - }, - "min-indent@1.0.1": { - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" - }, - "minimatch@3.1.5": { - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dependencies": [ - "brace-expansion@1.1.12" - ] - }, - "minimatch@5.1.9": { - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "dependencies": [ - "brace-expansion@2.0.2" - ] - }, - "minimist-options@4.1.0": { - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dependencies": [ - "arrify", - "is-plain-obj@1.1.0", - "kind-of" - ] - }, - "minimist@1.2.8": { - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "modify-values@1.0.1": { - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==" - }, - "ms@2.1.3": { - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "negotiator@1.0.0": { - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==" - }, - "neo-async@2.6.2": { - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-html-parser@6.1.13": { - "integrity": "sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==", - "dependencies": [ - "css-select", - "he" - ] - }, - "normalize-package-data@2.5.0": { - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dependencies": [ - "hosted-git-info@2.8.9", - "resolve", - "semver@5.7.2", - "validate-npm-package-license" - ] - }, - "normalize-package-data@3.0.3": { - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dependencies": [ - "hosted-git-info@4.1.0", - "is-core-module", - "semver@7.7.4", - "validate-npm-package-license" - ] - }, - "nth-check@2.1.1": { - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": [ - "boolbase" - ] - }, - "object-assign@4.1.1": { - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-inspect@1.13.4": { - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - }, - "on-finished@2.4.1": { - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": [ - "ee-first" - ] - }, - "once@1.4.0": { - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": [ - "wrappy" - ] - }, - "onetime@7.0.0": { - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dependencies": [ - "mimic-function" - ] - }, - "p-limit@2.3.0": { - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": [ - "p-try" - ] - }, - "p-locate@4.1.0": { - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": [ - "p-limit" - ] - }, - "p-try@2.2.0": { - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "parent-module@1.0.1": { - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": [ - "callsites" - ] - }, - "parse-diff@0.11.1": { - "integrity": "sha512-Oq4j8LAOPOcssanQkIjxosjATBIEJhCxMCxPhMu+Ci4wdNmAEdx0O+a7gzbR2PyKXgKPvRLIN5g224+dJAsKHA==" - }, - "parse-github-repo-url@1.4.1": { - "integrity": "sha512-bSWyzBKqcSL4RrncTpGsEKoJ7H8a4L3++ifTAbTFeMHyq2wRV+42DGmQcHIrJIvdcacjIOxEuKH/w4tthF17gg==" - }, - "parse-json@5.2.0": { - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": [ - "@babel/code-frame", - "error-ex", - "json-parse-even-better-errors", - "lines-and-columns" - ] - }, - "parseurl@1.3.3": { - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-exists@4.0.0": { - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-is-absolute@1.0.1": { - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-parse@1.0.7": { - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-to-regexp@8.3.0": { - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==" - }, - "picocolors@1.1.1": { - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "picomatch@2.3.1": { - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "proxy-addr@2.0.7": { - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": [ - "forwarded", - "ipaddr.js" - ] - }, - "qs@6.15.0": { - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", - "dependencies": [ - "side-channel" - ] - }, - "quick-lru@4.0.1": { - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==" - }, - "range-parser@1.2.1": { - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body@3.0.2": { - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "dependencies": [ - "bytes", - "http-errors", - "iconv-lite", - "unpipe" - ] - }, - "read-pkg-up@7.0.1": { - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": [ - "find-up", - "read-pkg", - "type-fest@0.8.1" - ] - }, - "read-pkg@5.2.0": { - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": [ - "@types/normalize-package-data", - "normalize-package-data@2.5.0", - "parse-json", - "type-fest@0.6.0" - ] - }, - "redent@3.0.0": { - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dependencies": [ - "indent-string", - "strip-indent" - ] - }, - "release-please@17.3.0": { - "integrity": "sha512-dB7HsFUpAvU1Wj9RGCINUz8Zi2qQDZiGbDEEVnJ7baNfJmk5XdYhuUFL6RcuDGjReGhp1gzY8Tc2g7vHlM4zpg==", - "dependencies": [ - "@conventional-commits/parser", - "@google-automations/git-file-utils", - "@iarna/toml", - "@octokit/graphql", - "@octokit/request", - "@octokit/request-error", - "@octokit/rest", - "@types/npm-package-arg", - "@xmldom/xmldom", - "chalk", - "code-suggester", - "conventional-changelog-conventionalcommits@6.1.0", - "conventional-changelog-writer", - "conventional-commits-filter", - "detect-indent", - "diff", - "figures", - "http-proxy-agent", - "https-proxy-agent", - "js-yaml", - "jsonpath-plus", - "node-html-parser", - "parse-github-repo-url", - "semver@7.7.4", - "type-fest@3.13.1", - "typescript@4.9.5", - "unist-util-visit", - "unist-util-visit-parents", - "xpath", - "yaml", - "yargs@17.7.2" - ], - "bin": true - }, - "require-directory@2.1.1": { - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - }, - "require-from-string@2.0.2": { - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "resolve-from@4.0.0": { - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "resolve-from@5.0.0": { - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "resolve@1.22.11": { - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dependencies": [ - "is-core-module", - "path-parse", - "supports-preserve-symlinks-flag" - ], - "bin": true - }, - "restore-cursor@5.1.0": { - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dependencies": [ - "onetime", - "signal-exit" - ] - }, - "retry@0.13.1": { - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" - }, - "rfdc@1.4.1": { - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" - }, - "router@2.2.0": { - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "dependencies": [ - "debug", - "depd", - "is-promise", - "parseurl", - "path-to-regexp" - ] - }, - "safer-buffer@2.1.2": { - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver@5.7.2": { - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": true - }, - "semver@7.7.4": { - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "bin": true - }, - "send@1.2.1": { - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "dependencies": [ - "debug", - "encodeurl", - "escape-html", - "etag", - "fresh", - "http-errors", - "mime-types@3.0.2", - "ms", - "on-finished", - "range-parser", - "statuses" - ] - }, - "serve-static@2.2.1": { - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "dependencies": [ - "encodeurl", - "escape-html", - "parseurl", - "send" - ] - }, - "setprototypeof@1.2.0": { - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "side-channel-list@1.0.0": { - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dependencies": [ - "es-errors", - "object-inspect" - ] - }, - "side-channel-map@1.0.1": { - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dependencies": [ - "call-bound", - "es-errors", - "get-intrinsic", - "object-inspect" - ] - }, - "side-channel-weakmap@1.0.2": { - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dependencies": [ - "call-bound", - "es-errors", - "get-intrinsic", - "object-inspect", - "side-channel-map" - ] - }, - "side-channel@1.1.0": { - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dependencies": [ - "es-errors", - "object-inspect", - "side-channel-list", - "side-channel-map", - "side-channel-weakmap" - ] - }, - "signal-exit@4.1.0": { - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "slice-ansi@7.1.2": { - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", - "dependencies": [ - "ansi-styles@6.2.3", - "is-fullwidth-code-point@5.1.0" - ] - }, - "slice-ansi@8.0.0": { - "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", - "dependencies": [ - "ansi-styles@6.2.3", - "is-fullwidth-code-point@5.1.0" - ] - }, - "source-map@0.6.1": { - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "spdx-correct@3.2.0": { - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dependencies": [ - "spdx-expression-parse", - "spdx-license-ids" - ] - }, - "spdx-exceptions@2.5.0": { - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" - }, - "spdx-expression-parse@3.0.1": { - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dependencies": [ - "spdx-exceptions", - "spdx-license-ids" - ] - }, - "spdx-license-ids@3.0.23": { - "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==" - }, - "split@1.0.1": { - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dependencies": [ - "through" - ] - }, - "statuses@2.0.2": { - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - }, - "string-argv@0.3.2": { - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==" - }, - "string-width@4.2.3": { - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": [ - "emoji-regex@8.0.0", - "is-fullwidth-code-point@3.0.0", - "strip-ansi@6.0.1" - ] - }, - "string-width@7.2.0": { - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dependencies": [ - "emoji-regex@10.6.0", - "get-east-asian-width", - "strip-ansi@7.2.0" - ] - }, - "string-width@8.2.0": { - "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", - "dependencies": [ - "get-east-asian-width", - "strip-ansi@7.2.0" - ] - }, - "strip-ansi@6.0.1": { - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": [ - "ansi-regex@5.0.1" - ] - }, - "strip-ansi@7.2.0": { - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dependencies": [ - "ansi-regex@6.2.2" - ] - }, - "strip-indent@3.0.0": { - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dependencies": [ - "min-indent" - ] - }, - "superagent@10.3.0": { - "integrity": "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==", - "dependencies": [ - "component-emitter", - "cookiejar", - "debug", - "fast-safe-stringify", - "form-data", - "formidable", - "methods", - "mime", - "qs" - ] - }, - "supertest@7.2.2": { - "integrity": "sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==", - "dependencies": [ - "cookie-signature", - "methods", - "superagent" - ] - }, - "supports-color@7.2.0": { - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": [ - "has-flag" - ] - }, - "supports-preserve-symlinks-flag@1.0.0": { - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "through@2.3.8": { - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "tinyexec@1.0.2": { - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==" - }, - "to-regex-range@5.0.1": { - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": [ - "is-number" - ] - }, - "toidentifier@1.0.1": { - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "trim-newlines@3.0.1": { - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==" - }, - "ts-toolbelt@9.6.0": { - "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==" - }, - "tslib@2.5.2": { - "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==" - }, - "type-fest@0.18.1": { - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==" - }, - "type-fest@0.6.0": { - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" - }, - "type-fest@0.8.1": { - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - }, - "type-fest@3.13.1": { - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==" - }, - "type-is@2.0.1": { - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "dependencies": [ - "content-type", - "media-typer", - "mime-types@3.0.2" - ] - }, - "typescript@4.9.5": { - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "bin": true - }, - "typescript@5.9.3": { - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "bin": true - }, - "uglify-js@3.19.3": { - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "bin": true - }, - "undici-types@7.18.2": { - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==" - }, - "unist-util-is@4.1.0": { - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" - }, - "unist-util-visit-parents@3.1.1": { - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", - "dependencies": [ - "@types/unist", - "unist-util-is" - ] - }, - "unist-util-visit@2.0.3": { - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "dependencies": [ - "@types/unist", - "unist-util-is", - "unist-util-visit-parents" - ] - }, - "universal-user-agent@6.0.1": { - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" - }, - "unpipe@1.0.0": { - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "validate-npm-package-license@3.0.4": { - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dependencies": [ - "spdx-correct", - "spdx-expression-parse" - ] - }, - "vary@1.1.2": { - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "wordwrap@1.0.0": { - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" - }, - "wrap-ansi@7.0.0": { - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": [ - "ansi-styles@4.3.0", - "string-width@4.2.3", - "strip-ansi@6.0.1" - ] - }, - "wrap-ansi@9.0.2": { - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dependencies": [ - "ansi-styles@6.2.3", - "string-width@7.2.0", - "strip-ansi@7.2.0" - ] - }, - "wrappy@1.0.2": { - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "xpath@0.0.34": { - "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==" - }, - "y18n@5.0.8": { - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist@4.0.0": { - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml@2.8.2": { - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "bin": true - }, - "yargs-parser@20.2.9": { - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" - }, - "yargs-parser@21.1.1": { - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" - }, - "yargs-parser@22.0.0": { - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==" - }, - "yargs@16.2.0": { - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": [ - "cliui@7.0.4", - "escalade", - "get-caller-file", - "require-directory", - "string-width@4.2.3", - "y18n", - "yargs-parser@20.2.9" - ] - }, - "yargs@17.7.2": { - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": [ - "cliui@8.0.1", - "escalade", - "get-caller-file", - "require-directory", - "string-width@4.2.3", - "y18n", - "yargs-parser@21.1.1" - ] - }, - "yargs@18.0.0": { - "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", - "dependencies": [ - "cliui@9.0.1", - "escalade", - "get-caller-file", - "string-width@7.2.0", - "y18n", - "yargs-parser@22.0.0" - ] - }, - "zod@4.3.6": { - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==" - } - }, - "workspace": { - "dependencies": [ - "npm:@commitlint/cli@^20.4.3", - "npm:@commitlint/config-conventional@^20.4.3", - "npm:lint-staged@^16.3.1" - ], - "members": { - "packages/api": { - "dependencies": [ - "npm:fast-deep-equal@^3.1.3", - "npm:ts-toolbelt@^9.6.0", - "npm:zod@^4.3.6" - ] - }, - "packages/client": { - "dependencies": [ - "jsr:@targetd/api@^8.0.3", - "npm:ts-toolbelt@^9.6.0", - "npm:zod@^4.3.6" - ] - }, - "packages/date-range": { - "dependencies": [ - "jsr:@targetd/api@^8.0.3", - "npm:zod@^4.3.6" - ] - }, - "packages/explode": { - "dependencies": [ - "jsr:@targetd/api@^8.0.3", - "npm:flat@^6.0.1", - "npm:ts-toolbelt@^9.6.0", - "npm:zod@^4.3.6" - ] - }, - "packages/fs": { - "dependencies": [ - "jsr:@es-toolkit/es-toolkit@^1.45.1", - "jsr:@targetd/api@^8.0.3", - "npm:@johngw/fs@^3.0.1", - "npm:ts-toolbelt@^9.6.0", - "npm:yaml@^2.8.2", - "npm:zod@^4.3.6" - ] - }, - "packages/json-schema": { - "dependencies": [ - "jsr:@es-toolkit/es-toolkit@^1.45.1", - "jsr:@targetd/api@^8.0.3", - "npm:@types/yargs@^17.0.35", - "npm:yargs@18", - "npm:zod@^4.3.6" - ] - }, - "packages/server": { - "dependencies": [ - "jsr:@targetd/api@^8.0.3", - "npm:@johngw/error@^2.2.2", - "npm:@types/express@^5.0.6", - "npm:@types/qs@^6.15.0", - "npm:cors@^2.8.6", - "npm:express-query-boolean@2", - "npm:express@^5.2.1", - "npm:qs@^6.15.0", - "npm:zod@^4.3.6" - ] - } - } - } -} diff --git a/lint-staged.config.js b/lint-staged.config.js index bd3502d7e..6cac8788c 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -4,6 +4,5 @@ * @type {import('lint-staged').Configuration} */ export default { - '*.{js,mjs,cjs,ts,mts,cts,tsx,jsx,json,jsonc,md,markdown,yml,yaml}': - 'deno fmt', + '*.{js,mjs,cjs,ts,mts,cts,tsx,jsx,json,jsonc,md,markdown,yml,yaml}': 'oxfmt', } diff --git a/oxfmt.config.ts b/oxfmt.config.ts new file mode 100644 index 000000000..867a8089d --- /dev/null +++ b/oxfmt.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'oxfmt' + +export default defineConfig({ + semi: false, + singleQuote: true, +}) diff --git a/oxlint.config.ts b/oxlint.config.ts new file mode 100644 index 000000000..b70f4df0f --- /dev/null +++ b/oxlint.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'oxlint' + +export default defineConfig({ + rules: { + 'no-explicit-any': 'off', + 'ban-types': 'off', + }, +}) diff --git a/package.json b/package.json new file mode 100644 index 000000000..86f97cc65 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "@targetd/monorepo", + "version": "0.0.0", + "private": true, + "workspaces": [ + "packages/*" + ], + "type": "module", + "scripts": { + "test": "bun test packages/**/test", + "check": "tsc --noEmit", + "lint": "oxlint", + "fmt": "oxfmt", + "commitlint": "commitlint" + }, + "devDependencies": { + "@commitlint/cli": "^20.4.3", + "@commitlint/config-conventional": "^20.4.3", + "@types/bun": "catalog:", + "lint-staged": "^16.3.1", + "oxlint": "^1.56.0", + "typescript": "catalog:" + }, + "catalog": { + "@types/bun": "^1.3.10", + "@types/sinon": "^21.0.0", + "es-toolkit": "^1.45.1", + "sinon": "^21.0.3", + "ts-toolbelt": "^9.6.0", + "typescript": "^5.9.3", + "zod": "^4.3.6" + } +} diff --git a/packages/api/deno.json b/packages/api/deno.json deleted file mode 100644 index b1b38c029..000000000 --- a/packages/api/deno.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@targetd/api", - "description": "Type-safe targeting and feature flag system with dynamic content delivery based on query conditions. Perfect for A/B testing, feature flags, and content personalization.", - "version": "8.0.0", - "exports": "./src/index.ts", - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "lint": { - "rules": { - "exclude": [ - "no-import-prefix", - "no-unversioned-import" - ] - } - }, - "tasks": { - "pwd": "echo $(pwd)", - "test": "deno test --allow-all --trace-leaks" - }, - "imports": { - "fast-deep-equal": "npm:fast-deep-equal@^3.1.3", - "ts-toolbelt": "npm:ts-toolbelt@^9.6.0", - "zod": "npm:zod@^4.3.6" - }, - "publish": { - "include": [ - "deno.json", - "src/", - "LICENSE", - "README.md" - ] - } -} diff --git a/packages/api/jsr.json b/packages/api/jsr.json new file mode 100644 index 000000000..95642d70d --- /dev/null +++ b/packages/api/jsr.json @@ -0,0 +1,8 @@ +{ + "name": "@targetd/api", + "version": "8.1.1", + "exports": "./src/index.ts", + "publish": { + "include": ["src/", "LICENSE", "README.md"] + } +} diff --git a/packages/api/package.json b/packages/api/package.json new file mode 100644 index 000000000..3377f3247 --- /dev/null +++ b/packages/api/package.json @@ -0,0 +1,27 @@ +{ + "name": "@targetd/api", + "version": "8.1.1", + "description": "Type-safe targeting and feature flag system with dynamic content delivery based on query conditions. Perfect for A/B testing, feature flags, and content personalization.", + "files": [ + "src/", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": "./src/index.ts", + "scripts": { + "test": "bun test" + }, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "ts-toolbelt": "catalog:" + }, + "devDependencies": { + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:" + }, + "peerDependencies": { + "zod": "catalog:" + } +} diff --git a/packages/api/test/Data.test.ts b/packages/api/test/Data.test.ts index f16e78374..9dcf5e5c9 100644 --- a/packages/api/test/Data.test.ts +++ b/packages/api/test/Data.test.ts @@ -1,27 +1,16 @@ -import { - assertEquals, - assertRejects, - assertStrictEquals, -} from 'jsr:@std/assert' -import { assertSnapshot } from 'jsr:@std/testing/snapshot' +import { test, expect } from 'bun:test' import { setTimeout } from 'node:timers/promises' import z, { type ZodError } from 'zod' -import { - createTargetingDescriptor, - Data, - targetEquals, - targetIncludes, -} from '@targetd/api' - -Deno.test('getPayload', async () => { +import { createTargetingDescriptor, Data, targetEquals, targetIncludes } from '@targetd/api' + +test('getPayload', async () => { const data = await Data.create() - .usePayload({ 'foo': z.string() }) + .usePayload({ foo: z.string() }) .useTargeting({ weather: targetIncludes(z.string()), highTide: targetEquals(z.boolean()), asyncThing: { - predicate: (q) => - setTimeout(10, (t: boolean) => q === t && setTimeout(10, true)), + predicate: (q) => setTimeout(10, (t: boolean) => q === t && setTimeout(10, true)), queryParser: z.boolean(), targetingParser: z.boolean(), }, @@ -63,28 +52,22 @@ Deno.test('getPayload', async () => { }, ]) - assertStrictEquals(await data.getPayload('foo'), 'bar') - assertStrictEquals(await data.getPayload('foo', { weather: 'sunny' }), '😎') - assertStrictEquals(await data.getPayload('foo', { weather: 'rainy' }), '☂️') - assertStrictEquals(await data.getPayload('foo', { highTide: true }), '🌊') - assertStrictEquals( - await data.getPayload('foo', { highTide: true, weather: 'sunny' }), - '🏄‍♂️', - ) - assertStrictEquals( - await data.getPayload('foo', { asyncThing: true }), - 'Async payload', - ) + expect(await data.getPayload('foo')).toBe('bar') + expect(await data.getPayload('foo', { weather: 'sunny' })).toBe('😎') + expect(await data.getPayload('foo', { weather: 'rainy' })).toBe('☂️') + expect(await data.getPayload('foo', { highTide: true })).toBe('🌊') + expect(await data.getPayload('foo', { highTide: true, weather: 'sunny' })).toBe('🏄‍♂️') + expect(await data.getPayload('foo', { asyncThing: true })).toBe('Async payload') // @ts-expect-error Mung data type does not exist await data.getPayload('mung') - await assertRejects(() => + await expect( // @ts-expect-error 'nonExistantKey' is not a queriable value - data.getPayload('foo', { nonExistantKey: 'some value' }) - ) + data.getPayload('foo', { nonExistantKey: 'some value' }), + ).rejects.toThrow() - await assertRejects(() => + await expect( data.addRules('foo', [ { targeting: { @@ -93,11 +76,11 @@ Deno.test('getPayload', async () => { }, payload: 'error', }, - ]) - ) + ]), + ).rejects.toThrow() }) -Deno.test('targeting with multiple conditions', async () => { +test('targeting with multiple conditions', async () => { const data = await Data.create() .usePayload({ foo: z.string() }) .useTargeting({ @@ -121,18 +104,12 @@ Deno.test('targeting with multiple conditions', async () => { }, ]) - assertStrictEquals( - await data.getPayload('foo', { weather: 'sunny' }), - 'The time is now', - ) - assertStrictEquals( - await data.getPayload('foo', { highTide: true }), - 'The time is now', - ) - assertStrictEquals(await data.getPayload('foo'), 'bar') + expect(await data.getPayload('foo', { weather: 'sunny' })).toBe('The time is now') + expect(await data.getPayload('foo', { highTide: true })).toBe('The time is now') + expect(await data.getPayload('foo')).toBe('bar') }) -Deno.test('targeting without requiring a query', async () => { +test('targeting without requiring a query', async () => { const data = await Data.create() .usePayload({ foo: z.string(), @@ -157,10 +134,10 @@ Deno.test('targeting without requiring a query', async () => { }, ]) - assertStrictEquals(await data.getPayload('foo'), 'The time is now') + expect(await data.getPayload('foo')).toBe('The time is now') }) -Deno.test('getPayloads', async (t) => { +test('getPayloads', async () => { const data = await Data.create() .usePayload({ foo: z.string(), @@ -193,10 +170,10 @@ Deno.test('getPayloads', async (t) => { }, ]) - await assertSnapshot(t, await data.getPayloads('foo', { weather: 'sunny' })) + expect(await data.getPayloads('foo', { weather: 'sunny' })).toMatchSnapshot() }) -Deno.test('payload runtype validation', async (t) => { +test('payload runtype validation', async () => { try { await Data.create() .usePayload({ @@ -208,14 +185,14 @@ Deno.test('payload runtype validation', async (t) => { }, ]) } catch (error: any) { - await assertSnapshot(t, error.message) + expect(error.message).toMatchSnapshot() return } throw new Error('Didnt error correctly') }) -Deno.test('getPayloadForEachName', async (t) => { +test('getPayloadForEachName', async () => { const data = await Data.create() .usePayload({ foo: z.string(), @@ -225,8 +202,7 @@ Deno.test('getPayloadForEachName', async (t) => { weather: targetIncludes(z.string()), highTide: targetIncludes(z.boolean()), asyncThing: { - predicate: (q) => - setTimeout(10, (t: boolean) => q === t && setTimeout(10, true)), + predicate: (q) => setTimeout(10, (t: boolean) => q === t && setTimeout(10, true)), queryParser: z.boolean(), targetingParser: z.boolean(), }, @@ -266,17 +242,11 @@ Deno.test('getPayloadForEachName', async (t) => { }, ]) - await assertSnapshot( - t, - await data.getPayloadForEachName({ weather: 'sunny' }), - ) - await assertSnapshot( - t, - await data.getPayloadForEachName({ asyncThing: true }), - ) + expect(await data.getPayloadForEachName({ weather: 'sunny' })).toMatchSnapshot() + expect(await data.getPayloadForEachName({ asyncThing: true })).toMatchSnapshot() }) -Deno.test('fallThrough targeting', async (t) => { +test('fallThrough targeting', async () => { const data = await Data.create() .usePayload({ foo: z.string(), @@ -340,12 +310,12 @@ Deno.test('fallThrough targeting', async (t) => { }, ]) - await assertSnapshot(t, data.data) - await assertSnapshot(t, await data.getPayloadForEachName({ surf: 'tame' })) - await assertSnapshot(t, await data.getPayloadForEachName({ surf: 'strong' })) + expect(data.data).toMatchSnapshot() + expect(await data.getPayloadForEachName({ surf: 'tame' })).toMatchSnapshot() + expect(await data.getPayloadForEachName({ surf: 'strong' })).toMatchSnapshot() }) -Deno.test('inserting data', async (t) => { +test('inserting data', async () => { const data = await Data.create() .usePayload({ moo: z.string(), @@ -394,13 +364,10 @@ Deno.test('inserting data', async (t) => { moo: 'glue', }) - await assertSnapshot( - t, - await data.getPayloadForEachName({ weather: 'sunny' }), - ) + expect(await data.getPayloadForEachName({ weather: 'sunny' })).toMatchSnapshot() }) -Deno.test('inserting data with variables', async (t) => { +test('inserting data with variables', async () => { const data = await Data.create() .usePayload({ moo: z.string(), @@ -452,20 +419,17 @@ Deno.test('inserting data with variables', async (t) => { moo: 'glue', }) - await assertSnapshot( - t, - await data.getPayloadForEachName({ weather: 'sunny', highTide: true }), - ) + expect(await data.getPayloadForEachName({ weather: 'sunny', highTide: true })).toMatchSnapshot() }) -Deno.test('targeting predicate with full query object', async () => { +test('targeting predicate with full query object', async () => { const mungTargeting = createTargetingDescriptor({ queryParser: z.string(), targetingParser: z.string().array(), - predicate: (queryValue, { bar }: { bar?: boolean }) => (targeting) => - bar === true && - queryValue !== undefined && - targeting.includes(queryValue), + predicate: + (queryValue, { bar }: { bar?: boolean }) => + (targeting) => + bar === true && queryValue !== undefined && targeting.includes(queryValue), }) const data = await Data.create() @@ -492,15 +456,12 @@ Deno.test('targeting predicate with full query object', async () => { }, ]) - assertStrictEquals(await data.getPayload('foo'), undefined) - assertStrictEquals(await data.getPayload('foo', { mung: 'mung' }), undefined) - assertStrictEquals( - await data.getPayload('foo', { bar: true, mung: 'mung' }), - 'yay', - ) + expect(await data.getPayload('foo')).toBe(undefined) + expect(await data.getPayload('foo', { mung: 'mung' })).toBe(undefined) + expect(await data.getPayload('foo', { bar: true, mung: 'mung' })).toBe('yay') }) -Deno.test('broken', async (t) => { +test('broken', async () => { const browserTargeting = targetIncludes(z.enum(['chrome', 'edge'])) const channelTargeting = targetIncludes(z.enum(['foo', 'bar'])) @@ -540,11 +501,11 @@ Deno.test('broken', async (t) => { }, ]) - await assertSnapshot(t, await data.getPayloadForEachName({ channel: 'foo' })) - await assertSnapshot(t, await data.getPayloadForEachName({ channel: 'bar' })) + expect(await data.getPayloadForEachName({ channel: 'foo' })).toMatchSnapshot() + expect(await data.getPayloadForEachName({ channel: 'bar' })).toMatchSnapshot() }) -Deno.test('variables', async (t) => { +test('variables', async () => { const data = await Data.create() .usePayload({ foo: z.strictObject({ @@ -575,9 +536,7 @@ Deno.test('variables', async (t) => { payload: 'bar', }, ], - d: [ - { payload: 1 }, - ], + d: [{ payload: 1 }], }, rules: [ { @@ -593,12 +552,12 @@ Deno.test('variables', async (t) => { ], }) - await assertSnapshot(t, await data.getPayload('foo', { channel: 'bar' })) + expect(await data.getPayload('foo', { channel: 'bar' })).toMatchSnapshot() - await assertSnapshot(t, await data.getPayload('foo')) + expect(await data.getPayload('foo')).toMatchSnapshot() }) -Deno.test('variables using fallthrough targeting', async (t) => { +test('variables using fallthrough targeting', async () => { const data = await Data.create() .usePayload({ foo: z.strictObject({ @@ -629,9 +588,7 @@ Deno.test('variables using fallthrough targeting', async (t) => { payload: '2', }, ], - d: [ - { payload: 1 }, - ], + d: [{ payload: 1 }], }, rules: [ { @@ -650,10 +607,10 @@ Deno.test('variables using fallthrough targeting', async (t) => { ], }) - await assertSnapshot(t, await data.getPayload('foo', { channel: 'bar' })) + expect(await data.getPayload('foo', { channel: 'bar' })).toMatchSnapshot() }) -Deno.test('variables in records', async () => { +test('variables in records', async () => { const data = await Data.create() .usePayload({ foo: z.record(z.string(), z.array(z.number())), @@ -666,23 +623,27 @@ Deno.test('variables in records', async () => { }) const payload = await data.getPayload('foo') - assertEquals(payload, { a: [1, 2, 3] }) + expect(payload).toEqual({ a: [1, 2, 3] }) }) -Deno.test('variables in arrays', async (t) => { +test('variables in arrays', async () => { const data = await Data.create() .usePayload({ foo: z.array(z.number()), - bar: z.array(z.strictObject({ - b: z.number(), - c: z.string(), - })), - }).addRules('foo', { + bar: z.array( + z.strictObject({ + b: z.number(), + c: z.string(), + }), + ), + }) + .addRules('foo', { variables: { a: [{ payload: 1 }], }, rules: [{ payload: ['{{a}}'] }], - }).addRules('bar', { + }) + .addRules('bar', { variables: { b: [{ payload: 2 }], c: [{ payload: '3' }], @@ -690,91 +651,78 @@ Deno.test('variables in arrays', async (t) => { rules: [{ payload: [{ b: '{{b}}', c: '{{c}}' }] }], }) - await assertSnapshot( - t, - data.data, - ) + expect(data.data).toMatchSnapshot() - assertEquals( - await data.getPayload('foo'), - [1], - ) + expect(await data.getPayload('foo')).toEqual([1]) - assertEquals( - await data.getPayload('bar'), - [{ b: 2, c: '3' }], - ) + expect(await data.getPayload('bar')).toEqual([{ b: 2, c: '3' }]) }) -Deno.test('errors when using variables with incorrect types', async (t) => { - const data = await Data.create() - .usePayload({ - foo: z.strictObject({ - a: z.strictObject({ - b: z.strictObject({ - c: z.string(), - }), +test('errors when using variables with incorrect types', async () => { + const data = await Data.create().usePayload({ + foo: z.strictObject({ + a: z.strictObject({ + b: z.strictObject({ + c: z.string(), }), }), - }) + }), + }) - await assertSnapshot( - t, - await data.addRules('foo', { - variables: { - c: [ + expect( + await data + .addRules('foo', { + variables: { + c: [ + { + payload: 2, + }, + ], + }, + rules: [ { - payload: 2, - }, - ], - }, - rules: [ - { - payload: { - a: { - b: { - c: '{{c}}', + payload: { + a: { + b: { + c: '{{c}}', + }, }, }, }, - }, - ], - }).catch((error: ZodError) => error.issues), - ) + ], + }) + .catch((error: ZodError) => error.issues), + ).toMatchSnapshot() }) -Deno.test( - 'make sure fallthrough targeting predicates are not called', - async () => { - const minInnerWindowWidthTargeting = createTargetingDescriptor({ - queryParser: z.unknown(), - targetingParser: z.number(), - requiresQuery: false, - predicate: () => () => { - throw new Error('This should never get called') - }, - }) - const baseSchema = Data.create() - .usePayload({ 'foo': z.string() }) - const clientSchema = baseSchema - .useTargeting({ fft: minInnerWindowWidthTargeting }) - const serverSchema = baseSchema - .useFallThroughTargeting((await clientSchema).targetingParsers) - .addRules('foo', { - variables: { - x: [{ +test('make sure fallthrough targeting predicates are not called', async () => { + const minInnerWindowWidthTargeting = createTargetingDescriptor({ + queryParser: z.unknown(), + targetingParser: z.number(), + requiresQuery: false, + predicate: () => () => { + throw new Error('This should never get called') + }, + }) + const baseSchema = Data.create().usePayload({ foo: z.string() }) + const clientSchema = baseSchema.useTargeting({ fft: minInnerWindowWidthTargeting }) + const serverSchema = baseSchema + .useFallThroughTargeting((await clientSchema).targetingParsers) + .addRules('foo', { + variables: { + x: [ + { targeting: { fft: 129, }, payload: 'fft', - }, { + }, + { payload: 'st', - }], - }, - rules: [ - { payload: '{{x}}' }, + }, ], - }) - await serverSchema.getPayloadForEachName() - }, -) + }, + rules: [{ payload: '{{x}}' }], + }) + await serverSchema.getPayloadForEachName() +}) diff --git a/packages/api/test/__snapshots__/Data.test.ts.snap b/packages/api/test/__snapshots__/Data.test.ts.snap index 20cd38c2f..bfacb3979 100644 --- a/packages/api/test/__snapshots__/Data.test.ts.snap +++ b/packages/api/test/__snapshots__/Data.test.ts.snap @@ -1,6 +1,6 @@ -export const snapshot = {}; +// Bun Snapshot v1, https://bun.sh/docs/test/snapshots -snapshot[`getPayloads 1`] = ` +exports[`getPayloads 1`] = ` [ "😎", "☂️", @@ -8,8 +8,8 @@ snapshot[`getPayloads 1`] = ` ] `; -snapshot[`payload runtype validation 1`] = ` -'[ +exports[`payload runtype validation 1`] = ` +"[ { "code": "custom", "path": [ @@ -20,184 +20,184 @@ snapshot[`payload runtype validation 1`] = ` ], "message": "Should be bar" } -]' +]" `; -snapshot[`getPayloadForEachName 1`] = ` +exports[`getPayloadForEachName 1`] = ` { - bar: "😁", - foo: "😎", + "bar": "😁", + "foo": "😎", } `; -snapshot[`getPayloadForEachName 2`] = ` +exports[`getPayloadForEachName 2`] = ` { - bar: "async payloads!", - foo: undefined, + "bar": "async payloads!", + "foo": undefined, } `; -snapshot[`fallThrough targeting 1`] = ` +exports[`fallThrough targeting 1`] = ` { - bar: { - rules: [ + "bar": { + "rules": [ { - fallThrough: [ + "fallThrough": [ { - payload: "😟", - targeting: { - weather: [ + "payload": "😟", + "targeting": { + "weather": [ "rainy", ], }, }, { - payload: "😁", - targeting: { - weather: [ + "payload": "😁", + "targeting": { + "weather": [ "sunny", ], }, }, { - payload: "😐", - targeting: {}, + "payload": "😐", + "targeting": {}, }, ], - targeting: {}, + "targeting": {}, }, ], - variables: {}, + "variables": {}, }, - foo: { - rules: [ + "foo": { + "rules": [ { - fallThrough: [ + "fallThrough": [ { - payload: "🏄‍♂️", - targeting: { - weather: [ + "payload": "🏄‍♂️", + "targeting": { + "weather": [ "sunny", ], }, }, ], - targeting: { - surf: [ + "targeting": { + "surf": [ "strong", ], }, }, { - fallThrough: [ + "fallThrough": [ { - payload: "😎", - targeting: { - weather: [ + "payload": "😎", + "targeting": { + "weather": [ "sunny", ], }, }, { - payload: "☂️", - targeting: { - weather: [ + "payload": "☂️", + "targeting": { + "weather": [ "rainy", ], }, }, ], - targeting: {}, + "targeting": {}, }, ], - variables: {}, + "variables": {}, }, - mung: { - rules: [ + "mung": { + "rules": [ { - fallThrough: [ + "fallThrough": [ { - payload: "☂️", - targeting: { - weather: [ + "payload": "☂️", + "targeting": { + "weather": [ "rainy", ], }, }, ], - targeting: { - surf: [ + "targeting": { + "surf": [ "!strong", ], }, }, { - fallThrough: [ + "fallThrough": [ { - payload: "🏄‍♂️", - targeting: { - weather: [ + "payload": "🏄‍♂️", + "targeting": { + "weather": [ "sunny", ], }, }, ], - targeting: { - surf: [ + "targeting": { + "surf": [ "strong", ], }, }, ], - variables: {}, + "variables": {}, }, } `; -snapshot[`fallThrough targeting 2`] = ` +exports[`fallThrough targeting 2`] = ` { - bar: { - __rules__: [ + "bar": { + "__rules__": [ { - payload: "😟", - targeting: { - weather: [ + "payload": "😟", + "targeting": { + "weather": [ "rainy", ], }, }, { - payload: "😁", - targeting: { - weather: [ + "payload": "😁", + "targeting": { + "weather": [ "sunny", ], }, }, { - payload: "😐", - targeting: {}, + "payload": "😐", + "targeting": {}, }, ], }, - foo: { - __rules__: [ + "foo": { + "__rules__": [ { - payload: "🏄‍♂️", - targeting: { - weather: [ + "payload": "🏄‍♂️", + "targeting": { + "weather": [ "sunny", ], }, }, ], }, - mung: { - __rules__: [ + "mung": { + "__rules__": [ { - payload: "☂️", - targeting: { - weather: [ + "payload": "☂️", + "targeting": { + "weather": [ "rainy", ], }, @@ -207,50 +207,50 @@ snapshot[`fallThrough targeting 2`] = ` } `; -snapshot[`fallThrough targeting 3`] = ` +exports[`fallThrough targeting 3`] = ` { - bar: { - __rules__: [ + "bar": { + "__rules__": [ { - payload: "😟", - targeting: { - weather: [ + "payload": "😟", + "targeting": { + "weather": [ "rainy", ], }, }, { - payload: "😁", - targeting: { - weather: [ + "payload": "😁", + "targeting": { + "weather": [ "sunny", ], }, }, { - payload: "😐", - targeting: {}, + "payload": "😐", + "targeting": {}, }, ], }, - foo: { - __rules__: [ + "foo": { + "__rules__": [ { - payload: "🏄‍♂️", - targeting: { - weather: [ + "payload": "🏄‍♂️", + "targeting": { + "weather": [ "sunny", ], }, }, ], }, - mung: { - __rules__: [ + "mung": { + "__rules__": [ { - payload: "🏄‍♂️", - targeting: { - weather: [ + "payload": "🏄‍♂️", + "targeting": { + "weather": [ "sunny", ], }, @@ -260,59 +260,59 @@ snapshot[`fallThrough targeting 3`] = ` } `; -snapshot[`inserting data 1`] = ` +exports[`inserting data 1`] = ` { - bar: { - __rules__: [ + "bar": { + "__rules__": [ { - payload: "😟", - targeting: { - highTide: false, + "payload": "😟", + "targeting": { + "highTide": false, }, }, { - payload: "😁", - targeting: { - highTide: true, + "payload": "😁", + "targeting": { + "highTide": true, }, }, ], }, - foo: "😎", - moo: "glue", + "foo": "😎", + "moo": "glue", } `; -snapshot[`inserting data with variables 1`] = ` +exports[`inserting data with variables 1`] = ` { - bar: "😁", - foo: "😎", - moo: "glue", + "bar": "😁", + "foo": "😎", + "moo": "glue", } `; -snapshot[`broken 1`] = ` +exports[`broken 1`] = ` { - foo: "face", + "foo": "face", } `; -snapshot[`broken 2`] = ` +exports[`broken 2`] = ` { - foo: { - __rules__: [ + "foo": { + "__rules__": [ { - payload: "yay", - targeting: { - browser: [ + "payload": "yay", + "targeting": { + "browser": [ "chrome", ], }, }, { - payload: "nay", - targeting: { - browser: [ + "payload": "nay", + "targeting": { + "browser": [ "edge", ], }, @@ -322,105 +322,99 @@ snapshot[`broken 2`] = ` } `; -snapshot[`variables 1`] = ` +exports[`variables 1`] = ` { - a: { - b: { - c: "foo", - d: 1, + "a": { + "b": { + "c": "foo", + "d": 1, }, }, } `; -snapshot[`variables 2`] = ` +exports[`variables 2`] = ` { - a: { - b: { - c: "bar", - d: 1, + "a": { + "b": { + "c": "bar", + "d": 1, }, }, } `; -snapshot[`variables using fallthrough targeting 1`] = ` +exports[`variables using fallthrough targeting 1`] = ` { - __rules__: [ + "__rules__": [ { - payload: { - a: { - b: { - c: "{{c}}", - d: 1, + "payload": { + "a": { + "b": { + "c": "{{c}}", + "d": 1, }, }, }, }, ], - __variables__: { - c: [ + "__variables__": { + "c": [ { - payload: "1", - targeting: { - browser: [ + "payload": "1", + "targeting": { + "browser": [ "chrome", ], }, }, { - payload: "2", - targeting: {}, + "payload": "2", + "targeting": {}, }, ], }, } `; -snapshot[`variables in arrays 1`] = ` +exports[`variables in arrays 1`] = ` { - bar: { - rules: [ + "bar": { + "rules": [ { - payload: [ + "payload": [ { - b: [Function: resolver] { - "\$\$resolver\$\$": true, - }, - c: [Function: resolver] { - "\$\$resolver\$\$": true, - }, + "b": [Function], + "c": [Function], }, ], }, ], - variables: { - b: [ + "variables": { + "b": [ { - payload: 2, + "payload": 2, }, ], - c: [ + "c": [ { - payload: "3", + "payload": "3", }, ], }, }, - foo: { - rules: [ + "foo": { + "rules": [ { - payload: [ - [Function: resolver] { - "\$\$resolver\$\$": true, - }, + "payload": [ + [Function], ], }, ], - variables: { - a: [ + "variables": { + "a": [ { - payload: 1, + "payload": 1, }, ], }, @@ -428,14 +422,16 @@ snapshot[`variables in arrays 1`] = ` } `; -snapshot[`errors when using variables with incorrect types 1`] = ` +exports[`errors when using variables with incorrect types 1`] = ` [ { - code: "invalid_type", - expected: "string", - message: "The variable {{c}} cannot be used where it currently is in the payload. -Invalid input: expected string, received number", - path: [ + "code": "invalid_type", + "expected": "string", + "message": +"The variable {{c}} cannot be used where it currently is in the payload. +Invalid input: expected string, received number" +, + "path": [ "foo", "variables", "c", diff --git a/packages/api/test/parsers/switch.test.ts b/packages/api/test/parsers/switch.test.ts index c3e95d375..d0ce056a0 100644 --- a/packages/api/test/parsers/switch.test.ts +++ b/packages/api/test/parsers/switch.test.ts @@ -14,10 +14,10 @@ import { union, } from 'zod/mini' import { zodSwitch } from '../../src/parsers/switch.ts' -import { assertEquals, assertIsError } from 'jsr:@std/assert' +import { test, expect } from 'bun:test' import { $ZodError } from 'zod/v4/core' -Deno.test('zodSwitch', () => { +test('zodSwitch', () => { const variableParser = templateLiteral(['{{', string(), '}}']) const numberParser = number() @@ -26,24 +26,16 @@ Deno.test('zodSwitch', () => { [any(), numberParser], ]) - assertEquals( - parse(parser, '{{mung}}'), - '{{mung}}', - ) + expect(parse(parser, '{{mung}}')).toEqual('{{mung}}') - assertEquals( - parse(parser, 1_000), - 1_000, - ) + expect(parse(parser, 1_000)).toEqual(1_000) - assertIsError( - safeParse(parser, 'mung').error, - $ZodError, - '"expected": "number"', - ) + const result = safeParse(parser, 'mung') + expect(result.error).toBeInstanceOf($ZodError) + expect(result.error?.message).toContain('"expected": "number"') }) -Deno.test('zodSwitch 2', () => { +test('zodSwitch 2', () => { const min1 = () => number().check(minimum(1)) const BaseAdListItem = strictObject({ @@ -69,16 +61,15 @@ Deno.test('zodSwitch 2', () => { [any(), RecurringAdListItem], ]) - assertEquals( + expect( parse(AdListItem, { position: 'left', index: 1, range: 4, }), - { - position: 'left', - index: 1, - range: 4, - }, - ) + ).toEqual({ + position: 'left', + index: 1, + range: 4, + }) }) diff --git a/packages/api/test/tsconfig.json b/packages/api/test/tsconfig.json new file mode 100644 index 000000000..28ce09649 --- /dev/null +++ b/packages/api/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["../src", "."], + "compilerOptions": { + "rootDir": "../" + } +} diff --git a/packages/api/test/utils.test.ts b/packages/api/test/utils.test.ts index 8a7901858..5ca48c6c7 100644 --- a/packages/api/test/utils.test.ts +++ b/packages/api/test/utils.test.ts @@ -1,13 +1,8 @@ -import { assertEquals, assertStrictEquals } from 'jsr:@std/assert' -import { - arrayInit, - arrayLast, - objectEveryAsync, - objectMap, -} from '../src/util.ts' +import { test, expect } from 'bun:test' +import { arrayInit, arrayLast, objectEveryAsync, objectMap } from '../src/util.ts' -Deno.test('objectMap', () => { - assertEquals( +test('objectMap', () => { + expect( objectMap( { foo: 123, @@ -15,15 +10,14 @@ Deno.test('objectMap', () => { }, (v) => v + 1, ), - { - foo: 124, - bar: 322, - }, - ) + ).toEqual({ + foo: 124, + bar: 322, + }) }) -Deno.test('objectEveryAsync', async () => { - assertStrictEquals( +test('objectEveryAsync', async () => { + expect( await objectEveryAsync( { foo: 1, @@ -33,9 +27,8 @@ Deno.test('objectEveryAsync', async () => { }, (value) => Promise.resolve(value).then((v) => v > 2), ), - false, - ) - assertStrictEquals( + ).toBe(false) + expect( await objectEveryAsync( { foo: 1, @@ -45,14 +38,13 @@ Deno.test('objectEveryAsync', async () => { }, (value) => Promise.resolve(value).then((v) => v > 0), ), - true, - ) + ).toBe(true) }) -Deno.test('arrayInit', () => { - assertEquals(arrayInit([1, 2, 3, 4, 5]), [1, 2, 3, 4]) +test('arrayInit', () => { + expect(arrayInit([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4]) }) -Deno.test('arrayLast', () => { - assertStrictEquals(arrayLast([1, 2, 3, 4, 5]), 5) +test('arrayLast', () => { + expect(arrayLast([1, 2, 3, 4, 5])).toBe(5) }) diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json new file mode 100644 index 000000000..d0a8f7171 --- /dev/null +++ b/packages/api/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src" + } +} diff --git a/packages/client/deno.json b/packages/client/deno.json deleted file mode 100644 index e41440761..000000000 --- a/packages/client/deno.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@targetd/client", - "description": "Type-safe HTTP client for querying @targetd/server instances. Mirrors the Data API with full TypeScript inference.", - "version": "7.0.2", - "exports": "./src/index.ts", - "imports": { - "@targetd/api": "jsr:@targetd/api@^8.0.3", - "ts-toolbelt": "npm:ts-toolbelt@^9.6.0", - "zod": "npm:zod@^4.3.6" - }, - "lint": { - "rules": { - "exclude": [ - "no-import-prefix", - "no-unversioned-import" - ] - } - }, - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "tasks": { - "pwd": "echo $(pwd)", - "test": "deno test --allow-all --trace-leaks" - }, - "publish": { - "include": [ - "deno.json", - "src/", - "LICENSE", - "README.md" - ] - } -} diff --git a/packages/client/jsr.json b/packages/client/jsr.json new file mode 100644 index 000000000..b82f7526e --- /dev/null +++ b/packages/client/jsr.json @@ -0,0 +1,8 @@ +{ + "name": "@targetd/client", + "version": "7.0.2", + "exports": "./src/index.ts", + "publish": { + "include": ["src/", "LICENSE", "README.md"] + } +} diff --git a/packages/client/package.json b/packages/client/package.json new file mode 100644 index 000000000..64d4ed851 --- /dev/null +++ b/packages/client/package.json @@ -0,0 +1,30 @@ +{ + "name": "@targetd/client", + "version": "7.0.2", + "description": "Type-safe HTTP client for querying @targetd/server instances. Mirrors the Data API with full TypeScript inference.", + "files": [ + "src/", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": "./src/index.ts", + "scripts": { + "test": "bun test" + }, + "dependencies": { + "ts-toolbelt": "catalog:" + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@targetd/date-range": "workspace:*", + "@targetd/server": "workspace:*", + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:" + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:" + } +} diff --git a/packages/client/test/__snapshots__/index.test.ts.snap b/packages/client/test/__snapshots__/index.test.ts.snap index 7ef713708..89a94b39c 100644 --- a/packages/client/test/__snapshots__/index.test.ts.snap +++ b/packages/client/test/__snapshots__/index.test.ts.snap @@ -1,47 +1,47 @@ -export const snapshot = {}; +// Bun Snapshot v1, https://bun.sh/docs/test/snapshots -snapshot[`get one data point 1`] = `"Async payload"`; +exports[`get one data point 1`] = `"Async payload"`; -snapshot[`get one data point 2`] = `"in time"`; +exports[`get one data point 2`] = `"in time"`; -snapshot[`get all 1`] = ` +exports[`get all 1`] = ` { - bar: 123, - foo: "bar", + "bar": 123, + "foo": "bar", } `; -snapshot[`get all 2`] = ` +exports[`get all 2`] = ` { - bar: 123, - foo: "😎", + "bar": 123, + "foo": "😎", } `; -snapshot[`get all 3`] = ` +exports[`get all 3`] = ` { - bar: 123, - foo: "☂️", + "bar": 123, + "foo": "☂️", } `; -snapshot[`get all 4`] = ` +exports[`get all 4`] = ` { - bar: 123, - foo: "🌊", + "bar": 123, + "foo": "🌊", } `; -snapshot[`get all 5`] = ` +exports[`get all 5`] = ` { - bar: 123, - foo: "🏄‍♂️", + "bar": 123, + "foo": "🏄‍♂️", } `; -snapshot[`get all 6`] = ` +exports[`get all 6`] = ` { - bar: 123, - foo: "Async payload", + "bar": 123, + "foo": "Async payload", } `; diff --git a/packages/client/test/index.test.ts b/packages/client/test/index.test.ts index e846ee029..46e0d8161 100644 --- a/packages/client/test/index.test.ts +++ b/packages/client/test/index.test.ts @@ -1,5 +1,4 @@ -import { assertStrictEquals } from 'jsr:@std/assert' -import { assertSnapshot } from 'jsr:@std/testing/snapshot' +import { test, expect } from 'bun:test' import { Data, targetEquals, targetIncludes } from '@targetd/api' import dateRangeTargeting from '@targetd/date-range' import { createServer } from '@targetd/server' @@ -75,62 +74,36 @@ const data = await Data.create() }, ]) -Deno.test('get one data point', async (t) => { +test('get one data point', async () => { await using service = await startService() const { client } = service - assertStrictEquals(await client.getPayload('foo'), 'bar') - assertStrictEquals(await client.getPayload('foo', { weather: 'sunny' }), '😎') - assertStrictEquals(await client.getPayload('foo', { weather: 'rainy' }), '☂️') - assertStrictEquals(await client.getPayload('foo', { highTide: true }), '🌊') - assertStrictEquals( - await client.getPayload('foo', { highTide: true, weather: 'sunny' }), - '🏄‍♂️', - ) - await assertSnapshot(t, await client.getPayload('foo', { asyncThing: true })) - await assertSnapshot( - t, - await client.getPayload('timed', { date: { start: '2002-01-01' } }), - ) - assertStrictEquals( - await client.getPayload('timed', { date: { start: '2012-01-01' } }), - undefined, - ) + expect(await client.getPayload('foo')).toBe('bar') + expect(await client.getPayload('foo', { weather: 'sunny' })).toBe('😎') + expect(await client.getPayload('foo', { weather: 'rainy' })).toBe('☂️') + expect(await client.getPayload('foo', { highTide: true })).toBe('🌊') + expect(await client.getPayload('foo', { highTide: true, weather: 'sunny' })).toBe('🏄‍♂️') + expect(await client.getPayload('foo', { asyncThing: true })).toMatchSnapshot() + expect(await client.getPayload('timed', { date: { start: '2002-01-01' } })).toMatchSnapshot() + expect(await client.getPayload('timed', { date: { start: '2012-01-01' } })).toBe(undefined) }) -Deno.test('get all', async (t) => { +test('get all', async () => { await using service = await startService() const { client } = service - await assertSnapshot(t, await client.getPayloadForEachName()) - await assertSnapshot( - t, - await client.getPayloadForEachName({ weather: 'sunny' }), - ) - await assertSnapshot( - t, - await client.getPayloadForEachName({ weather: 'rainy' }), - ) - await assertSnapshot( - t, - await client.getPayloadForEachName({ highTide: true }), - ) - await assertSnapshot( - t, - await client.getPayloadForEachName({ highTide: true, weather: 'sunny' }), - ) - await assertSnapshot( - t, - await client.getPayloadForEachName({ asyncThing: true }), - ) + expect(await client.getPayloadForEachName()).toMatchSnapshot() + expect(await client.getPayloadForEachName({ weather: 'sunny' })).toMatchSnapshot() + expect(await client.getPayloadForEachName({ weather: 'rainy' })).toMatchSnapshot() + expect(await client.getPayloadForEachName({ highTide: true })).toMatchSnapshot() + expect(await client.getPayloadForEachName({ highTide: true, weather: 'sunny' })).toMatchSnapshot() + expect(await client.getPayloadForEachName({ asyncThing: true })).toMatchSnapshot() }) -async function startService(): Promise< - AsyncDisposable & { client: ClientWithData } -> { +async function startService(): Promise }> { const app = createServer(data) const { promise, reject, resolve } = Promise.withResolvers() - const server = app.listen(0, (error) => error ? reject(error) : resolve()) + const server = app.listen(0, (error) => (error ? reject(error) : resolve())) await promise const address = server.address() as AddressInfo const client = new Client(`http://localhost:${address.port}`, data) diff --git a/packages/client/test/queryToURLSearchParams.test.ts b/packages/client/test/queryToURLSearchParams.test.ts index 562bfbc68..eb0ccb5ac 100644 --- a/packages/client/test/queryToURLSearchParams.test.ts +++ b/packages/client/test/queryToURLSearchParams.test.ts @@ -1,47 +1,34 @@ -import { assertStrictEquals } from 'jsr:@std/assert' +import { test, expect } from 'bun:test' import { queryToURLSearchParams } from '../src/queryToURLSearchParams.ts' -Deno.test('numbers', () => { - assertStrictEquals( - queryToURLSearchParams({ number: 1 }).toString(), - 'number=1', - ) +test('numbers', () => { + expect(queryToURLSearchParams({ number: 1 }).toString()).toBe('number=1') }) -Deno.test('strings', () => { - assertStrictEquals( - queryToURLSearchParams({ string: 'foo' }).toString(), - 'string=foo', - ) +test('strings', () => { + expect(queryToURLSearchParams({ string: 'foo' }).toString()).toBe('string=foo') }) -Deno.test('booleans', () => { - assertStrictEquals( - queryToURLSearchParams({ bool: true }).toString(), - 'bool=true', - ) +test('booleans', () => { + expect(queryToURLSearchParams({ bool: true }).toString()).toBe('bool=true') }) -Deno.test('arrays', () => { - assertStrictEquals( - queryToURLSearchParams({ array: [1, 2, true, 'foo'] }).toString(), +test('arrays', () => { + expect(queryToURLSearchParams({ array: [1, 2, true, 'foo'] }).toString()).toBe( 'array=1&array=2&array=true&array=foo', ) }) -Deno.test('objects', () => { - assertStrictEquals( - queryToURLSearchParams({ a: { b: { c: 'foo' }, d: 'bar' }, e: 'ber' }) - .toString(), +test('objects', () => { + expect(queryToURLSearchParams({ a: { b: { c: 'foo' }, d: 'bar' }, e: 'ber' }).toString()).toBe( encodeURI('a[b][c]=foo&a[d]=bar&e=ber'), ) }) -Deno.test('arrays and objects', () => { - assertStrictEquals( +test('arrays and objects', () => { + expect( queryToURLSearchParams({ a: [{ b: ['foo', 'bar'] }, { b: ['boo', 'far'] }], }).toString(), - encodeURI('a[b]=foo&a[b]=bar&a[b]=boo&a[b]=far'), - ) + ).toBe(encodeURI('a[b]=foo&a[b]=bar&a[b]=boo&a[b]=far')) }) diff --git a/packages/client/test/tsconfig.json b/packages/client/test/tsconfig.json new file mode 100644 index 000000000..28ce09649 --- /dev/null +++ b/packages/client/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["../src", "."], + "compilerOptions": { + "rootDir": "../" + } +} diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json new file mode 100644 index 000000000..d0a8f7171 --- /dev/null +++ b/packages/client/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src" + } +} diff --git a/packages/date-range/deno.json b/packages/date-range/deno.json deleted file mode 100644 index 6aabecb7e..000000000 --- a/packages/date-range/deno.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@targetd/date-range", - "description": "Built-in targeting descriptor for date range queries in ISO 8601 format with automatic current time evaluation.", - "version": "6.0.2", - "exports": "./src/index.ts", - "imports": { - "@targetd/api": "jsr:@targetd/api@^8.0.3", - "zod": "npm:zod@^4.3.6" - }, - "lint": { - "rules": { - "exclude": [ - "no-import-prefix", - "no-unversioned-import" - ] - } - }, - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "tasks": { - "pwd": "echo $(pwd)", - "test": "deno test --allow-all --trace-leaks" - }, - "publish": { - "include": [ - "deno.json", - "src/", - "LICENSE", - "README.md" - ] - } -} diff --git a/packages/date-range/jsr.json b/packages/date-range/jsr.json new file mode 100644 index 000000000..ee8fb04fd --- /dev/null +++ b/packages/date-range/jsr.json @@ -0,0 +1,8 @@ +{ + "name": "@targetd/date-range", + "version": "6.0.2", + "exports": "./src/index.ts", + "publish": { + "include": ["src/", "LICENSE", "README.md"] + } +} diff --git a/packages/date-range/package.json b/packages/date-range/package.json new file mode 100644 index 000000000..4459641d1 --- /dev/null +++ b/packages/date-range/package.json @@ -0,0 +1,27 @@ +{ + "name": "@targetd/date-range", + "version": "6.0.2", + "description": "Built-in targeting descriptor for date range queries in ISO 8601 format with automatic current time evaluation.", + "files": [ + "src/", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": "./src/index.ts", + "scripts": { + "test": "bun test" + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "@types/sinon": "catalog:", + "sinon": "catalog:", + "typescript": "catalog:", + "zod": "catalog:" + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:" + } +} diff --git a/packages/date-range/test/index.test.ts b/packages/date-range/test/index.test.ts index d35745a95..8852b1522 100644 --- a/packages/date-range/test/index.test.ts +++ b/packages/date-range/test/index.test.ts @@ -1,10 +1,20 @@ -import { assertStrictEquals } from 'jsr:@std/assert' -import { FakeTime } from 'jsr:@std/testing/time' +import { test, expect, beforeEach, afterEach } from 'bun:test' import { Data } from '@targetd/api' import z from 'zod' import dateRangeTargeting from '@targetd/date-range' +import { type SinonFakeTimers, useFakeTimers } from 'sinon' -Deno.test('date range predicate', async () => { +let clock: SinonFakeTimers + +beforeEach(() => { + clock = useFakeTimers() +}) + +afterEach(() => { + clock.restore() +}) + +test('date range predicate', async () => { const data = await Data.create() .usePayload({ foo: z.string(), @@ -43,24 +53,14 @@ Deno.test('date range predicate', async () => { await assertUsingRange({ start: '2019-01-01', end: '2019-12-01' }, 'bar') async function assertUsingFakeTime(iso: string, expectation: string) { - using _fakeTime = setTime(iso) - assertStrictEquals(await data.getPayload('foo'), expectation) + clock.setSystemTime(new Date(iso)) + expect(await data.getPayload('foo'), iso).toBe(expectation) } async function assertUsingRange( - dateRange: NonNullable< - Required>[1]> - >['dateRange'], + dateRange: NonNullable>[1]>>['dateRange'], expectation: string, ) { - assertStrictEquals( - await data.getPayload('foo', { dateRange }), - expectation, - ) + expect(await data.getPayload('foo', { dateRange })).toBe(expectation) } }) - -function setTime(iso: string) { - const fakeTime = new FakeTime(iso) - return { [Symbol.dispose]: () => fakeTime.restore() } -} diff --git a/packages/date-range/test/tsconfig.json b/packages/date-range/test/tsconfig.json new file mode 100644 index 000000000..28ce09649 --- /dev/null +++ b/packages/date-range/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["../src", "."], + "compilerOptions": { + "rootDir": "../" + } +} diff --git a/packages/date-range/tsconfig.json b/packages/date-range/tsconfig.json new file mode 100644 index 000000000..d0a8f7171 --- /dev/null +++ b/packages/date-range/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src" + } +} diff --git a/packages/explode/deno.json b/packages/explode/deno.json deleted file mode 100644 index 0aff535de..000000000 --- a/packages/explode/deno.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "@targetd/explode", - "description": "Transform flat key notation to nested objects with full TypeScript type inference.", - "version": "4.0.2", - "exports": "./src/index.ts", - "imports": { - "@targetd/api": "jsr:@targetd/api@^8.0.3", - "flat": "npm:flat@^6.0.1", - "ts-toolbelt": "npm:ts-toolbelt@^9.6.0", - "zod": "npm:zod@^4.3.6" - }, - "lint": { - "rules": { - "exclude": [ - "no-import-prefix", - "no-unversioned-import" - ] - } - }, - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "tasks": { - "pwd": "echo $(pwd)", - "test": "deno test --allow-all --trace-leaks" - }, - "publish": { - "include": [ - "deno.json", - "src/", - "LICENSE", - "README.md" - ] - } -} diff --git a/packages/explode/jsr.json b/packages/explode/jsr.json new file mode 100644 index 000000000..89fa21814 --- /dev/null +++ b/packages/explode/jsr.json @@ -0,0 +1,8 @@ +{ + "name": "@targetd/explode", + "version": "4.0.2", + "exports": "./src/index.ts", + "publish": { + "include": ["src/", "LICENSE", "README.md"] + } +} diff --git a/packages/explode/package.json b/packages/explode/package.json new file mode 100644 index 000000000..b9c728983 --- /dev/null +++ b/packages/explode/package.json @@ -0,0 +1,29 @@ +{ + "name": "@targetd/explode", + "version": "4.0.2", + "description": "Transform flat key notation to nested objects with full TypeScript type inference.", + "files": [ + "src/", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": "./src/index.ts", + "scripts": { + "test": "bun test" + }, + "dependencies": { + "flat": "^6.0.1", + "ts-toolbelt": "catalog:" + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:" + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:" + } +} diff --git a/packages/explode/test/explode.test.ts b/packages/explode/test/explode.test.ts index 1c69bb097..1f6bf4c4f 100644 --- a/packages/explode/test/explode.test.ts +++ b/packages/explode/test/explode.test.ts @@ -1,7 +1,7 @@ -import { assertEquals } from 'jsr:@std/assert' +import { test, expect } from 'bun:test' import { type Explode, explode } from '@targetd/explode' -Deno.test('Explode', () => { +test('Explode', () => { function check( x: Explode< { @@ -54,8 +54,8 @@ Deno.test('Explode', () => { }) }) -Deno.test('explode()', () => { - assertEquals( +test('explode()', () => { + expect( explode( { 'foo.bar': 'something', @@ -64,22 +64,21 @@ Deno.test('explode()', () => { }, '.', ), - { - foo: { - bar: 'something', - }, - a: { - b: { - c: { - d: { - e: { - f: 'g', - g: 'h', - }, + ).toEqual({ + foo: { + bar: 'something', + }, + a: { + b: { + c: { + d: { + e: { + f: 'g', + g: 'h', }, }, }, }, }, - ) + }) }) diff --git a/packages/explode/test/tsconfig.json b/packages/explode/test/tsconfig.json new file mode 100644 index 000000000..28ce09649 --- /dev/null +++ b/packages/explode/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["../src", "."], + "compilerOptions": { + "rootDir": "../" + } +} diff --git a/packages/explode/tsconfig.json b/packages/explode/tsconfig.json new file mode 100644 index 000000000..d0a8f7171 --- /dev/null +++ b/packages/explode/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src" + } +} diff --git a/packages/fs/deno.json b/packages/fs/deno.json deleted file mode 100644 index a16e9eca1..000000000 --- a/packages/fs/deno.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@targetd/fs", - "description": "Load targeting rules from JSON/YAML files with hot-reloading support for @targetd/api Data instances.", - "version": "7.1.0", - "exports": "./src/index.ts", - "imports": { - "@es-toolkit/es-toolkit": "jsr:@es-toolkit/es-toolkit@^1.45.1", - "@johngw/fs": "npm:@johngw/fs@^3.0.1", - "@targetd/api": "jsr:@targetd/api@^8.0.3", - "ts-toolbelt": "npm:ts-toolbelt@^9.6.0", - "yaml": "npm:yaml@^2.8.2", - "zod": "npm:zod@^4.3.6" - }, - "lint": { - "rules": { - "exclude": [ - "no-import-prefix", - "no-unversioned-import" - ] - } - }, - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "tasks": { - "pwd": "echo $(pwd)", - "test": "deno test --allow-all --trace-leaks" - }, - "publish": { - "include": [ - "deno.json", - "src/", - "LICENSE", - "README.md" - ] - } -} diff --git a/packages/fs/jsr.json b/packages/fs/jsr.json new file mode 100644 index 000000000..554b414b5 --- /dev/null +++ b/packages/fs/jsr.json @@ -0,0 +1,8 @@ +{ + "name": "@targetd/fs", + "version": "7.1.0", + "exports": "./src/index.ts", + "publish": { + "include": ["src/", "LICENSE", "README.md"] + } +} diff --git a/packages/fs/package.json b/packages/fs/package.json new file mode 100644 index 000000000..69b092d48 --- /dev/null +++ b/packages/fs/package.json @@ -0,0 +1,31 @@ +{ + "name": "@targetd/fs", + "version": "7.1.0", + "description": "Load targeting rules from JSON/YAML files with hot-reloading support for @targetd/api Data instances.", + "files": [ + "src/", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": "./src/index.ts", + "scripts": { + "test": "bun test" + }, + "dependencies": { + "@johngw/fs": "^3.0.1", + "es-toolkit": "catalog:", + "ts-toolbelt": "catalog:", + "yaml": "^2.8.2" + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "typescript": "catalog:", + "zod": "catalog:" + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:" + } +} diff --git a/packages/fs/src/watch.ts b/packages/fs/src/watch.ts index 56328d554..ce15884f8 100644 --- a/packages/fs/src/watch.ts +++ b/packages/fs/src/watch.ts @@ -1,9 +1,6 @@ import type { DT } from '@targetd/api' -import { debounce, Mutex } from '@es-toolkit/es-toolkit' -import { - watch as fsWatch, - type WatchOptions as BaseWatchOptions, -} from 'node:fs' +import { debounce, Mutex } from 'es-toolkit' +import { watch as fsWatch, type WatchOptions as BaseWatchOptions } from 'node:fs' import { load, pathIsLoadable } from './load.ts' /** @@ -82,11 +79,7 @@ export function watch( onLoad: OnLoad, ): WatchDisposer -export function watch( - data: D, - dir: string, - onLoad: OnLoad, -): WatchDisposer +export function watch(data: D, dir: string, onLoad: OnLoad): WatchDisposer export function watch( data: D, @@ -94,9 +87,7 @@ export function watch( optionsOrOnLoad: WatchOptions | OnLoad, onLoadParam?: OnLoad, ) { - const { debounceMS = 300, ...fsOptions } = onLoadParam - ? optionsOrOnLoad as WatchOptions - : {} + const { debounceMS = 300, ...fsOptions } = onLoadParam ? (optionsOrOnLoad as WatchOptions) : {} const onLoad = (onLoadParam || optionsOrOnLoad) as OnLoad const mutex = new Mutex() @@ -104,7 +95,7 @@ export function watch( await mutex.acquire() let error: Error | null = null try { - data = await load(data.removeAllRules(), dir) as D + data = (await load(data.removeAllRules(), dir)) as D } catch ($error: any) { error = $error } finally { @@ -116,13 +107,10 @@ export function watch( const watcher = fsWatch( dir, fsOptions, - debounce( - async (_eventType, filename) => { - if (filename && !pathIsLoadable(filename)) return - await onChange() - }, - debounceMS, - ), + debounce(async (_eventType, filename) => { + if (filename && !pathIsLoadable(filename)) return + await onChange() + }, debounceMS), ) const stop: WatchDisposer = () => watcher.close() diff --git a/packages/fs/test/load.test.ts b/packages/fs/test/load.test.ts index 264afb1e0..77ae7930a 100644 --- a/packages/fs/test/load.test.ts +++ b/packages/fs/test/load.test.ts @@ -1,13 +1,10 @@ -import { assertStrictEquals } from 'jsr:@std/assert' +import { test, expect } from 'bun:test' import * as path from 'node:path' import { load } from '@targetd/fs' import { data } from './fixtures/data.ts' -Deno.test('load', async () => { - const $data = await load( - data, - path.join(import.meta.dirname ?? '', 'fixtures', 'rules'), - ) - assertStrictEquals(await $data.getPayload('foo'), 'bar') - assertStrictEquals(await $data.getPayload('b'), 'b is a letter') +test('load', async () => { + const $data = await load(data, path.join(import.meta.dirname ?? '', 'fixtures', 'rules')) + expect(await $data.getPayload('foo')).toBe('bar') + expect(await $data.getPayload('b')).toBe('b is a letter') }) diff --git a/packages/fs/test/tsconfig.json b/packages/fs/test/tsconfig.json new file mode 100644 index 000000000..28ce09649 --- /dev/null +++ b/packages/fs/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["../src", "."], + "compilerOptions": { + "rootDir": "../" + } +} diff --git a/packages/fs/test/watch.test.ts b/packages/fs/test/watch.test.ts index 39d4d53b0..0fe4af981 100644 --- a/packages/fs/test/watch.test.ts +++ b/packages/fs/test/watch.test.ts @@ -1,49 +1,42 @@ -import { assertStrictEquals } from 'jsr:@std/assert' +import { test, expect } from 'bun:test' import { setTimeout } from 'node:timers/promises' import * as path from 'node:path' -import { copy } from 'jsr:@std/fs/copy' +import { cp, mkdtemp, rm } from 'node:fs/promises' +import { tmpdir } from 'node:os' import { data } from './fixtures/data.ts' import { watch } from '@targetd/fs' -Deno.test('watch', async () => { +test('watch', async () => { const { promise, reject, resolve } = Promise.withResolvers() await using disposable = new AsyncDisposableStack() - const dirTo = disposable.adopt( - await Deno.makeTempDir(), - (path) => Deno.remove(path, { recursive: true }), + const dirTo = disposable.adopt(await mkdtemp(path.join(tmpdir(), 'targetd-')), (path) => + rm(path, { recursive: true }), ) let firstCall = true disposable.adopt( - watch( - data, - dirTo, - async (error, data) => { - if (firstCall) { - firstCall = false - await setTimeout(100) - copy( - path.join(import.meta.dirname ?? '', 'fixtures', 'rules'), - dirTo, - { - overwrite: true, - }, - ) - } else { - try { - assertStrictEquals(error, null) - assertStrictEquals(await data.getPayload('foo', {}), 'bar') - assertStrictEquals(await data.getPayload('b', {}), 'b is a letter') - } catch (error) { - return reject(error) - } - resolve() + watch(data, dirTo, async (error, data) => { + if (firstCall) { + firstCall = false + await setTimeout(100) + cp(path.join(import.meta.dirname ?? '', 'fixtures', 'rules'), dirTo, { + recursive: true, + force: true, + }) + } else { + try { + expect(error).toBe(null) + expect(await data.getPayload('foo', {})).toBe('bar') + expect(await data.getPayload('b', {})).toBe('b is a letter') + } catch (error) { + return reject(error) } - }, - ), + resolve() + } + }), (stopWatching) => stopWatching(), ) diff --git a/packages/fs/tsconfig.json b/packages/fs/tsconfig.json new file mode 100644 index 000000000..d0a8f7171 --- /dev/null +++ b/packages/fs/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src" + } +} diff --git a/packages/json-schema/deno.json b/packages/json-schema/deno.json deleted file mode 100644 index ecdedc5f3..000000000 --- a/packages/json-schema/deno.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@targetd/json-schema", - "version": "5.2.0", - "description": "Generate JSON Schema from @targetd/api Data instances for API documentation and validation.", - "exports": { - ".": "./src/index.ts", - "./cli": "./src/cli.ts" - }, - "imports": { - "@es-toolkit/es-toolkit": "jsr:@es-toolkit/es-toolkit@^1.45.1", - "@targetd/api": "jsr:@targetd/api@^8.0.3", - "@types/yargs": "npm:@types/yargs@^17.0.35", - "yargs": "npm:yargs@^18.0.0", - "zod": "npm:zod@^4.3.6" - }, - "lint": { - "rules": { - "exclude": [ - "no-import-prefix", - "no-unversioned-import" - ] - } - }, - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "tasks": { - "pwd": "echo $(pwd)", - "test": "deno test --allow-all --trace-leaks" - }, - "publish": { - "include": [ - "deno.json", - "src/", - "LICENSE", - "README.md" - ] - } -} diff --git a/packages/json-schema/jsr.json b/packages/json-schema/jsr.json new file mode 100644 index 000000000..8d2e90085 --- /dev/null +++ b/packages/json-schema/jsr.json @@ -0,0 +1,11 @@ +{ + "name": "@targetd/json-schema", + "version": "5.2.0", + "exports": { + ".": "./src/index.ts", + "./cli": "./src/cli.ts" + }, + "publish": { + "include": ["src/", "LICENSE", "README.md"] + } +} diff --git a/packages/json-schema/package.json b/packages/json-schema/package.json new file mode 100644 index 000000000..73732754e --- /dev/null +++ b/packages/json-schema/package.json @@ -0,0 +1,33 @@ +{ + "name": "@targetd/json-schema", + "version": "5.2.0", + "description": "Generate JSON Schema from @targetd/api Data instances for API documentation and validation.", + "files": [ + "src/", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": { + ".": "./src/index.ts", + "./cli": "./src/cli.ts" + }, + "scripts": { + "test": "bun test" + }, + "dependencies": { + "es-toolkit": "catalog:", + "yargs": "^18.0.0" + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@types/bun": "catalog:", + "@types/yargs": "^17.0.35", + "typescript": "catalog:", + "zod": "catalog:" + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:" + } +} diff --git a/packages/json-schema/src/index.ts b/packages/json-schema/src/index.ts index 40a0dc3ab..b1261d5ec 100644 --- a/packages/json-schema/src/index.ts +++ b/packages/json-schema/src/index.ts @@ -1,10 +1,5 @@ -import { omit } from '@es-toolkit/es-toolkit' -import { - DataItemParser, - DataItemsParser, - type DT, - isZodSwitch, -} from '@targetd/api' +import { omit } from 'es-toolkit' +import { DataItemParser, DataItemsParser, type DT, isZodSwitch } from '@targetd/api' import { extend, optional, string, toJSONSchema } from 'zod/mini' import type { JSONSchema } from 'zod/v4/core' diff --git a/packages/json-schema/test/__snapshots__/index.test.ts.snap b/packages/json-schema/test/__snapshots__/index.test.ts.snap index a1d5ad45c..9f2adcb1d 100644 --- a/packages/json-schema/test/__snapshots__/index.test.ts.snap +++ b/packages/json-schema/test/__snapshots__/index.test.ts.snap @@ -1,537 +1,546 @@ -export const snapshot = {}; +// Bun Snapshot v1, https://bun.sh/docs/test/snapshots -snapshot[`json schema for simple data object 1`] = ` +exports[`json schema for simple data object 1`] = ` { - "\$defs": { - __schema0: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "$defs": { + "__schema0": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", + "type": "object", }, - __schema10: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "__schema1": { + "items": { + "type": "string", + }, + "type": "array", + }, + "__schema10": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", + "type": "object", }, - __schema11: { - type: "string", + "__schema11": { + "type": "string", }, - __schema12: { - items: { - additionalProperties: false, - properties: { - payload: { - anyOf: [ + "__schema12": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, {}, ], }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema13", + "$ref": "#/$defs/__schema13", }, { - items: { - "\$ref": "#/\$defs/__schema13", + "items": { + "$ref": "#/$defs/__schema13", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - __schema13: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "__schema13": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", + "type": "object", }, - __schema14: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "__schema14": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", + "type": "object", }, - __schema15: { - type: "string", + "__schema15": { + "type": "string", }, - __schema16: { - items: { - additionalProperties: false, - properties: { - payload: { - anyOf: [ + "__schema16": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, {}, ], }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema17", + "$ref": "#/$defs/__schema17", }, { - items: { - "\$ref": "#/\$defs/__schema17", + "items": { + "$ref": "#/$defs/__schema17", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - __schema17: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "__schema17": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", - }, - __schema1: { - items: { - type: "string", - }, - type: "array", + "type": "object", }, - __schema2: { - items: { - type: "string", + "__schema2": { + "items": { + "type": "string", }, - type: "array", + "type": "array", }, - __schema3: { - type: "string", + "__schema3": { + "type": "string", }, - __schema4: { - items: { - additionalProperties: false, - properties: { - payload: { - anyOf: [ + "__schema4": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, {}, ], }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema5", + "$ref": "#/$defs/__schema5", }, { - items: { - "\$ref": "#/\$defs/__schema5", + "items": { + "$ref": "#/$defs/__schema5", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - __schema5: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "__schema5": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", + "type": "object", }, - __schema6: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "__schema6": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", + "type": "object", }, - __schema7: { - type: "string", + "__schema7": { + "type": "string", }, - __schema8: { - items: { - additionalProperties: false, - properties: { - payload: { - anyOf: [ + "__schema8": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, {}, ], }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema9", + "$ref": "#/$defs/__schema9", }, { - items: { - "\$ref": "#/\$defs/__schema9", + "items": { + "$ref": "#/$defs/__schema9", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - __schema9: { - additionalProperties: false, - properties: { - browser: { - "\$ref": "#/\$defs/__schema2", + "__schema9": { + "additionalProperties": false, + "properties": { + "browser": { + "$ref": "#/$defs/__schema2", }, - weather: { - "\$ref": "#/\$defs/__schema1", + "weather": { + "$ref": "#/$defs/__schema1", }, }, - type: "object", + "type": "object", }, }, - "\$schema": "https://json-schema.org/draft/2020-12/schema", - additionalProperties: false, - properties: { - "\$schema": { - type: "string", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", }, - array: { - additionalProperties: false, - properties: { - rules: { - items: { - additionalProperties: false, - properties: { - payload: { - anyOf: [ + "array": { + "additionalProperties": false, + "properties": { + "rules": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, { - items: { - anyOf: [ + "items": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, { - type: "number", + "type": "number", }, ], }, - type: "array", + "type": "array", }, ], }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema14", + "$ref": "#/$defs/__schema14", }, { - items: { - "\$ref": "#/\$defs/__schema14", + "items": { + "$ref": "#/$defs/__schema14", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - variables: { - additionalProperties: { - "\$ref": "#/\$defs/__schema16", + "variables": { + "additionalProperties": { + "$ref": "#/$defs/__schema16", }, - propertyNames: { - "\$ref": "#/\$defs/__schema15", + "propertyNames": { + "$ref": "#/$defs/__schema15", }, - type: "object", + "type": "object", }, }, - required: [ + "required": [ "rules", ], - type: "object", + "type": "object", }, - bar: { - additionalProperties: false, - properties: { - rules: { - items: { - additionalProperties: false, - properties: { - payload: { - anyOf: [ + "bar": { + "additionalProperties": false, + "properties": { + "rules": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, { - additionalProperties: false, - properties: { - a: { - anyOf: [ + "additionalProperties": false, + "properties": { + "a": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, { - type: "number", + "type": "number", }, ], }, - b: { - anyOf: [ + "b": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, { - items: { - type: "string", + "items": { + "type": "string", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "a", "b", ], - type: "object", + "type": "object", }, ], }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema6", + "$ref": "#/$defs/__schema6", }, { - items: { - "\$ref": "#/\$defs/__schema6", + "items": { + "$ref": "#/$defs/__schema6", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - variables: { - additionalProperties: { - "\$ref": "#/\$defs/__schema8", + "variables": { + "additionalProperties": { + "$ref": "#/$defs/__schema8", }, - propertyNames: { - "\$ref": "#/\$defs/__schema7", + "propertyNames": { + "$ref": "#/$defs/__schema7", }, - type: "object", + "type": "object", }, }, - required: [ + "required": [ "rules", ], - type: "object", + "type": "object", }, - foo: { - additionalProperties: false, - properties: { - rules: { - items: { - additionalProperties: false, - properties: { - payload: { - type: "string", + "foo": { + "additionalProperties": false, + "properties": { + "rules": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "type": "string", }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema0", + "$ref": "#/$defs/__schema0", }, { - items: { - "\$ref": "#/\$defs/__schema0", + "items": { + "$ref": "#/$defs/__schema0", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - variables: { - additionalProperties: { - "\$ref": "#/\$defs/__schema4", + "variables": { + "additionalProperties": { + "$ref": "#/$defs/__schema4", }, - propertyNames: { - "\$ref": "#/\$defs/__schema3", + "propertyNames": { + "$ref": "#/$defs/__schema3", }, - type: "object", + "type": "object", }, }, - required: [ + "required": [ "rules", ], - type: "object", + "type": "object", }, - record: { - additionalProperties: false, - properties: { - rules: { - items: { - additionalProperties: false, - properties: { - payload: { - anyOf: [ + "record": { + "additionalProperties": false, + "properties": { + "rules": { + "items": { + "additionalProperties": false, + "properties": { + "payload": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, { - additionalProperties: { - anyOf: [ + "additionalProperties": { + "anyOf": [ { - pattern: "^\\\\{\\\\{[\\\\s\\\\S]{0,}\\\\}\\\\}\$", - type: "string", + "pattern": "^\\{\\{[\\s\\S]{0,}\\}\\}$", + "type": "string", }, { - type: "number", + "type": "number", }, ], }, - propertyNames: { - type: "string", + "propertyNames": { + "type": "string", }, - type: "object", + "type": "object", }, ], }, - targeting: { - anyOf: [ + "targeting": { + "anyOf": [ { - "\$ref": "#/\$defs/__schema10", + "$ref": "#/$defs/__schema10", }, { - items: { - "\$ref": "#/\$defs/__schema10", + "items": { + "$ref": "#/$defs/__schema10", }, - type: "array", + "type": "array", }, ], }, }, - required: [ + "required": [ "payload", ], - type: "object", + "type": "object", }, - type: "array", + "type": "array", }, - variables: { - additionalProperties: { - "\$ref": "#/\$defs/__schema12", + "variables": { + "additionalProperties": { + "$ref": "#/$defs/__schema12", }, - propertyNames: { - "\$ref": "#/\$defs/__schema11", + "propertyNames": { + "$ref": "#/$defs/__schema11", }, - type: "object", + "type": "object", }, }, - required: [ + "required": [ "rules", ], - type: "object", + "type": "object", + }, + }, + "type": "object", + "~standard": { + "jsonSchema": { + "input": [Function], + "output": [Function], }, + "validate": [Function], + "vendor": "zod", + "version": 1, }, - type: "object", } `; diff --git a/packages/json-schema/test/index.test.ts b/packages/json-schema/test/index.test.ts index 465b5913e..66fa5cd74 100644 --- a/packages/json-schema/test/index.test.ts +++ b/packages/json-schema/test/index.test.ts @@ -1,10 +1,7 @@ -import { assertSnapshot } from 'jsr:@std/testing/snapshot' +import { test, expect } from 'bun:test' import { dataJSONSchemas } from '@targetd/json-schema' import { data } from './fixtures/data.ts' -Deno.test('json schema for simple data object', async (t) => { - await assertSnapshot( - t, - dataJSONSchemas(data), - ) +test('json schema for simple data object', async () => { + expect(dataJSONSchemas(data)).toMatchSnapshot() }) diff --git a/packages/json-schema/test/tsconfig.json b/packages/json-schema/test/tsconfig.json new file mode 100644 index 000000000..28ce09649 --- /dev/null +++ b/packages/json-schema/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["../src", "."], + "compilerOptions": { + "rootDir": "../" + } +} diff --git a/packages/json-schema/tsconfig.json b/packages/json-schema/tsconfig.json new file mode 100644 index 000000000..d0a8f7171 --- /dev/null +++ b/packages/json-schema/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src" + } +} diff --git a/packages/server/deno.json b/packages/server/deno.json deleted file mode 100644 index 57f493f9c..000000000 --- a/packages/server/deno.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@targetd/server", - "description": "Express-based HTTP server for exposing @targetd/api Data instances via REST endpoints with built-in CORS and error handling.", - "version": "8.1.2", - "exports": "./src/index.ts", - "imports": { - "@johngw/error": "npm:@johngw/error@^2.2.2", - "@targetd/api": "jsr:@targetd/api@^8.0.3", - "@types/express": "npm:@types/express@^5.0.6", - "@types/qs": "npm:@types/qs@^6.15.0", - "cors": "npm:cors@^2.8.6", - "express": "npm:express@^5.2.1", - "express-query-boolean": "npm:express-query-boolean@^2.0.0", - "qs": "npm:qs@^6.15.0", - "zod": "npm:zod@^4.3.6" - }, - "lint": { - "rules": { - "exclude": [ - "no-import-prefix", - "no-unversioned-import" - ] - } - }, - "fmt": { - "semiColons": false, - "singleQuote": true - }, - "tasks": { - "pwd": "echo $(pwd)", - "test": "deno test --allow-all --trace-leaks" - }, - "publish": { - "include": [ - "deno.json", - "src/", - "LICENSE", - "README.md" - ] - } -} diff --git a/packages/server/jsr.json b/packages/server/jsr.json new file mode 100644 index 000000000..262e8d24e --- /dev/null +++ b/packages/server/jsr.json @@ -0,0 +1,8 @@ +{ + "name": "@targetd/server", + "version": "8.1.2", + "exports": "./src/index.ts", + "publish": { + "include": ["src/", "LICENSE", "README.md"] + } +} diff --git a/packages/server/package.json b/packages/server/package.json new file mode 100644 index 000000000..28db5f20c --- /dev/null +++ b/packages/server/package.json @@ -0,0 +1,38 @@ +{ + "name": "@targetd/server", + "version": "8.1.2", + "description": "Express-based HTTP server for exposing @targetd/api Data instances via REST endpoints with built-in CORS and error handling.", + "files": [ + "src/", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": "./src/index.ts", + "scripts": { + "test": "bun test" + }, + "dependencies": { + "@johngw/error": "^2.2.2", + "cors": "^2.8.6", + "express": "^5.2.1", + "express-query-boolean": "^2.0.0", + "qs": "^6.15.0" + }, + "devDependencies": { + "@targetd/api": "workspace:*", + "@targetd/date-range": "workspace:*", + "@types/bun": "catalog:", + "@types/express": "^5.0.6", + "@types/qs": "^6.15.0", + "@types/supertest": "latest", + "lodash": "latest", + "supertest": "latest", + "typescript": "catalog:", + "zod": "catalog:" + }, + "peerDependencies": { + "@targetd/api": "workspace:*", + "zod": "catalog:" + } +} diff --git a/packages/server/test/__snapshots__/index.test.ts.snap b/packages/server/test/__snapshots__/index.test.ts.snap index bc517ac10..b20ee11a4 100644 --- a/packages/server/test/__snapshots__/index.test.ts.snap +++ b/packages/server/test/__snapshots__/index.test.ts.snap @@ -1,97 +1,97 @@ -export const snapshot = {}; +// Bun Snapshot v1, https://bun.sh/docs/test/snapshots -snapshot[`get one data point 1`] = ` +exports[`get one data point 1`] = ` { - issues: [ + "issues": [ { - code: "invalid_type", - expected: "string", - message: "Invalid input: expected string, received array", - path: [ + "code": "invalid_type", + "expected": "string", + "message": "Invalid input: expected string, received array", + "path": [ "weather", ], }, ], - status: "validation error", + "status": "validation error", } `; -snapshot[`get all 1`] = ` +exports[`get all 1`] = ` { - bar: 123, - foo: "bar", - timed: "out of time", + "bar": 123, + "foo": "bar", + "timed": "out of time", } `; -snapshot[`get all 2`] = ` +exports[`get all 2`] = ` { - bar: 123, - foo: "😎", - timed: "out of time", + "bar": 123, + "foo": "😎", + "timed": "out of time", } `; -snapshot[`get all 3`] = ` +exports[`get all 3`] = ` { - bar: 123, - foo: "☂️", - timed: "out of time", + "bar": 123, + "foo": "☂️", + "timed": "out of time", } `; -snapshot[`get all 4`] = ` +exports[`get all 4`] = ` { - bar: 123, - foo: "🌊", - timed: "out of time", + "bar": 123, + "foo": "🌊", + "timed": "out of time", } `; -snapshot[`get all 5`] = ` +exports[`get all 5`] = ` { - bar: 123, - foo: "🏄‍♂️", - timed: "out of time", + "bar": 123, + "foo": "🏄‍♂️", + "timed": "out of time", } `; -snapshot[`get all 6`] = ` +exports[`get all 6`] = ` { - bar: 123, - foo: "Async payload", - timed: "out of time", + "bar": 123, + "foo": "Async payload", + "timed": "out of time", } `; -snapshot[`error handling 1`] = ` +exports[`error handling 1`] = ` { - issues: [ + "issues": [ { - code: "invalid_type", - expected: "string", - message: "Invalid input: expected string, received array", - path: [ + "code": "invalid_type", + "expected": "string", + "message": "Invalid input: expected string, received array", + "path": [ "weather", ], }, ], - status: "validation error", + "status": "validation error", } `; -snapshot[`error handling 2`] = ` +exports[`error handling 2`] = ` { - issues: [ + "issues": [ { - code: "invalid_type", - expected: "boolean", - message: "Invalid input: expected boolean, received string", - path: [ + "code": "invalid_type", + "expected": "boolean", + "message": "Invalid input: expected boolean, received string", + "path": [ "highTide", ], }, ], - status: "validation error", + "status": "validation error", } `; diff --git a/packages/server/test/index.test.ts b/packages/server/test/index.test.ts index b0c04cc72..2fd599e41 100644 --- a/packages/server/test/index.test.ts +++ b/packages/server/test/index.test.ts @@ -1,23 +1,18 @@ -import { assertSnapshot } from 'jsr:@std/testing/snapshot' +import { test, expect } from 'bun:test' import { Data, type DT, targetEquals, targetIncludes } from '@targetd/api' import dateRangeTargeting from '@targetd/date-range' -import _ from 'npm:lodash' +import _ from 'lodash' import { setTimeout } from 'node:timers/promises' -// @ts-types='npm:@types/supertest' -import request from 'npm:supertest' +import request from 'supertest' import z from 'zod' import { createServer } from '@targetd/server' import { promisify } from 'node:util' import type { Server } from 'node:http' -Deno.test('get one data point', async (t) => { +test('get one data point', async () => { await using server = await createDisposableServer() - await request(server) - .get('/foo') - .expect('Content-Type', /json/) - .expect('"bar"') - .expect(200) + await request(server).get('/foo').expect('Content-Type', /json/).expect('"bar"').expect(200) await request(server) .get('/foo?weather=sunny') @@ -73,50 +68,36 @@ Deno.test('get one data point', async (t) => { .expect('"b t\'ing"') .expect(200) - const response = await request(server) - .get('/foo?weather=rainy&weather=sunny') - .expect(400) - await assertSnapshot(t, response.body) + const response = await request(server).get('/foo?weather=rainy&weather=sunny').expect(400) + expect(response.body).toMatchSnapshot() }) -Deno.test('get all', async (t) => { +test('get all', async () => { await using server = await createDisposableServer() - let response = await request(server) - .get('/') - .expect('Content-Type', /json/) - .expect(200) - await assertSnapshot(t, response.body) + let response = await request(server).get('/').expect('Content-Type', /json/).expect(200) + expect(response.body).toMatchSnapshot() - response = await request(server) - .get('/?weather=sunny') - .expect('Content-Type', /json/) - .expect(200) - await assertSnapshot(t, response.body) + response = await request(server).get('/?weather=sunny').expect('Content-Type', /json/).expect(200) + expect(response.body).toMatchSnapshot() - response = await request(server) - .get('/?weather=rainy') - .expect('Content-Type', /json/) - .expect(200) - await assertSnapshot(t, response.body) + response = await request(server).get('/?weather=rainy').expect('Content-Type', /json/).expect(200) + expect(response.body).toMatchSnapshot() - response = await request(server) - .get('/?highTide=true') - .expect('Content-Type', /json/) - .expect(200) - await assertSnapshot(t, response.body) + response = await request(server).get('/?highTide=true').expect('Content-Type', /json/).expect(200) + expect(response.body).toMatchSnapshot() response = await request(server) .get('/?highTide=true&weather=sunny') .expect('Content-Type', /json/) .expect(200) - await assertSnapshot(t, response.body) + expect(response.body).toMatchSnapshot() response = await request(server) .get('/?asyncThing=true') .expect('Content-Type', /json/) .expect(200) - await assertSnapshot(t, response.body) + expect(response.body).toMatchSnapshot() }) async function createDisposableServer(options?: { @@ -128,7 +109,7 @@ async function createDisposableServer(options?: { pathStructure: options?.pathStructure as any, }) const { promise, reject, resolve } = Promise.withResolvers() - const server = app.listen(0, (error) => error ? reject(error) : resolve()) + const server = app.listen(0, (error) => (error ? reject(error) : resolve())) await promise server[Symbol.asyncDispose] = promisify(server.close.bind(server)) return server @@ -145,8 +126,7 @@ function createData() { weather: targetIncludes(z.string()), highTide: targetEquals(z.boolean()), asyncThing: { - predicate: (q) => - setTimeout(10, (t) => q === t && setTimeout(10, true)), + predicate: (q) => setTimeout(10, (t) => q === t && setTimeout(10, true)), queryParser: z.boolean(), targetingParser: z.boolean(), }, @@ -223,7 +203,7 @@ function createData() { ]) } -Deno.test('custom path structure', async () => { +test('custom path structure', async () => { const data = await Data.create() .usePayload({ content: z.string(), @@ -296,9 +276,7 @@ Deno.test('custom path structure', async () => { .expect(200) .expect((res) => { if (res.body.content !== 'US Mobile Content') { - throw new Error( - `Expected "US Mobile Content", got "${res.body.content}"`, - ) + throw new Error(`Expected "US Mobile Content", got "${res.body.content}"`) } if (res.body.config !== 10) { throw new Error(`Expected 10, got "${res.body.config}"`) @@ -311,9 +289,7 @@ Deno.test('custom path structure', async () => { .expect(200) .expect((res) => { if (res.body.content !== 'US Desktop Content') { - throw new Error( - `Expected "US Desktop Content", got "${res.body.content}"`, - ) + throw new Error(`Expected "US Desktop Content", got "${res.body.content}"`) } if (res.body.config !== 50) { throw new Error(`Expected 50, got "${res.body.config}"`) @@ -326,9 +302,7 @@ Deno.test('custom path structure', async () => { .expect(200) .expect((res) => { if (res.body.content !== 'EU Mobile Content') { - throw new Error( - `Expected "EU Mobile Content", got "${res.body.content}"`, - ) + throw new Error(`Expected "EU Mobile Content", got "${res.body.content}"`) } }) @@ -338,9 +312,7 @@ Deno.test('custom path structure', async () => { .expect(200) .expect((res) => { if (res.body.content !== 'EU Desktop Content') { - throw new Error( - `Expected "EU Desktop Content", got "${res.body.content}"`, - ) + throw new Error(`Expected "EU Desktop Content", got "${res.body.content}"`) } }) @@ -351,9 +323,7 @@ Deno.test('custom path structure', async () => { .expect(200) .expect((res) => { if (res.body.content !== 'Default Content') { - throw new Error( - `Expected "Default Content", got "${res.body.content}"`, - ) + throw new Error(`Expected "Default Content", got "${res.body.content}"`) } if (res.body.config !== 5) { throw new Error(`Expected 5, got "${res.body.config}"`) @@ -361,26 +331,23 @@ Deno.test('custom path structure', async () => { }) }) -Deno.test('error handling', async (t) => { +test('error handling', async () => { await using server = await createDisposableServer() // Test 404 for non-existent payload name - await request(server) - .get('/nonexistent') - .expect('Content-Type', /json/) - .expect(404) + await request(server).get('/nonexistent').expect('Content-Type', /json/).expect(404) // Test 400 for invalid query parameter (Zod validation error) let response = await request(server) .get('/foo?weather=rainy&weather=sunny') .expect('Content-Type', /json/) .expect(400) - await assertSnapshot(t, response.body) + expect(response.body).toMatchSnapshot() // Test 400 for invalid boolean value response = await request(server) .get('/foo?highTide=notaboolean') .expect('Content-Type', /json/) .expect(400) - await assertSnapshot(t, response.body) + expect(response.body).toMatchSnapshot() }) diff --git a/packages/server/test/tsconfig.json b/packages/server/test/tsconfig.json new file mode 100644 index 000000000..28ce09649 --- /dev/null +++ b/packages/server/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["../src", "."], + "compilerOptions": { + "rootDir": "../" + } +} diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json new file mode 100644 index 000000000..d0a8f7171 --- /dev/null +++ b/packages/server/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src" + } +} diff --git a/release-please-config.json b/release-please-config.json index aee8ec9e3..8cb041605 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -3,85 +3,53 @@ "last-release-sha": "a8393d88d0311bce7ff9daf4dd5c4fdb6c3d9774", "packages": { "packages/api": { - "release-type": "simple", + "release-type": "node", "package-name": "@targetd/api", "tag-separator": "-", "include-component-in-tag": true, - "extra-files": [ - "deno.json", - { - "type": "json", - "path": "packages/client/deno.json", - "jsonpath": "$.imports['@targetd/api']" - }, - { - "type": "json", - "path": "packages/date-range/deno.json", - "jsonpath": "$.imports['@targetd/api']" - }, - { - "type": "json", - "path": "packages/explode/deno.json", - "jsonpath": "$.imports['@targetd/api']" - }, - { - "type": "json", - "path": "packages/fs/deno.json", - "jsonpath": "$.imports['@targetd/api']" - }, - { - "type": "json", - "path": "packages/json-schema/deno.json", - "jsonpath": "$.imports['@targetd/api']" - }, - { - "type": "json", - "path": "packages/server/deno.json", - "jsonpath": "$.imports['@targetd/api']" - } - ] + "extra-files": ["jsr.json"] }, "packages/client": { - "release-type": "simple", + "release-type": "node", "package-name": "@targetd/client", "tag-separator": "-", "include-component-in-tag": true, - "extra-files": ["deno.json"] + "extra-files": ["jsr.json"] }, "packages/date-range": { - "release-type": "simple", + "release-type": "node", "package-name": "@targetd/date-range", "tag-separator": "-", "include-component-in-tag": true, - "extra-files": ["deno.json"] + "extra-files": ["jsr.json"] }, "packages/explode": { - "release-type": "simple", + "release-type": "node", "package-name": "@targetd/explode", "tag-separator": "-", "include-component-in-tag": true, - "extra-files": ["deno.json"] + "extra-files": ["jsr.json"] }, "packages/fs": { - "release-type": "simple", + "release-type": "node", "package-name": "@targetd/fs", "tag-separator": "-", "include-component-in-tag": true, - "extra-files": ["deno.json"] + "extra-files": ["jsr.json"] }, "packages/json-schema": { - "release-type": "simple", + "release-type": "node", "package-name": "@targetd/json-schema", "tag-separator": "-", "include-component-in-tag": true, - "extra-files": ["deno.json"] + "extra-files": ["jsr.json"] }, "packages/server": { - "release-type": "simple", + "release-type": "node", "package-name": "@targetd/server", "tag-separator": "-", "include-component-in-tag": true, - "extra-files": ["deno.json"] + "extra-files": ["jsr.json"] } } } diff --git a/targetd.code-workspace b/targetd.code-workspace index cc3217b4d..f620b9cec 100644 --- a/targetd.code-workspace +++ b/targetd.code-workspace @@ -10,34 +10,14 @@ { "name": "📦 @targetd/server", "path": "packages/server" }, { "name": "🤖 github", "path": ".github" } ], + "extensions": { + "recommendations": ["oxc.oxc-vscode"] + }, "settings": { - "deno.enable": true, - "deno.lint": true, - "eslint.enable": false, - "editor.defaultFormatter": "denoland.vscode-deno", - "[typescript]": { - "editor.defaultFormatter": "denoland.vscode-deno" - }, - "[typescriptreact]": { - "editor.defaultFormatter": "denoland.vscode-deno" - }, - "[json]": { - "editor.defaultFormatter": "denoland.vscode-deno" - }, - "[javascript]": { - "editor.defaultFormatter": "denoland.vscode-deno" + "editor.codeActionsOnSave": { + "source.fixAll.oxc": "always" }, - "[jsonc]": { - "editor.defaultFormatter": "denoland.vscode-deno" - }, - "[yaml]": { - "editor.defaultFormatter": "denoland.vscode-deno" - }, - "[html]": { - "editor.defaultFormatter": "denoland.vscode-deno" - } - }, - "extensions": { - "recommendations": ["denoland.vscode-deno"] + "editor.defaultFormatter": "oxc.oxc-vscode", + "oxc.enable": true } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..ee2dba86b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "allowJs": false, + "declaration": true, + "declarationMap": true, + "importHelpers": true, + "lib": ["ESNext"], + "module": "Preserve", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": false, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "dist", + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "ESNext", + "verbatimModuleSyntax": true + } +} From bbc70f4af861f95f597b306289e7dce877e3946e Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:11:12 +0000 Subject: [PATCH 02/17] ci: convert dependencies before publishin --- .github/workflows/release.yml | 6 +++++- packages/api/jsr.json | 1 + packages/client/jsr.json | 1 + packages/date-range/jsr.json | 1 + packages/explode/jsr.json | 1 + packages/fs/jsr.json | 1 + packages/json-schema/jsr.json | 1 + packages/server/jsr.json | 1 + 8 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index afdd94847..503614ec7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,4 +44,8 @@ jobs: uses: ./.github/actions/test - if: steps.package.outputs.private != 'true' working-directory: ${{ matrix.path_released }} - run: bunx jsr publish + run: | # shell + bun pm pack --filename=$(pwd)/temp.tgz + tar -xOf temp.tgz package/package.json > package.json + rm -rf package temp.tgz + bunx jsr publish diff --git a/packages/api/jsr.json b/packages/api/jsr.json index 95642d70d..f94fdb2ef 100644 --- a/packages/api/jsr.json +++ b/packages/api/jsr.json @@ -1,4 +1,5 @@ { + "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@targetd/api", "version": "8.1.1", "exports": "./src/index.ts", diff --git a/packages/client/jsr.json b/packages/client/jsr.json index b82f7526e..8598d7f32 100644 --- a/packages/client/jsr.json +++ b/packages/client/jsr.json @@ -1,4 +1,5 @@ { + "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@targetd/client", "version": "7.0.2", "exports": "./src/index.ts", diff --git a/packages/date-range/jsr.json b/packages/date-range/jsr.json index ee8fb04fd..43a6fbb07 100644 --- a/packages/date-range/jsr.json +++ b/packages/date-range/jsr.json @@ -1,4 +1,5 @@ { + "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@targetd/date-range", "version": "6.0.2", "exports": "./src/index.ts", diff --git a/packages/explode/jsr.json b/packages/explode/jsr.json index 89fa21814..f9a5d9b33 100644 --- a/packages/explode/jsr.json +++ b/packages/explode/jsr.json @@ -1,4 +1,5 @@ { + "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@targetd/explode", "version": "4.0.2", "exports": "./src/index.ts", diff --git a/packages/fs/jsr.json b/packages/fs/jsr.json index 554b414b5..6fd304348 100644 --- a/packages/fs/jsr.json +++ b/packages/fs/jsr.json @@ -1,4 +1,5 @@ { + "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@targetd/fs", "version": "7.1.0", "exports": "./src/index.ts", diff --git a/packages/json-schema/jsr.json b/packages/json-schema/jsr.json index 8d2e90085..ec4288efd 100644 --- a/packages/json-schema/jsr.json +++ b/packages/json-schema/jsr.json @@ -1,4 +1,5 @@ { + "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@targetd/json-schema", "version": "5.2.0", "exports": { diff --git a/packages/server/jsr.json b/packages/server/jsr.json index 262e8d24e..3cc18118b 100644 --- a/packages/server/jsr.json +++ b/packages/server/jsr.json @@ -1,4 +1,5 @@ { + "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@targetd/server", "version": "8.1.2", "exports": "./src/index.ts", From 2abbb8fb7885965480a0a7b3c6334c7af509348d Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:32:14 +0000 Subject: [PATCH 03/17] chore: tsc checks --- bun.lock | 3 + package.json | 2 +- packages/api/package.json | 1 + .../src/parsers/DataItemVariablesParser.ts | 40 ++++--------- packages/client/package.json | 1 + packages/client/src/index.ts | 57 +++++++------------ packages/date-range/package.json | 1 + packages/explode/package.json | 1 + packages/fs/package.json | 1 + packages/json-schema/package.json | 1 + packages/server/package.json | 2 + packages/server/src/index.ts | 54 ++++++------------ tsconfig.json | 4 +- 13 files changed, 63 insertions(+), 105 deletions(-) diff --git a/bun.lock b/bun.lock index 7afd36a8a..e50f4429b 100644 --- a/bun.lock +++ b/bun.lock @@ -135,6 +135,7 @@ "@targetd/api": "workspace:*", "@targetd/date-range": "workspace:*", "@types/bun": "catalog:", + "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/qs": "^6.15.0", "@types/supertest": "latest", @@ -277,6 +278,8 @@ "@types/cookiejar": ["@types/cookiejar@2.1.5", "", {}, "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q=="], + "@types/cors": ["@types/cors@2.8.19", "", { "dependencies": { "@types/node": "*" } }, "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg=="], + "@types/express": ["@types/express@5.0.6", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", "@types/serve-static": "^2" } }, "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA=="], "@types/express-serve-static-core": ["@types/express-serve-static-core@5.1.1", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A=="], diff --git a/package.json b/package.json index 86f97cc65..12af834df 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "type": "module", "scripts": { "test": "bun test packages/**/test", - "check": "tsc --noEmit", + "check": "bun --workspaces check", "lint": "oxlint", "fmt": "oxfmt", "commitlint": "commitlint" diff --git a/packages/api/package.json b/packages/api/package.json index 3377f3247..434666558 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -10,6 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { + "check": "tsc", "test": "bun test" }, "dependencies": { diff --git a/packages/api/src/parsers/DataItemVariablesParser.ts b/packages/api/src/parsers/DataItemVariablesParser.ts index 194bdbae3..cd568c056 100644 --- a/packages/api/src/parsers/DataItemVariablesParser.ts +++ b/packages/api/src/parsers/DataItemVariablesParser.ts @@ -20,18 +20,10 @@ export function DataItemVariablesParser<$ extends DT.Meta>( ): DataItemVariablesParser<$> { return record( string(), - DataItemRulesParser( - variablesRegistry, - any(), - targeting, - fallThroughTargeting, - strictTargeting, - ), + DataItemRulesParser(variablesRegistry, any(), targeting, fallThroughTargeting, strictTargeting), ).check((ctx) => { const variables = variablesRegistry.getAll() - for ( - const [varName, { parser }] of Object.entries(variables) - ) { + for (const [varName, { parser }] of Object.entries(variables)) { if (!(varName in ctx.value)) { ctx.issues.push({ code: 'custom', @@ -39,26 +31,17 @@ export function DataItemVariablesParser<$ extends DT.Meta>( message: `Variable ${varName} has not been set`, }) } else { - ctx.value[varName].forEach((rule, index) => { + ctx.value[varName]!.forEach((rule, index) => { if ('payload' in rule) { - parseVarPayload(varName, parser, rule.payload, [ - varName, - index, - 'payload', - ]) + parseVarPayload(varName, parser, rule.payload, [varName, index, 'payload']) } else { for (const fallthroughRule of rule.fallThrough) { - parseVarPayload( + parseVarPayload(varName, parser, fallthroughRule.payload, [ varName, - parser, - fallthroughRule.payload, - [ - varName, - index, - JSON.stringify({ targeting: fallthroughRule.targeting }), - 'payload', - ], - ) + index, + JSON.stringify({ targeting: fallthroughRule.targeting }), + 'payload', + ]) } } }) @@ -76,9 +59,8 @@ export function DataItemVariablesParser<$ extends DT.Meta>( ctx.issues.push( ...result.error.issues.map((issue) => ({ ...issue, - input: issue.input ?? payload as any, - message: - `The variable {{${varName}}} cannot be used where it currently is in the payload.\n${issue.message}`, + input: issue.input ?? (payload as any), + message: `The variable {{${varName}}} cannot be used where it currently is in the payload.\n${issue.message}`, path: [...path, ...issue.path], })), ) diff --git a/packages/client/package.json b/packages/client/package.json index 64d4ed851..eaac8e46c 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -10,6 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { + "check": "tsc", "test": "bun test" }, "dependencies": { diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index f6dea2900..8116dc376 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -39,11 +39,7 @@ export class Client<$ extends DT.Meta> { * }) * ``` */ - constructor( - baseURL: string, - data: Data<$>, - init?: RequestInit, - ) { + constructor(baseURL: string, data: Data<$>, init?: RequestInit) { this.#baseURL = baseURL this.#data = data.removeAllRules() this.#init = init @@ -70,35 +66,28 @@ export class Client<$ extends DT.Meta> { async getPayload( name: Name, rawQuery: Partial> = {}, - ): Promise< - | PT.Payload<$, $['PayloadParsers'][Name]> - | void - > { + ): Promise | void> { const query = this.#data.QueryParser.parse(rawQuery) const urlSearchParams = queryToURLSearchParams(query) - const response = await fetch( - `${this.#baseURL}/${String(name)}?${urlSearchParams}`, - { - method: 'GET', - ...this.#init, - }, - ) + const response = await fetch(`${this.#baseURL}/${String(name)}?${urlSearchParams}`, { + method: 'GET', + ...this.#init, + }) switch (true) { case response.status === 204: return undefined + // @ts-expect-error Fallthrough case in switch.ts(7029) case response.status === 400: - await response.json() - .then( - (error) => { - if (error.name === '$ZodError') { - throw new ZodError(JSON.parse(error.message)) - } - }, - () => {}, - ) - // fallthrough - case response.status > 200 || response.status < 200: + await response.json().then( + (error: any) => { + if (error.name === '$ZodError') { + throw new ZodError(JSON.parse(error.message)) + } + }, + () => {}, + ) + case response.status >= 200 || response.status < 300: throw new ResponseError(response) default: { const data = await this.#data.insert({ @@ -121,16 +110,10 @@ export class Client<$ extends DT.Meta> { * // Returns: { greeting: 'Hello!', feature: {...}, ... } * ``` */ - async getPayloadForEachName( - rawQuery: Partial> = {}, - ): Promise< - Partial< - { - [Name in keyof $['PayloadParsers']]: - | PT.Payload<$, $['PayloadParsers'][Name]> - | undefined - } - > + async getPayloadForEachName(rawQuery: Partial> = {}): Promise< + Partial<{ + [Name in keyof $['PayloadParsers']]: PT.Payload<$, $['PayloadParsers'][Name]> | undefined + }> > { const query = this.#data.QueryParser.parse(rawQuery) const urlSearchParams = queryToURLSearchParams(query) diff --git a/packages/date-range/package.json b/packages/date-range/package.json index 4459641d1..130359ebd 100644 --- a/packages/date-range/package.json +++ b/packages/date-range/package.json @@ -10,6 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { + "check": "tsc", "test": "bun test" }, "devDependencies": { diff --git a/packages/explode/package.json b/packages/explode/package.json index b9c728983..a007d4292 100644 --- a/packages/explode/package.json +++ b/packages/explode/package.json @@ -10,6 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { + "check": "tsc", "test": "bun test" }, "dependencies": { diff --git a/packages/fs/package.json b/packages/fs/package.json index 69b092d48..11f6c3499 100644 --- a/packages/fs/package.json +++ b/packages/fs/package.json @@ -10,6 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { + "check": "tsc", "test": "bun test" }, "dependencies": { diff --git a/packages/json-schema/package.json b/packages/json-schema/package.json index 73732754e..0aafd1d6a 100644 --- a/packages/json-schema/package.json +++ b/packages/json-schema/package.json @@ -13,6 +13,7 @@ "./cli": "./src/cli.ts" }, "scripts": { + "check": "tsc", "test": "bun test" }, "dependencies": { diff --git a/packages/server/package.json b/packages/server/package.json index 28db5f20c..b20191f5d 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -10,6 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { + "check": "tsc", "test": "bun test" }, "dependencies": { @@ -23,6 +24,7 @@ "@targetd/api": "workspace:*", "@targetd/date-range": "workspace:*", "@types/bun": "catalog:", + "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/qs": "^6.15.0", "@types/supertest": "latest", diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index cd6e78c55..edf0b5d98 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -78,15 +78,9 @@ export interface CreateServerOptions< * createServer(() => currentData).listen(3000) * ``` */ -export function createServer< - D extends DT.Any, - App extends express.Express = express.Express, ->( +export function createServer( data: MaybePromise | (() => MaybePromise), - { - app = express() as App, - pathStructure, - }: CreateServerOptions = {}, + { app = express() as App, pathStructure }: CreateServerOptions = {}, ): App { const getData = typeof data === 'function' ? data : () => data @@ -99,7 +93,9 @@ export function createServer< castQueryArrayProps(getData), async (req, res) => { res.json( - await (await getData()).getPayloadForEachName({ + await ( + await getData() + ).getPayloadForEachName({ ...req.params, ...(res.locals.query ?? req.query), }), @@ -109,35 +105,21 @@ export function createServer< } return server - .get( - '/:name', - castQueryProp(), - castQueryArrayProps(getData), - async (req, res) => { - const query = res.locals.query ?? req.query - const data = await getData() + .get('/:name', castQueryProp(), castQueryArrayProps(getData), async (req, res) => { + const query = res.locals.query ?? req.query + const data = await getData() - if (!(req.params.name in data.payloadParsers)) { - throw new StatusError(404, `Unknown data property ${req.params.name}`) - } + if (!(req.params.name! in data.payloadParsers)) { + throw new StatusError(404, `Unknown data property ${req.params.name}`) + } - const payload = await data.getPayload(req.params.name, query) + const payload = await data.getPayload(req.params.name!, query) - if (payload === undefined) res.sendStatus(204) - else res.json(payload) - }, - ) - .get( - '/', - castQueryProp(), - castQueryArrayProps(getData), - async (req, res) => { - res.json( - await (await getData()).getPayloadForEachName( - res.locals.query ?? req.query, - ), - ) - }, - ) + if (payload === undefined) res.sendStatus(204) + else res.json(payload) + }) + .get('/', castQueryProp(), castQueryArrayProps(getData), async (req, res) => { + res.json(await (await getData()).getPayloadForEachName(res.locals.query ?? req.query)) + }) .use(errorHandler()) } diff --git a/tsconfig.json b/tsconfig.json index ee2dba86b..5c813059c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "allowImportingTsExtensions": true, "allowJs": false, "declaration": true, "declarationMap": true, @@ -19,7 +20,6 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "target": "ESNext", - "verbatimModuleSyntax": true + "target": "ESNext" } } From 9f6ab6059a2c83e71bf6b460da419d26153a2f26 Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:34:35 +0000 Subject: [PATCH 04/17] ci: fix working-directory Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/workflows/release.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 503614ec7..ebce99bf8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,7 +39,10 @@ jobs: steps: - uses: actions/checkout@v6 - id: package - run: echo "private=$(cat package.json | jq -r '.private // false')" >> $GITHUB_OUTPUT + working-directory: ${{ matrix.path_released }} + run: | # shell + private=$(bun -e "console.log(require('./package.json').private ?? false)") + echo "private=$private" >> "$GITHUB_OUTPUT" - if: steps.package.outputs.private != 'true' uses: ./.github/actions/test - if: steps.package.outputs.private != 'true' From 7058d4cc9e76c4e531b42211d1222232d5da7a92 Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:35:05 +0000 Subject: [PATCH 05/17] ci: add workflow permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/pull-request.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 16d3dcc94..3dbf175ac 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -3,6 +3,9 @@ name: Pull Request on: pull_request: +permissions: + contents: read + concurrency: group: ${{ github.head_ref }} cancel-in-progress: true From 41097a501a10c927cb52db5a012f97481f08909e Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:36:15 +0000 Subject: [PATCH 06/17] ci: install with frozen lockfile Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/actions/test/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 5fe2d2df5..c2b947ef1 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -6,7 +6,7 @@ runs: using: composite steps: - shell: bash - run: bun install + run: bun install --frozen-lockfile - shell: bash run: bun run check - shell: bash From ab39c2fc7f6f03f175bdd05109dd8a4ff55b8992 Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:39:14 +0000 Subject: [PATCH 07/17] fix(client): correct status checking --- packages/client/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 8116dc376..ecffbfc01 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -87,7 +87,7 @@ export class Client<$ extends DT.Meta> { }, () => {}, ) - case response.status >= 200 || response.status < 300: + case response.status < 200 || response.status > 299: throw new ResponseError(response) default: { const data = await this.#data.insert({ From dc5788dbbd214619aafd3e76468623a72feb64d7 Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:58:15 +0000 Subject: [PATCH 08/17] chore: git hooks --- .hooks/commit-msg | 4 ---- .hooks/pre-commit | 4 ---- .husky/commit-msg | 1 + .husky/pre-commit | 1 + bun.lock | 3 +++ package.json | 4 +++- 6 files changed, 8 insertions(+), 9 deletions(-) delete mode 100755 .hooks/commit-msg delete mode 100755 .hooks/pre-commit create mode 100644 .husky/commit-msg create mode 100644 .husky/pre-commit diff --git a/.hooks/commit-msg b/.hooks/commit-msg deleted file mode 100755 index aec787742..000000000 --- a/.hooks/commit-msg +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/hook.sh" - -deno task commitlint --edit diff --git a/.hooks/pre-commit b/.hooks/pre-commit deleted file mode 100755 index a893fdf96..000000000 --- a/.hooks/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/hook.sh" - -deno x lint-staged diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 000000000..12094e055 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +bunx commitlint --edit diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 000000000..ea5a55b6f --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +bunx lint-staged diff --git a/bun.lock b/bun.lock index e50f4429b..bd6b33fe1 100644 --- a/bun.lock +++ b/bun.lock @@ -8,6 +8,7 @@ "@commitlint/cli": "^20.4.3", "@commitlint/config-conventional": "^20.4.3", "@types/bun": "catalog:", + "husky": "^9.1.7", "lint-staged": "^16.3.1", "oxlint": "^1.56.0", "typescript": "catalog:", @@ -474,6 +475,8 @@ "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], + "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], diff --git a/package.json b/package.json index 12af834df..445c9a1a9 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,14 @@ "check": "bun --workspaces check", "lint": "oxlint", "fmt": "oxfmt", - "commitlint": "commitlint" + "commitlint": "commitlint", + "prepare": "husky" }, "devDependencies": { "@commitlint/cli": "^20.4.3", "@commitlint/config-conventional": "^20.4.3", "@types/bun": "catalog:", + "husky": "^9.1.7", "lint-staged": "^16.3.1", "oxlint": "^1.56.0", "typescript": "catalog:" From e96b675b421788fe4fd97257dbf15cc6f9803a93 Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 21:58:45 +0000 Subject: [PATCH 09/17] chore: nubx oxfmt --- lint-staged.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lint-staged.config.js b/lint-staged.config.js index 6cac8788c..a161ae2bd 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -4,5 +4,5 @@ * @type {import('lint-staged').Configuration} */ export default { - '*.{js,mjs,cjs,ts,mts,cts,tsx,jsx,json,jsonc,md,markdown,yml,yaml}': 'oxfmt', + '*.{js,mjs,cjs,ts,mts,cts,tsx,jsx,json,jsonc,md,markdown,yml,yaml}': 'bunx oxfmt', } From 6b826ed80668c20d5fa1391a63589c6c00ff2f1a Mon Sep 17 00:00:00 2001 From: John Wright Date: Mon, 16 Mar 2026 22:06:36 +0000 Subject: [PATCH 10/17] chore: debugger config --- packages/api/.vscode/launch.json | 5 ++--- packages/server/.vscode/launch.json | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/api/.vscode/launch.json b/packages/api/.vscode/launch.json index 89ebf2ebd..8ab9aa1d6 100644 --- a/packages/api/.vscode/launch.json +++ b/packages/api/.vscode/launch.json @@ -10,11 +10,10 @@ "type": "node", "cwd": "${workspaceFolder}", "env": {}, - "runtimeExecutable": "/Users/john.wright/.deno/bin/deno", + "runtimeExecutable": "/Users/john.wright/.bun/bin/bun", "runtimeArgs": [ - "test", "--inspect-wait", - "--allow-all" + "test" ], "attachSimplePort": 9229 } diff --git a/packages/server/.vscode/launch.json b/packages/server/.vscode/launch.json index c90fca226..006d7b0c2 100644 --- a/packages/server/.vscode/launch.json +++ b/packages/server/.vscode/launch.json @@ -11,11 +11,10 @@ "program": "${workspaceFolder}/test/index.test.ts", "cwd": "${workspaceFolder}", "env": {}, - "runtimeExecutable": "/Users/john.wright/.deno/bin/deno", + "runtimeExecutable": "/Users/john.wright/.bun/bin/bun", "runtimeArgs": [ "run", - "--inspect-brk", - "--allow-all" + "--inspect-brk" ], "attachSimplePort": 9229 } From f979121426acfbc94b53284046b60f25e51c07a6 Mon Sep 17 00:00:00 2001 From: John Wright Date: Tue, 17 Mar 2026 09:45:40 +0000 Subject: [PATCH 11/17] feat: move back to npm --- .github/actions/test/action.yml | 2 +- .github/copilot-instructions.md | 12 +- .github/workflows/release.yml | 33 ++- .gitignore | 1 + README.md | 11 +- bun.lock | 51 +++- package.json | 13 +- packages/api/README.md | 26 +- packages/api/package.json | 2 +- packages/api/src/Data.ts | 260 +++++++----------- packages/api/src/IData.ts | 31 +-- packages/api/src/PromisedData.ts | 62 ++--- packages/api/src/createTargetingDescriptor.ts | 6 +- packages/api/src/index.ts | 38 +-- packages/api/src/parsers/DataItem.ts | 45 +-- packages/api/src/parsers/DataItemRule.ts | 69 ++--- packages/api/src/parsers/DataItemRules.ts | 154 ++++------- .../src/parsers/DataItemVariableResolver.ts | 49 +--- .../src/parsers/DataItemVariablesParser.ts | 6 +- packages/api/src/parsers/DataItems.ts | 32 +-- .../api/src/parsers/TargetingDescriptor.ts | 9 +- .../api/src/parsers/TargetingPredicate.ts | 2 +- .../api/src/parsers/TargetingPredicates.ts | 8 +- .../api/src/parsers/attachVariableResolver.ts | 157 +++++------ packages/api/src/predicates/equals.ts | 5 +- packages/api/src/predicates/targetIncludes.ts | 5 +- packages/api/src/types/Data.ts | 39 +-- .../api/src/types/FallThroughTargeting.ts | 31 +-- packages/api/src/types/Payload.ts | 9 +- packages/api/src/types/Query.ts | 11 +- packages/api/src/types/Targeting.ts | 12 +- packages/api/src/util.ts | 11 +- packages/api/test/parsers/switch.test.ts | 2 +- packages/api/test/tsconfig.json | 1 + packages/api/test/utils.test.ts | 2 +- packages/api/tsconfig.json | 2 + packages/client/README.md | 18 +- packages/client/package.json | 2 +- packages/client/src/index.ts | 6 +- .../test/queryToURLSearchParams.test.ts | 2 +- packages/client/test/tsconfig.json | 1 + packages/client/tsconfig.json | 9 +- packages/date-range/README.md | 17 +- packages/date-range/package.json | 2 +- packages/date-range/test/tsconfig.json | 1 + packages/date-range/tsconfig.json | 5 +- packages/explode/README.md | 28 +- packages/explode/package.json | 2 +- packages/explode/src/explode.ts | 10 +- packages/explode/src/index.ts | 4 +- packages/explode/test/tsconfig.json | 1 + packages/explode/tsconfig.json | 5 +- packages/fs/README.md | 74 ++--- packages/fs/package.json | 2 +- packages/fs/src/index.ts | 4 +- packages/fs/src/watch.ts | 2 +- packages/fs/test/load.test.ts | 2 +- packages/fs/test/tsconfig.json | 1 + packages/fs/test/watch.test.ts | 2 +- packages/fs/tsconfig.json | 5 +- packages/json-schema/README.md | 4 +- packages/json-schema/package.json | 2 +- packages/json-schema/src/cli.ts | 10 +- packages/json-schema/test/index.test.ts | 2 +- packages/json-schema/test/tsconfig.json | 1 + packages/json-schema/tsconfig.json | 5 +- packages/server/README.md | 54 ++-- packages/server/package.json | 8 +- packages/server/src/index.ts | 10 +- .../src/middleware/castQueryArrayProps.ts | 8 +- packages/server/test/index.test.ts | 4 +- packages/server/test/tsconfig.json | 1 + packages/server/tsconfig.json | 5 +- tsconfig.json | 14 +- 74 files changed, 633 insertions(+), 909 deletions(-) diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index c2b947ef1..ad122549e 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -8,7 +8,7 @@ runs: - shell: bash run: bun install --frozen-lockfile - shell: bash - run: bun run check + run: bun run build - shell: bash run: bun run lint - shell: bash diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 9420421bb..3516662c2 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,9 +2,9 @@ ## Project Overview -This is a **Deno-first monorepo** for a type-safe targeting and feature flag +This is a **Bun-first monorepo** for a type-safe targeting and feature flag system. The architecture enables dynamic content delivery based on query -conditions, with packages distributed via JSR (JavaScript Registry). +conditions, with packages distributed via npm. **Core concept**: Store flat key-value rules with targeting conditions, query at runtime to get the matching payload. Think feature flags meets content @@ -76,9 +76,7 @@ const userSegment = createTargetingDescriptor({ const platformMatch = { predicate: (query) => (targets) => { if (!query) return true - return targets.some((t) => - t.startsWith('!') ? t.slice(1) !== query : t === query - ) + return targets.some((t) => (t.startsWith('!') ? t.slice(1) !== query : t === query)) }, queryParser: string(), requiresQuery: false, @@ -157,8 +155,8 @@ Re-export types with `export type *` and utilities appropriately. - **Automated via Release Please** on pushes to `master` - Each package has independent versioning - Tags follow pattern: `@targetd/[package]-v[version]` -- Published to **JSR** (not npm), accessible via `jsr:@targetd/[package]` -- GitHub Actions workflow: test → release-please → publish to JSR +- Published to **npm**, accessible via `npm install @targetd/[package]` +- GitHub Actions workflow: test → release-please → publish to npm ## Common Pitfalls diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ebce99bf8..4e401d30f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: name: Github Release runs-on: ubuntu-latest concurrency: - group: release + group: release-github permissions: contents: write issues: write @@ -23,14 +23,25 @@ jobs: with: token: ${{ secrets.PUSH_TOKEN }} - release-jsr: + release-test: needs: [release-github] if: needs.release-github.outputs.releases_created == 'true' runs-on: ubuntu-latest + container: + image: oven/bun:1 + steps: + - uses: actions/checkout@v6 + - uses: ./.github/actions/test + + release-npm: + needs: [release-github, release-test] + runs-on: ubuntu-latest strategy: matrix: path_released: ${{ fromJson(needs.release-github.outputs.paths_released) }} - name: Publish ${{ matrix.path_released }} to JSR + name: Publish ${{ matrix.path_released }} to NPM + environment: npm + concurrency: release-npm container: image: oven/bun:1 permissions: @@ -38,17 +49,5 @@ jobs: id-token: write steps: - uses: actions/checkout@v6 - - id: package - working-directory: ${{ matrix.path_released }} - run: | # shell - private=$(bun -e "console.log(require('./package.json').private ?? false)") - echo "private=$private" >> "$GITHUB_OUTPUT" - - if: steps.package.outputs.private != 'true' - uses: ./.github/actions/test - - if: steps.package.outputs.private != 'true' - working-directory: ${{ matrix.path_released }} - run: | # shell - bun pm pack --filename=$(pwd)/temp.tgz - tar -xOf temp.tgz package/package.json > package.json - rm -rf package temp.tgz - bunx jsr publish + - working-directory: ${{ matrix.path_released }} + run: npm publish diff --git a/.gitignore b/.gitignore index 08b57f41d..8bf6bb645 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ dist *.log node_modules +tsconfig.tsbuildinfo *.validator.ts diff --git a/README.md b/README.md index da0d4e266..d58978152 100644 --- a/README.md +++ b/README.md @@ -130,13 +130,13 @@ Generate JSON Schema from Zod schemas for documentation and validation. ```bash # Core API -npm install zod && npx jsr add @targetd/api +npm install @targetd/api zod # With server and client -npx jsr add @targetd/api @targetd/server @targetd/client +npm install @targetd/api @targetd/server @targetd/client zod # With file loading -npx jsr add @targetd/api @targetd/fs +npm install @targetd/api @targetd/fs zod ``` ### Basic Example @@ -203,10 +203,7 @@ const allPayloads = await client.getPayloadForEachName({ isPremium: true }) const data = await Data.create() .usePayload({ newFeature: z.boolean() }) .useTargeting({ userTier: targetEquals(z.string()) }) - .addRules('newFeature', [ - { targeting: { userTier: 'beta' }, payload: true }, - { payload: false }, - ]) + .addRules('newFeature', [{ targeting: { userTier: 'beta' }, payload: true }, { payload: false }]) ``` ### A/B Testing diff --git a/bun.lock b/bun.lock index bd6b33fe1..cbe6783a2 100644 --- a/bun.lock +++ b/bun.lock @@ -10,6 +10,7 @@ "@types/bun": "catalog:", "husky": "^9.1.7", "lint-staged": "^16.3.1", + "oxfmt": "^0.41.0", "oxlint": "^1.56.0", "typescript": "catalog:", }, @@ -139,9 +140,9 @@ "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/qs": "^6.15.0", - "@types/supertest": "latest", - "lodash": "latest", - "supertest": "latest", + "@types/supertest": "^7.2.0", + "es-toolkit": "catalog:", + "supertest": "^7.2.2", "typescript": "catalog:", "zod": "catalog:", }, @@ -207,6 +208,44 @@ "@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.41.0", "", { "os": "android", "cpu": "arm" }, "sha512-REfrqeMKGkfMP+m/ScX4f5jJBSmVNYcpoDF8vP8f8eYPDuPGZmzp56NIUsYmx3h7f6NzC6cE3gqh8GDWrJHCKw=="], + + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.41.0", "", { "os": "android", "cpu": "arm64" }, "sha512-s0b1dxNgb2KomspFV2LfogC2XtSJB42POXF4bMCLJyvQmAGos4ZtjGPfQreToQEaY0FQFjz3030ggI36rF1q5g=="], + + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.41.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EGXGualADbv/ZmamE7/2DbsrYmjoPlAmHEpTL4vapLF4EfVD6fr8/uQDFnPJkUBjiSWFJZtFNsGeN1B6V3owmA=="], + + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.41.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-WxySJEvdQQYMmyvISH3qDpTvoS0ebnIP63IMxLLWowJyPp/AAH0hdWtlo+iGNK5y3eVfa5jZguwNaQkDKWpGSw=="], + + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.41.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Y2kzMkv3U3oyuYaR4wTfGjOTYTXiFC/hXmG0yVASKkbh02BJkvD98Ij8bIevr45hNZ0DmZEgqiXF+9buD4yMYQ=="], + + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.41.0", "", { "os": "linux", "cpu": "arm" }, "sha512-ptazDjdUyhket01IjPTT6ULS1KFuBfTUU97osTP96X5y/0oso+AgAaJzuH81oP0+XXyrWIHbRzozSAuQm4p48g=="], + + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.41.0", "", { "os": "linux", "cpu": "arm" }, "sha512-UkoL2OKxFD+56bPEBcdGn+4juTW4HRv/T6w1dIDLnvKKWr6DbarB/mtHXlADKlFiJubJz8pRkttOR7qjYR6lTA=="], + + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.41.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-gofu0PuumSOHYczD8p62CPY4UF6ee+rSLZJdUXkpwxg6pILiwSDBIouPskjF/5nF3A7QZTz2O9KFNkNxxFN9tA=="], + + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.41.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-VfVZxL0+6RU86T8F8vKiDBa+iHsr8PAjQmKGBzSCAX70b6x+UOMFl+2dNihmKmUwqkCazCPfYjt6SuAPOeQJ3g=="], + + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.41.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-bwzokz2eGvdfJbc0i+zXMJ4BBjQPqg13jyWpEEZDOrBCQ91r8KeY2Mi2kUeuMTZNFXju+jcAbAbpyJxRGla0eg=="], + + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.41.0", "", { "os": "linux", "cpu": "none" }, "sha512-POLM//PCH9uqDeNDwWL3b3DkMmI3oI2cU6hwc2lnztD1o7dzrQs3R9nq555BZ6wI7t2lyhT9CS+CRaz5X0XqLA=="], + + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.41.0", "", { "os": "linux", "cpu": "none" }, "sha512-NNK7PzhFqLUwx/G12Xtm6scGv7UITvyGdAR5Y+TlqsG+essnuRWR4jRNODWRjzLZod0T3SayRbnkSIWMBov33w=="], + + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.41.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-qVf/zDC5cN9eKe4qI/O/m445er1IRl6swsSl7jHkqmOSVfknwCe5JXitYjZca+V/cNJSU/xPlC5EFMabMMFDpw=="], + + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.41.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ojxYWu7vUb6ysYqVCPHuAPVZHAI40gfZ0PDtZAMwVmh2f0V8ExpPIKoAKr7/8sNbAXJBBpZhs2coypIo2jJX4w=="], + + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.41.0", "", { "os": "linux", "cpu": "x64" }, "sha512-O2exZLBxoCMIv2vlvcbkdedazJPTdG0VSup+0QUCfYQtx751zCZNboX2ZUOiQ/gDTdhtXvSiot0h6GEGkOyalA=="], + + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.41.0", "", { "os": "none", "cpu": "arm64" }, "sha512-N+31/VoL+z+NNBt8viy3I4NaIdPbiYeOnB884LKqvXldaE2dRztdPv3q5ipfZYv0RwFp7JfqS4I27K/DSHCakg=="], + + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.41.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z7NAtu/RN8kjCQ1y5oDD0nTAeRswh3GJ93qwcW51srmidP7XPBmZbLlwERu1W5veCevQJtPS9xmkpcDTYsGIwQ=="], + + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.41.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-uNxxP3l4bJ6VyzIeRqCmBU2Q0SkCFgIhvx9/9dJ9V8t/v+jP1IBsuaLwCXGR8JPHtkj4tFp+RHtUmU2ZYAUpMA=="], + + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.41.0", "", { "os": "win32", "cpu": "x64" }, "sha512-49ZSpbZ1noozyPapE8SUOSm3IN0Ze4b5nkO+4+7fq6oEYQQJFhE0saj5k/Gg4oewVPdjn0L3ZFeWk2Vehjcw7A=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.56.0", "", { "os": "android", "cpu": "arm" }, "sha512-IyfYPthZyiSKwAv/dLjeO18SaK8MxLI9Yss2JrRDyweQAkuL3LhEy7pwIwI7uA3KQc1Vdn20kdmj3q0oUIQL6A=="], "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.56.0", "", { "os": "android", "cpu": "arm64" }, "sha512-Ga5zYrzH6vc/VFxhn6MmyUnYEfy9vRpwTIks99mY3j6Nz30yYpIkWryI0QKPCgvGUtDSXVLEaMum5nA+WrNOSg=="], @@ -515,8 +554,6 @@ "listr2": ["listr2@9.0.5", "", { "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g=="], - "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], - "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="], "lodash.kebabcase": ["lodash.kebabcase@4.1.1", "", {}, "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="], @@ -565,6 +602,8 @@ "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], + "oxfmt": ["oxfmt@0.41.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.41.0", "@oxfmt/binding-android-arm64": "0.41.0", "@oxfmt/binding-darwin-arm64": "0.41.0", "@oxfmt/binding-darwin-x64": "0.41.0", "@oxfmt/binding-freebsd-x64": "0.41.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.41.0", "@oxfmt/binding-linux-arm-musleabihf": "0.41.0", "@oxfmt/binding-linux-arm64-gnu": "0.41.0", "@oxfmt/binding-linux-arm64-musl": "0.41.0", "@oxfmt/binding-linux-ppc64-gnu": "0.41.0", "@oxfmt/binding-linux-riscv64-gnu": "0.41.0", "@oxfmt/binding-linux-riscv64-musl": "0.41.0", "@oxfmt/binding-linux-s390x-gnu": "0.41.0", "@oxfmt/binding-linux-x64-gnu": "0.41.0", "@oxfmt/binding-linux-x64-musl": "0.41.0", "@oxfmt/binding-openharmony-arm64": "0.41.0", "@oxfmt/binding-win32-arm64-msvc": "0.41.0", "@oxfmt/binding-win32-ia32-msvc": "0.41.0", "@oxfmt/binding-win32-x64-msvc": "0.41.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-sKLdJZdQ3bw6x9qKiT7+eID4MNEXlDHf5ZacfIircrq6Qwjk0L6t2/JQlZZrVHTXJawK3KaMuBoJnEJPcqCEdg=="], + "oxlint": ["oxlint@1.56.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.56.0", "@oxlint/binding-android-arm64": "1.56.0", "@oxlint/binding-darwin-arm64": "1.56.0", "@oxlint/binding-darwin-x64": "1.56.0", "@oxlint/binding-freebsd-x64": "1.56.0", "@oxlint/binding-linux-arm-gnueabihf": "1.56.0", "@oxlint/binding-linux-arm-musleabihf": "1.56.0", "@oxlint/binding-linux-arm64-gnu": "1.56.0", "@oxlint/binding-linux-arm64-musl": "1.56.0", "@oxlint/binding-linux-ppc64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-musl": "1.56.0", "@oxlint/binding-linux-s390x-gnu": "1.56.0", "@oxlint/binding-linux-x64-gnu": "1.56.0", "@oxlint/binding-linux-x64-musl": "1.56.0", "@oxlint/binding-openharmony-arm64": "1.56.0", "@oxlint/binding-win32-arm64-msvc": "1.56.0", "@oxlint/binding-win32-ia32-msvc": "1.56.0", "@oxlint/binding-win32-x64-msvc": "1.56.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.15.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g=="], "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], @@ -639,6 +678,8 @@ "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], + "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], "ts-toolbelt": ["ts-toolbelt@9.6.0", "", {}, "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w=="], diff --git a/package.json b/package.json index 445c9a1a9..74f339ad4 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,14 @@ ], "type": "module", "scripts": { - "test": "bun test packages/**/test", - "check": "bun --workspaces check", - "lint": "oxlint", - "fmt": "oxfmt", + "build": "tsc --build", + "check": "tsc --build --noEmit", "commitlint": "commitlint", - "prepare": "husky" + "fmt": "oxfmt", + "lint": "oxlint", + "prepare": "husky", + "start": "tsc --build --watch --preserveWatchOutput", + "test": "bun test packages/**/test" }, "devDependencies": { "@commitlint/cli": "^20.4.3", @@ -20,6 +22,7 @@ "@types/bun": "catalog:", "husky": "^9.1.7", "lint-staged": "^16.3.1", + "oxfmt": "^0.41.0", "oxlint": "^1.56.0", "typescript": "catalog:" }, diff --git a/packages/api/README.md b/packages/api/README.md index 67b68061c..7e6dd42d2 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -7,9 +7,9 @@ different content based on query conditions. | JS Runtime | Command | | ---------- | --------------------------- | -| Node.js | `npx jsr add @targetd/api` | -| Bun | `bunx jsr add @targetd/api` | -| Deno | `deno add jsr:@targetd/api` | +| Node.js | `npm install @targetd/api` | +| Bun | `bun add @targetd/api` | +| Deno | `deno add npm:@targetd/api` | ## Overview @@ -68,14 +68,13 @@ Define the types of data your store will manage using [Zod](https://zod.dev/) schemas: ```typescript -const data = await Data.create() - .usePayload({ - message: z.string(), - config: z.object({ - enabled: z.boolean(), - maxRetries: z.number(), - }), - }) +const data = await Data.create().usePayload({ + message: z.string(), + config: z.object({ + enabled: z.boolean(), + maxRetries: z.number(), + }), +}) ``` ### 2. Targeting @@ -86,6 +85,7 @@ built-in predicates or create custom ones: #### Built-in Predicates - **`targetIncludes`**: Check if a value is in an array + ```typescript .useTargeting({ channels: targetIncludes(z.string()) @@ -180,9 +180,9 @@ the first matching rule wins: .addRules('feature', [ { // Most specific rule first - targeting: { + targeting: { country: ['US'], - isPremium: true + isPremium: true }, payload: 'Premium US feature' }, diff --git a/packages/api/package.json b/packages/api/package.json index 434666558..2f3d765f6 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -10,7 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { - "check": "tsc", + "check": "tsc --noEmit", "test": "bun test" }, "dependencies": { diff --git a/packages/api/src/Data.ts b/packages/api/src/Data.ts index 4386fc658..32d654db9 100644 --- a/packages/api/src/Data.ts +++ b/packages/api/src/Data.ts @@ -1,4 +1,4 @@ -import type TargetingPredicates from './parsers/TargetingPredicates.ts' +import type TargetingPredicates from './parsers/TargetingPredicates.js' import { objectEntries, objectEveryAsync, @@ -6,17 +6,17 @@ import { objectKeys, objectMap, objectSize, -} from './util.ts' -import { type DataItemsOut, DataItemsParser } from './parsers/DataItems.ts' -import type { DataItemIn, DataItemOut } from './parsers/DataItem.ts' -import type { DataItemRule } from './parsers/DataItemRule.ts' -import type { MaybeArray, MaybePromise, ZodPartialObject } from './types.ts' -import type { DataItemRulesIn } from './parsers/DataItemRules.ts' -import type * as DT from './types/Data.ts' -import type * as TT from './types/Targeting.ts' -import type * as FTTT from './types/FallThroughTargeting.ts' -import type * as PT from './types/Payload.ts' -import type * as QT from './types/Query.ts' +} from './util.js' +import { type DataItemsOut, DataItemsParser } from './parsers/DataItems.js' +import type { DataItemIn, DataItemOut } from './parsers/DataItem.js' +import type { DataItemRule } from './parsers/DataItemRule.js' +import type { MaybeArray, MaybePromise, ZodPartialObject } from './types.js' +import type { DataItemRulesIn } from './parsers/DataItemRules.js' +import type * as DT from './types/Data.js' +import type * as TT from './types/Targeting.js' +import type * as FTTT from './types/FallThroughTargeting.js' +import type * as PT from './types/Payload.js' +import type * as QT from './types/Query.js' import { type $InferObjectOutput, type $strict, @@ -26,9 +26,9 @@ import { type output, } from 'zod/v4/core' import { partial, strictObject } from 'zod/mini' -import { PromisedData } from './PromisedData.ts' -import { resolveVariables } from './parsers/DataItemVariableResolver.ts' -import type { IData } from './IData.ts' +import { PromisedData } from './PromisedData.js' +import { resolveVariables } from './parsers/DataItemVariableResolver.js' +import type { IData } from './IData.js' /** * In-memory data store. @@ -97,9 +97,7 @@ export default class Data<$ extends DT.Meta> implements IData<$> { queryParsers: $['QueryParsers'], fallThroughTargetingParsers: $['FallThroughTargetingParsers'], ) { - this.#fallThroughTargetingParsers = Object.freeze( - fallThroughTargetingParsers, - ) + this.#fallThroughTargetingParsers = Object.freeze(fallThroughTargetingParsers) this.#data = Object.freeze(data) this.#payloadParsers = Object.freeze(payloadParsers) this.#targetingPredicates = Object.freeze(targetingPredicates) @@ -192,9 +190,9 @@ export default class Data<$ extends DT.Meta> implements IData<$> { * }) * ``` */ - async usePayload(parsers: Parsers): Promise< - Data<$ & { PayloadParsers: $['PayloadParsers'] & Parsers }> - > { + async usePayload( + parsers: Parsers, + ): Promise> { type $$ = $ & { PayloadParsers: $['PayloadParsers'] & Parsers } const payloadParsers = this.#mergePayloadParsers(parsers) @@ -215,9 +213,7 @@ export default class Data<$ extends DT.Meta> implements IData<$> { ) } - #mergePayloadParsers( - parsers: Parsers, - ): $['PayloadParsers'] & Parsers { + #mergePayloadParsers(parsers: Parsers): $['PayloadParsers'] & Parsers { return { ...this.#payloadParsers, ...parsers, @@ -251,26 +247,23 @@ export default class Data<$ extends DT.Meta> implements IData<$> { false, ).parseAsync( Object.entries(data).reduce((data, [name, value]) => { - const dataItem = this.#data[name] || - { - rules: [], - variables: {}, - } + const dataItem = this.#data[name] || { + rules: [], + variables: {}, + } return { ...data, [name]: { ...dataItem, rules: [ ...dataItem.rules, - ...this.#isFallThroughRulesPayload(value!) + ...(this.#isFallThroughRulesPayload(value!) ? value.__rules__ - : [{ payload: value }], + : [{ payload: value }]), ], variables: { ...dataItem.variables, - ...this.#isFallThroughRulesPayload(value!) - ? value.__variables__ - : {}, + ...(this.#isFallThroughRulesPayload(value!) ? value.__variables__ : {}), }, }, } @@ -288,9 +281,7 @@ export default class Data<$ extends DT.Meta> implements IData<$> { ) } - readonly #isFallThroughRulesPayload = < - Name extends keyof $['PayloadParsers'], - >( + readonly #isFallThroughRulesPayload = ( payload: PT.Payload<$, $['PayloadParsers'][Name]>, ): payload is FTTT.Rules<$, $['PayloadParsers'][Name]> => typeof payload === 'object' && payload !== null && '__rules__' in payload @@ -329,19 +320,14 @@ export default class Data<$ extends DT.Meta> implements IData<$> { * }) * ``` */ - async addRules< - Name extends keyof $['PayloadParsers'], - >( + async addRules( name: Name, - opts: - | DataItemIn<$, $['PayloadParsers'][Name]> - | DataItemRulesIn<$, $['PayloadParsers'][Name]>, + opts: DataItemIn<$, $['PayloadParsers'][Name]> | DataItemRulesIn<$, $['PayloadParsers'][Name]>, ): Promise> { - const dataItem = this.#data[name] || - { - rules: [], - variables: {}, - } + const dataItem = this.#data[name] || { + rules: [], + variables: {}, + } const rules = Array.isArray(opts) ? opts : opts.rules const variables = Array.isArray(opts) ? {} : opts.variables @@ -424,7 +410,9 @@ export default class Data<$ extends DT.Meta> implements IData<$> { * }) * ``` */ - async useTargeting(targeting: TDs): Promise< + async useTargeting( + targeting: TDs, + ): Promise< Data< $ & { TargetingParsers: $['TargetingParsers'] & TT.ParserRecord @@ -437,24 +425,17 @@ export default class Data<$ extends DT.Meta> implements IData<$> { QueryParsers: $['QueryParsers'] & QT.ParserRecord } - const targetingParsers: $$['TargetingParsers'] = this - .#mergeTargetingParsers( - targeting, - ) + const targetingParsers: $$['TargetingParsers'] = this.#mergeTargetingParsers(targeting) - const targetingPredicates = this.#mergeTargetingPredicates( - targeting, - ) as TargetingPredicates<$$> + const targetingPredicates = this.#mergeTargetingPredicates(targeting) as TargetingPredicates<$$> - const queryParsers: $$['QueryParsers'] = this.#mergeQueryPredicates( - targeting, - ) + const queryParsers: $$['QueryParsers'] = this.#mergeQueryPredicates(targeting) - const data = await DataItemsParser( + const data = (await DataItemsParser( this.#payloadParsers, targetingParsers, this.#fallThroughTargetingParsers, - ).parseAsync(this.#data) as DataItemsOut<$$> + ).parseAsync(this.#data)) as DataItemsOut<$$> return new Data<$$>( data, @@ -480,9 +461,8 @@ export default class Data<$ extends DT.Meta> implements IData<$> { ...this.#targetingPredicates, ...objectMap(targeting, (targetingDescriptor) => ({ predicate: targetingDescriptor.predicate, - requiresQuery: 'requiresQuery' in targetingDescriptor - ? targetingDescriptor.requiresQuery - : true, + requiresQuery: + 'requiresQuery' in targetingDescriptor ? targetingDescriptor.requiresQuery : true, })), } } @@ -532,21 +512,15 @@ export default class Data<$ extends DT.Meta> implements IData<$> { ): Promise< Data< $ & { - FallThroughTargetingParsers: - & $['FallThroughTargetingParsers'] - & FTTT.ParsersRecord + FallThroughTargetingParsers: $['FallThroughTargetingParsers'] & FTTT.ParsersRecord } > > { type $$ = $ & { - FallThroughTargetingParsers: - & $['FallThroughTargetingParsers'] - & FTTT.ParsersRecord + FallThroughTargetingParsers: $['FallThroughTargetingParsers'] & FTTT.ParsersRecord } - const fallThroughTargetingParsers = this.#mergeFallThroughTargeting( - targeting, - ) + const fallThroughTargetingParsers = this.#mergeFallThroughTargeting(targeting) const data = (await DataItemsParser( this.#payloadParsers, @@ -569,12 +543,10 @@ export default class Data<$ extends DT.Meta> implements IData<$> { ): $['FallThroughTargetingParsers'] & FTTT.ParsersRecord { return { ...this.#fallThroughTargetingParsers, - ...objectMap( - targeting, - (descriptorOrParser) => - descriptorOrParser instanceof $ZodType - ? descriptorOrParser - : descriptorOrParser.targetingParser, + ...objectMap(targeting, (descriptorOrParser) => + descriptorOrParser instanceof $ZodType + ? descriptorOrParser + : descriptorOrParser.targetingParser, ), } } @@ -591,9 +563,7 @@ export default class Data<$ extends DT.Meta> implements IData<$> { * // Returns: { greeting: 'Hello!', feature: {...}, ... } * ``` */ - async getPayloadForEachName( - rawQuery: QT.Raw<$['QueryParsers']> = {}, - ): Promise> { + async getPayloadForEachName(rawQuery: QT.Raw<$['QueryParsers']> = {}): Promise> { const payloads = {} as PT.Payloads<$> await Promise.all( @@ -632,15 +602,10 @@ export default class Data<$ extends DT.Meta> implements IData<$> { async getPayload( name: Name, rawQuery: QT.Raw<$['QueryParsers']> = {}, - ): Promise< - | PT.Payload<$, $['PayloadParsers'][Name]> - | undefined - > { + ): Promise | undefined> { const predicate = await this.#createRulePredicate(rawQuery) const targetableItem = this.#getTargetableItem(name) - let payload: - | PT.Payload<$, $['PayloadParsers'][Name]> - | undefined + let payload: PT.Payload<$, $['PayloadParsers'][Name]> | undefined for (const rule of targetableItem.rules) { if (await predicate(rule)) { @@ -656,41 +621,28 @@ export default class Data<$ extends DT.Meta> implements IData<$> { variables, (value) => !this.#isFallThroughRulesPayload(value), ) - const nonResolvableVariables = objectFitler( - variables, - this.#isFallThroughRulesPayload, - ) - const resolvedPayload = resolveVariables( - resolvableVariables, - payload, - ) + const nonResolvableVariables = objectFitler(variables, this.#isFallThroughRulesPayload) + const resolvedPayload = resolveVariables(resolvableVariables, payload) return objectSize(nonResolvableVariables) ? { - __variables__: objectMap( - nonResolvableVariables, - (value) => value.__rules__, - ), - __rules__: this.#isFallThroughRulesPayload(resolvedPayload) - ? resolvedPayload.__rules__ - : [{ payload: resolvedPayload }], - } + __variables__: objectMap(nonResolvableVariables, (value) => value.__rules__), + __rules__: this.#isFallThroughRulesPayload(resolvedPayload) + ? resolvedPayload.__rules__ + : [{ payload: resolvedPayload }], + } : resolvedPayload } async #getVariables( targetableItem: DataItemOut<$, $['PayloadParsers'][Name]>, - predicate: ( - rule: DataItemRule<$, $['PayloadParsers'][Name]>, - ) => Promise, + predicate: (rule: DataItemRule<$, $['PayloadParsers'][Name]>) => Promise, ) { const variables: Record = {} if (objectSize(targetableItem.variables)) { - for ( - const [variableName, rules] of objectEntries(targetableItem.variables) - ) { + for (const [variableName, rules] of objectEntries(targetableItem.variables)) { for (const rule of rules) { - if (await (predicate(rule))) { + if (await predicate(rule)) { variables[variableName] = this.#mapRule(rule) break } @@ -718,9 +670,7 @@ export default class Data<$ extends DT.Meta> implements IData<$> { async getPayloads( name: Name, rawQuery: QT.Raw<$['QueryParsers']> = {}, - ): Promise< - PT.Payload<$, $['PayloadParsers'][Name]>[] - > { + ): Promise[]> { const payloads: PT.Payload<$, $['PayloadParsers'][Name]>[] = [] const predicate = await this.#createRulePredicate(rawQuery) const targetableItem = this.#getTargetableItem(name) @@ -740,10 +690,10 @@ export default class Data<$ extends DT.Meta> implements IData<$> { rule: DataItemRule<$, PayloadParser>, ): PT.Payload<$, PayloadParser> | undefined { return hasPayload(rule) - ? rule.payload as output + ? (rule.payload as output) : 'fallThrough' in rule - ? { __rules__: rule.fallThrough } as FTTT.Rules<$, PayloadParser> - : undefined + ? ({ __rules__: rule.fallThrough } as FTTT.Rules<$, PayloadParser>) + : undefined } async #createRulePredicate( @@ -751,39 +701,29 @@ export default class Data<$ extends DT.Meta> implements IData<$> { ) { const query = await this.#QueryParser.parseAsync(rawQuery) - return ( - rule: DataItemRule<$, $['PayloadParsers'][Name]>, - ) => - ( - !('targeting' in rule) || + return (rule: DataItemRule<$, $['PayloadParsers'][Name]>) => + (!('targeting' in rule) || this.#targetingPredicate( query as any, rule.targeting! as any, - objectMap( - this.#targetingPredicates, - (target, targetingKey) => ({ - predicate: () => - target.predicate( - // We haven't yet made sure that the QueryParsers - // and TargetingParsers have the same keys. - (query as any)[targetingKey], - query as any, - ), - requiresQuery: target.requiresQuery, - }), - ), - ) - ) as Promise + objectMap(this.#targetingPredicates, (target, targetingKey) => ({ + predicate: () => + target.predicate( + // We haven't yet made sure that the QueryParsers + // and TargetingParsers have the same keys. + (query as any)[targetingKey], + query as any, + ), + requiresQuery: target.requiresQuery, + })), + )) as Promise } #getTargetableItem(name: Name) { return ( ( this.#data as unknown as { - [Name in keyof $['PayloadParsers']]: DataItemOut< - $, - $['PayloadParsers'][Name] - > + [Name in keyof $['PayloadParsers']]: DataItemOut<$, $['PayloadParsers'][Name]> } )[name] ?? { rules: [], variables: {} } ) @@ -797,9 +737,7 @@ export default class Data<$ extends DT.Meta> implements IData<$> { targeting: MaybeArray< $InferObjectOutput< { - [K in keyof $['TargetingParsers']]: $ZodOptional< - $['TargetingParsers'][K] - > + [K in keyof $['TargetingParsers']]: $ZodOptional<$['TargetingParsers'][K]> }, {} > @@ -815,27 +753,19 @@ export default class Data<$ extends DT.Meta> implements IData<$> { const targetings = Array.isArray(targeting) ? targeting : [targeting] for (const targeting of targetings) { if ( - await objectEveryAsync( - targeting, - async (targetingValue, targetingKey) => { - if ( - !(targetingKey in query) && - predicates[targetingKey]?.requiresQuery - ) { - return false - } - - if (targetingKey in predicates) { - return (await predicates[targetingKey].predicate())( - targetingValue, - ) - } else { - console.warn(`Invalid targeting property ${String(targetingKey)}`) - } - + await objectEveryAsync(targeting, async (targetingValue, targetingKey) => { + if (!(targetingKey in query) && predicates[targetingKey]?.requiresQuery) { return false - }, - ) + } + + if (targetingKey in predicates) { + return (await predicates[targetingKey].predicate())(targetingValue) + } else { + console.warn(`Invalid targeting property ${String(targetingKey)}`) + } + + return false + }) ) { return true } diff --git a/packages/api/src/IData.ts b/packages/api/src/IData.ts index 8aa52379b..51dddf082 100644 --- a/packages/api/src/IData.ts +++ b/packages/api/src/IData.ts @@ -1,16 +1,18 @@ import type { $ZodShape } from 'zod/v4/core' -import type * as DT from './types/Data.ts' -import type * as FTTT from './types/FallThroughTargeting.ts' -import type * as PT from './types/Payload.ts' -import type * as QT from './types/Query.ts' -import type * as TT from './types/Targeting.ts' +import type * as DT from './types/Data.js' +import type * as FTTT from './types/FallThroughTargeting.js' +import type * as PT from './types/Payload.js' +import type * as QT from './types/Query.js' +import type * as TT from './types/Targeting.js' export interface IData<$ extends DT.Meta> { usePayload( parsers: Parsers, ): Promise> - useTargeting(targeting: TDs): Promise< + useTargeting( + targeting: TDs, + ): Promise< IData< $ & { TargetingParsers: $['TargetingParsers'] & TT.ParserRecord @@ -24,31 +26,22 @@ export interface IData<$ extends DT.Meta> { ): Promise< IData< $ & { - FallThroughTargetingParsers: - & $['FallThroughTargetingParsers'] - & FTTT.ParsersRecord + FallThroughTargetingParsers: $['FallThroughTargetingParsers'] & FTTT.ParsersRecord } > > insert(data: DT.InsertableData<$>): Promise> - getPayloadForEachName( - rawQuery?: QT.Raw<$['QueryParsers']>, - ): Promise> + getPayloadForEachName(rawQuery?: QT.Raw<$['QueryParsers']>): Promise> getPayload( name: Name, rawQuery?: QT.Raw<$['QueryParsers']>, - ): Promise< - | PT.Payload<$, $['PayloadParsers'][Name]> - | undefined - > + ): Promise | undefined> getPayloads( name: Name, rawQuery?: QT.Raw<$['QueryParsers']>, - ): Promise< - PT.Payload<$, $['PayloadParsers'][Name]>[] - > + ): Promise[]> } diff --git a/packages/api/src/PromisedData.ts b/packages/api/src/PromisedData.ts index f1e1bea82..a6e639c10 100644 --- a/packages/api/src/PromisedData.ts +++ b/packages/api/src/PromisedData.ts @@ -1,14 +1,14 @@ import type { $ZodShape } from 'zod/v4/core' -import type Data from './Data.ts' -import type * as DT from './types/Data.ts' -import type * as PT from './types/Payload.ts' -import type * as TT from './types/Targeting.ts' -import type * as FTTT from './types/FallThroughTargeting.ts' -import type * as QT from './types/Query.ts' -import type { DataItemRulesIn } from './parsers/DataItemRules.ts' -import type { MaybePromise } from './types.ts' -import type { DataItemIn } from './parsers/DataItem.ts' -import type { IData } from './IData.ts' +import type Data from './Data.js' +import type * as DT from './types/Data.js' +import type * as PT from './types/Payload.js' +import type * as TT from './types/Targeting.js' +import type * as FTTT from './types/FallThroughTargeting.js' +import type * as QT from './types/Query.js' +import type { DataItemRulesIn } from './parsers/DataItemRules.js' +import type { MaybePromise } from './types.js' +import type { DataItemIn } from './parsers/DataItem.js' +import type { IData } from './IData.js' /** * A Promise-based wrapper for Data that implements the IData interface. @@ -21,8 +21,7 @@ import type { IData } from './IData.ts' * @extends {Promise>} * @implements {IData<$>} */ -export class PromisedData<$ extends DT.Meta> extends Promise> - implements IData<$> { +export class PromisedData<$ extends DT.Meta> extends Promise> implements IData<$> { /** * Creates a new PromisedData instance. * @@ -44,9 +43,7 @@ export class PromisedData<$ extends DT.Meta> extends Promise> * @param promisedData - A Data instance or a Promise that resolves to a Data instance * @returns A new PromisedData instance */ - static create<$ extends DT.Meta>( - promisedData: MaybePromise>, - ): PromisedData<$> { + static create<$ extends DT.Meta>(promisedData: MaybePromise>): PromisedData<$> { return new PromisedData((resolve) => resolve(promisedData)) } @@ -57,9 +54,7 @@ export class PromisedData<$ extends DT.Meta> extends Promise> * @param cb - Callback function that transforms the Data instance * @returns A new PromisedData instance with the transformed Data */ - #create<$$ extends DT.Meta>( - cb: (data: Data<$>) => MaybePromise>, - ): PromisedData<$$> { + #create<$$ extends DT.Meta>(cb: (data: Data<$>) => MaybePromise>): PromisedData<$$> { return new PromisedData((resolve) => resolve(this.then(cb))) } @@ -72,9 +67,7 @@ export class PromisedData<$ extends DT.Meta> extends Promise> */ usePayload( parsers: Parsers, - ): PromisedData< - $ & { PayloadParsers: $['PayloadParsers'] & Parsers } - > { + ): PromisedData<$ & { PayloadParsers: $['PayloadParsers'] & Parsers }> { return this.#create((data) => data.usePayload(parsers)) } @@ -96,13 +89,9 @@ export class PromisedData<$ extends DT.Meta> extends Promise> * @param opts - The data item or rules configuration to add * @returns A new PromisedData instance with the added rules */ - addRules< - Name extends keyof $['PayloadParsers'], - >( + addRules( name: Name, - opts: - | DataItemIn<$, $['PayloadParsers'][Name]> - | DataItemRulesIn<$, $['PayloadParsers'][Name]>, + opts: DataItemIn<$, $['PayloadParsers'][Name]> | DataItemRulesIn<$, $['PayloadParsers'][Name]>, ): PromisedData<$> { return this.#create((data) => data.addRules(name, opts)) } @@ -137,9 +126,7 @@ export class PromisedData<$ extends DT.Meta> extends Promise> targeting: TDs, ): PromisedData< $ & { - FallThroughTargetingParsers: - & $['FallThroughTargetingParsers'] - & FTTT.ParsersRecord + FallThroughTargetingParsers: $['FallThroughTargetingParsers'] & FTTT.ParsersRecord } > { return this.#create((data) => data.useFallThroughTargeting(targeting)) @@ -151,11 +138,7 @@ export class PromisedData<$ extends DT.Meta> extends Promise> * @param rawQuery - Optional raw query object for filtering * @returns A Promise that resolves to an object containing payloads for each name */ - async getPayloadForEachName( - rawQuery?: QT.Raw<$['QueryParsers']>, - ): Promise< - PT.Payloads<$> - > { + async getPayloadForEachName(rawQuery?: QT.Raw<$['QueryParsers']>): Promise> { const data = await this return data.getPayloadForEachName(rawQuery) } @@ -171,10 +154,7 @@ export class PromisedData<$ extends DT.Meta> extends Promise> async getPayload( name: Name, rawQuery?: QT.Raw<$['QueryParsers']>, - ): Promise< - | PT.Payload<$, $['PayloadParsers'][Name]> - | undefined - > { + ): Promise | undefined> { const data = await this return data.getPayload(name, rawQuery) } @@ -190,9 +170,7 @@ export class PromisedData<$ extends DT.Meta> extends Promise> async getPayloads( name: Name, rawQuery?: QT.Raw<$['QueryParsers']>, - ): Promise< - PT.Payload<$, $['PayloadParsers'][Name]>[] - > { + ): Promise[]> { const data = await this return data.getPayloads(name, rawQuery) } diff --git a/packages/api/src/createTargetingDescriptor.ts b/packages/api/src/createTargetingDescriptor.ts index 0fd07f220..839eb98ac 100644 --- a/packages/api/src/createTargetingDescriptor.ts +++ b/packages/api/src/createTargetingDescriptor.ts @@ -1,5 +1,5 @@ import type { $ZodType } from 'zod/v4/core' -import type TargetingDescriptor from './parsers/TargetingDescriptor.ts' +import type TargetingDescriptor from './parsers/TargetingDescriptor.js' /** * Create a targeting descriptor with default options. @@ -25,8 +25,6 @@ export default function createTargetingDescriptor< TV extends $ZodType, QV extends $ZodType, Query extends Record = {}, ->( - targetingDescriptor: TargetingDescriptor, -): TargetingDescriptor { +>(targetingDescriptor: TargetingDescriptor): TargetingDescriptor { return { requiresQuery: true, ...targetingDescriptor } } diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 674960404..e6e6902cd 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,39 +1,39 @@ -export { default as Data } from './Data.ts' -export * from './PromisedData.ts' -export { DataItemParser } from './parsers/DataItem.ts' -export { DataItemsParser } from './parsers/DataItems.ts' -export { DataItemRuleParser } from './parsers/DataItemRule.ts' -export { DataItemRulesParser } from './parsers/DataItemRules.ts' -export * from './parsers/switch.ts' -export { default as createTargetingDescriptor } from './createTargetingDescriptor.ts' -export type { default as TargetingDescriptor } from './parsers/TargetingDescriptor.ts' -export type { default as TargetingPredicate } from './parsers/TargetingPredicate.ts' -export type { default as TargetingPredicates } from './parsers/TargetingPredicates.ts' -export { targetEquals } from './predicates/equals.ts' -export { targetIncludes } from './predicates/targetIncludes.ts' -export type { StaticRecord } from './types.ts' +export { default as Data } from './Data.js' +export * from './PromisedData.js' +export { DataItemParser } from './parsers/DataItem.js' +export { DataItemsParser } from './parsers/DataItems.js' +export { DataItemRuleParser } from './parsers/DataItemRule.js' +export { DataItemRulesParser } from './parsers/DataItemRules.js' +export * from './parsers/switch.js' +export { default as createTargetingDescriptor } from './createTargetingDescriptor.js' +export type { default as TargetingDescriptor } from './parsers/TargetingDescriptor.js' +export type { default as TargetingPredicate } from './parsers/TargetingPredicate.js' +export type { default as TargetingPredicates } from './parsers/TargetingPredicates.js' +export { targetEquals } from './predicates/equals.js' +export { targetIncludes } from './predicates/targetIncludes.js' +export type { StaticRecord } from './types.js' /** * Type helpers for the {@link Data} class. */ -export type * as DT from './types/Data.ts' +export type * as DT from './types/Data.js' /** * Type helers for fallthrough-targeting */ -export type * as FTTT from './types/FallThroughTargeting.ts' +export type * as FTTT from './types/FallThroughTargeting.js' /** * Type helers for payloads */ -export type * as PT from './types/Payload.ts' +export type * as PT from './types/Payload.js' /** * Type helpers for queries */ -export type * as QT from './types/Query.ts' +export type * as QT from './types/Query.js' /** * Type helpers for targeting */ -export type * as TT from './types/Targeting.ts' +export type * as TT from './types/Targeting.js' diff --git a/packages/api/src/parsers/DataItem.ts b/packages/api/src/parsers/DataItem.ts index 9285ce44f..1df6eb3a6 100644 --- a/packages/api/src/parsers/DataItem.ts +++ b/packages/api/src/parsers/DataItem.ts @@ -10,10 +10,10 @@ import { type DataItemRulesIn, type DataItemRulesOut, DataItemRulesParser, -} from './DataItemRules.ts' -import { DataItemVariablesParser } from './DataItemVariablesParser.ts' -import { variablesFor } from './variablesRegistry.ts' -import type * as DT from '../types/Data.ts' +} from './DataItemRules.js' +import { DataItemVariablesParser } from './DataItemVariablesParser.js' +import { variablesFor } from './variablesRegistry.js' +import type * as DT from '../types/Data.js' /** * Parses an "item". @@ -24,10 +24,7 @@ import type * as DT from '../types/Data.ts' * @remarks * Currently this is just restricted to `rules`. */ -export function DataItemParser< - $ extends DT.Meta, - PayloadParser extends $ZodType, ->( +export function DataItemParser<$ extends DT.Meta, PayloadParser extends $ZodType>( Payload: PayloadParser, targeting: $['TargetingParsers'], fallThroughTargeting: $['FallThroughTargetingParsers'], @@ -43,12 +40,7 @@ export function DataItemParser< strictTargeting, ), variables: _default( - DataItemVariablesParser( - variablesRegistry, - targeting, - fallThroughTargeting, - strictTargeting, - ), + DataItemVariablesParser(variablesRegistry, targeting, fallThroughTargeting, strictTargeting), {}, ), }) @@ -60,10 +52,7 @@ export function DataItemParser< * @template $ - Data meta configuration. * @template PayloadParser - Zod parser for the payload type. */ -export type DataItemParser< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> = ZodMiniObject< +export type DataItemParser<$ extends DT.Meta, PayloadParser extends $ZodType> = ZodMiniObject< { rules: DataItemRulesParser<$, PayloadParser> variables: ZodMiniDefault> @@ -74,27 +63,15 @@ export type DataItemParser< /** * The data shape expected for {@link DataItemParser} inputs. */ -export interface DataItemIn< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> { +export interface DataItemIn<$ extends DT.Meta, PayloadParser extends $ZodType> { rules: DataItemRulesIn<$, PayloadParser> - variables?: Record< - string, - DataItemRulesIn<$, ZodMiniAny> - > + variables?: Record> } /** * The data shape expected for {@link DataItemParser} outputs. */ -export interface DataItemOut< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> { +export interface DataItemOut<$ extends DT.Meta, PayloadParser extends $ZodType> { rules: DataItemRulesOut<$, PayloadParser> - variables: Record< - string, - DataItemRulesOut<$, ZodMiniAny> - > + variables: Record> } diff --git a/packages/api/src/parsers/DataItemRule.ts b/packages/api/src/parsers/DataItemRule.ts index ac44e27ac..1496a6418 100644 --- a/packages/api/src/parsers/DataItemRule.ts +++ b/packages/api/src/parsers/DataItemRule.ts @@ -10,14 +10,11 @@ import { type ZodMiniOptional, type ZodMiniUnion, } from 'zod/mini' -import type { ZodPartialObject } from '../types.ts' +import type { ZodPartialObject } from '../types.js' import type { $strict, $ZodShape, $ZodType, input, output } from 'zod/v4/core' -import { - attachVariableResolver, - type RecursiveVariableResolver, -} from './attachVariableResolver.ts' -import type { VariablesRegistry } from './variablesRegistry.ts' -import type * as DT from '../types/Data.ts' +import { attachVariableResolver, type RecursiveVariableResolver } from './attachVariableResolver.js' +import type { VariablesRegistry } from './variablesRegistry.js' +import type * as DT from '../types/Data.js' /** * Parses a single item rule. @@ -27,7 +24,7 @@ import type * as DT from '../types/Data.ts' * ```ts * import { equal, assertThrows } from 'jsr:@std/assert' * import { z } from 'zod/mini' - * import { variablesFor } from './variablesRegistry.ts' + * import { variablesFor } from './variablesRegistry.js' * const dataItemRuleParser = DataItemRuleParser( * variablesFor(z.number()), * z.number(), @@ -99,17 +96,8 @@ export function DataItemRuleParser< targeting: $['TargetingParsers'], fallThroughTargeting: $['FallThroughTargetingParsers'], allowMultipleTargeting = true, -): DataItemRuleParser< - $, - PayloadParser, - AllowMultipleTargeting -> { - const Rule = RuleWithPayloadParser( - variablesRegistry, - Payload, - targeting, - allowMultipleTargeting, - ) +): DataItemRuleParser<$, PayloadParser, AllowMultipleTargeting> { + const Rule = RuleWithPayloadParser(variablesRegistry, Payload, targeting, allowMultipleTargeting) const FallThroughRule = RuleWithFallThroughParser( variablesRegistry, @@ -149,17 +137,10 @@ export type DataItemRule< PayloadParser extends $ZodType, AllowMultipleTargeting extends boolean = true, > = - | RuleWithPayload< - PayloadParser, - $['TargetingParsers'], - AllowMultipleTargeting - > + | RuleWithPayload | RuleWithFallThrough<$, PayloadParser, AllowMultipleTargeting> -type SingularRuleTargeting = ZodPartialObject< - Targeting, - $strict -> +type SingularRuleTargeting = ZodPartialObject function SingularRuleTargeting( targeting: Targeting, @@ -169,10 +150,7 @@ function SingularRuleTargeting( } type MultipleRuleTargeting = ZodMiniUnion< - [ - ZodPartialObject, - ZodMiniArray>, - ] + [ZodPartialObject, ZodMiniArray>] > function MultipleRuleTargeting( @@ -254,12 +232,9 @@ export interface RuleWithPayloadIn< > { payload: input> targeting?: input< - AllowMultipleTargeting extends true ? MultipleRuleTargeting< - $['TargetingParsers'] & $['FallThroughTargetingParsers'] - > - : SingularRuleTargeting< - $['TargetingParsers'] & $['FallThroughTargetingParsers'] - > + AllowMultipleTargeting extends true + ? MultipleRuleTargeting<$['TargetingParsers'] & $['FallThroughTargetingParsers']> + : SingularRuleTargeting<$['TargetingParsers'] & $['FallThroughTargetingParsers']> > } @@ -280,7 +255,8 @@ export interface RuleWithPayload< > { payload: output targeting?: output< - AllowMultipleTargeting extends true ? MultipleRuleTargeting + AllowMultipleTargeting extends true + ? MultipleRuleTargeting : SingularRuleTargeting > } @@ -296,13 +272,7 @@ export type RuleWithFallThroughParser< ? MultipleRuleTargeting<$['TargetingParsers']> : SingularRuleTargeting<$['TargetingParsers']> > - fallThrough: ZodMiniArray< - RuleWithPayloadParser< - $, - PayloadParser, - AllowMultipleTargeting - > - > + fallThrough: ZodMiniArray> }, $strict > @@ -354,12 +324,7 @@ export function RuleWithFallThroughParser< : SingularRuleTargeting(targeting, strictTargeting), ), fallThrough: array( - RuleWithPayloadParser( - variablesRegistry, - payload, - fallThroughTargeting, - strictTargeting, - ), + RuleWithPayloadParser(variablesRegistry, payload, fallThroughTargeting, strictTargeting), ), }) as RuleWithFallThroughParser<$, PayloadParser, AllowMultipleTargeting> } diff --git a/packages/api/src/parsers/DataItemRules.ts b/packages/api/src/parsers/DataItemRules.ts index ef8008c05..4874579f8 100644 --- a/packages/api/src/parsers/DataItemRules.ts +++ b/packages/api/src/parsers/DataItemRules.ts @@ -3,13 +3,8 @@ import { type RuleWithFallThrough, type RuleWithPayloadIn, RuleWithPayloadParser, -} from './DataItemRule.ts' -import { - arrayLast, - intersection, - objectSize, - someKeysIntersect, -} from '../util.ts' +} from './DataItemRule.js' +import { arrayLast, intersection, objectSize, someKeysIntersect } from '../util.js' import deepEqual from 'fast-deep-equal' import { array, @@ -20,9 +15,9 @@ import { type ZodMiniTransform, } from 'zod/mini' import type { $ZodShape, $ZodType } from 'zod/v4/core' -import type { ZodPartialInferObject } from '../types.ts' -import type * as DT from '../types/Data.ts' -import type { VariablesRegistry } from './variablesRegistry.ts' +import type { ZodPartialInferObject } from '../types.js' +import type * as DT from '../types/Data.js' +import type { VariablesRegistry } from './variablesRegistry.js' /** * Parses an item's `rules` field. @@ -58,10 +53,7 @@ import type { VariablesRegistry } from './variablesRegistry.ts' * ) * ``` */ -export function DataItemRulesParser< - $ extends DT.Meta, - PayloadParser extends $ZodType, ->( +export function DataItemRulesParser<$ extends DT.Meta, PayloadParser extends $ZodType>( variablesRegistry: VariablesRegistry, payloadParser: PayloadParser, targetingParsers: $['TargetingParsers'], @@ -81,13 +73,7 @@ export function DataItemRulesParser< ), ), transform( - ( - rules: RuleWithPayloadIn<$, PayloadParser>[], - ): DataItemRule< - $, - PayloadParser, - false - >[] => { + (rules: RuleWithPayloadIn<$, PayloadParser>[]): DataItemRule<$, PayloadParser, false>[] => { const singularTargetedRules = spreadMultiTargetsToSeparateRules(rules) let transformedRules: DataItemRule<$, PayloadParser, false>[] = [] @@ -96,17 +82,11 @@ export function DataItemRulesParser< const prevRule = arrayLast(transformedRules) if (!prevRule) { - transformedRules.push( - adaptRule(targetingParsers, fallThroughTargetingParsers, rule), - ) + transformedRules.push(adaptRule(targetingParsers, fallThroughTargetingParsers, rule)) continue } - const thisRuleAndPrevRuleCanCombine = canRulesCombine( - targetingParsers, - prevRule, - rule, - ) + const thisRuleAndPrevRuleCanCombine = canRulesCombine(targetingParsers, prevRule, rule) if (thisRuleAndPrevRuleCanCombine) { const adaptedPrevRule = adaptRuleIntoFallThroughRule( @@ -123,14 +103,9 @@ export function DataItemRulesParser< adaptedPrevRule.fallThrough.push(...adaptedRule.fallThrough) - transformedRules = [ - ...transformedRules.slice(0, -1), - adaptedPrevRule, - ] + transformedRules = [...transformedRules.slice(0, -1), adaptedPrevRule] } else { - transformedRules.push( - adaptRule(targetingParsers, fallThroughTargetingParsers, rule), - ) + transformedRules.push(adaptRule(targetingParsers, fallThroughTargetingParsers, rule)) } } @@ -140,52 +115,43 @@ export function DataItemRulesParser< ) } -export type DataItemRulesParser< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> = ZodMiniPipe< +export type DataItemRulesParser<$ extends DT.Meta, PayloadParser extends $ZodType> = ZodMiniPipe< ZodMiniArray>, - ZodMiniTransform< - DataItemRulesOut<$, PayloadParser>, - DataItemRulesIn<$, PayloadParser> - > + ZodMiniTransform, DataItemRulesIn<$, PayloadParser>> > -export type DataItemRulesIn< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> = RuleWithPayloadIn<$, PayloadParser>[] +export type DataItemRulesIn<$ extends DT.Meta, PayloadParser extends $ZodType> = RuleWithPayloadIn< + $, + PayloadParser +>[] /** * Output type for {@link DataItemRulesParser}. * Returns transformed rules with fallthrough structure applied. * * @template $ - Data meta configuration. * @template PayloadParser - Zod parser for the payload type. - */ export type DataItemRulesOut< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> = DataItemRule<$, PayloadParser, false>[] - -function spreadMultiTargetsToSeparateRules< - $ extends DT.Meta, - PayloadParser extends $ZodType, ->(rules: RuleWithPayloadIn<$, PayloadParser>[]) { - return rules.reduce[]>( - (rules, rule) => { - if (Array.isArray(rule.targeting)) { - for (const targeting of rule.targeting) { - rules.push({ - payload: rule.payload, - targeting, - }) - } - } else { - rules.push(rule as RuleWithPayloadIn<$, PayloadParser, false>) + */ export type DataItemRulesOut<$ extends DT.Meta, PayloadParser extends $ZodType> = DataItemRule< + $, + PayloadParser, + false +>[] + +function spreadMultiTargetsToSeparateRules<$ extends DT.Meta, PayloadParser extends $ZodType>( + rules: RuleWithPayloadIn<$, PayloadParser>[], +) { + return rules.reduce[]>((rules, rule) => { + if (Array.isArray(rule.targeting)) { + for (const targeting of rule.targeting) { + rules.push({ + payload: rule.payload, + targeting, + }) } - return rules - }, - [], - ) + } else { + rules.push(rule as RuleWithPayloadIn<$, PayloadParser, false>) + } + return rules + }, []) } function canRulesCombine( @@ -193,30 +159,23 @@ function canRulesCombine( a: DataItemRule, b: DataItemRule, ) { - const aTargeting = a.targeting - ? intersection(a.targeting, targetingParsers) - : {} + const aTargeting = a.targeting ? intersection(a.targeting, targetingParsers) : {} const aTargetingKeys = Object.keys(aTargeting) - const bTargeting = b.targeting - ? intersection(b.targeting, targetingParsers) - : {} + const bTargeting = b.targeting ? intersection(b.targeting, targetingParsers) : {} const bTargetingKeys = Object.keys(bTargeting) return ( - deepEqual(aTargeting, bTargeting) && + (deepEqual(aTargeting, bTargeting) && (bTargetingKeys.length !== objectSize(b.targeting || {}) || - aTargetingKeys.length !== objectSize(a.targeting || {})) || - !bTargetingKeys.length && !aTargetingKeys.length + aTargetingKeys.length !== objectSize(a.targeting || {}))) || + (!bTargetingKeys.length && !aTargetingKeys.length) ) } -function adaptRule< - $ extends DT.Meta, - PayloadParser extends $ZodType, ->( +function adaptRule<$ extends DT.Meta, PayloadParser extends $ZodType>( targetingParsers: $['TargetingParsers'], fallThroughTargetingParsers: $['FallThroughTargetingParsers'], rule: RuleWithPayloadIn<$, PayloadParser, false>, @@ -224,35 +183,28 @@ function adaptRule< return ( someKeysIntersect(fallThroughTargetingParsers, rule.targeting || {}) ? adaptRuleIntoFallThroughRule( - targetingParsers, - fallThroughTargetingParsers, - rule as DataItemRule<$, PayloadParser, false>, - ) + targetingParsers, + fallThroughTargetingParsers, + rule as DataItemRule<$, PayloadParser, false>, + ) : rule ) as DataItemRule<$, PayloadParser, false> } -function adaptRuleIntoFallThroughRule< - $ extends DT.Meta, - PayloadParser extends $ZodType, ->( +function adaptRuleIntoFallThroughRule<$ extends DT.Meta, PayloadParser extends $ZodType>( targetingParsers: $['TargetingParsers'], fallThroughTargetingParsers: $['FallThroughTargetingParsers'], rule: DataItemRule<$, PayloadParser, false>, ): RuleWithFallThrough<$, PayloadParser, false> { if ('fallThrough' in rule) return rule return { - targeting: intersection( - rule.targeting || {}, - targetingParsers, - ) as ZodPartialInferObject<$['TargetingParsers']>, + targeting: intersection(rule.targeting || {}, targetingParsers) as ZodPartialInferObject< + $['TargetingParsers'] + >, fallThrough: [ { payload: rule.payload, - targeting: intersection( - rule.targeting || {}, - fallThroughTargetingParsers, - ), + targeting: intersection(rule.targeting || {}, fallThroughTargetingParsers), }, ], } as RuleWithFallThrough<$, PayloadParser, false> diff --git a/packages/api/src/parsers/DataItemVariableResolver.ts b/packages/api/src/parsers/DataItemVariableResolver.ts index be957571a..48d3b01ac 100644 --- a/packages/api/src/parsers/DataItemVariableResolver.ts +++ b/packages/api/src/parsers/DataItemVariableResolver.ts @@ -8,16 +8,11 @@ import { type ZodMiniTemplateLiteral, type ZodMiniTransform, } from 'zod/mini' -import type { - $PartsToTemplateLiteral, - $ZodType, - ParsePayload, -} from 'zod/v4/core' -import { objectMap } from '../util.ts' -import type { VariablesRegistry } from './variablesRegistry.ts' +import type { $PartsToTemplateLiteral, $ZodType, ParsePayload } from 'zod/v4/core' +import { objectMap } from '../util.js' +import type { VariablesRegistry } from './variablesRegistry.js' -export const variableStringParser = () => - templateLiteral(['{{', string(), '}}']) +export const variableStringParser = () => templateLiteral(['{{', string(), '}}']) export type VariableStringParser = ZodMiniTemplateLiteral<`{{${string}}}`> @@ -27,9 +22,7 @@ export function DataItemVariableResolverParser( ): DataItemVariableResolverParser { return pipe( variableStringParser(), - transform((input, ctx) => - stringToVariableResolver(registry, parser, input, ctx) - ), + transform((input, ctx) => stringToVariableResolver(registry, parser, input, ctx)), ) } @@ -40,20 +33,13 @@ export function DataItemVariableResolverTransformer( ctx: ParsePayload, ): T extends VariableString ? VariableResolver : T { return isVariableString(input) - ? stringToVariableResolver(registry, parser, input, ctx) as any - : input as any + ? (stringToVariableResolver(registry, parser, input, ctx) as any) + : (input as any) } export type DataItemVariableResolverParser = ZodMiniPipe< - ZodMiniTemplateLiteral< - $PartsToTemplateLiteral< - ['{{', ZodMiniString, '}}'] - > - >, - ZodMiniTransform< - VariableResolver, - `{{${string}}}` - > + ZodMiniTemplateLiteral<$PartsToTemplateLiteral<['{{', ZodMiniString, '}}']>>, + ZodMiniTransform > export interface VariableResolver { @@ -62,20 +48,19 @@ export interface VariableResolver { } export function isVariableResolver(x: unknown): x is VariableResolver { - return typeof x === 'function' && '$$resolver$$' in x && - x.$$resolver$$ === true + return typeof x === 'function' && '$$resolver$$' in x && x.$$resolver$$ === true } export function resolveVariables(variables: Record, x: unknown) { return Array.isArray(x) ? recursivelyResolveArrayVariables(variables, x) : typeof x === 'object' && x !== null - ? recursivelyResolveObjectVariables(variables, x as Record) - : resolveVariable(variables, x) + ? recursivelyResolveObjectVariables(variables, x as Record) + : resolveVariable(variables, x) } export function isVariableString(input: string): input is VariableString { - return /^\{\{[^\}]+\}\}$/.test(input) + return /^\{\{[^}]+\}\}$/.test(input) } type VariableString = `{{${string}}}` @@ -84,10 +69,7 @@ function resolveVariable(variables: Record, x: unknown) { return isVariableResolver(x) ? x(variables) : x } -function recursivelyResolveArrayVariables( - variables: Record, - x: unknown[], -): unknown[] { +function recursivelyResolveArrayVariables(variables: Record, x: unknown[]): unknown[] { return x.map((value) => resolveVariables(variables, value)) } @@ -105,8 +87,7 @@ function stringToVariableResolver( ctx: ParsePayload, ): VariableResolver { const key = extractVariableName(input) - const resolver: VariableResolver = (variables: Record) => - variables[key] ?? input + const resolver: VariableResolver = (variables: Record) => variables[key] ?? input resolver.$$resolver$$ = true registry.set(key, { ctx, diff --git a/packages/api/src/parsers/DataItemVariablesParser.ts b/packages/api/src/parsers/DataItemVariablesParser.ts index cd568c056..5c0de2027 100644 --- a/packages/api/src/parsers/DataItemVariablesParser.ts +++ b/packages/api/src/parsers/DataItemVariablesParser.ts @@ -8,9 +8,9 @@ import { type ZodMiniRecord, type ZodMiniString, } from 'zod/mini' -import { DataItemRulesParser } from './DataItemRules.ts' -import type { VariablesRegistry } from './variablesRegistry.ts' -import type * as DT from '../types/Data.ts' +import { DataItemRulesParser } from './DataItemRules.js' +import type { VariablesRegistry } from './variablesRegistry.js' +import type * as DT from '../types/Data.js' export function DataItemVariablesParser<$ extends DT.Meta>( variablesRegistry: VariablesRegistry, diff --git a/packages/api/src/parsers/DataItems.ts b/packages/api/src/parsers/DataItems.ts index a47529c26..70df90bcc 100644 --- a/packages/api/src/parsers/DataItems.ts +++ b/packages/api/src/parsers/DataItems.ts @@ -1,10 +1,6 @@ -import type * as DT from '../types/Data.ts' -import type { ObjValues, ZodPartialObject } from '../types.ts' -import { - type DataItemIn, - type DataItemOut, - DataItemParser, -} from './DataItem.ts' +import type * as DT from '../types/Data.js' +import type { ObjValues, ZodPartialObject } from '../types.js' +import { type DataItemIn, type DataItemOut, DataItemParser } from './DataItem.js' import { object, partial, strictObject } from 'zod/mini' import type { $strict } from 'zod/v4/core' @@ -30,9 +26,7 @@ import type { $strict } from 'zod/v4/core' * ) * ``` */ -export function DataItemsParser< - $ extends DT.Meta, ->( +export function DataItemsParser<$ extends DT.Meta>( payloadParsers: $['PayloadParsers'], targeting: $['TargetingParsers'], fallThroughTargeting: $['FallThroughTargetingParsers'], @@ -47,9 +41,7 @@ export function DataItemsParser< strict, ) } - return partial( - (strict ? strictObject : object)(dataItems), - ) as DataItemsParser<$> + return partial((strict ? strictObject : object)(dataItems)) as DataItemsParser<$> } /** @@ -58,14 +50,9 @@ export function DataItemsParser< * * @template $ - Data meta configuration. */ -export type DataItemsParser< - $ extends DT.Meta, -> = ZodPartialObject< +export type DataItemsParser<$ extends DT.Meta> = ZodPartialObject< { - [Name in keyof $['PayloadParsers']]: DataItemParser< - $, - $['PayloadParsers'][Name] - > + [Name in keyof $['PayloadParsers']]: DataItemParser<$, $['PayloadParsers'][Name]> }, $strict > @@ -87,8 +74,5 @@ export type DataItemsIn<$ extends DT.Meta> = { * @template $ - Data meta configuration. */ export type DataItemsOut<$ extends DT.Meta> = { - [Name in keyof $['PayloadParsers']]?: DataItemOut< - $, - $['PayloadParsers'][Name] - > + [Name in keyof $['PayloadParsers']]?: DataItemOut<$, $['PayloadParsers'][Name]> } diff --git a/packages/api/src/parsers/TargetingDescriptor.ts b/packages/api/src/parsers/TargetingDescriptor.ts index b509fa385..4763902d0 100644 --- a/packages/api/src/parsers/TargetingDescriptor.ts +++ b/packages/api/src/parsers/TargetingDescriptor.ts @@ -1,5 +1,5 @@ import type { $ZodType } from 'zod/v4/core' -import type TargetingPredicate from './TargetingPredicate.ts' +import type TargetingPredicate from './TargetingPredicate.js' /** * Configuration for a targeting field that defines how to parse and evaluate targeting conditions. @@ -22,10 +22,9 @@ export default interface TargetingDescriptor< /** * Targeting descriptor guard */ -export function isTargetingDescriptor< - TV extends $ZodType, - QV extends $ZodType, ->(x: unknown): x is TargetingDescriptor { +export function isTargetingDescriptor( + x: unknown, +): x is TargetingDescriptor { return ( typeof x === 'object' && x !== null && diff --git a/packages/api/src/parsers/TargetingPredicate.ts b/packages/api/src/parsers/TargetingPredicate.ts index d9f3057a4..123180ae4 100644 --- a/packages/api/src/parsers/TargetingPredicate.ts +++ b/packages/api/src/parsers/TargetingPredicate.ts @@ -1,5 +1,5 @@ import type { $ZodType, output } from 'zod/v4/core' -import type { MaybePromise } from '../types.ts' +import type { MaybePromise } from '../types.js' /** * Function that determines if a targeting rule matches a query. diff --git a/packages/api/src/parsers/TargetingPredicates.ts b/packages/api/src/parsers/TargetingPredicates.ts index 294353efd..28897d2f4 100644 --- a/packages/api/src/parsers/TargetingPredicates.ts +++ b/packages/api/src/parsers/TargetingPredicates.ts @@ -1,6 +1,6 @@ import type { Keys } from 'ts-toolbelt/out/Any/Keys' -import type TargetingPredicate from './TargetingPredicate.ts' -import type * as DT from '../types/Data.ts' +import type TargetingPredicate from './TargetingPredicate.js' +import type * as DT from '../types/Data.js' import type { $InferObjectOutput, $strict, output } from 'zod/v4/core' /** @@ -9,9 +9,7 @@ import type { $InferObjectOutput, $strict, output } from 'zod/v4/core' * * @template $ - Data meta configuration with TargetingParsers and QueryParsers. */ -type TargetingPredicates< - $ extends Pick, -> = { +type TargetingPredicates<$ extends Pick> = { [Name in Keys<$['TargetingParsers']>]: { predicate: TargetingPredicate< $['QueryParsers'][Name], diff --git a/packages/api/src/parsers/attachVariableResolver.ts b/packages/api/src/parsers/attachVariableResolver.ts index d25e8c438..6f04ae92f 100644 --- a/packages/api/src/parsers/attachVariableResolver.ts +++ b/packages/api/src/parsers/attachVariableResolver.ts @@ -8,21 +8,19 @@ import { type ZodMiniPipe, type ZodMiniTransform, } from 'zod/mini' -import { objectEntries } from '../util.ts' +import { objectEntries } from '../util.js' import { DataItemVariableResolverParser, DataItemVariableResolverTransformer, type VariableStringParser, variableStringParser, -} from './DataItemVariableResolver.ts' +} from './DataItemVariableResolver.js' import type { $ZodArray, $ZodObject, $ZodRecord, $ZodType } from 'zod/v4/core' import { any, type ZodObject } from 'zod' -import { type ZodSwitch, zodSwitch } from './switch.ts' -import type { VariablesRegistry } from './variablesRegistry.ts' +import { type ZodSwitch, zodSwitch } from './switch.js' +import type { VariablesRegistry } from './variablesRegistry.js' -export function attachVariableResolver< - Parser extends $ZodType, ->( +export function attachVariableResolver( variablesRegistry: VariablesRegistry, parser: Parser, ): RecursiveVariableResolver { @@ -30,7 +28,7 @@ export function attachVariableResolver< case 'object': return objectVariableResolverParser( variablesRegistry, - parser as unknown as (ZodObject | ZodMiniObject), + parser as unknown as ZodObject | ZodMiniObject, ) as unknown as RecursiveVariableResolver case 'record': @@ -46,38 +44,27 @@ export function attachVariableResolver< ) as RecursiveVariableResolver default: - return variableResolverParser( - variablesRegistry, - parser, - ) as RecursiveVariableResolver + return variableResolverParser(variablesRegistry, parser) as RecursiveVariableResolver } } -function variableResolverParser< - Parser extends $ZodType, ->( +function variableResolverParser( variablesRegistry: VariablesRegistry, parser: Parser, ): WithVariableResolver { - return (parser._zod.def.type === 'string' - ? pipe( - parser, - transform((input, ctx) => - DataItemVariableResolverTransformer( - variablesRegistry, + return ( + parser._zod.def.type === 'string' + ? pipe( parser, - input as string, - ctx, + transform((input, ctx) => + DataItemVariableResolverTransformer(variablesRegistry, parser, input as string, ctx), + ), ) - ), - ) - : zodSwitch([ - [ - variableStringParser(), - DataItemVariableResolverParser(variablesRegistry, parser), - ], - [any(), parser], - ])) as WithVariableResolver + : zodSwitch([ + [variableStringParser(), DataItemVariableResolverParser(variablesRegistry, parser)], + [any(), parser], + ]) + ) as WithVariableResolver } function arrayVariableResolverParser( @@ -86,10 +73,7 @@ function arrayVariableResolverParser( ): RecursiveVariableResolver { const $arrayParser = new arrayParser._zod.constr({ ...arrayParser._zod.def, - element: attachVariableResolver( - variablesRegistry, - arrayParser._zod.def.element, - ), + element: attachVariableResolver(variablesRegistry, arrayParser._zod.def.element), }) return variableResolverParser( variablesRegistry, @@ -103,10 +87,7 @@ function recordVariableResolverParser( ): RecursiveVariableResolver { const $recordParser = new recordParser._zod.constr({ ...recordParser._zod.def, - valueType: attachVariableResolver( - variablesRegistry, - recordParser._zod.def.valueType, - ), + valueType: attachVariableResolver(variablesRegistry, recordParser._zod.def.valueType), }) return variableResolverParser( variablesRegistry, @@ -114,71 +95,57 @@ function recordVariableResolverParser( ) as RecursiveVariableResolver } -function objectVariableResolverParser< - Parser extends ZodObject | ZodMiniObject, ->( +function objectVariableResolverParser( variablesRegistry: VariablesRegistry, objectParser: Parser, ): RecursiveVariableResolver { - const $objectParser = objectParser instanceof ZodMiniObject - ? objectEntries(objectParser._zod.def.shape).reduce( - (acc, [key, parser]) => - safeExtend(acc, { - [key]: attachVariableResolver(variablesRegistry, parser), - }), - objectParser, - ) - : objectEntries(objectParser._zod.def.shape).reduce( - (acc, [key, parser]) => - acc.safeExtend({ - [key]: attachVariableResolver(variablesRegistry, parser) as any, - }), - objectParser, - ) + const $objectParser = + objectParser instanceof ZodMiniObject + ? objectEntries(objectParser._zod.def.shape).reduce( + (acc, [key, parser]) => + safeExtend(acc, { + [key]: attachVariableResolver(variablesRegistry, parser), + }), + objectParser, + ) + : objectEntries(objectParser._zod.def.shape).reduce( + (acc, [key, parser]) => + acc.safeExtend({ + [key]: attachVariableResolver(variablesRegistry, parser) as any, + }), + objectParser, + ) return variableResolverParser( variablesRegistry, $objectParser, - ) as RecursiveVariableResolver< - Parser - > + ) as RecursiveVariableResolver } -type WithVariableResolver< - Parser extends $ZodType, -> = Parser['_zod']['def']['type'] extends 'string' +type WithVariableResolver = Parser['_zod']['def']['type'] extends 'string' ? ZodMiniPipe>> - : ZodSwitch<[ - [VariableStringParser, DataItemVariableResolverParser], - [ZodMiniAny, Parser], - ]> + : ZodSwitch<[[VariableStringParser, DataItemVariableResolverParser], [ZodMiniAny, Parser]]> -export type RecursiveVariableResolver< - Parser extends $ZodType, -> = Parser extends $ZodArray ? WithVariableResolver< - $ZodArray< - RecursiveVariableResolver - > - > - : Parser extends $ZodRecord ? WithVariableResolver< - $ZodRecord< - Parser['_zod']['def']['keyType'], - RecursiveVariableResolver - > - > - : Parser extends $ZodObject ? WithVariableResolver< - $ZodObject< - { - [K in keyof Parser['_zod']['def']['shape']]: - RecursiveVariableResolver< - Parser['_zod']['def']['shape'][K] - > - }, - ZodObjectConfig +export type RecursiveVariableResolver = Parser extends $ZodArray + ? WithVariableResolver<$ZodArray>> + : Parser extends $ZodRecord + ? WithVariableResolver< + $ZodRecord< + Parser['_zod']['def']['keyType'], + RecursiveVariableResolver + > > - > - : WithVariableResolver + : Parser extends $ZodObject + ? WithVariableResolver< + $ZodObject< + { + [K in keyof Parser['_zod']['def']['shape']]: RecursiveVariableResolver< + Parser['_zod']['def']['shape'][K] + > + }, + ZodObjectConfig + > + > + : WithVariableResolver -type ZodObjectConfig = T extends $ZodObject - ? V - : never +type ZodObjectConfig = T extends $ZodObject ? V : never diff --git a/packages/api/src/predicates/equals.ts b/packages/api/src/predicates/equals.ts index 6219f3f8c..0d645d72b 100644 --- a/packages/api/src/predicates/equals.ts +++ b/packages/api/src/predicates/equals.ts @@ -1,4 +1,4 @@ -import type TargetingDescriptor from '../parsers/TargetingDescriptor.ts' +import type TargetingDescriptor from '../parsers/TargetingDescriptor.js' import type { $ZodType } from 'zod/v4/core' /** @@ -38,8 +38,7 @@ export function targetEquals( options: { withNegate?: boolean } = {}, ): TargetingDescriptor { return { - predicate: (q) => (t) => - !q || q === t || (!!options.withNegate && t !== `!${q}`), + predicate: (q) => (t) => !q || q === t || (!!options.withNegate && t !== `!${q}`), queryParser: t, targetingParser: t, } diff --git a/packages/api/src/predicates/targetIncludes.ts b/packages/api/src/predicates/targetIncludes.ts index a92e3b3f8..43871720d 100644 --- a/packages/api/src/predicates/targetIncludes.ts +++ b/packages/api/src/predicates/targetIncludes.ts @@ -1,4 +1,4 @@ -import type TargetingDescriptor from '../parsers/TargetingDescriptor.ts' +import type TargetingDescriptor from '../parsers/TargetingDescriptor.js' import type { $ZodArray, $ZodType, output } from 'zod/v4/core' import { array } from 'zod/mini' @@ -42,8 +42,7 @@ export function targetIncludes( options: { withNegate?: boolean } = {}, ): TargetingDescriptor<$ZodArray, T> { return { - predicate: (q) => (t) => - !q || t.includes(q) || (!!options.withNegate && checkNegate(q, t)), + predicate: (q) => (t) => !q || t.includes(q) || (!!options.withNegate && checkNegate(q, t)), queryParser: t, targetingParser: array(t), } diff --git a/packages/api/src/types/Data.ts b/packages/api/src/types/Data.ts index 851c3f053..75d8c810f 100644 --- a/packages/api/src/types/Data.ts +++ b/packages/api/src/types/Data.ts @@ -1,5 +1,5 @@ -import type Data from '../Data.ts' -import type * as FTTT from './FallThroughTargeting.ts' +import type Data from '../Data.js' +import type * as FTTT from './FallThroughTargeting.js' import type { $ZodShape, output } from 'zod/v4/core' /** @@ -26,14 +26,12 @@ export interface EmptyMeta { /** * Match any Data */ -export type Any = Data< - { - PayloadParsers: any - TargetingParsers: any - QueryParsers: any - FallThroughTargetingParsers: any - } -> +export type Any = Data<{ + PayloadParsers: any + TargetingParsers: any + QueryParsers: any + FallThroughTargetingParsers: any +}> /** * Extract the Meta configuration from a Data type. @@ -60,9 +58,7 @@ export type QueryParsers = $['QueryParsers'] /** * Get the FallThroughTargetingParsers from a Data type */ -export type FallThroughTargetingParsers = $< - D ->['FallThroughTargetingParsers'] +export type FallThroughTargetingParsers = $['FallThroughTargetingParsers'] /** * Data shape that can be inserted into a Data instance. @@ -70,20 +66,15 @@ export type FallThroughTargetingParsers = $< * * @template $ - Data meta configuration. */ -export type InsertableData<$ extends Meta> = Partial< - { - [Name in keyof $['PayloadParsers']]: - | output<$['PayloadParsers'][Name]> - | FTTT.Rules< - $, - $['PayloadParsers'][Name] - > - | FTTT.Rules< +export type InsertableData<$ extends Meta> = Partial<{ + [Name in keyof $['PayloadParsers']]: + | output<$['PayloadParsers'][Name]> + | FTTT.Rules<$, $['PayloadParsers'][Name]> + | FTTT.Rules< $ & { TargetingParsers: {} FallThroughTargetingParsers: $['TargetingParsers'] }, $['PayloadParsers'][Name] > - } -> +}> diff --git a/packages/api/src/types/FallThroughTargeting.ts b/packages/api/src/types/FallThroughTargeting.ts index 73f9f6ace..ff9829d7e 100644 --- a/packages/api/src/types/FallThroughTargeting.ts +++ b/packages/api/src/types/FallThroughTargeting.ts @@ -1,18 +1,15 @@ -import type TargetingDescriptor from '../parsers/TargetingDescriptor.ts' -import type * as TT from './Targeting.ts' -import type { RuleWithPayload } from '../parsers/DataItemRule.ts' +import type TargetingDescriptor from '../parsers/TargetingDescriptor.js' +import type * as TT from './Targeting.js' +import type { RuleWithPayload } from '../parsers/DataItemRule.js' import type { $ZodType } from 'zod/v4/core' -import type { DataItemRulesOut } from '../parsers/DataItemRules.ts' -import type * as DT from './Data.ts' +import type { DataItemRulesOut } from '../parsers/DataItemRules.js' +import type * as DT from './Data.js' import type { ZodMiniAny } from 'zod/mini' /** * Matches any fallthrough targeting descriptor record */ -export type DescriptorRecord = Record< - string, - $ZodType | TargetingDescriptor -> +export type DescriptorRecord = Record> /** * Extracts the fallthrough parser from a targeting descriptor. @@ -20,10 +17,8 @@ export type DescriptorRecord = Record< * * @template T - Targeting descriptor or parser. */ -export type ParserFromDescriptor< - T extends $ZodType | TargetingDescriptor, -> = T extends TargetingDescriptor ? TT.ParserFromDescriptor - : T +export type ParserFromDescriptor> = + T extends TargetingDescriptor ? TT.ParserFromDescriptor : T /** * Maps targeting descriptor names to their fallthrough parser types. @@ -41,16 +36,10 @@ export type ParsersRecord = { * @template $ - Data meta configuration. * @template PayloadParser - Zod parser for the payload type. */ -export type Rules< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> = { +export type Rules<$ extends DT.Meta, PayloadParser extends $ZodType> = { __rules__: RuleWithPayload[] __variables__?: Record< string, - DataItemRulesOut< - $ & { TargetingParsers: $['FallThroughTargetingParsers'] }, - ZodMiniAny - > + DataItemRulesOut<$ & { TargetingParsers: $['FallThroughTargetingParsers'] }, ZodMiniAny> > } diff --git a/packages/api/src/types/Payload.ts b/packages/api/src/types/Payload.ts index 361797520..eb3241a35 100644 --- a/packages/api/src/types/Payload.ts +++ b/packages/api/src/types/Payload.ts @@ -1,6 +1,6 @@ import type { $ZodType, output } from 'zod/v4/core' -import type * as FTTT from './FallThroughTargeting.ts' -import type * as DT from './Data.ts' +import type * as FTTT from './FallThroughTargeting.js' +import type * as DT from './Data.js' /** * A payload value that can be either a direct value or a set of fallthrough rules. @@ -8,10 +8,7 @@ import type * as DT from './Data.ts' * @template $ - Data meta configuration. * @template PayloadParser - Zod parser for the payload type. */ -export type Payload< - $ extends DT.Meta, - PayloadParser extends $ZodType, -> = +export type Payload<$ extends DT.Meta, PayloadParser extends $ZodType> = | output | FTTT.Rules<$, PayloadParser> diff --git a/packages/api/src/types/Query.ts b/packages/api/src/types/Query.ts index 2a85ddc84..6e2e5cf5d 100644 --- a/packages/api/src/types/Query.ts +++ b/packages/api/src/types/Query.ts @@ -1,6 +1,6 @@ -import type { StaticRecord } from '../types.ts' -import type TargetingDescriptor from '../parsers/TargetingDescriptor.ts' -import type * as TT from './Targeting.ts' +import type { StaticRecord } from '../types.js' +import type TargetingDescriptor from '../parsers/TargetingDescriptor.js' +import type * as TT from './Targeting.js' import type { $ZodShape } from 'zod/v4/core' /** @@ -13,9 +13,8 @@ export type Raw = Partial> /** * Gets the query parser from a targeting descriptor */ -export type ParserFromDescriptor< - TD extends TargetingDescriptor, -> = TD extends TargetingDescriptor ? QV : never +export type ParserFromDescriptor> = + TD extends TargetingDescriptor ? QV : never /** * Maps targeting descriptor names to their query parser types. diff --git a/packages/api/src/types/Targeting.ts b/packages/api/src/types/Targeting.ts index dbf7acb9e..071c53e99 100644 --- a/packages/api/src/types/Targeting.ts +++ b/packages/api/src/types/Targeting.ts @@ -1,12 +1,9 @@ -import type TargetingDescriptor from '../parsers/TargetingDescriptor.ts' +import type TargetingDescriptor from '../parsers/TargetingDescriptor.js' /** * Matches a record of targeting descriptors */ -export type DescriptorRecord = Record< - string, - TargetingDescriptor -> +export type DescriptorRecord = Record> /** * Maps targeting descriptor names to their targeting parser types. @@ -22,6 +19,5 @@ export type ParserRecord = { * * @template TD - Targeting descriptor. */ -export type ParserFromDescriptor< - TD extends TargetingDescriptor, -> = TD extends TargetingDescriptor ? TV : never +export type ParserFromDescriptor> = + TD extends TargetingDescriptor ? TV : never diff --git a/packages/api/src/util.ts b/packages/api/src/util.ts index 90eda1cad..6fa1345db 100644 --- a/packages/api/src/util.ts +++ b/packages/api/src/util.ts @@ -1,5 +1,5 @@ import type { L } from 'ts-toolbelt' -import type { MaybePromise } from './types.ts' +import type { MaybePromise } from './types.js' export function objectMap, R>( obj: O, @@ -11,9 +11,7 @@ export function objectMap, R>( ) } -export function objectKeys>( - obj: O, -): (keyof O)[] { +export function objectKeys>(obj: O): (keyof O)[] { return Object.keys(obj) } @@ -70,10 +68,7 @@ export function objectSome>( return false } -export function someKeysIntersect( - aObj: Record, - bObj: Record, -) { +export function someKeysIntersect(aObj: Record, bObj: Record) { return objectSome(aObj, (_, key) => key in bObj) } diff --git a/packages/api/test/parsers/switch.test.ts b/packages/api/test/parsers/switch.test.ts index d0ce056a0..a3d32b6dd 100644 --- a/packages/api/test/parsers/switch.test.ts +++ b/packages/api/test/parsers/switch.test.ts @@ -13,7 +13,7 @@ import { templateLiteral, union, } from 'zod/mini' -import { zodSwitch } from '../../src/parsers/switch.ts' +import { zodSwitch } from '../../src/parsers/switch.js' import { test, expect } from 'bun:test' import { $ZodError } from 'zod/v4/core' diff --git a/packages/api/test/tsconfig.json b/packages/api/test/tsconfig.json index 28ce09649..8d6fdc461 100644 --- a/packages/api/test/tsconfig.json +++ b/packages/api/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "include": ["../src", "."], "compilerOptions": { + "noEmit": true, "rootDir": "../" } } diff --git a/packages/api/test/utils.test.ts b/packages/api/test/utils.test.ts index 5ca48c6c7..cc44fa504 100644 --- a/packages/api/test/utils.test.ts +++ b/packages/api/test/utils.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'bun:test' -import { arrayInit, arrayLast, objectEveryAsync, objectMap } from '../src/util.ts' +import { arrayInit, arrayLast, objectEveryAsync, objectMap } from '../src/util.js' test('objectMap', () => { expect( diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index d0a8f7171..3d9234905 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -2,6 +2,8 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { + "noEmit": false, + "outDir": "dist", "rootDir": "src" } } diff --git a/packages/client/README.md b/packages/client/README.md index 0ab955940..cf5bd1fe4 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -1,21 +1,21 @@ # @targetd/client A type-safe HTTP client for querying -[@targetd/server](https://jsr.io/@targetd/server) instances with full TypeScript +[@targetd/server](../server) instances with full TypeScript inference. ## Installation | JS Runtime | Command | | ---------- | ----------------------------------------------- | -| Node.js | `npx jsr add @targetd/api @targetd/client` | -| Bun | `bunx jsr add @targetd/api @targetd/client` | -| Deno | `deno add jsr:@targetd/api jsr:@targetd/client` | +| Node.js | `npm install @targetd/api @targetd/client` | +| Bun | `bun add @targetd/api @targetd/client` | +| Deno | `deno add npm:@targetd/api npm:@targetd/client` | ## Overview `@targetd/client` provides a strongly-typed HTTP client that mirrors the -[@targetd/api](https://jsr.io/@targetd/api) Data interface. It allows you to +[@targetd/api](../api) Data interface. It allows you to query remote targeting servers while maintaining full type safety and IDE autocomplete. @@ -51,7 +51,7 @@ export const data = await Data.create() ### 2. Set Up the Server -Use [@targetd/server](https://jsr.io/@targetd/server) to create an HTTP +Use [@targetd/server](../server) to create an HTTP endpoint: ```typescript @@ -256,10 +256,8 @@ try { ## Related Packages -- [@targetd/api](https://jsr.io/@targetd/api) - Core targeting and data querying - API -- [@targetd/server](https://jsr.io/@targetd/server) - HTTP server for serving - targeted data +- [@targetd/api](../api) - Core targeting and data querying API +- [@targetd/server](../server) - HTTP server for serving targeted data ## License diff --git a/packages/client/package.json b/packages/client/package.json index eaac8e46c..fc982f96d 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -10,7 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { - "check": "tsc", + "check": "tsc --noEmit", "test": "bun test" }, "dependencies": { diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index ecffbfc01..7ae1ef191 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -1,7 +1,7 @@ import type { Data, DT, PT, StaticRecord } from '@targetd/api' -import { queryToURLSearchParams } from './queryToURLSearchParams.ts' +import { queryToURLSearchParams } from './queryToURLSearchParams.js' import { ZodError } from 'zod' -import { ResponseError } from './ResponseError.ts' +import { ResponseError } from './ResponseError.js' /** * Type-safe HTTP client for querying @targetd/server instances. @@ -10,7 +10,7 @@ import { ResponseError } from './ResponseError.ts' * @example * ```ts * import { Client } from '@targetd/client' - * import { data } from './data.ts' // Your Data instance definition + * import { data } from './data.js' // Your Data instance definition * * const client = new Client('http://localhost:3000', data) * diff --git a/packages/client/test/queryToURLSearchParams.test.ts b/packages/client/test/queryToURLSearchParams.test.ts index eb0ccb5ac..3ca77df32 100644 --- a/packages/client/test/queryToURLSearchParams.test.ts +++ b/packages/client/test/queryToURLSearchParams.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'bun:test' -import { queryToURLSearchParams } from '../src/queryToURLSearchParams.ts' +import { queryToURLSearchParams } from '../src/queryToURLSearchParams.js' test('numbers', () => { expect(queryToURLSearchParams({ number: 1 }).toString()).toBe('number=1') diff --git a/packages/client/test/tsconfig.json b/packages/client/test/tsconfig.json index 28ce09649..8d6fdc461 100644 --- a/packages/client/test/tsconfig.json +++ b/packages/client/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "include": ["../src", "."], "compilerOptions": { + "noEmit": true, "rootDir": "../" } } diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json index d0a8f7171..e4591631f 100644 --- a/packages/client/tsconfig.json +++ b/packages/client/tsconfig.json @@ -2,6 +2,13 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { + "noEmit": false, + "outDir": "dist", "rootDir": "src" - } + }, + "references": [ + { "path": "../api/tsconfig.json" }, + { "path": "../date-range/tsconfig.json" }, + { "path": "../server/tsconfig.json" } + ] } diff --git a/packages/date-range/README.md b/packages/date-range/README.md index a5bb854af..19e76d87c 100644 --- a/packages/date-range/README.md +++ b/packages/date-range/README.md @@ -1,16 +1,16 @@ # @targetd/date-range A time-based targeting descriptor for -[@targetd/api](https://jsr.io/@targetd/api) that enables content delivery based +[@targetd/api](../api) that enables content delivery based on date ranges. ## Installation | JS Runtime | Command | | ---------- | --------------------------------------------------- | -| Node.js | `npx jsr add @targetd/api @targetd/date-range` | -| Bun | `bunx jsr add @targetd/api @targetd/date-range` | -| Deno | `deno add jsr:@targetd/api jsr:@targetd/date-range` | +| Node.js | `npm install @targetd/api @targetd/date-range` | +| Bun | `bun add @targetd/api @targetd/date-range` | +| Deno | `deno add npm:@targetd/api npm:@targetd/date-range` | ## Overview @@ -289,12 +289,9 @@ target: { start: '2024-07-01', end: '2024-07-31' } ## Related Packages -- [@targetd/api](https://jsr.io/@targetd/api) - Core targeting and data querying - API -- [@targetd/server](https://jsr.io/@targetd/server) - HTTP server for serving - targeted data -- [@targetd/client](https://jsr.io/@targetd/client) - Type-safe HTTP client for - querying servers +- [@targetd/api](../api) - Core targeting and data querying API +- [@targetd/server](../server) - HTTP server for serving targeted data +- [@targetd/client](../client) - Type-safe HTTP client for querying servers ## License diff --git a/packages/date-range/package.json b/packages/date-range/package.json index 130359ebd..4a308cf2a 100644 --- a/packages/date-range/package.json +++ b/packages/date-range/package.json @@ -10,7 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { - "check": "tsc", + "check": "tsc --noEmit", "test": "bun test" }, "devDependencies": { diff --git a/packages/date-range/test/tsconfig.json b/packages/date-range/test/tsconfig.json index 28ce09649..8d6fdc461 100644 --- a/packages/date-range/test/tsconfig.json +++ b/packages/date-range/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "include": ["../src", "."], "compilerOptions": { + "noEmit": true, "rootDir": "../" } } diff --git a/packages/date-range/tsconfig.json b/packages/date-range/tsconfig.json index d0a8f7171..61a8ff6db 100644 --- a/packages/date-range/tsconfig.json +++ b/packages/date-range/tsconfig.json @@ -2,6 +2,9 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { + "noEmit": false, + "outDir": "dist", "rootDir": "src" - } + }, + "references": [{ "path": "../api/tsconfig.json" }] } diff --git a/packages/explode/README.md b/packages/explode/README.md index e0a1349fd..e25e8f5be 100644 --- a/packages/explode/README.md +++ b/packages/explode/README.md @@ -7,14 +7,14 @@ structures. | JS Runtime | Command | | ---------- | ------------------------------------------------ | -| Node.js | `npx jsr add @targetd/api @targetd/explode` | -| Bun | `bunx jsr add @targetd/api @targetd/explode` | -| Deno | `deno add jsr:@targetd/api jsr:@targetd/explode` | +| Node.js | `npm install @targetd/api @targetd/explode` | +| Bun | `bun add @targetd/api @targetd/explode` | +| Deno | `deno add npm:@targetd/api npm:@targetd/explode` | ## Overview `@targetd/explode` provides a utility to convert flat key-value structures into -nested objects. Since [@targetd/api](https://jsr.io/@targetd/api) stores data as +nested objects. Since [@targetd/api](../api) stores data as flat key-value pairs, this package helps you organize related payloads using namespaced keys (e.g., `'feature.mobile.enabled'`) and then transform them into a hierarchical structure. @@ -141,10 +141,7 @@ const data = await Data.create() .addRules('feature.desktop.enabled', [{ payload: true }]) .addRules('feature.desktop.maxItems', [{ payload: 50 }]) -const features = explode( - await data.getPayloadForEachName({ platform: 'ios' }), - '.', -) +const features = explode(await data.getPayloadForEachName({ platform: 'ios' }), '.') // { // feature: { // mobile: { @@ -204,7 +201,7 @@ const nested2 = explode({ 'namespace:key:subkey': 'data' }, ':') // { namespace: { key: { subkey: 'data' } } } // Using underscore -const nested3 = explode({ 'section_subsection_field': true }, '_') +const nested3 = explode({ section_subsection_field: true }, '_') // { section: { subsection: { field: true } } } ``` @@ -220,7 +217,7 @@ import type { Explode } from '@targetd/explode' type Flat = { 'foo.bar': string 'foo.baz': number - 'qux': boolean + qux: boolean } type Nested = Explode @@ -236,7 +233,7 @@ type Nested = Explode const flat: Flat = { 'foo.bar': 'hello', 'foo.baz': 42, - 'qux': true, + qux: true, } const nested = explode(flat, '.') @@ -295,12 +292,9 @@ const theme = explode(await data.getPayloadForEachName(), '.') ## Related Packages -- [@targetd/api](https://jsr.io/@targetd/api) - Core targeting and data querying - API -- [@targetd/client](https://jsr.io/@targetd/client) - Type-safe HTTP client for - querying servers -- [@targetd/server](https://jsr.io/@targetd/server) - HTTP server for serving - targeted data +- [@targetd/api](../api) - Core targeting and data querying API +- [@targetd/client](../client) - Type-safe HTTP client for querying servers +- [@targetd/server](../server) - HTTP server for serving targeted data ## License diff --git a/packages/explode/package.json b/packages/explode/package.json index a007d4292..f2aab0a27 100644 --- a/packages/explode/package.json +++ b/packages/explode/package.json @@ -10,7 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { - "check": "tsc", + "check": "tsc --noEmit", "test": "bun test" }, "dependencies": { diff --git a/packages/explode/src/explode.ts b/packages/explode/src/explode.ts index e610f51a3..60fba3ddd 100644 --- a/packages/explode/src/explode.ts +++ b/packages/explode/src/explode.ts @@ -1,5 +1,5 @@ import { unflatten } from 'flat' -import type { Explode } from './types.ts' +import type { Explode } from './types.js' /** * Transform flat key notation to nested objects. @@ -22,9 +22,9 @@ import type { Explode } from './types.ts' * // Returns: { config: { api: { url: 'https://api.com' } } } * ``` */ -export function explode< - T extends Record, - PathSeparator extends string, ->(x: T, pathSeparator: PathSeparator): Explode { +export function explode, PathSeparator extends string>( + x: T, + pathSeparator: PathSeparator, +): Explode { return unflatten(x, { delimiter: pathSeparator }) } diff --git a/packages/explode/src/index.ts b/packages/explode/src/index.ts index 2fab7ff13..0237f2d0e 100644 --- a/packages/explode/src/index.ts +++ b/packages/explode/src/index.ts @@ -1,2 +1,2 @@ -export { explode } from './explode.ts' -export type { Explode, ExplodedPayloads } from './types.ts' +export { explode } from './explode.js' +export type { Explode, ExplodedPayloads } from './types.js' diff --git a/packages/explode/test/tsconfig.json b/packages/explode/test/tsconfig.json index 28ce09649..8d6fdc461 100644 --- a/packages/explode/test/tsconfig.json +++ b/packages/explode/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "include": ["../src", "."], "compilerOptions": { + "noEmit": true, "rootDir": "../" } } diff --git a/packages/explode/tsconfig.json b/packages/explode/tsconfig.json index d0a8f7171..61a8ff6db 100644 --- a/packages/explode/tsconfig.json +++ b/packages/explode/tsconfig.json @@ -2,6 +2,9 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { + "noEmit": false, + "outDir": "dist", "rootDir": "src" - } + }, + "references": [{ "path": "../api/tsconfig.json" }] } diff --git a/packages/fs/README.md b/packages/fs/README.md index 3a674d05c..61662953b 100644 --- a/packages/fs/README.md +++ b/packages/fs/README.md @@ -1,15 +1,15 @@ # @targetd/fs -Load and watch [@targetd/api](https://jsr.io/@targetd/api) rules from JSON and +Load and watch [@targetd/api](../api) rules from JSON and YAML files. ## Installation | JS Runtime | Command | | ---------- | ------------------------------------------- | -| Node.js | `npx jsr add @targetd/api @targetd/fs` | -| Bun | `bunx jsr add @targetd/api @targetd/fs` | -| Deno | `deno add jsr:@targetd/api jsr:@targetd/fs` | +| Node.js | `npm install @targetd/api @targetd/fs` | +| Bun | `bun add @targetd/api @targetd/fs` | +| Deno | `deno add npm:@targetd/api npm:@targetd/fs` | ## Overview @@ -118,19 +118,15 @@ const data = await Data.create() }) // Watch directory and reload on changes -const stopWatching = watch( - data, - './rules', - (error, updatedData) => { - if (error) { - console.error('Failed to load rules:', error) - return - } - - console.log('Rules reloaded!') - // Use updatedData which contains the latest rules - }, -) +const stopWatching = watch(data, './rules', (error, updatedData) => { + if (error) { + console.error('Failed to load rules:', error) + return + } + + console.log('Rules reloaded!') + // Use updatedData which contains the latest rules +}) // Later: stop watching stopWatching() @@ -200,10 +196,7 @@ const data = await Data.create() }) // Load rules from filesystem -const appData = await load( - data, - path.join(import.meta.dirname, 'config'), -) +const appData = await load(data, path.join(import.meta.dirname, 'config')) // Query data const config = await appData.getPayloadForEachName({ @@ -217,14 +210,10 @@ console.log(config) ```json { "app.title": { - "rules": [ - { "payload": "My Application" } - ] + "rules": [{ "payload": "My Application" }] }, "app.version": { - "rules": [ - { "payload": "1.0.0" } - ] + "rules": [{ "payload": "1.0.0" }] } } ``` @@ -261,19 +250,15 @@ const data = await Data.create() }) // Watch for changes during development -const stopWatching = watch( - data, - './rules', - (error, updatedData) => { - if (error) { - console.error('Error loading rules:', error) - return - } - - currentData = updatedData - console.log('✓ Rules reloaded') - }, -) +const stopWatching = watch(data, './rules', (error, updatedData) => { + if (error) { + console.error('Error loading rules:', error) + return + } + + currentData = updatedData + console.log('✓ Rules reloaded') +}) // Your application uses currentData async function getFeature(environment: string) { @@ -399,12 +384,9 @@ watch(data, './rules', (error, data) => { ## Related Packages -- [@targetd/api](https://jsr.io/@targetd/api) - Core targeting and data querying - API -- [@targetd/server](https://jsr.io/@targetd/server) - HTTP server for serving - targeted data -- [@targetd/client](https://jsr.io/@targetd/client) - Type-safe HTTP client for - querying servers +- [@targetd/api](../api) - Core targeting and data querying API +- [@targetd/server](../server) - HTTP server for serving targeted data +- [@targetd/client](../client) - Type-safe HTTP client for querying servers ## License diff --git a/packages/fs/package.json b/packages/fs/package.json index 11f6c3499..46e509a64 100644 --- a/packages/fs/package.json +++ b/packages/fs/package.json @@ -10,7 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { - "check": "tsc", + "check": "tsc --noEmit", "test": "bun test" }, "dependencies": { diff --git a/packages/fs/src/index.ts b/packages/fs/src/index.ts index 8635ff3bd..fe083fa9f 100644 --- a/packages/fs/src/index.ts +++ b/packages/fs/src/index.ts @@ -1,2 +1,2 @@ -export { load } from './load.ts' -export * from './watch.ts' +export { load } from './load.js' +export * from './watch.js' diff --git a/packages/fs/src/watch.ts b/packages/fs/src/watch.ts index ce15884f8..826743905 100644 --- a/packages/fs/src/watch.ts +++ b/packages/fs/src/watch.ts @@ -1,7 +1,7 @@ import type { DT } from '@targetd/api' import { debounce, Mutex } from 'es-toolkit' import { watch as fsWatch, type WatchOptions as BaseWatchOptions } from 'node:fs' -import { load, pathIsLoadable } from './load.ts' +import { load, pathIsLoadable } from './load.js' /** * Callback function invoked when rules are loaded or reloaded by the watch function. diff --git a/packages/fs/test/load.test.ts b/packages/fs/test/load.test.ts index 77ae7930a..006014dac 100644 --- a/packages/fs/test/load.test.ts +++ b/packages/fs/test/load.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'bun:test' import * as path from 'node:path' import { load } from '@targetd/fs' -import { data } from './fixtures/data.ts' +import { data } from './fixtures/data.js' test('load', async () => { const $data = await load(data, path.join(import.meta.dirname ?? '', 'fixtures', 'rules')) diff --git a/packages/fs/test/tsconfig.json b/packages/fs/test/tsconfig.json index 28ce09649..8d6fdc461 100644 --- a/packages/fs/test/tsconfig.json +++ b/packages/fs/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "include": ["../src", "."], "compilerOptions": { + "noEmit": true, "rootDir": "../" } } diff --git a/packages/fs/test/watch.test.ts b/packages/fs/test/watch.test.ts index 0fe4af981..f388b20ea 100644 --- a/packages/fs/test/watch.test.ts +++ b/packages/fs/test/watch.test.ts @@ -3,7 +3,7 @@ import { setTimeout } from 'node:timers/promises' import * as path from 'node:path' import { cp, mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' -import { data } from './fixtures/data.ts' +import { data } from './fixtures/data.js' import { watch } from '@targetd/fs' test('watch', async () => { diff --git a/packages/fs/tsconfig.json b/packages/fs/tsconfig.json index d0a8f7171..61a8ff6db 100644 --- a/packages/fs/tsconfig.json +++ b/packages/fs/tsconfig.json @@ -2,6 +2,9 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { + "noEmit": false, + "outDir": "dist", "rootDir": "src" - } + }, + "references": [{ "path": "../api/tsconfig.json" }] } diff --git a/packages/json-schema/README.md b/packages/json-schema/README.md index 51d46552c..1447c6767 100644 --- a/packages/json-schema/README.md +++ b/packages/json-schema/README.md @@ -6,8 +6,8 @@ ``` # Node.js -npx xjsr @targetd/json-schema/cli --inputModule src/data.ts --dataExport data --outputFile src/data.schema.json +npx @targetd/json-schema --inputModule src/data.ts --dataExport data --outputFile src/data.schema.json # Deno -deno run jsr:@targetd/json-schema/cli --inputModule src/data.ts --dataExport data --outputFile src/data.schema.json +deno run npm:@targetd/json-schema/cli --inputModule src/data.ts --dataExport data --outputFile src/data.schema.json ``` diff --git a/packages/json-schema/package.json b/packages/json-schema/package.json index 0aafd1d6a..9eee5bdcd 100644 --- a/packages/json-schema/package.json +++ b/packages/json-schema/package.json @@ -13,7 +13,7 @@ "./cli": "./src/cli.ts" }, "scripts": { - "check": "tsc", + "check": "tsc --noEmit", "test": "bun test" }, "dependencies": { diff --git a/packages/json-schema/src/cli.ts b/packages/json-schema/src/cli.ts index a25bb226a..1979f8b5a 100644 --- a/packages/json-schema/src/cli.ts +++ b/packages/json-schema/src/cli.ts @@ -4,7 +4,7 @@ import * as path from 'node:path' import { pathToFileURL } from 'node:url' import { writeFile } from 'node:fs/promises' import { argv, cwd } from 'node:process' -import { dataJSONSchemas } from './index.ts' +import { dataJSONSchemas } from './index.js' const { dataExport, inputModule, outputFile } = await yargs() .usage('targetd-json-schema [args]') @@ -31,15 +31,11 @@ const { dataExport, inputModule, outputFile } = await yargs() .help() .parseAsync(argv) -const input = await import( - pathToFileURL(path.resolve(cwd(), inputModule)).href -) +const input = await import(pathToFileURL(path.resolve(cwd(), inputModule)).href) const data = input[dataExport] if (!isDataLike(data)) { - throw new Error( - `Export "${dataExport}" from "${inputModule}" is not of a \`Data\` type.`, - ) + throw new Error(`Export "${dataExport}" from "${inputModule}" is not of a \`Data\` type.`) } const jsonSchema = JSON.stringify(dataJSONSchemas(data), null, 2) diff --git a/packages/json-schema/test/index.test.ts b/packages/json-schema/test/index.test.ts index 66fa5cd74..c6b3e9138 100644 --- a/packages/json-schema/test/index.test.ts +++ b/packages/json-schema/test/index.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'bun:test' import { dataJSONSchemas } from '@targetd/json-schema' -import { data } from './fixtures/data.ts' +import { data } from './fixtures/data.js' test('json schema for simple data object', async () => { expect(dataJSONSchemas(data)).toMatchSnapshot() diff --git a/packages/json-schema/test/tsconfig.json b/packages/json-schema/test/tsconfig.json index 28ce09649..8d6fdc461 100644 --- a/packages/json-schema/test/tsconfig.json +++ b/packages/json-schema/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "include": ["../src", "."], "compilerOptions": { + "noEmit": true, "rootDir": "../" } } diff --git a/packages/json-schema/tsconfig.json b/packages/json-schema/tsconfig.json index d0a8f7171..61a8ff6db 100644 --- a/packages/json-schema/tsconfig.json +++ b/packages/json-schema/tsconfig.json @@ -2,6 +2,9 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { + "noEmit": false, + "outDir": "dist", "rootDir": "src" - } + }, + "references": [{ "path": "../api/tsconfig.json" }] } diff --git a/packages/server/README.md b/packages/server/README.md index 568efcd0a..46c38b64b 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -1,20 +1,20 @@ # @targetd/server -HTTP server for serving [@targetd/api](https://jsr.io/@targetd/api) targeting +HTTP server for serving [@targetd/api](../api) targeting data over REST endpoints. ## Installation | JS Runtime | Command | | ---------- | ----------------------------------------------- | -| Node.js | `npx jsr add @targetd/api @targetd/server` | -| Bun | `bunx jsr add @targetd/api @targetd/server` | -| Deno | `deno add jsr:@targetd/api jsr:@targetd/server` | +| Node.js | `npm install @targetd/api @targetd/server` | +| Bun | `bun add @targetd/api @targetd/server` | +| Deno | `deno add npm:@targetd/api npm:@targetd/server` | ## Overview `@targetd/server` creates an Express-based HTTP server that exposes your -[@targetd/api](https://jsr.io/@targetd/api) Data instance via REST endpoints. +[@targetd/api](../api) Data instance via REST endpoints. Clients can query targeted payloads using query parameters. Key features: @@ -23,7 +23,7 @@ Key features: - **Query parameters**: Pass targeting queries via URL parameters - **CORS enabled**: Ready for cross-origin requests - **Type-safe**: Works seamlessly with - [@targetd/client](https://jsr.io/@targetd/client) + [@targetd/client](../client) - **Express-based**: Built on Express for easy integration and middleware support @@ -227,10 +227,9 @@ import { Data } from '@targetd/api' import { watch } from '@targetd/fs' import { createServer } from '@targetd/server' -let currentData = await Data.create() - .usePayload({ - content: z.string(), - }) +let currentData = await Data.create().usePayload({ + content: z.string(), +}) // Watch for file changes watch(baseData, './rules', (error, updatedData) => { @@ -330,7 +329,7 @@ Now you have both your custom routes and targetd endpoints on the same server. ### Date Range Targeting -Combine with [@targetd/date-range](https://jsr.io/@targetd/date-range) for +Combine with [@targetd/date-range](../date-range) for time-based content: ```typescript @@ -480,10 +479,12 @@ import { createServer } from '@targetd/server' const app = express() // Custom CORS -app.use(cors({ - origin: 'https://example.com', - credentials: true, -})) +app.use( + cors({ + origin: 'https://example.com', + credentials: true, + }), +) createServer(data, { app }) ``` @@ -491,7 +492,7 @@ createServer(data, { app }) ## Working with @targetd/client The server is designed to work seamlessly with -[@targetd/client](https://jsr.io/@targetd/client): +[@targetd/client](../client): **Server:** @@ -502,10 +503,7 @@ import { createServer } from '@targetd/server' export const data = await Data.create() .usePayload({ greeting: z.string() }) .useTargeting({ country: targetIncludes(z.string()) }) - .addRules('greeting', [ - { targeting: { country: ['US'] }, payload: 'Hello!' }, - { payload: 'Hi!' }, - ]) + .addRules('greeting', [{ targeting: { country: ['US'] }, payload: 'Hello!' }, { payload: 'Hi!' }]) createServer(data).listen(3000) ``` @@ -531,10 +529,7 @@ import { Data } from '@targetd/api' import { load } from '@targetd/fs' import { createServer } from '@targetd/server' -const data = await load( - baseData, - process.env.RULES_DIR || './rules', -) +const data = await load(baseData, process.env.RULES_DIR || './rules') const port = process.env.PORT || 3000 @@ -568,13 +563,10 @@ CMD ["node", "server.js"] ## Related Packages -- [@targetd/api](https://jsr.io/@targetd/api) - Core targeting and data querying - API -- [@targetd/client](https://jsr.io/@targetd/client) - Type-safe HTTP client for - querying servers -- [@targetd/fs](https://jsr.io/@targetd/fs) - Load rules from JSON/YAML files -- [@targetd/date-range](https://jsr.io/@targetd/date-range) - Date range - targeting descriptor +- [@targetd/api](../api) - Core targeting and data querying API +- [@targetd/client](../client) - Type-safe HTTP client for querying servers +- [@targetd/fs](../fs) - Load rules from JSON/YAML files +- [@targetd/date-range](../date-range) - Date range targeting descriptor ## License diff --git a/packages/server/package.json b/packages/server/package.json index b20191f5d..5d626a967 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -10,7 +10,7 @@ "type": "module", "exports": "./src/index.ts", "scripts": { - "check": "tsc", + "check": "tsc --noEmit", "test": "bun test" }, "dependencies": { @@ -27,9 +27,9 @@ "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/qs": "^6.15.0", - "@types/supertest": "latest", - "lodash": "latest", - "supertest": "latest", + "@types/supertest": "^7.2.0", + "es-toolkit": "catalog:", + "supertest": "^7.2.2", "typescript": "catalog:", "zod": "catalog:" }, diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index edf0b5d98..4bb73ad90 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1,11 +1,11 @@ import type { DT } from '@targetd/api' import cors from 'cors' import express from 'express' -import { errorHandler } from './middleware/error.ts' -import { StatusError } from './StatusError.ts' -import { castQueryArrayProps } from './middleware/castQueryArrayProps.ts' -import { castQueryProp } from './middleware/castQueryProp.ts' -import type { MaybePromise } from './types.ts' +import { errorHandler } from './middleware/error.js' +import { StatusError } from './StatusError.js' +import { castQueryArrayProps } from './middleware/castQueryArrayProps.js' +import { castQueryProp } from './middleware/castQueryProp.js' +import type { MaybePromise } from './types.js' /** * Configuration options for createServer. diff --git a/packages/server/src/middleware/castQueryArrayProps.ts b/packages/server/src/middleware/castQueryArrayProps.ts index 5b9c0c7a7..506525b66 100644 --- a/packages/server/src/middleware/castQueryArrayProps.ts +++ b/packages/server/src/middleware/castQueryArrayProps.ts @@ -1,7 +1,7 @@ import type { DT } from '@targetd/api' import type { RequestHandler } from 'express' -import type { MaybePromise } from '../types.ts' -import type { ParsedQs } from './castQueryProp.ts' +import type { MaybePromise } from '../types.js' +import type { ParsedQs } from './castQueryProp.js' /** * Express middleware that ensures array query parameters are actually arrays. @@ -18,9 +18,7 @@ export function castQueryArrayProps< ReqBody, ReqQuery, Locals extends { query: ParsedQs }, ->( - getData: () => MaybePromise, -): RequestHandler { +>(getData: () => MaybePromise): RequestHandler { return async (_req, res, next) => { const { queryParsers } = await getData() diff --git a/packages/server/test/index.test.ts b/packages/server/test/index.test.ts index 2fd599e41..b4d2b4fd1 100644 --- a/packages/server/test/index.test.ts +++ b/packages/server/test/index.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'bun:test' import { Data, type DT, targetEquals, targetIncludes } from '@targetd/api' import dateRangeTargeting from '@targetd/date-range' -import _ from 'lodash' +import { difference } from 'es-toolkit' import { setTimeout } from 'node:timers/promises' import request from 'supertest' import z from 'zod' @@ -131,7 +131,7 @@ function createData() { targetingParser: z.boolean(), }, arrayThing: { - predicate: (q) => (t) => _.difference(q, t).length === 0, + predicate: (q) => (t) => difference(q, t).length === 0, queryParser: z.string().array(), targetingParser: z.string().array(), }, diff --git a/packages/server/test/tsconfig.json b/packages/server/test/tsconfig.json index 28ce09649..8d6fdc461 100644 --- a/packages/server/test/tsconfig.json +++ b/packages/server/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "include": ["../src", "."], "compilerOptions": { + "noEmit": true, "rootDir": "../" } } diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index d0a8f7171..b3f7b2afb 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -2,6 +2,9 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { + "noEmit": false, + "outDir": "dist", "rootDir": "src" - } + }, + "references": [{ "path": "../api/tsconfig.json" }, { "path": "../date-range/tsconfig.json" }] } diff --git a/tsconfig.json b/tsconfig.json index 5c813059c..74fd746ea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { - "allowImportingTsExtensions": true, "allowJs": false, + "composite": true, "declaration": true, "declarationMap": true, "importHelpers": true, @@ -21,5 +21,15 @@ "sourceMap": true, "strict": true, "target": "ESNext" - } + }, + "include": [], + "references": [ + { "path": "packages/api/tsconfig.json" }, + { "path": "packages/client/tsconfig.json" }, + { "path": "packages/date-range/tsconfig.json" }, + { "path": "packages/explode/tsconfig.json" }, + { "path": "packages/fs/tsconfig.json" }, + { "path": "packages/json-schema/tsconfig.json" }, + { "path": "packages/server/tsconfig.json" } + ] } From 9bf131e4e88eab7d58e48b562cdcadc4bc656d7b Mon Sep 17 00:00:00 2001 From: John Wright Date: Tue, 17 Mar 2026 10:13:15 +0000 Subject: [PATCH 12/17] ci: publish to npm and jsr --- .github/workflows/release.yml | 32 +++++++++++++++++++++++++++++-- packages/api/package.json | 2 +- packages/client/package.json | 2 +- packages/date-range/package.json | 2 +- packages/explode/package.json | 2 +- packages/fs/package.json | 2 +- packages/json-schema/package.json | 2 +- packages/server/package.json | 2 +- 8 files changed, 37 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4e401d30f..ce45c9231 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,30 @@ jobs: path_released: ${{ fromJson(needs.release-github.outputs.paths_released) }} name: Publish ${{ matrix.path_released }} to NPM environment: npm - concurrency: release-npm + concurrency: + group: release-npm-${{ matrix.path_released }} + container: + image: oven/bun:1 + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v6 + - working-directory: ${{ matrix.path_released }} + run: | + bun pm pack --filename=$(pwd)/package.tgz + npm publish $(pwd)/package.tgz + + release-jsr: + needs: [release-github, release-test] + runs-on: ubuntu-latest + strategy: + matrix: + path_released: ${{ fromJson(needs.release-github.outputs.paths_released) }} + name: Publish ${{ matrix.path_released }} to JSR + environment: jsr + concurrency: + group: release-jsr-${{ matrix.path_released }} container: image: oven/bun:1 permissions: @@ -50,4 +73,9 @@ jobs: steps: - uses: actions/checkout@v6 - working-directory: ${{ matrix.path_released }} - run: npm publish + run: | # shell + PACK="$(pwd)/package.tgz" + bun pm pack --filename=$PACK + tar -xOf $PACK package/package.json > package.json + rm -rf package $PACK + bunx jsr publish diff --git a/packages/api/package.json b/packages/api/package.json index 2f3d765f6..77cd98edc 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -3,7 +3,7 @@ "version": "8.1.1", "description": "Type-safe targeting and feature flag system with dynamic content delivery based on query conditions. Perfect for A/B testing, feature flags, and content personalization.", "files": [ - "src/", + "dist/", "LICENSE", "README.md" ], diff --git a/packages/client/package.json b/packages/client/package.json index fc982f96d..03158122d 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -3,7 +3,7 @@ "version": "7.0.2", "description": "Type-safe HTTP client for querying @targetd/server instances. Mirrors the Data API with full TypeScript inference.", "files": [ - "src/", + "dist/", "LICENSE", "README.md" ], diff --git a/packages/date-range/package.json b/packages/date-range/package.json index 4a308cf2a..a2b13dfdb 100644 --- a/packages/date-range/package.json +++ b/packages/date-range/package.json @@ -3,7 +3,7 @@ "version": "6.0.2", "description": "Built-in targeting descriptor for date range queries in ISO 8601 format with automatic current time evaluation.", "files": [ - "src/", + "dist/", "LICENSE", "README.md" ], diff --git a/packages/explode/package.json b/packages/explode/package.json index f2aab0a27..299189990 100644 --- a/packages/explode/package.json +++ b/packages/explode/package.json @@ -3,7 +3,7 @@ "version": "4.0.2", "description": "Transform flat key notation to nested objects with full TypeScript type inference.", "files": [ - "src/", + "dist/", "LICENSE", "README.md" ], diff --git a/packages/fs/package.json b/packages/fs/package.json index 46e509a64..c8ee6c035 100644 --- a/packages/fs/package.json +++ b/packages/fs/package.json @@ -3,7 +3,7 @@ "version": "7.1.0", "description": "Load targeting rules from JSON/YAML files with hot-reloading support for @targetd/api Data instances.", "files": [ - "src/", + "dist/", "LICENSE", "README.md" ], diff --git a/packages/json-schema/package.json b/packages/json-schema/package.json index 9eee5bdcd..9b31b20bd 100644 --- a/packages/json-schema/package.json +++ b/packages/json-schema/package.json @@ -3,7 +3,7 @@ "version": "5.2.0", "description": "Generate JSON Schema from @targetd/api Data instances for API documentation and validation.", "files": [ - "src/", + "dist/", "LICENSE", "README.md" ], diff --git a/packages/server/package.json b/packages/server/package.json index 5d626a967..2aef0c45d 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -3,7 +3,7 @@ "version": "8.1.2", "description": "Express-based HTTP server for exposing @targetd/api Data instances via REST endpoints with built-in CORS and error handling.", "files": [ - "src/", + "dist/", "LICENSE", "README.md" ], From 15378c084c6904b160b917cd9f5cb32c137f86b9 Mon Sep 17 00:00:00 2001 From: John Wright Date: Tue, 17 Mar 2026 10:17:36 +0000 Subject: [PATCH 13/17] docs: comment on fallthrough switch case --- packages/client/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 7ae1ef191..b699e54f7 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -87,6 +87,7 @@ export class Client<$ extends DT.Meta> { }, () => {}, ) + // fallthrough case response.status < 200 || response.status > 299: throw new ResponseError(response) default: { From d879a5ff3bdd81cc8a4091de0fb44fde905f35fa Mon Sep 17 00:00:00 2001 From: John Wright Date: Tue, 17 Mar 2026 10:32:37 +0000 Subject: [PATCH 14/17] fix: correct exports for npm --- packages/api/package.json | 2 +- packages/client/package.json | 2 +- packages/date-range/package.json | 2 +- packages/explode/package.json | 2 +- packages/fs/package.json | 2 +- packages/json-schema/package.json | 4 ++-- packages/server/package.json | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 77cd98edc..f290659e2 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -8,7 +8,7 @@ "README.md" ], "type": "module", - "exports": "./src/index.ts", + "exports": "./dist/index.js", "scripts": { "check": "tsc --noEmit", "test": "bun test" diff --git a/packages/client/package.json b/packages/client/package.json index 03158122d..d3bd423cc 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -8,7 +8,7 @@ "README.md" ], "type": "module", - "exports": "./src/index.ts", + "exports": "./dist/index.js", "scripts": { "check": "tsc --noEmit", "test": "bun test" diff --git a/packages/date-range/package.json b/packages/date-range/package.json index a2b13dfdb..c9ecaa473 100644 --- a/packages/date-range/package.json +++ b/packages/date-range/package.json @@ -8,7 +8,7 @@ "README.md" ], "type": "module", - "exports": "./src/index.ts", + "exports": "./dist/index.js", "scripts": { "check": "tsc --noEmit", "test": "bun test" diff --git a/packages/explode/package.json b/packages/explode/package.json index 299189990..53335137f 100644 --- a/packages/explode/package.json +++ b/packages/explode/package.json @@ -8,7 +8,7 @@ "README.md" ], "type": "module", - "exports": "./src/index.ts", + "exports": "./dist/index.js", "scripts": { "check": "tsc --noEmit", "test": "bun test" diff --git a/packages/fs/package.json b/packages/fs/package.json index c8ee6c035..69b3bb274 100644 --- a/packages/fs/package.json +++ b/packages/fs/package.json @@ -8,7 +8,7 @@ "README.md" ], "type": "module", - "exports": "./src/index.ts", + "exports": "./dist/index.js", "scripts": { "check": "tsc --noEmit", "test": "bun test" diff --git a/packages/json-schema/package.json b/packages/json-schema/package.json index 9b31b20bd..054994f53 100644 --- a/packages/json-schema/package.json +++ b/packages/json-schema/package.json @@ -9,8 +9,8 @@ ], "type": "module", "exports": { - ".": "./src/index.ts", - "./cli": "./src/cli.ts" + ".": "./dist/index.js", + "./cli": "./dist/cli.js" }, "scripts": { "check": "tsc --noEmit", diff --git a/packages/server/package.json b/packages/server/package.json index 2aef0c45d..3f4a1172a 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -8,7 +8,7 @@ "README.md" ], "type": "module", - "exports": "./src/index.ts", + "exports": "./dist/index.js", "scripts": { "check": "tsc --noEmit", "test": "bun test" From 6f98bd032b050c779026c4e262f7b12dda0b0eff Mon Sep 17 00:00:00 2001 From: John Wright Date: Tue, 17 Mar 2026 10:49:47 +0000 Subject: [PATCH 15/17] chore: remove references to my directory structure --- packages/api/.vscode/launch.json | 9 ++------- packages/json-schema/.vscode/launch.json | 10 ++-------- packages/server/.vscode/launch.json | 10 ++-------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/packages/api/.vscode/launch.json b/packages/api/.vscode/launch.json index 8ab9aa1d6..64a5d3d2b 100644 --- a/packages/api/.vscode/launch.json +++ b/packages/api/.vscode/launch.json @@ -7,15 +7,10 @@ { "request": "launch", "name": "API Debug", - "type": "node", + "type": "bun", "cwd": "${workspaceFolder}", "env": {}, - "runtimeExecutable": "/Users/john.wright/.bun/bin/bun", - "runtimeArgs": [ - "--inspect-wait", - "test" - ], - "attachSimplePort": 9229 + "program": "${workspaceFolder}/test/Data.test.ts" } ] } diff --git a/packages/json-schema/.vscode/launch.json b/packages/json-schema/.vscode/launch.json index 9df82f2c0..eb709809f 100644 --- a/packages/json-schema/.vscode/launch.json +++ b/packages/json-schema/.vscode/launch.json @@ -7,16 +7,10 @@ { "request": "launch", "name": "JSON Schema Debug", - "type": "node", + "type": "bun", "cwd": "${workspaceFolder}", "env": {}, - "runtimeExecutable": "/Users/john.wright/.deno/bin/deno", - "runtimeArgs": [ - "test", - "--inspect-wait", - "--allow-all" - ], - "attachSimplePort": 9229 + "program": "${workspaceFolder}/test/index.test.ts" } ] } diff --git a/packages/server/.vscode/launch.json b/packages/server/.vscode/launch.json index 006d7b0c2..7f56aaddf 100644 --- a/packages/server/.vscode/launch.json +++ b/packages/server/.vscode/launch.json @@ -7,16 +7,10 @@ { "request": "launch", "name": "Test", - "type": "node", + "type": "bun", "program": "${workspaceFolder}/test/index.test.ts", "cwd": "${workspaceFolder}", - "env": {}, - "runtimeExecutable": "/Users/john.wright/.bun/bin/bun", - "runtimeArgs": [ - "run", - "--inspect-brk" - ], - "attachSimplePort": 9229 + "env": {} } ] } From 04e91af3ff9cdc929ea3562959c07d9baee3aaa8 Mon Sep 17 00:00:00 2001 From: John Wright Date: Tue, 17 Mar 2026 11:42:24 +0000 Subject: [PATCH 16/17] ci: install and building before packing --- .github/actions/install-build/action.yml | 10 ++++++++++ .github/actions/test/action.yml | 5 +---- .github/workflows/release.yml | 2 ++ 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 .github/actions/install-build/action.yml diff --git a/.github/actions/install-build/action.yml b/.github/actions/install-build/action.yml new file mode 100644 index 000000000..11d729411 --- /dev/null +++ b/.github/actions/install-build/action.yml @@ -0,0 +1,10 @@ +name: Install & Build +description: Install all dependencies and builds the app + +runs: + using: composite + steps: + - shell: bash + run: | # shell + bun install ----frozen-lockfile + bun run build diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index ad122549e..b8a9f02f2 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -5,10 +5,7 @@ description: Run checks and tests runs: using: composite steps: - - shell: bash - run: bun install --frozen-lockfile - - shell: bash - run: bun run build + - uses: ./.github/actions/install-build - shell: bash run: bun run lint - shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce45c9231..f9991334e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,6 +50,7 @@ jobs: id-token: write steps: - uses: actions/checkout@v6 + - uses: ./.github/actions/install-build - working-directory: ${{ matrix.path_released }} run: | bun pm pack --filename=$(pwd)/package.tgz @@ -72,6 +73,7 @@ jobs: id-token: write steps: - uses: actions/checkout@v6 + - uses: ./.github/actions/install-build - working-directory: ${{ matrix.path_released }} run: | # shell PACK="$(pwd)/package.tgz" From 02d8fcb27aabfc4a62d5ea3e29818b441a489cdb Mon Sep 17 00:00:00 2001 From: John Wright Date: Tue, 17 Mar 2026 11:51:47 +0000 Subject: [PATCH 17/17] ci: fix command --- .github/actions/install-build/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/install-build/action.yml b/.github/actions/install-build/action.yml index 11d729411..5e570406f 100644 --- a/.github/actions/install-build/action.yml +++ b/.github/actions/install-build/action.yml @@ -6,5 +6,5 @@ runs: steps: - shell: bash run: | # shell - bun install ----frozen-lockfile + bun install --frozen-lockfile bun run build