diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad4f105..24ffb47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,31 +6,73 @@ on: pull_request: jobs: - ci: - name: Node ${{ matrix.node }} + test: runs-on: ubuntu-latest - strategy: - matrix: - node: [22, 24] steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: 1.3.14 + + # Node is still a supported runtime and npm pack is part of the release + # contract. Pin both rather than relying on the runner image defaults. - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: - node-version: ${{ matrix.node }} - cache: npm + node-version: 22 - name: Install - run: npm ci + run: bun install --frozen-lockfile - name: Typecheck - run: npm run typecheck + run: bun run typecheck - name: Build - run: npm run build + run: bun run build - name: Test - run: npm test + run: bun test + + - name: Verify packed npm package + run: node scripts/check-package.mjs + + - name: Binary smoke test + run: scripts/smoke-binary.sh + + - name: Cross-compile all release targets + run: | + scripts/build-binaries.sh v0.0.0-ci + test "$(wc -l < dist/binaries/checksums.txt | tr -d ' ')" -eq 8 + (cd dist/binaries && shasum -a 256 -c checksums.txt) + + - name: Validate generated Homebrew formula + run: | + scripts/update-homebrew-formula.sh v0.0.0 dist/binaries/checksums.txt /tmp/workos-emulate.rb + ruby -c /tmp/workos-emulate.rb + + node-smoke: + name: Node ${{ matrix.node }} compatibility + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node: [22, 24] + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: 1.3.14 + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ matrix.node }} + + - name: Install + run: bun install --frozen-lockfile + + - name: Build + run: bun run build - - name: Pack - run: npm pack --dry-run + - name: Node library compatibility suite + run: node scripts/smoke-node.mjs diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index 116ad1e..87b8319 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -8,7 +8,7 @@ permissions: pull-requests: read jobs: - lint: + lint-pr-title: runs-on: ubuntu-latest steps: - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d66121c..d31a30d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,16 +11,15 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - node-version: 24 - cache: npm + bun-version: 1.3.14 - name: Install - run: npm ci + run: bun install --frozen-lockfile - name: Lint - run: npm run lint + run: bun run lint - name: Format check - run: npm run fmt:check + run: bun run fmt:check diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 0df21cb..2e0fa6f 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -28,3 +28,6 @@ jobs: uses: ./.github/workflows/release.yml with: tag_name: ${{ needs.release-please.outputs.tag_name }} + # The Homebrew job needs the SDK bot credentials. Passing all repository + # secrets also keeps workflow_dispatch retries equivalent to called runs. + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 68b3a4a..0664314 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,34 +1,212 @@ name: Release +# release-please creates the release and pushes its tag. This workflow builds +# every standalone target, executes the exact artifacts on native hardware, and +# uploads only binaries that pass. npm and Homebrew follow binary validation. on: workflow_call: inputs: tag_name: description: Release tag name (e.g., v0.12.0-beta.1) type: string - default: '' + required: true + secrets: + SDK_BOT_PRIVATE_KEY: + description: Private key for the org SDK bot GitHub App, used to mint a short-lived token scoped to workos/homebrew-tap + required: false + workflow_dispatch: + inputs: + tag_name: + description: Existing release tag to build and publish + type: string + required: true + +concurrency: + group: release-${{ inputs.tag_name }} + +permissions: + contents: read jobs: - publish: + build: + name: Build ${{ matrix.target }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - target: bun-darwin-arm64 + asset: workos-emulate-darwin-arm64 + - target: bun-darwin-x64-baseline + asset: workos-emulate-darwin-x64 + - target: bun-linux-x64-baseline + asset: workos-emulate-linux-x64 + - target: bun-linux-arm64 + asset: workos-emulate-linux-arm64 + - target: bun-linux-x64-musl-baseline + asset: workos-emulate-linux-x64-musl + - target: bun-linux-arm64-musl + asset: workos-emulate-linux-arm64-musl + - target: bun-windows-x64-baseline + asset: workos-emulate-windows-x64.exe + - target: bun-windows-arm64 + asset: workos-emulate-windows-arm64.exe + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.tag_name }} + + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: 1.3.14 + + - name: Install + run: bun install --frozen-lockfile + + - name: Build standalone binary + run: >- + bun build + --compile + --no-compile-autoload-dotenv + --no-compile-autoload-bunfig + --target="${{ matrix.target }}" + ./src/cli.ts + --outfile "dist/${{ matrix.asset }}" + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ matrix.asset }} + path: dist/${{ matrix.asset }} + if-no-files-found: error + retention-days: 1 + + smoke: + name: Smoke test ${{ matrix.asset }} + needs: build + strategy: + fail-fast: false + matrix: + include: + - asset: workos-emulate-darwin-arm64 + runner: macos-15 + - asset: workos-emulate-darwin-x64 + runner: macos-15-intel + - asset: workos-emulate-linux-x64 + runner: ubuntu-24.04 + - asset: workos-emulate-linux-arm64 + runner: ubuntu-24.04-arm + - asset: workos-emulate-linux-x64-musl + runner: ubuntu-24.04 + musl: true + - asset: workos-emulate-linux-arm64-musl + runner: ubuntu-24.04-arm + musl: true + - asset: workos-emulate-windows-x64.exe + runner: windows-latest + - asset: workos-emulate-windows-arm64.exe + runner: windows-11-arm + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.tag_name }} + + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ matrix.asset }} + path: dist/smoke + + # Bun ad-hoc signs cross-compiled Mach-O files. Inspect the signature for + # diagnostics; executing the exact artifact below is the hard gate. + - name: Inspect macOS code signature + if: startsWith(matrix.runner, 'macos') + run: codesign -dvvv "dist/smoke/${{ matrix.asset }}" || true + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + if: matrix.musl != true + with: + node-version: 22 + + - name: Run the binary + if: matrix.musl != true + shell: bash + env: + BINARY: dist/smoke/${{ matrix.asset }} + run: | + case "$BINARY" in + *.exe) ;; + *) chmod +x "$BINARY" ;; + esac + node scripts/smoke-binary.mjs "$BINARY" + + - name: Run the binary on musl + if: matrix.musl == true + env: + BINARY: dist/smoke/${{ matrix.asset }} + run: | + chmod +x "$BINARY" + docker run --rm \ + --volume "${PWD}/${BINARY}:/workos:ro" \ + --volume "${PWD}/scripts/smoke-binary.mjs:/smoke-binary.mjs:ro" \ + alpine:3.22 \ + sh -eu -c 'apk add --no-cache libstdc++ libgcc nodejs >/dev/null; + node /smoke-binary.mjs /workos' + + upload-binaries: + name: Upload release binaries + needs: [build, smoke] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + path: dist/binaries + merge-multiple: true + + - name: Generate checksums + working-directory: dist/binaries + run: | + test "$(find . -maxdepth 1 -type f -name 'workos-emulate-*' | wc -l | tr -d ' ')" -eq 8 + sha256sum workos-emulate-* > checksums.txt + + - name: Upload assets + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + TAG_NAME: ${{ inputs.tag_name }} + run: | + test -n "$TAG_NAME" + gh release upload "$TAG_NAME" dist/binaries/* --clobber + + publish-npm: name: Publish to npm + needs: upload-binaries runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.tag_name }} + + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: 1.3.14 + # npm publish --provenance (OIDC trusted publishing) is the deliberate + # npm exception to the Bun conversion — setup-node configures the registry. - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 24 registry-url: 'https://registry.npmjs.org' - cache: npm - name: Install - run: npm ci + run: bun install --frozen-lockfile - name: Build - run: npm run build + run: bun run build - name: Determine npm tag id: npm-tag @@ -36,11 +214,6 @@ jobs: TAG_NAME: ${{ inputs.tag_name }} run: | VERSION="${TAG_NAME#v}" - - if [[ -z "$VERSION" ]]; then - VERSION="$(node -p "require('./package.json').version")" - fi - if [[ "$VERSION" == *"-"* ]]; then echo "tag=beta" >> "$GITHUB_OUTPUT" else @@ -48,7 +221,76 @@ jobs: fi - name: Publish + env: + TAG_NAME: ${{ inputs.tag_name }} run: | sed -i '/_authToken/d' "$NPM_CONFIG_USERCONFIG" unset NODE_AUTH_TOKEN + + VERSION="${TAG_NAME#v}" + PACKAGE_NAME="$(node -p "require('./package.json').name")" + PACKAGE_VERSION="$(node -p "require('./package.json').version")" + test "$PACKAGE_VERSION" = "$VERSION" + + if npm view "$PACKAGE_NAME@$VERSION" version >/dev/null 2>&1; then + echo "$PACKAGE_NAME@$VERSION already published; skipping" + exit 0 + fi + npm publish --tag ${{ steps.npm-tag.outputs.tag }} --access public --provenance + + homebrew: + name: Update Homebrew formula + runs-on: macos-15 + needs: upload-binaries + # Homebrew only ships stable releases; prerelease tags skip the bump. + if: ${{ !contains(inputs.tag_name, '-') }} + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.tag_name }} + + - name: Generate a tap-scoped token + id: tap-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + app-id: ${{ vars.SDK_BOT_APP_ID }} + private-key: ${{ secrets.SDK_BOT_PRIVATE_KEY }} + owner: workos + repositories: homebrew-tap + permission-contents: write + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: workos/homebrew-tap + token: ${{ steps.tap-token.outputs.token }} + path: homebrew-tap + + # Re-download the published checksum file so the formula can never drift + # from the assets users actually receive. + - name: Download checksums from the release + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + TAG_NAME: ${{ inputs.tag_name }} + run: gh release download "$TAG_NAME" --pattern checksums.txt --dir dist/binaries + + - name: Update formula and push + env: + TAG_NAME: ${{ inputs.tag_name }} + run: | + scripts/update-homebrew-formula.sh "$TAG_NAME" dist/binaries/checksums.txt homebrew-tap/Formula/workos-emulate.rb + ruby -c homebrew-tap/Formula/workos-emulate.rb + brew style homebrew-tap/Formula/workos-emulate.rb + cd homebrew-tap + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add Formula/workos-emulate.rb + if git diff --staged --quiet; then + echo "Formula already up to date for ${TAG_NAME}; nothing to push" + else + git commit -m "workos-emulate ${TAG_NAME}" + git push + fi diff --git a/.gitignore b/.gitignore index 6761199..2f485b8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules dist coverage .DS_Store +*.bun-build diff --git a/.husky/pre-push b/.husky/pre-push index f0ada5f..c8be0d9 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,5 +1,5 @@ #!/usr/bin/env sh # Mirror the CI lint workflow so a push never fails checks it could have caught locally. -npm run lint -npm run fmt:check +bun run lint +bun run fmt:check diff --git a/README.md b/README.md index 1a265a5..1bf4dcd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,63 @@ Local WorkOS API emulator for tests and development. +## Installation + +### Homebrew (macOS and Linux) + +```bash +brew install workos/tap/workos-emulate +``` + +### Direct binary download + +Self-contained executables for supported macOS, Linux, and Windows targets are attached to each +[GitHub release](https://github.com/workos/emulate/releases) — no Node, npm, or Bun required. Intel +and x64 builds use Bun's baseline target for compatibility with older CPUs. + +```bash +# macOS (Apple Silicon) +curl -fsSL -o workos-emulate https://github.com/workos/emulate/releases/latest/download/workos-emulate-darwin-arm64 +chmod +x workos-emulate + +# macOS (Intel) +curl -fsSL -o workos-emulate https://github.com/workos/emulate/releases/latest/download/workos-emulate-darwin-x64 +chmod +x workos-emulate + +# Linux with glibc (x64) +curl -fsSL -o workos-emulate https://github.com/workos/emulate/releases/latest/download/workos-emulate-linux-x64 +chmod +x workos-emulate + +# Linux with glibc (arm64) +curl -fsSL -o workos-emulate https://github.com/workos/emulate/releases/latest/download/workos-emulate-linux-arm64 +chmod +x workos-emulate + +# Alpine Linux / musl (x64) +curl -fsSL -o workos-emulate https://github.com/workos/emulate/releases/latest/download/workos-emulate-linux-x64-musl +chmod +x workos-emulate + +# Alpine Linux / musl (arm64) +curl -fsSL -o workos-emulate https://github.com/workos/emulate/releases/latest/download/workos-emulate-linux-arm64-musl +chmod +x workos-emulate +``` + +On Windows, download `workos-emulate-windows-x64.exe` or `workos-emulate-windows-arm64.exe` from +the [latest release](https://github.com/workos/emulate/releases/latest) and run it directly (there +is no Homebrew path for Windows). + +Each release also ships a `checksums.txt` with the SHA-256 of every binary. + +### npm + +For JavaScript projects (or one-off runs via npx): + +```bash +npm install --save-dev @workos/emulate + +# or run without installing +npx @workos/emulate +``` + ## CLI ```bash @@ -9,11 +66,18 @@ workos-emulate workos-emulate --port 9100 --json workos-emulate --seed workos-emulate.config.yaml workos-emulate --interactive # serve login pages for E2E browser testing +workos-emulate --version ``` The emulator defaults to `http://localhost:4100` and the API key `sk_test_default`. Use `GET /health` for readiness checks. +In an interactive terminal, the CLI checks for new stable releases without delaying startup. npm +installations follow the npm registry; Homebrew and direct-download installations follow GitHub +Releases after their checksums are available. Set `NO_UPDATE_NOTIFIER=1` or +`WORKOS_EMULATE_DISABLE_UPDATE_CHECK=1` to disable the check. JSON output, CI, and non-interactive +invocations never perform it. + ## Using from Any Language The emulator is a plain HTTP server, so any language can use it — just point your WorkOS SDK's base URL at the emulator instead of `https://api.workos.com`. @@ -700,3 +764,18 @@ The WorkOS Emulator is designed for testing and development environments. When u - **Use environment variables**: Store sensitive configuration (API keys, secrets) in environment variables. - **Regular updates**: Keep the emulator updated to get security fixes and improvements. - **Network isolation**: Run the emulator in an isolated network environment when possible. + +## Development + +The repository uses Bun 1.3.14, pinned by the `packageManager` field in `package.json`. + +```bash +bun install --frozen-lockfile +bun run typecheck +bun test +bun run build +``` + +`bun run test:coverage` writes text output and `coverage/lcov.info`. `bun run build:binary` produces +a standalone executable for the current platform, while `scripts/build-binaries.sh ` builds +every release target. diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..d4decb4 --- /dev/null +++ b/bun.lock @@ -0,0 +1,275 @@ +{ + "lockfileVersion": 1, + "configVersion": 0, + "workspaces": { + "": { + "name": "@workos/emulate", + "dependencies": { + "@hono/node-server": "^1", + "chalk": "^5.6.2", + "hono": "^4", + "semver": "^7.7.4", + "yaml": "^2.8.2", + }, + "devDependencies": { + "@types/bun": "^1.3.14", + "@types/node": "~22.19.7", + "@types/semver": "^7.7.1", + "@workos/openapi-spec": "^0.41.0", + "husky": "^9.1.7", + "oxfmt": "^0.54.0", + "oxlint": "^1.69.0", + "typescript": "^5.9.3", + }, + }, + }, + "packages": { + "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], + + "@hono/node-server": ["@hono/node-server@1.19.14", "", { "peerDependencies": { "hono": "^4" } }, "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw=="], + + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.54.0", "", { "os": "android", "cpu": "arm" }, "sha512-NAtpl/SiaeU103e7/OmZw0MvUnsUUopW7hEm/ecegJg7YM0skQaA0IXEZoyTV6NUdiNPupdIUreRqUZTShbn/g=="], + + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.54.0", "", { "os": "android", "cpu": "arm64" }, "sha512-B4VZfBUlKK1rmMChsssNZbkZjE8+FzG3avMjGgMDwbGxXRoXkoeXiAZ+78Oa+eyDPHvDCiUb4zH/vmCOUSafLQ=="], + + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.54.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-i02vF75b+ePsQP3tHqSxVYI5S6b8X/xqdPu7/mDHXtpgXLTYXi3jJmfHU0j+dnZZDKaYTx/ioCK7QYJmtiJR2g=="], + + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.54.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8VMFvGvooXj7mswkbrhdVZ2/sgiDaBzWpkkbtO+qGDLV4EfJd67nQadHkQC0ZNbaWA9ajXfqI6i7PZLIeDzxEQ=="], + + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.54.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0cRHnp43WN1Jrc5s0BdbdKgR1XirdvHy7TAFi3JEsoEVQVJxTXMbpVd76sxXlgRswNMDhVFSJw+y7Eb8mEavFQ=="], + + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.54.0", "", { "os": "linux", "cpu": "arm" }, "sha512-JyQAk3hK/OEtup7Rw6kZwfdzbKqTVD5jXXb8Xpfay29suwZyfBDMVW/bj4RqEPySYWc6zCp198pOluf8n5uYzg=="], + + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.54.0", "", { "os": "linux", "cpu": "arm" }, "sha512-qnvLatTpM8vtvjOfcckBOzJjk+n6ce/wwpP8OFeUrD5aNLYcKyWAitwj+Rk3PK9jGanbZvKsJnv14JGQ6XqFdw=="], + + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-SMkhnCzIYZYDk9vw3W/80eeYKmrMpGF0Giuxt4HruFlCH7jEtnPeb3SdQKMfgYi/dgtaf+hZAb5XWPYnxqCQ3w=="], + + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-QrwJlBFFKnxOd95TAaszpMbZBLzMoYMpGaQTZF8oibacnF5rv8l12IhILhQRPmksWiBqg0YSe2Mnl7ayeJAHSA=="], + + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.54.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-WILatiol/TUHTlhod7R09+7Az/XlhKwmY1MHfLZNmewltPWNN/EwxP2rQSHahibZ/cB8gmckEBjBOByD+5bYsQ=="], + + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-f05YMG4BH4G8S4ME6UM6fi1MnJ9094mrnvO5Pa4SJlMfWlUM+1/ZWMEF4NnjM7shZAvbHsHRuVYpUo0PHC4P9Q=="], + + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-UfL+2hj1ClNqcCRT9s8vBU4axDpjxgVxX96G+9DYAYjoc5b0u15CJtn2jgsi9iM+EbGNc5CW1HVRgwVu76UsSA=="], + + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.54.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-3/XZe931Hka+J6NjnaqJzYpsWWxDTuRdUdwSQHnOuJEgbC+SehIMFJS8hsEjV7LBhVSL2OCnRLvbVW8O97XIyw=="], + + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Ik93RlObtu43GbxApafayFjwYE06L6Xr08cSwpBPYbDrLp2ReZx0Jm1DqwRyYRnukUJy+rK2WaEvUQOxdytU9Q=="], + + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-yZcakmPlD86CNymknd7KfW+FH+qfbqJH+i0h69CYfV1+KMoVeM9UED+8+TDVoU4haxI0NxY7RPCvRLy3Sqd2Qg=="], + + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.54.0", "", { "os": "none", "cpu": "arm64" }, "sha512-GiVBZNnEZnKu00f1jTg49nomv187d0GQX+O+ocykoLeiaALuEO+swoTehHn9TehTfi7V8H0i0e/yvUjCqnwk1w=="], + + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.54.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-J0SSB8Z1Fre2sxRolYcW6Rl1RQmKdQ2hnHyq4YJrfBRiXTObLw4DXnIVraM/UyqGqwOi7yTrQA4VT7DPxlHVKA=="], + + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.54.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-O61UDVj8zz6yXJjkHPf05VaMLOXmEF8P5kf/N0W7AQMmd6bcQogl+KJc7rMutKTL524oE9iH32JXZClBFmEQIg=="], + + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.54.0", "", { "os": "win32", "cpu": "x64" }, "sha512-1MDpqJPiFqxWtIHas8vkb1VZ7f7eKyTffAwmO8isxQYMaG1OFKsH666BWLeXQLO+IWNfiMssLD55hbR1lIPTqg=="], + + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.69.0", "", { "os": "android", "cpu": "arm" }, "sha512-DKQQbD5cZ/MYfDgDI7YGyGD9FSxABlsBsYFo5p26lloob543tP9+4N3guwdXIYJN+7HSZxLe8YJuwcOWw5qnHg=="], + + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.69.0", "", { "os": "android", "cpu": "arm64" }, "sha512-lEhb+I5pr4inux+JFwfCa1HRq3Os7NirEFQ0H1I35SVEHPm6byX0Ah47xmRha3qi6LAkxUcxViL8o/9PivjzBg=="], + + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.69.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GY2YE8lOZW59BW1Ia1y+1gR0XyjrZRvVWHAr8LGeGhYHE0OQJ/7cRKXTkx1P+E9/6awEc3SX8a68SFTjh/E//A=="], + + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.69.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ax1oZnOjHX3LB7myQyHEaQkDwfLb6str3/nSP6O7EVUviQGNkEGzGV0EqcBJWK+Ufwx0l4xPgyYayurvhAdl2Q=="], + + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.69.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kHWeHv4g2h8NY+mpCxzCtY4uerMJWTN/TSnNj1CPbakFpHEJ6cTya2wWV0pDSYWOJ2+0UiEbhn3AtXxHtsnKjg=="], + + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.69.0", "", { "os": "linux", "cpu": "arm" }, "sha512-gq84vM1a1oEehXo27YCDzGVcxPsZDI1yswZwz2Da1/cbnWtrL16XZZnz0G/+gIU8edtHpfjxq5c+vWEHqJfWoQ=="], + + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.69.0", "", { "os": "linux", "cpu": "arm" }, "sha512-kIqEa98JQ0VRyrcncxA417m2AzasqTlD+FyVT1AksjvjkqQcvm7pBWYvoW3/mpyOP2XYvi5nSCCTIe6De1yu5g=="], + + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.69.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-j+xYiXozxGWx2cpjCrwwGR4awTxPFsRv3JZrv23RCogEPMc4R7UqjHW47p/RG0aRlbWiROCJ8coUfCwy0dvzHA=="], + + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.69.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-xEPpNppTfN1l/nM7gYSf9iocscu/as+p/7vxkLeLEKnYU+09Dm+5V6IhDYDh+Uz6FajEupWwCLt5SOG0y1PCKg=="], + + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.69.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Ug0+eU7HJBlek+SjklYH62IlOMirEJsdxpihH0kSqX0XdrDD4NdHpQc10fK1JC35yn6KrrcN+uYzlHD38XAf8Q=="], + + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.69.0", "", { "os": "linux", "cpu": "none" }, "sha512-iEyI3GIg0l/s3G4qy2TlaaWKdzj4PJJStwtlocpDTC00PY9hZueotf6OKUj9+yfQh0lrpBW/pLMgTztbAHKJEg=="], + + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.69.0", "", { "os": "linux", "cpu": "none" }, "sha512-NjHjpiI4WIKSMwuoJSZi5VToPeoYOS1FR52HLIDG6lidMdqquusgtODb4iLk0+lb1q3Z0nv2/aPRcC/olmpQGg=="], + + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.69.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Ai/prDewoItkDXbp38gwGZi41DycZbUTZJ3UidwoHgQC0/DaqC2TGdtBTQLJ6hSD+SAxASzh8+/eSBPmxfOacA=="], + + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.69.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Gt3KHgp46mRKz4sJeaASmKvD8ayXookRw07RMf+NowhEztGGDZ7VrXpoW96XuKJLjFukWizOFVNjmYb/u7caNQ=="], + + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.69.0", "", { "os": "linux", "cpu": "x64" }, "sha512-7tQhJ2+p/oHv1zcfnjYI7YVzC/7iBaVOfIvFYtxdJ5F45mWgEdrCyXZXZGfiLey5t/5JhOhsaMnnv1kAzckd7g=="], + + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.69.0", "", { "os": "none", "cpu": "arm64" }, "sha512-vmWz6TKp/3hfA4lksR0zHBv/6xuX1jhym6eqOjdH2DXsDDHZWcp2f0KG0VCAnlVbIrjk29G4wAWMXb/Hn1YobA=="], + + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.69.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-9RExaLgmaw6IoIkU9cTpT71mLfI0xZ86iZH8x518LVsOkjquJMYqb9P7KpC8lgd1t0Dxs41p2pxynq4XR3Ttzw=="], + + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.69.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-1907kRPF8/PrcIw1E7LMs9JbVrpgnt/MvFdss3an8oDkYNAACXzTntV3t3869ZZhMZxb2AzRGbz1pA/jdFatXA=="], + + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.69.0", "", { "os": "win32", "cpu": "x64" }, "sha512-w8SOXv3mT9Fi6jY8OXdXCfnvX/3KNLXGNr4HEz2TA7S4Mv/PYAOmpB8y/ge40mxvBMgGNaSaaDwZpAsQn7HtWA=="], + + "@redocly/ajv": ["@redocly/ajv@8.18.3", "", { "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-l42u0of3hY98sN2A+M4qTX1O/KrpgGH32Hu9kP2GtHyD5Dfqq86PKFLe5dwaD8DEnNmlOlll2BAmeEtf0DaySg=="], + + "@redocly/config": ["@redocly/config@0.51.0", "", { "dependencies": { "json-schema-to-ts": "2.7.2" } }, "sha512-XoSkEN28ojqvF1fP8mhOlzHPowpr1/jkvbo3qXKIKXG8RqTiQkLCGTvYdMBjcagEheFFXAsaJKM/GMdoczd4Zg=="], + + "@redocly/openapi-core": ["@redocly/openapi-core@2.39.0", "", { "dependencies": { "@redocly/ajv": "^8.18.1", "@redocly/config": "^0.51.0", "ajv": "npm:@redocly/ajv@8.18.1", "ajv-formats": "^3.0.1", "colorette": "^1.2.0", "graphql": "^16.14.1", "js-levenshtein": "^1.1.6", "js-yaml": "^4.2.0", "picomatch": "^4.0.4", "pluralize": "^8.0.0", "yaml-ast-parser": "0.0.43" } }, "sha512-sACPZX1LUf/GLdZ7xyYV7dgZ73gRzi0TVgNXME5OGKVEHPeNv8z91v2KYhuJso8XJ+E5EVpwBU02UEkrKvSycA=="], + + "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], + + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + + "@types/node": ["@types/node@22.19.19", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew=="], + + "@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="], + + "@workos/oagen": ["@workos/oagen@0.25.1", "", { "dependencies": { "@redocly/openapi-core": "^2.25.1", "commander": "^13.1.0", "dotenv": "^17.3.1", "tree-sitter": "^0.21.1", "tree-sitter-c-sharp": "0.23.1", "tree-sitter-elixir": "^0.3.5", "tree-sitter-go": "^0.23.4", "tree-sitter-kotlin": "github:fwcd/tree-sitter-kotlin#f66d2908542e93c0204c6c241f794afe4e9cd5d1", "tree-sitter-php": "^0.23.12", "tree-sitter-python": "^0.21.0", "tree-sitter-ruby": "^0.21.0", "tree-sitter-rust": "^0.21.0", "tree-sitter-typescript": "^0.23.2", "tsx": "^4.19.0", "typescript": "^6.0.0" }, "bin": { "oagen": "dist/cli/index.mjs" } }, "sha512-AAimhzErMB2GazAe8iqo2KudBj4Zo27fX3XRrtOn/EfnXvh1cioPXfd97FLc9F/KnJrkncIrJbN23JhmwMihBA=="], + + "@workos/openapi-spec": ["@workos/openapi-spec@0.41.0", "", { "dependencies": { "@workos/oagen": "^0.25.0" } }, "sha512-6Ic94jnpf0wHgwigjcdQtV7IQG5P6si8GPoGC88uDMJb2MqgZablQ6KbpzVzP0hwX/ZmHSSBGZgpsA2iUGXzmw=="], + + "ajv": ["@redocly/ajv@8.18.1", "", { "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-Ifm/pP/tul1qmAecpbVxCBluVE32rKfjf8gYXH4xI2gCv9mRWFhJMHzkPDM4TXlxwPQYIFegymlsy8lXz7optA=="], + + "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" }, "peerDependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], + + "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "colorette": ["colorette@1.4.0", "", {}, "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="], + + "commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], + + "dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], + + "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": "bin/esbuild" }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-uri": ["fast-uri@3.1.4", "", {}, "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "graphql": ["graphql@16.14.2", "", {}, "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA=="], + + "hono": ["hono@4.12.26", "", {}, "sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw=="], + + "husky": ["husky@9.1.7", "", { "bin": "bin.js" }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], + + "js-levenshtein": ["js-levenshtein@1.1.6", "", {}, "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g=="], + + "js-yaml": ["js-yaml@4.3.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="], + + "json-schema-to-ts": ["json-schema-to-ts@2.7.2", "", { "dependencies": { "@babel/runtime": "^7.18.3", "@types/json-schema": "^7.0.9", "ts-algebra": "^1.2.0" } }, "sha512-R1JfqKqbBR4qE8UyBR56Ms30LL62/nlhoz+1UkfI/VE7p54Awu919FZ6ZUPG8zIa3XB65usPJgr1ONVncUGSaQ=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "node-addon-api": ["node-addon-api@8.9.0", "", {}, "sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q=="], + + "node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="], + + "oxfmt": ["oxfmt@0.54.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.54.0", "@oxfmt/binding-android-arm64": "0.54.0", "@oxfmt/binding-darwin-arm64": "0.54.0", "@oxfmt/binding-darwin-x64": "0.54.0", "@oxfmt/binding-freebsd-x64": "0.54.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.54.0", "@oxfmt/binding-linux-arm-musleabihf": "0.54.0", "@oxfmt/binding-linux-arm64-gnu": "0.54.0", "@oxfmt/binding-linux-arm64-musl": "0.54.0", "@oxfmt/binding-linux-ppc64-gnu": "0.54.0", "@oxfmt/binding-linux-riscv64-gnu": "0.54.0", "@oxfmt/binding-linux-riscv64-musl": "0.54.0", "@oxfmt/binding-linux-s390x-gnu": "0.54.0", "@oxfmt/binding-linux-x64-gnu": "0.54.0", "@oxfmt/binding-linux-x64-musl": "0.54.0", "@oxfmt/binding-openharmony-arm64": "0.54.0", "@oxfmt/binding-win32-arm64-msvc": "0.54.0", "@oxfmt/binding-win32-ia32-msvc": "0.54.0", "@oxfmt/binding-win32-x64-msvc": "0.54.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": "bin/oxfmt" }, "sha512-DjnMwn7smSLF+Mc2+pRItnuPftm/dkUFpY/d4+33y9TfKrsHZo8GLhmUg9BrOIUEy94Rlom1Q11N6vuhE+e0oQ=="], + + "oxlint": ["oxlint@1.69.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.69.0", "@oxlint/binding-android-arm64": "1.69.0", "@oxlint/binding-darwin-arm64": "1.69.0", "@oxlint/binding-darwin-x64": "1.69.0", "@oxlint/binding-freebsd-x64": "1.69.0", "@oxlint/binding-linux-arm-gnueabihf": "1.69.0", "@oxlint/binding-linux-arm-musleabihf": "1.69.0", "@oxlint/binding-linux-arm64-gnu": "1.69.0", "@oxlint/binding-linux-arm64-musl": "1.69.0", "@oxlint/binding-linux-ppc64-gnu": "1.69.0", "@oxlint/binding-linux-riscv64-gnu": "1.69.0", "@oxlint/binding-linux-riscv64-musl": "1.69.0", "@oxlint/binding-linux-s390x-gnu": "1.69.0", "@oxlint/binding-linux-x64-gnu": "1.69.0", "@oxlint/binding-linux-x64-musl": "1.69.0", "@oxlint/binding-openharmony-arm64": "1.69.0", "@oxlint/binding-win32-arm64-msvc": "1.69.0", "@oxlint/binding-win32-ia32-msvc": "1.69.0", "@oxlint/binding-win32-x64-msvc": "1.69.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": "bin/oxlint" }, "sha512-ypZkK/aDc5NQV8zIR6s2H2Tl3aNW8FmJ1m9+2qsaYuRenl8vgnHNCGwTHviWJdUQzglOlHFchgopdtGhSy17Rw=="], + + "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + + "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], + + "tree-sitter": ["tree-sitter@0.21.1", "", { "dependencies": { "node-addon-api": "^8.0.0", "node-gyp-build": "^4.8.0" } }, "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ=="], + + "tree-sitter-c-sharp": ["tree-sitter-c-sharp@0.23.1", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "sha512-9zZ4FlcTRWWfRf6f4PgGhG8saPls6qOOt75tDfX7un9vQZJmARjPrAC6yBNCX2T/VKcCjIDbgq0evFaB3iGhQw=="], + + "tree-sitter-elixir": ["tree-sitter-elixir@0.3.5", "", { "dependencies": { "node-addon-api": "^7.1.0", "node-gyp-build": "^4.8.0" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-xozQMvYK0aSolcQZAx2d84Xe/YMWFuRPYFlLVxO01bM2GITh5jyiIp0TqPCQa8754UzRAI7A83hZmfiYub5TZQ=="], + + "tree-sitter-go": ["tree-sitter-go@0.23.4", "", { "dependencies": { "node-addon-api": "^8.2.1", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "sha512-iQaHEs4yMa/hMo/ZCGqLfG61F0miinULU1fFh+GZreCRtKylFLtvn798ocCZjO2r/ungNZgAY1s1hPFyAwkc7w=="], + + "tree-sitter-javascript": ["tree-sitter-javascript@0.23.1", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "sha512-/bnhbrTD9frUYHQTiYnPcxyHORIw157ERBa6dqzaKxvR/x3PC4Yzd+D1pZIMS6zNg2v3a8BZ0oK7jHqsQo9fWA=="], + + "tree-sitter-kotlin": ["tree-sitter-kotlin@git+ssh://git@github.com/fwcd/tree-sitter-kotlin.git#f66d2908542e93c0204c6c241f794afe4e9cd5d1", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "f66d2908542e93c0204c6c241f794afe4e9cd5d1", "sha512-onbogYgMICW34xos1mQNJEKnoq+m643z9MBC+AYa7mn4mH/KU4VJZnMVLcTViUErJ8h99KTRQbPH6wPlQLpepg=="], + + "tree-sitter-php": ["tree-sitter-php@0.23.12", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "sha512-VwkBVOahhC2NYXK/Fuqq30NxuL/6c2hmbxEF4jrB7AyR5rLc7nT27mzF3qoi+pqx9Gy2AbXnGezF7h4MeM6YRA=="], + + "tree-sitter-python": ["tree-sitter-python@0.21.0", "", { "dependencies": { "node-addon-api": "^7.1.0", "node-gyp-build": "^4.8.0" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-IUKx7JcTVbByUx1iHGFS/QsIjx7pqwTMHL9bl/NGyhyyydbfNrpruo2C7W6V4KZrbkkCOlX8QVrCoGOFW5qecg=="], + + "tree-sitter-ruby": ["tree-sitter-ruby@0.21.0", "", { "dependencies": { "node-addon-api": "^8.0.0", "node-gyp-build": "^4.8.1" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-UrMpF9CZxKbZ5UFuPdXDuraaaYSMMlAiuzTpQXwNm7y0D48ibc9stWU5D6vDyJD0qf5/R+3yKTYHdHkqibmLSQ=="], + + "tree-sitter-rust": ["tree-sitter-rust@0.21.0", "", { "dependencies": { "node-addon-api": "^7.1.0", "node-gyp-build": "^4.8.0" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "sha512-unVr73YLn3VC4Qa/GF0Nk+Wom6UtI526p5kz9Rn2iZSqwIFedyCZ3e0fKCEmUJLIPGrTb/cIEdu3ZUNGzfZx7A=="], + + "tree-sitter-typescript": ["tree-sitter-typescript@0.23.2", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2", "tree-sitter-javascript": "^0.23.1" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-e04JUUKxTT53/x3Uq1zIL45DoYKVfHH4CZqwgZhPg5qYROl5nQjV+85ruFzFGZxu+QeFVbRTPDRnqL9UbU4VeA=="], + + "ts-algebra": ["ts-algebra@1.2.2", "", {}, "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA=="], + + "tsx": ["tsx@4.22.3", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": "dist/cli.mjs" }, "sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "yaml": ["yaml@2.9.0", "", { "bin": "bin.mjs" }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + + "yaml-ast-parser": ["yaml-ast-parser@0.0.43", "", {}, "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A=="], + + "@workos/oagen/typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "tree-sitter-elixir/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "tree-sitter-python/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "tree-sitter-rust/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + } +} diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..dce222d --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,5 @@ +[test] +coverageReporter = ["text", "lcov"] +coverageDir = "coverage" +coverageSkipTestFiles = true +coveragePathIgnorePatterns = ["dist/**"] diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 15f1f97..0000000 --- a/package-lock.json +++ /dev/null @@ -1,3513 +0,0 @@ -{ - "name": "@workos/emulate", - "version": "0.3.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@workos/emulate", - "version": "0.3.0", - "license": "MIT", - "dependencies": { - "@hono/node-server": "^1", - "chalk": "^5.6.2", - "hono": "^4", - "yaml": "^2.8.2" - }, - "bin": { - "workos-emulate": "dist/cli.js" - }, - "devDependencies": { - "@types/node": "~22.19.7", - "@vitest/coverage-v8": "^4.0.18", - "@workos/openapi-spec": "^0.41.0", - "husky": "^9.1.7", - "oxfmt": "^0.54.0", - "oxlint": "^1.69.0", - "tsx": "^4.20.3", - "typescript": "^5.9.3", - "vitest": "^4.0.18" - }, - "engines": { - "node": ">=22.11" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", - "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.7" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", - "license": "MIT", - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "hono": "^4" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", - "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" - } - }, - "node_modules/@oxc-project/types": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", - "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@oxfmt/binding-android-arm-eabi": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.54.0.tgz", - "integrity": "sha512-NAtpl/SiaeU103e7/OmZw0MvUnsUUopW7hEm/ecegJg7YM0skQaA0IXEZoyTV6NUdiNPupdIUreRqUZTShbn/g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-android-arm64": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.54.0.tgz", - "integrity": "sha512-B4VZfBUlKK1rmMChsssNZbkZjE8+FzG3avMjGgMDwbGxXRoXkoeXiAZ+78Oa+eyDPHvDCiUb4zH/vmCOUSafLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-darwin-arm64": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.54.0.tgz", - "integrity": "sha512-i02vF75b+ePsQP3tHqSxVYI5S6b8X/xqdPu7/mDHXtpgXLTYXi3jJmfHU0j+dnZZDKaYTx/ioCK7QYJmtiJR2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-darwin-x64": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.54.0.tgz", - "integrity": "sha512-8VMFvGvooXj7mswkbrhdVZ2/sgiDaBzWpkkbtO+qGDLV4EfJd67nQadHkQC0ZNbaWA9ajXfqI6i7PZLIeDzxEQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-freebsd-x64": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.54.0.tgz", - "integrity": "sha512-0cRHnp43WN1Jrc5s0BdbdKgR1XirdvHy7TAFi3JEsoEVQVJxTXMbpVd76sxXlgRswNMDhVFSJw+y7Eb8mEavFQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.54.0.tgz", - "integrity": "sha512-JyQAk3hK/OEtup7Rw6kZwfdzbKqTVD5jXXb8Xpfay29suwZyfBDMVW/bj4RqEPySYWc6zCp198pOluf8n5uYzg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-arm-musleabihf": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.54.0.tgz", - "integrity": "sha512-qnvLatTpM8vtvjOfcckBOzJjk+n6ce/wwpP8OFeUrD5aNLYcKyWAitwj+Rk3PK9jGanbZvKsJnv14JGQ6XqFdw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-arm64-gnu": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.54.0.tgz", - "integrity": "sha512-SMkhnCzIYZYDk9vw3W/80eeYKmrMpGF0Giuxt4HruFlCH7jEtnPeb3SdQKMfgYi/dgtaf+hZAb5XWPYnxqCQ3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-arm64-musl": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.54.0.tgz", - "integrity": "sha512-QrwJlBFFKnxOd95TAaszpMbZBLzMoYMpGaQTZF8oibacnF5rv8l12IhILhQRPmksWiBqg0YSe2Mnl7ayeJAHSA==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-ppc64-gnu": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.54.0.tgz", - "integrity": "sha512-WILatiol/TUHTlhod7R09+7Az/XlhKwmY1MHfLZNmewltPWNN/EwxP2rQSHahibZ/cB8gmckEBjBOByD+5bYsQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-riscv64-gnu": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.54.0.tgz", - "integrity": "sha512-f05YMG4BH4G8S4ME6UM6fi1MnJ9094mrnvO5Pa4SJlMfWlUM+1/ZWMEF4NnjM7shZAvbHsHRuVYpUo0PHC4P9Q==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-riscv64-musl": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.54.0.tgz", - "integrity": "sha512-UfL+2hj1ClNqcCRT9s8vBU4axDpjxgVxX96G+9DYAYjoc5b0u15CJtn2jgsi9iM+EbGNc5CW1HVRgwVu76UsSA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-s390x-gnu": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.54.0.tgz", - "integrity": "sha512-3/XZe931Hka+J6NjnaqJzYpsWWxDTuRdUdwSQHnOuJEgbC+SehIMFJS8hsEjV7LBhVSL2OCnRLvbVW8O97XIyw==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-x64-gnu": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.54.0.tgz", - "integrity": "sha512-Ik93RlObtu43GbxApafayFjwYE06L6Xr08cSwpBPYbDrLp2ReZx0Jm1DqwRyYRnukUJy+rK2WaEvUQOxdytU9Q==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-x64-musl": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.54.0.tgz", - "integrity": "sha512-yZcakmPlD86CNymknd7KfW+FH+qfbqJH+i0h69CYfV1+KMoVeM9UED+8+TDVoU4haxI0NxY7RPCvRLy3Sqd2Qg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-openharmony-arm64": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.54.0.tgz", - "integrity": "sha512-GiVBZNnEZnKu00f1jTg49nomv187d0GQX+O+ocykoLeiaALuEO+swoTehHn9TehTfi7V8H0i0e/yvUjCqnwk1w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-win32-arm64-msvc": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.54.0.tgz", - "integrity": "sha512-J0SSB8Z1Fre2sxRolYcW6Rl1RQmKdQ2hnHyq4YJrfBRiXTObLw4DXnIVraM/UyqGqwOi7yTrQA4VT7DPxlHVKA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-win32-ia32-msvc": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.54.0.tgz", - "integrity": "sha512-O61UDVj8zz6yXJjkHPf05VaMLOXmEF8P5kf/N0W7AQMmd6bcQogl+KJc7rMutKTL524oE9iH32JXZClBFmEQIg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-win32-x64-msvc": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.54.0.tgz", - "integrity": "sha512-1MDpqJPiFqxWtIHas8vkb1VZ7f7eKyTffAwmO8isxQYMaG1OFKsH666BWLeXQLO+IWNfiMssLD55hbR1lIPTqg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-android-arm-eabi": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.69.0.tgz", - "integrity": "sha512-DKQQbD5cZ/MYfDgDI7YGyGD9FSxABlsBsYFo5p26lloob543tP9+4N3guwdXIYJN+7HSZxLe8YJuwcOWw5qnHg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-android-arm64": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.69.0.tgz", - "integrity": "sha512-lEhb+I5pr4inux+JFwfCa1HRq3Os7NirEFQ0H1I35SVEHPm6byX0Ah47xmRha3qi6LAkxUcxViL8o/9PivjzBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-darwin-arm64": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.69.0.tgz", - "integrity": "sha512-GY2YE8lOZW59BW1Ia1y+1gR0XyjrZRvVWHAr8LGeGhYHE0OQJ/7cRKXTkx1P+E9/6awEc3SX8a68SFTjh/E//A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-darwin-x64": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.69.0.tgz", - "integrity": "sha512-ax1oZnOjHX3LB7myQyHEaQkDwfLb6str3/nSP6O7EVUviQGNkEGzGV0EqcBJWK+Ufwx0l4xPgyYayurvhAdl2Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-freebsd-x64": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.69.0.tgz", - "integrity": "sha512-kHWeHv4g2h8NY+mpCxzCtY4uerMJWTN/TSnNj1CPbakFpHEJ6cTya2wWV0pDSYWOJ2+0UiEbhn3AtXxHtsnKjg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm-gnueabihf": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.69.0.tgz", - "integrity": "sha512-gq84vM1a1oEehXo27YCDzGVcxPsZDI1yswZwz2Da1/cbnWtrL16XZZnz0G/+gIU8edtHpfjxq5c+vWEHqJfWoQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm-musleabihf": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.69.0.tgz", - "integrity": "sha512-kIqEa98JQ0VRyrcncxA417m2AzasqTlD+FyVT1AksjvjkqQcvm7pBWYvoW3/mpyOP2XYvi5nSCCTIe6De1yu5g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm64-gnu": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.69.0.tgz", - "integrity": "sha512-j+xYiXozxGWx2cpjCrwwGR4awTxPFsRv3JZrv23RCogEPMc4R7UqjHW47p/RG0aRlbWiROCJ8coUfCwy0dvzHA==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm64-musl": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.69.0.tgz", - "integrity": "sha512-xEPpNppTfN1l/nM7gYSf9iocscu/as+p/7vxkLeLEKnYU+09Dm+5V6IhDYDh+Uz6FajEupWwCLt5SOG0y1PCKg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-ppc64-gnu": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.69.0.tgz", - "integrity": "sha512-Ug0+eU7HJBlek+SjklYH62IlOMirEJsdxpihH0kSqX0XdrDD4NdHpQc10fK1JC35yn6KrrcN+uYzlHD38XAf8Q==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-riscv64-gnu": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.69.0.tgz", - "integrity": "sha512-iEyI3GIg0l/s3G4qy2TlaaWKdzj4PJJStwtlocpDTC00PY9hZueotf6OKUj9+yfQh0lrpBW/pLMgTztbAHKJEg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-riscv64-musl": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.69.0.tgz", - "integrity": "sha512-NjHjpiI4WIKSMwuoJSZi5VToPeoYOS1FR52HLIDG6lidMdqquusgtODb4iLk0+lb1q3Z0nv2/aPRcC/olmpQGg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-s390x-gnu": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.69.0.tgz", - "integrity": "sha512-Ai/prDewoItkDXbp38gwGZi41DycZbUTZJ3UidwoHgQC0/DaqC2TGdtBTQLJ6hSD+SAxASzh8+/eSBPmxfOacA==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-x64-gnu": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.69.0.tgz", - "integrity": "sha512-Gt3KHgp46mRKz4sJeaASmKvD8ayXookRw07RMf+NowhEztGGDZ7VrXpoW96XuKJLjFukWizOFVNjmYb/u7caNQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-x64-musl": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.69.0.tgz", - "integrity": "sha512-7tQhJ2+p/oHv1zcfnjYI7YVzC/7iBaVOfIvFYtxdJ5F45mWgEdrCyXZXZGfiLey5t/5JhOhsaMnnv1kAzckd7g==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-openharmony-arm64": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.69.0.tgz", - "integrity": "sha512-vmWz6TKp/3hfA4lksR0zHBv/6xuX1jhym6eqOjdH2DXsDDHZWcp2f0KG0VCAnlVbIrjk29G4wAWMXb/Hn1YobA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-win32-arm64-msvc": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.69.0.tgz", - "integrity": "sha512-9RExaLgmaw6IoIkU9cTpT71mLfI0xZ86iZH8x518LVsOkjquJMYqb9P7KpC8lgd1t0Dxs41p2pxynq4XR3Ttzw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-win32-ia32-msvc": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.69.0.tgz", - "integrity": "sha512-1907kRPF8/PrcIw1E7LMs9JbVrpgnt/MvFdss3an8oDkYNAACXzTntV3t3869ZZhMZxb2AzRGbz1pA/jdFatXA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-win32-x64-msvc": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.69.0.tgz", - "integrity": "sha512-w8SOXv3mT9Fi6jY8OXdXCfnvX/3KNLXGNr4HEz2TA7S4Mv/PYAOmpB8y/ge40mxvBMgGNaSaaDwZpAsQn7HtWA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@redocly/ajv": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.18.3.tgz", - "integrity": "sha512-l42u0of3hY98sN2A+M4qTX1O/KrpgGH32Hu9kP2GtHyD5Dfqq86PKFLe5dwaD8DEnNmlOlll2BAmeEtf0DaySg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@redocly/config": { - "version": "0.51.0", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.51.0.tgz", - "integrity": "sha512-XoSkEN28ojqvF1fP8mhOlzHPowpr1/jkvbo3qXKIKXG8RqTiQkLCGTvYdMBjcagEheFFXAsaJKM/GMdoczd4Zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-schema-to-ts": "2.7.2" - } - }, - "node_modules/@redocly/openapi-core": { - "version": "2.39.0", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-2.39.0.tgz", - "integrity": "sha512-sACPZX1LUf/GLdZ7xyYV7dgZ73gRzi0TVgNXME5OGKVEHPeNv8z91v2KYhuJso8XJ+E5EVpwBU02UEkrKvSycA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@redocly/ajv": "^8.18.1", - "@redocly/config": "^0.51.0", - "ajv": "npm:@redocly/ajv@8.18.1", - "ajv-formats": "^3.0.1", - "colorette": "^1.2.0", - "graphql": "^16.14.1", - "js-levenshtein": "^1.1.6", - "js-yaml": "^4.2.0", - "picomatch": "^4.0.4", - "pluralize": "^8.0.0", - "yaml-ast-parser": "0.0.43" - }, - "engines": { - "node": ">=22.12.0 || >=20.19.0 <21.0.0", - "npm": ">=10" - } - }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", - "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", - "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", - "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", - "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", - "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", - "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", - "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", - "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", - "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", - "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", - "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", - "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", - "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", - "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", - "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", - "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.19.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", - "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@vitest/coverage-v8": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.7.tgz", - "integrity": "sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.7", - "ast-v8-to-istanbul": "^1.0.0", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.2.0", - "magicast": "^0.5.2", - "obug": "^2.1.1", - "std-env": "^4.0.0-rc.1", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/browser": "4.1.7", - "vitest": "4.1.7" - }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } - } - }, - "node_modules/@vitest/expect": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.7.tgz", - "integrity": "sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.7", - "@vitest/utils": "4.1.7", - "chai": "^6.2.2", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.7.tgz", - "integrity": "sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "4.1.7", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@vitest/pretty-format": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.7.tgz", - "integrity": "sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.7.tgz", - "integrity": "sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "4.1.7", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.7.tgz", - "integrity": "sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.7", - "@vitest/utils": "4.1.7", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.7.tgz", - "integrity": "sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.7.tgz", - "integrity": "sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.7", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@workos/oagen": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@workos/oagen/-/oagen-0.25.1.tgz", - "integrity": "sha512-AAimhzErMB2GazAe8iqo2KudBj4Zo27fX3XRrtOn/EfnXvh1cioPXfd97FLc9F/KnJrkncIrJbN23JhmwMihBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@redocly/openapi-core": "^2.25.1", - "commander": "^13.1.0", - "dotenv": "^17.3.1", - "tree-sitter": "^0.21.1", - "tree-sitter-c-sharp": "0.23.1", - "tree-sitter-elixir": "^0.3.5", - "tree-sitter-go": "^0.23.4", - "tree-sitter-kotlin": "github:fwcd/tree-sitter-kotlin#f66d2908542e93c0204c6c241f794afe4e9cd5d1", - "tree-sitter-php": "^0.23.12", - "tree-sitter-python": "^0.21.0", - "tree-sitter-ruby": "^0.21.0", - "tree-sitter-rust": "^0.21.0", - "tree-sitter-typescript": "^0.23.2", - "tsx": "^4.19.0", - "typescript": "^6.0.0" - }, - "bin": { - "oagen": "dist/cli/index.mjs" - }, - "engines": { - "node": ">=24.10.0" - } - }, - "node_modules/@workos/oagen/node_modules/typescript": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", - "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/@workos/openapi-spec": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@workos/openapi-spec/-/openapi-spec-0.41.0.tgz", - "integrity": "sha512-6Ic94jnpf0wHgwigjcdQtV7IQG5P6si8GPoGC88uDMJb2MqgZablQ6KbpzVzP0hwX/ZmHSSBGZgpsA2iUGXzmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@workos/oagen": "^0.25.0" - } - }, - "node_modules/ajv": { - "name": "@redocly/ajv", - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.18.1.tgz", - "integrity": "sha512-Ifm/pP/tul1qmAecpbVxCBluVE32rKfjf8gYXH4xI2gCv9mRWFhJMHzkPDM4TXlxwPQYIFegymlsy8lXz7optA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/ast-v8-to-istanbul": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.2.tgz", - "integrity": "sha512-dKmJxJsGItLmc5CYZKuEjuG6GnBs6PG4gohMhyFOWKaNQoYCuRZJDECaBlHmcG0lv2wc2E0uU8lESmBEumC3DQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "estree-walker": "^3.0.3", - "js-tokens": "^10.0.0" - } - }, - "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", - "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/es-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", - "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", - "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/graphql": { - "version": "16.14.2", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.14.2.tgz", - "integrity": "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hono": { - "version": "4.12.26", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.26.tgz", - "integrity": "sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==", - "license": "MIT", - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "bin.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/js-tokens": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", - "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", - "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-to-ts": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-2.7.2.tgz", - "integrity": "sha512-R1JfqKqbBR4qE8UyBR56Ms30LL62/nlhoz+1UkfI/VE7p54Awu919FZ6ZUPG8zIa3XB65usPJgr1ONVncUGSaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@types/json-schema": "^7.0.9", - "ts-algebra": "^1.2.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/magicast": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", - "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.3", - "@babel/types": "^7.29.0", - "source-map-js": "^1.2.1" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-addon-api": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.0.tgz", - "integrity": "sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18 || ^20 || >= 21" - } - }, - "node_modules/node-gyp-build": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", - "dev": true, - "license": "MIT", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/sxzz", - "https://opencollective.com/debug" - ], - "license": "MIT" - }, - "node_modules/oxfmt": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.54.0.tgz", - "integrity": "sha512-DjnMwn7smSLF+Mc2+pRItnuPftm/dkUFpY/d4+33y9TfKrsHZo8GLhmUg9BrOIUEy94Rlom1Q11N6vuhE+e0oQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinypool": "2.1.0" - }, - "bin": { - "oxfmt": "bin/oxfmt" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxfmt/binding-android-arm-eabi": "0.54.0", - "@oxfmt/binding-android-arm64": "0.54.0", - "@oxfmt/binding-darwin-arm64": "0.54.0", - "@oxfmt/binding-darwin-x64": "0.54.0", - "@oxfmt/binding-freebsd-x64": "0.54.0", - "@oxfmt/binding-linux-arm-gnueabihf": "0.54.0", - "@oxfmt/binding-linux-arm-musleabihf": "0.54.0", - "@oxfmt/binding-linux-arm64-gnu": "0.54.0", - "@oxfmt/binding-linux-arm64-musl": "0.54.0", - "@oxfmt/binding-linux-ppc64-gnu": "0.54.0", - "@oxfmt/binding-linux-riscv64-gnu": "0.54.0", - "@oxfmt/binding-linux-riscv64-musl": "0.54.0", - "@oxfmt/binding-linux-s390x-gnu": "0.54.0", - "@oxfmt/binding-linux-x64-gnu": "0.54.0", - "@oxfmt/binding-linux-x64-musl": "0.54.0", - "@oxfmt/binding-openharmony-arm64": "0.54.0", - "@oxfmt/binding-win32-arm64-msvc": "0.54.0", - "@oxfmt/binding-win32-ia32-msvc": "0.54.0", - "@oxfmt/binding-win32-x64-msvc": "0.54.0" - }, - "peerDependencies": { - "svelte": "^5.0.0", - "vite-plus": "*" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - }, - "vite-plus": { - "optional": true - } - } - }, - "node_modules/oxlint": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.69.0.tgz", - "integrity": "sha512-ypZkK/aDc5NQV8zIR6s2H2Tl3aNW8FmJ1m9+2qsaYuRenl8vgnHNCGwTHviWJdUQzglOlHFchgopdtGhSy17Rw==", - "dev": true, - "license": "MIT", - "bin": { - "oxlint": "bin/oxlint" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxlint/binding-android-arm-eabi": "1.69.0", - "@oxlint/binding-android-arm64": "1.69.0", - "@oxlint/binding-darwin-arm64": "1.69.0", - "@oxlint/binding-darwin-x64": "1.69.0", - "@oxlint/binding-freebsd-x64": "1.69.0", - "@oxlint/binding-linux-arm-gnueabihf": "1.69.0", - "@oxlint/binding-linux-arm-musleabihf": "1.69.0", - "@oxlint/binding-linux-arm64-gnu": "1.69.0", - "@oxlint/binding-linux-arm64-musl": "1.69.0", - "@oxlint/binding-linux-ppc64-gnu": "1.69.0", - "@oxlint/binding-linux-riscv64-gnu": "1.69.0", - "@oxlint/binding-linux-riscv64-musl": "1.69.0", - "@oxlint/binding-linux-s390x-gnu": "1.69.0", - "@oxlint/binding-linux-x64-gnu": "1.69.0", - "@oxlint/binding-linux-x64-musl": "1.69.0", - "@oxlint/binding-openharmony-arm64": "1.69.0", - "@oxlint/binding-win32-arm64-msvc": "1.69.0", - "@oxlint/binding-win32-ia32-msvc": "1.69.0", - "@oxlint/binding-win32-x64-msvc": "1.69.0" - }, - "peerDependencies": { - "oxlint-tsgolint": ">=0.22.1", - "vite-plus": "*" - }, - "peerDependenciesMeta": { - "oxlint-tsgolint": { - "optional": true - }, - "vite-plus": { - "optional": true - } - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.12", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rolldown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", - "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@oxc-project/types": "=0.133.0", - "@rolldown/pluginutils": "^1.0.0" - }, - "bin": { - "rolldown": "bin/cli.mjs" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.3", - "@rolldown/binding-darwin-arm64": "1.0.3", - "@rolldown/binding-darwin-x64": "1.0.3", - "@rolldown/binding-freebsd-x64": "1.0.3", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", - "@rolldown/binding-linux-arm64-gnu": "1.0.3", - "@rolldown/binding-linux-arm64-musl": "1.0.3", - "@rolldown/binding-linux-ppc64-gnu": "1.0.3", - "@rolldown/binding-linux-s390x-gnu": "1.0.3", - "@rolldown/binding-linux-x64-gnu": "1.0.3", - "@rolldown/binding-linux-x64-musl": "1.0.3", - "@rolldown/binding-openharmony-arm64": "1.0.3", - "@rolldown/binding-wasm32-wasi": "1.0.3", - "@rolldown/binding-win32-arm64-msvc": "1.0.3", - "@rolldown/binding-win32-x64-msvc": "1.0.3" - } - }, - "node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/std-env": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", - "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.3.tgz", - "integrity": "sha512-g62dB+w1/OEFnPvmX0yd/HnetYITOL+1nJW7kitOycOeAvmbWC/nu0fwmmQ/kupNojqExzyC/T++pST/jRJ2mQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinypool": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", - "integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^20.0.0 || >=22.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tree-sitter": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", - "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.0.0", - "node-gyp-build": "^4.8.0" - } - }, - "node_modules/tree-sitter-c-sharp": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/tree-sitter-c-sharp/-/tree-sitter-c-sharp-0.23.1.tgz", - "integrity": "sha512-9zZ4FlcTRWWfRf6f4PgGhG8saPls6qOOt75tDfX7un9vQZJmARjPrAC6yBNCX2T/VKcCjIDbgq0evFaB3iGhQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.2.2", - "node-gyp-build": "^4.8.2" - }, - "peerDependencies": { - "tree-sitter": "^0.21.1" - }, - "peerDependenciesMeta": { - "tree-sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-elixir": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/tree-sitter-elixir/-/tree-sitter-elixir-0.3.5.tgz", - "integrity": "sha512-xozQMvYK0aSolcQZAx2d84Xe/YMWFuRPYFlLVxO01bM2GITh5jyiIp0TqPCQa8754UzRAI7A83hZmfiYub5TZQ==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "node-addon-api": "^7.1.0", - "node-gyp-build": "^4.8.0" - }, - "peerDependencies": { - "tree-sitter": "^0.21.0" - } - }, - "node_modules/tree-sitter-elixir/node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/tree-sitter-go": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/tree-sitter-go/-/tree-sitter-go-0.23.4.tgz", - "integrity": "sha512-iQaHEs4yMa/hMo/ZCGqLfG61F0miinULU1fFh+GZreCRtKylFLtvn798ocCZjO2r/ungNZgAY1s1hPFyAwkc7w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.2.1", - "node-gyp-build": "^4.8.2" - }, - "peerDependencies": { - "tree-sitter": "^0.21.1" - }, - "peerDependenciesMeta": { - "tree-sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-javascript": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/tree-sitter-javascript/-/tree-sitter-javascript-0.23.1.tgz", - "integrity": "sha512-/bnhbrTD9frUYHQTiYnPcxyHORIw157ERBa6dqzaKxvR/x3PC4Yzd+D1pZIMS6zNg2v3a8BZ0oK7jHqsQo9fWA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.2.2", - "node-gyp-build": "^4.8.2" - }, - "peerDependencies": { - "tree-sitter": "^0.21.1" - }, - "peerDependenciesMeta": { - "tree-sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-kotlin": { - "version": "0.4.0", - "resolved": "git+ssh://git@github.com/fwcd/tree-sitter-kotlin.git#f66d2908542e93c0204c6c241f794afe4e9cd5d1", - "integrity": "sha512-onbogYgMICW34xos1mQNJEKnoq+m643z9MBC+AYa7mn4mH/KU4VJZnMVLcTViUErJ8h99KTRQbPH6wPlQLpepg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.2.2", - "node-gyp-build": "^4.8.2" - }, - "peerDependencies": { - "tree-sitter": "^0.21.1" - }, - "peerDependenciesMeta": { - "tree_sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-php": { - "version": "0.23.12", - "resolved": "https://registry.npmjs.org/tree-sitter-php/-/tree-sitter-php-0.23.12.tgz", - "integrity": "sha512-VwkBVOahhC2NYXK/Fuqq30NxuL/6c2hmbxEF4jrB7AyR5rLc7nT27mzF3qoi+pqx9Gy2AbXnGezF7h4MeM6YRA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.2.2", - "node-gyp-build": "^4.8.2" - }, - "peerDependencies": { - "tree-sitter": "^0.21.1" - }, - "peerDependenciesMeta": { - "tree-sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-python": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/tree-sitter-python/-/tree-sitter-python-0.21.0.tgz", - "integrity": "sha512-IUKx7JcTVbByUx1iHGFS/QsIjx7pqwTMHL9bl/NGyhyyydbfNrpruo2C7W6V4KZrbkkCOlX8QVrCoGOFW5qecg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^7.1.0", - "node-gyp-build": "^4.8.0" - }, - "peerDependencies": { - "tree-sitter": "^0.21.0" - }, - "peerDependenciesMeta": { - "tree_sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-python/node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/tree-sitter-ruby": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/tree-sitter-ruby/-/tree-sitter-ruby-0.21.0.tgz", - "integrity": "sha512-UrMpF9CZxKbZ5UFuPdXDuraaaYSMMlAiuzTpQXwNm7y0D48ibc9stWU5D6vDyJD0qf5/R+3yKTYHdHkqibmLSQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.0.0", - "node-gyp-build": "^4.8.1" - }, - "peerDependencies": { - "tree-sitter": "^0.21.0" - }, - "peerDependenciesMeta": { - "tree_sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-rust": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/tree-sitter-rust/-/tree-sitter-rust-0.21.0.tgz", - "integrity": "sha512-unVr73YLn3VC4Qa/GF0Nk+Wom6UtI526p5kz9Rn2iZSqwIFedyCZ3e0fKCEmUJLIPGrTb/cIEdu3ZUNGzfZx7A==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^7.1.0", - "node-gyp-build": "^4.8.0" - }, - "peerDependencies": { - "tree-sitter": "^0.21.1" - }, - "peerDependenciesMeta": { - "tree_sitter": { - "optional": true - } - } - }, - "node_modules/tree-sitter-rust/node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/tree-sitter-typescript": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/tree-sitter-typescript/-/tree-sitter-typescript-0.23.2.tgz", - "integrity": "sha512-e04JUUKxTT53/x3Uq1zIL45DoYKVfHH4CZqwgZhPg5qYROl5nQjV+85ruFzFGZxu+QeFVbRTPDRnqL9UbU4VeA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.2.2", - "node-gyp-build": "^4.8.2", - "tree-sitter-javascript": "^0.23.1" - }, - "peerDependencies": { - "tree-sitter": "^0.21.0" - }, - "peerDependenciesMeta": { - "tree-sitter": { - "optional": true - } - } - }, - "node_modules/ts-algebra": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-1.2.2.tgz", - "integrity": "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA==", - "dev": true, - "license": "MIT" - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "optional": true - }, - "node_modules/tsx": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.3.tgz", - "integrity": "sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.28.0" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite": { - "version": "8.0.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", - "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", - "postcss": "^8.5.15", - "rolldown": "1.0.3", - "tinyglobby": "^0.2.17" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.18", - "esbuild": "^0.27.0 || ^0.28.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "@vitejs/devtools": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vitest": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.7.tgz", - "integrity": "sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.1.7", - "@vitest/mocker": "4.1.7", - "@vitest/pretty-format": "4.1.7", - "@vitest/runner": "4.1.7", - "@vitest/snapshot": "4.1.7", - "@vitest/spy": "4.1.7", - "@vitest/utils": "4.1.7", - "es-module-lexer": "^2.0.0", - "expect-type": "^1.3.0", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^4.0.0-rc.1", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.1.0", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.7", - "@vitest/browser-preview": "4.1.7", - "@vitest/browser-webdriverio": "4.1.7", - "@vitest/coverage-istanbul": "4.1.7", - "@vitest/coverage-v8": "4.1.7", - "@vitest/ui": "4.1.7", - "happy-dom": "*", - "jsdom": "*", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser-playwright": { - "optional": true - }, - "@vitest/browser-preview": { - "optional": true - }, - "@vitest/browser-webdriverio": { - "optional": true - }, - "@vitest/coverage-istanbul": { - "optional": true - }, - "@vitest/coverage-v8": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "vite": { - "optional": false - } - } - }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/yaml-ast-parser": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", - "dev": true, - "license": "Apache-2.0" - } - } -} diff --git a/package.json b/package.json index d7b3a8b..03cfe0a 100644 --- a/package.json +++ b/package.json @@ -43,40 +43,43 @@ "@hono/node-server": "^1", "chalk": "^5.6.2", "hono": "^4", + "semver": "^7.7.4", "yaml": "^2.8.2" }, "devDependencies": { + "@types/bun": "^1.3.14", "@types/node": "~22.19.7", - "@vitest/coverage-v8": "^4.0.18", + "@types/semver": "^7.7.1", "@workos/openapi-spec": "^0.41.0", "husky": "^9.1.7", "oxfmt": "^0.54.0", "oxlint": "^1.69.0", - "tsx": "^4.20.3", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "typescript": "^5.9.3" }, "engines": { "node": ">=22.11" }, + "packageManager": "bun@1.3.14", "scripts": { "clean": "rm -rf ./dist", - "prebuild": "npm run clean", - "build": "tsc", - "postbuild": "chmod +x ./dist/cli.js", - "start": "node ./dist/cli.js", - "test": "vitest run", - "test:watch": "vitest", - "test:coverage": "vitest run --coverage", - "typecheck": "tsc --noEmit", + "build": "rm -rf ./dist && tsc && chmod +x ./dist/cli.js", + "build:binary": "bun build --compile --no-compile-autoload-dotenv --no-compile-autoload-bunfig ./src/cli.ts --outfile ./dist/workos-emulate", + "start": "bun ./dist/cli.js", + "dev": "bun src/cli.ts", + "test": "bun test", + "test:node": "bun run build && node scripts/smoke-node.mjs", + "test:package": "bun run build && node scripts/check-package.mjs", + "test:watch": "bun test --watch", + "test:coverage": "bun test --coverage", + "typecheck": "tsc --noEmit && tsc -p tsconfig.tests.json", "lint": "oxlint", "lint:fix": "oxlint --fix", "fmt": "oxfmt", "fmt:check": "oxfmt --check", - "gen:routes": "tsx scripts/gen-routes.ts", - "gen:events": "tsx scripts/gen-events.ts", - "gen:shapes": "tsx scripts/gen-shapes.ts", - "check:coverage": "tsx scripts/check-coverage.ts", + "gen:routes": "bun scripts/gen-routes.ts", + "gen:events": "bun scripts/gen-events.ts", + "gen:shapes": "bun scripts/gen-shapes.ts", + "check:coverage": "bun scripts/check-coverage.ts", "prepare": "husky" }, "author": "WorkOS", diff --git a/scripts/build-binaries.sh b/scripts/build-binaries.sh new file mode 100755 index 0000000..d1df9e7 --- /dev/null +++ b/scripts/build-binaries.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +VERSION="${1:?usage: build-binaries.sh }" +OUT="dist/binaries" +rm -rf "$OUT" && mkdir -p "$OUT" + +# target:artifact pairs (plain array — macOS /bin/bash 3.2 has no associative arrays) +TARGETS=( + "bun-darwin-arm64:workos-emulate-darwin-arm64" + "bun-darwin-x64-baseline:workos-emulate-darwin-x64" + "bun-linux-x64-baseline:workos-emulate-linux-x64" + "bun-linux-arm64:workos-emulate-linux-arm64" + "bun-linux-x64-musl-baseline:workos-emulate-linux-x64-musl" + "bun-linux-arm64-musl:workos-emulate-linux-arm64-musl" + "bun-windows-x64-baseline:workos-emulate-windows-x64.exe" + "bun-windows-arm64:workos-emulate-windows-arm64.exe" +) + +for entry in "${TARGETS[@]}"; do + target="${entry%%:*}" + artifact="${entry#*:}" + bun build \ + --compile \ + --no-compile-autoload-dotenv \ + --no-compile-autoload-bunfig \ + --target="$target" \ + ./src/cli.ts \ + --outfile "$OUT/$artifact" +done + +(cd "$OUT" && shasum -a 256 workos-emulate-* > checksums.txt) +echo "Built ${#TARGETS[@]} binaries plus checksums for $VERSION" diff --git a/scripts/check-coverage.ts b/scripts/check-coverage.ts index 7853206..77bf972 100644 --- a/scripts/check-coverage.ts +++ b/scripts/check-coverage.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env tsx +#!/usr/bin/env bun /** * Coverage checker: compares the WorkOS OpenAPI spec against the emulator's * registered routes to find missing or extra endpoints. diff --git a/scripts/check-package.mjs b/scripts/check-package.mjs new file mode 100644 index 0000000..900deba --- /dev/null +++ b/scripts/check-package.mjs @@ -0,0 +1,122 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const projectRoot = dirname(dirname(fileURLToPath(import.meta.url))); +const packageJson = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8')); +const temporaryRoot = mkdtempSync(join(tmpdir(), 'workos-emulate-package-')); +const packDirectory = join(temporaryRoot, 'pack'); +const consumerDirectory = join(temporaryRoot, 'consumer'); +const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'; + +const requiredFiles = [ + 'LICENSE.txt', + 'README.md', + 'dist/cli.js', + 'dist/core/index.d.ts', + 'dist/core/index.js', + 'dist/index.d.ts', + 'dist/index.js', + 'dist/workos/index.d.ts', + 'dist/workos/index.js', + 'package.json', +]; + +try { + mkdirSync(packDirectory, { recursive: true }); + const packOutput = run(npm, ['pack', '--json', '--ignore-scripts', '--pack-destination', packDirectory], projectRoot); + const results = JSON.parse(packOutput); + assert.equal(results.length, 1, 'npm pack must produce exactly one tarball'); + + const packedFiles = results[0].files.map((file) => file.path); + const packedFileSet = new Set(packedFiles); + + for (const required of requiredFiles) { + assert.ok(packedFileSet.has(required), `npm package is missing required file: ${required}`); + } + + const unexpected = packedFiles.filter( + (path) => !path.startsWith('dist/') && !['LICENSE.txt', 'README.md', 'package.json'].includes(path), + ); + assert.deepEqual(unexpected, [], `npm package contains unexpected files: ${unexpected.join(', ')}`); + + const forbidden = packedFiles.filter( + (path) => + /(^|\/)(?:src|scripts|coverage|node_modules|\.github)\//.test(path) || + /(?:^|\/)\.env(?:\.|$)/.test(path) || + /\.(?:spec|test)\.[cm]?[jt]sx?$/.test(path) || + path.endsWith('.bun-build') || + path === 'bun.lock' || + path === 'bunfig.toml', + ); + assert.deepEqual(forbidden, [], `npm package contains development or sensitive files: ${forbidden.join(', ')}`); + + const tarball = join(packDirectory, results[0].filename); + assert.ok(existsSync(tarball), `npm pack did not create ${tarball}`); + + mkdirSync(consumerDirectory, { recursive: true }); + writeFileSync( + join(consumerDirectory, 'package.json'), + `${JSON.stringify({ name: 'package-contract-consumer', private: true, type: 'module' }, null, 2)}\n`, + ); + writeFileSync( + join(consumerDirectory, '.npmrc'), + ['audit=false', 'fund=false', 'package-lock=false', 'update-notifier=false'].join('\n'), + ); + + run( + npm, + ['install', '--ignore-scripts', '--no-audit', '--no-fund', '--package-lock=false', tarball], + consumerDirectory, + ); + + run( + process.execPath, + [ + '--input-type=module', + '--eval', + [ + "const root = await import('@workos/emulate');", + "const core = await import('@workos/emulate/core');", + "const workos = await import('@workos/emulate/workos');", + "if (typeof root.createEmulator !== 'function') throw new Error('root createEmulator export is missing');", + "if (Object.keys(core).length === 0) throw new Error('core export is empty');", + "if (Object.keys(workos).length === 0) throw new Error('workos export is empty');", + ].join('\n'), + ], + consumerDirectory, + ); + + const installedPackageRoot = join(consumerDirectory, 'node_modules', '@workos', 'emulate'); + const cliPath = join(installedPackageRoot, packageJson.bin['workos-emulate']); + assert.ok(existsSync(cliPath), `installed CLI is missing: ${cliPath}`); + assert.ok(existsSync(join(consumerDirectory, 'node_modules', '.bin', 'workos-emulate')), 'npm bin link is missing'); + + const installedVersion = run(process.execPath, [cliPath, '--version'], consumerDirectory); + assert.equal(installedVersion, packageJson.version); + + console.log(`check-package: OK (${packedFiles.length} files, imports and CLI verified under ${process.version})`); +} finally { + rmSync(temporaryRoot, { recursive: true, force: true }); +} + +function run(command, args, cwd) { + const result = spawnSync(command, args, { + cwd, + encoding: 'utf8', + env: { ...process.env, CI: 'true', NO_UPDATE_NOTIFIER: '1' }, + }); + + if (result.error) throw result.error; + if (result.status !== 0) { + throw new Error( + [`${command} ${args.join(' ')} failed with exit code ${result.status}`, result.stdout, result.stderr] + .filter(Boolean) + .join('\n'), + ); + } + return result.stdout.trim(); +} diff --git a/scripts/gen-events-lib.spec.ts b/scripts/gen-events-lib.spec.ts index 599bc41..7a3bc72 100644 --- a/scripts/gen-events-lib.spec.ts +++ b/scripts/gen-events-lib.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { type EventSchemaNode, eventConstantKey, diff --git a/scripts/gen-routes-lib.spec.ts b/scripts/gen-routes-lib.spec.ts index 1f98a92..198f577 100644 --- a/scripts/gen-routes-lib.spec.ts +++ b/scripts/gen-routes-lib.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { type OpenAPISpec, type ParsedEntity, diff --git a/scripts/gen-shapes-lib.spec.ts b/scripts/gen-shapes-lib.spec.ts index 5bd10b7..7a0c115 100644 --- a/scripts/gen-shapes-lib.spec.ts +++ b/scripts/gen-shapes-lib.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { resolveSchema, extractShape, diff --git a/scripts/smoke-binary.mjs b/scripts/smoke-binary.mjs new file mode 100644 index 0000000..b5eee14 --- /dev/null +++ b/scripts/smoke-binary.mjs @@ -0,0 +1,98 @@ +import assert from 'node:assert/strict'; +import { execFile, spawn } from 'node:child_process'; +import { get } from 'node:http'; +import { resolve } from 'node:path'; +import { createInterface } from 'node:readline'; +import { promisify } from 'node:util'; + +const input = process.argv[2]; +if (!input) { + throw new Error('usage: node scripts/smoke-binary.mjs '); +} + +const binary = resolve(input); +const execFileAsync = promisify(execFile); +const version = await execFileAsync(binary, ['--version'], { timeout: 10_000, windowsHide: true }); +assert.match(version.stdout.trim(), /^\d+\.\d+\.\d+(?:-.+)?$/); + +const child = spawn(binary, ['--port', '0', '--json'], { + stdio: ['ignore', 'pipe', 'pipe'], + windowsHide: true, +}); + +let stderr = ''; +child.stderr.setEncoding('utf8'); +child.stderr.on('data', (chunk) => { + stderr += chunk; +}); + +try { + const startup = await new Promise((resolveStartup, rejectStartup) => { + const timeout = setTimeout(() => { + rejectStartup(new Error(`binary did not report startup within 10 seconds\n${stderr}`)); + }, 10_000); + + const lines = createInterface({ input: child.stdout }); + lines.on('line', (line) => { + try { + const parsed = JSON.parse(line); + if (typeof parsed.url === 'string') { + clearTimeout(timeout); + lines.close(); + resolveStartup(parsed); + } + } catch { + // Ignore non-JSON startup output; --json should eventually emit one JSON line. + } + }); + child.once('error', (error) => { + clearTimeout(timeout); + rejectStartup(error); + }); + child.once('exit', (code, signal) => { + clearTimeout(timeout); + rejectStartup(new Error(`binary exited before startup (code=${code}, signal=${signal})\n${stderr}`)); + }); + }); + + const health = await getJson(`${startup.url}/health`); + assert.equal(health.status, 200); + assert.deepEqual(health.body, { status: 'ok' }); + + const jwksResponse = await getJson(`${startup.url}/oauth2/jwks`); + assert.equal(jwksResponse.status, 200); + const jwks = jwksResponse.body; + assert.ok(Array.isArray(jwks.keys) && jwks.keys.length > 0, 'JWKS must contain at least one key'); + + console.log(`smoke-binary: OK (${binary})`); +} finally { + if (child.exitCode === null && child.signalCode === null) { + const exit = new Promise((resolveExit) => child.once('exit', resolveExit)); + const timeout = new Promise((resolveTimeout) => { + const timer = setTimeout(resolveTimeout, 1_000); + timer.unref(); + }); + child.kill('SIGINT'); + await Promise.race([exit, timeout]); + } + if (child.exitCode === null && child.signalCode === null) child.kill('SIGKILL'); +} + +function getJson(url) { + return new Promise((resolveRequest, rejectRequest) => { + get(url, { agent: false }, (response) => { + const chunks = []; + response.on('data', (chunk) => chunks.push(chunk)); + response.on('end', () => { + try { + resolveRequest({ + status: response.statusCode, + body: JSON.parse(Buffer.concat(chunks).toString('utf8')), + }); + } catch (error) { + rejectRequest(error); + } + }); + }).once('error', rejectRequest); + }); +} diff --git a/scripts/smoke-binary.sh b/scripts/smoke-binary.sh new file mode 100755 index 0000000..ca46311 --- /dev/null +++ b/scripts/smoke-binary.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +BIN="./dist/workos-emulate" + +bun run build:binary +node scripts/smoke-binary.mjs "$BIN" diff --git a/scripts/smoke-node.mjs b/scripts/smoke-node.mjs new file mode 100644 index 0000000..4c5f563 --- /dev/null +++ b/scripts/smoke-node.mjs @@ -0,0 +1,167 @@ +// Black-box compatibility suite for the published Node library. +// Run with plain Node, never Bun: the invariant is that dist/ boots and its +// major integration boundaries work without Bun-only APIs. +import assert from 'node:assert/strict'; +import { createHmac } from 'node:crypto'; +import { createServer } from 'node:http'; +import { createEmulator } from '../dist/index.js'; + +const webhookSecret = 'node_compat_webhook_secret'; + +const receiver = await startWebhookReceiver(); +let emulator; + +try { + emulator = await createEmulator({ port: 0 }); + + const api = (path, init = {}) => + fetch(`${emulator.url}${path}`, { + ...init, + headers: { + Authorization: `Bearer ${emulator.apiKey}`, + 'Content-Type': 'application/json', + ...init.headers, + }, + }); + + const health = await fetch(`${emulator.url}/health`); + assert.equal(health.status, 200); + assert.deepEqual(await health.json(), { status: 'ok' }); + + const jwksResponse = await fetch(`${emulator.url}/oauth2/jwks`); + assert.equal(jwksResponse.status, 200); + const jwks = await jwksResponse.json(); + assert.ok(Array.isArray(jwks.keys) && jwks.keys.length > 0, 'JWKS must contain at least one key'); + + const endpointResponse = await api('/webhook_endpoints', { + method: 'POST', + body: JSON.stringify({ + endpoint_url: receiver.url, + events: ['user.created'], + secret: webhookSecret, + }), + }); + assert.equal(endpointResponse.status, 201); + + const email = 'node-compat@example.com'; + const userResponse = await api('/user_management/users', { + method: 'POST', + body: JSON.stringify({ + email, + password: 'correct horse battery staple', + first_name: 'Node', + last_name: 'Compatibility', + }), + }); + assert.equal(userResponse.status, 201); + const user = await userResponse.json(); + assert.equal(user.email, email); + assert.match(user.id, /^user_/); + + const webhook = await receiver.next(); + assert.equal(webhook.body.event, 'user.created'); + assert.equal(webhook.body.data.id, user.id); + verifyWebhookSignature(webhook.signature, webhook.rawBody); + + const authResponse = await api('/user_management/authenticate', { + method: 'POST', + body: JSON.stringify({ + grant_type: 'password', + email, + password: 'correct horse battery staple', + }), + }); + assert.equal(authResponse.status, 200); + const auth = await authResponse.json(); + assert.equal(auth.user.id, user.id); + assert.equal(auth.authentication_method, 'Password'); + assert.equal(typeof auth.access_token, 'string'); + assert.equal(typeof auth.refresh_token, 'string'); + + const hook = emulator.addErrorHook({ + method: 'GET', + path: '/user_management/users', + status: 503, + body: { code: 'node_compat_error', message: 'Node compatibility hook' }, + count: 1, + }); + const hookedResponse = await api('/user_management/users'); + assert.equal(hookedResponse.status, 503); + assert.equal((await hookedResponse.json()).code, 'node_compat_error'); + assert.equal( + emulator.listErrorHooks().some((candidate) => candidate.id === hook.id), + false, + ); + + emulator.reset(); + const usersAfterReset = await api('/user_management/users'); + assert.equal(usersAfterReset.status, 200); + assert.deepEqual((await usersAfterReset.json()).data, []); + + console.log('smoke-node: OK (HTTP, crypto, CRUD, auth, webhooks, hooks, reset)'); +} finally { + if (emulator) await emulator.close(); + await receiver.close(); +} + +function verifyWebhookSignature(signature, rawBody) { + const match = signature?.match(/^t=(\d+),v1=([a-f0-9]{64})$/); + assert.ok(match, `unexpected WorkOS-Signature: ${signature}`); + const expected = createHmac('sha256', webhookSecret).update(`${match[1]}.${rawBody}`).digest('hex'); + assert.equal(match[2], expected); +} + +async function startWebhookReceiver() { + const queue = []; + const waiters = []; + + const server = createServer((request, response) => { + const chunks = []; + request.on('data', (chunk) => chunks.push(chunk)); + request.on('end', () => { + const rawBody = Buffer.concat(chunks).toString('utf8'); + const delivery = { + rawBody, + body: JSON.parse(rawBody), + signature: request.headers['workos-signature'], + }; + + const waiter = waiters.shift(); + if (waiter) waiter(delivery); + else queue.push(delivery); + + response.writeHead(200); + response.end('ok'); + }); + }); + + await new Promise((resolve, reject) => { + server.once('error', reject); + server.listen(0, '127.0.0.1', resolve); + }); + + const address = server.address(); + assert.ok(address && typeof address === 'object'); + + return { + url: `http://127.0.0.1:${address.port}/webhooks`, + next() { + const queued = queue.shift(); + if (queued) return Promise.resolve(queued); + + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => reject(new Error('webhook was not delivered within 5 seconds')), 5_000); + waiters.push((delivery) => { + clearTimeout(timeout); + resolve(delivery); + }); + }); + }, + close() { + server.closeAllConnections(); + return new Promise((resolve, reject) => { + server.close((error) => (error ? reject(error) : resolve())); + }); + }, + }; +} diff --git a/scripts/update-homebrew-formula.sh b/scripts/update-homebrew-formula.sh new file mode 100755 index 0000000..4afe64a --- /dev/null +++ b/scripts/update-homebrew-formula.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +set -euo pipefail + +USAGE="usage: update-homebrew-formula.sh " +TAG="${1:?$USAGE}" +CHECKSUMS="${2:?$USAGE}" +OUTPUT="${3:?$USAGE}" + +VERSION="${TAG#v}" + +if [[ ! -f "$CHECKSUMS" ]]; then + echo "error: checksums file not found: $CHECKSUMS" >&2 + exit 1 +fi + +sha_for() { + local artifact="$1" + local sha + sha="$(awk -v artifact="$artifact" '$2 == artifact { print $1 }' "$CHECKSUMS")" + if [[ -z "$sha" ]]; then + echo "error: no checksum for $artifact in $CHECKSUMS" >&2 + exit 1 + fi + printf '%s' "$sha" +} + +SHA_DARWIN_ARM64="$(sha_for workos-emulate-darwin-arm64)" +SHA_DARWIN_X64="$(sha_for workos-emulate-darwin-x64)" +SHA_LINUX_ARM64="$(sha_for workos-emulate-linux-arm64)" +SHA_LINUX_X64="$(sha_for workos-emulate-linux-x64)" + +mkdir -p "$(dirname "$OUTPUT")" + +cat > "$OUTPUT" < "workos-emulate" + end + + test do + assert_match "workos-emulate", shell_output("#{bin}/workos-emulate --help") + end +end +EOF + +echo "Rendered $OUTPUT for version ${VERSION}" diff --git a/src/bind-hostname.spec.ts b/src/bind-hostname.spec.ts index 4ec5be9..274f243 100644 --- a/src/bind-hostname.spec.ts +++ b/src/bind-hostname.spec.ts @@ -7,7 +7,7 @@ * operator explicitly opts in via `hostname`. */ import { networkInterfaces } from 'node:os'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { createEmulator } from './index.js'; function firstNonLoopbackIPv4(): string | undefined { diff --git a/src/cli.ts b/src/cli.ts index d827908..92e9ad0 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -4,6 +4,8 @@ import { resolve } from 'node:path'; import chalk from 'chalk'; import { parse as parseYaml } from 'yaml'; import { createEmulator, type EmulatorSeedConfig } from './index.js'; +import { checkForUpdates, shouldCheckForUpdates } from './version-check.js'; +import { VERSION } from './version.js'; import { validateSeedConfig, formatValidationErrors } from './workos/config-validator.js'; interface CliArgs { @@ -12,6 +14,7 @@ interface CliArgs { seed?: string; json: boolean; help: boolean; + version: boolean; interactive: boolean; validateConfig: boolean; } @@ -32,12 +35,24 @@ Options: --interactive, -i Show login pages for SSO/AuthKit (for E2E browser testing) --validate-config Validate seed config file without starting server --json Print startup details as JSON + --version, -v Print the installed version --help, -h Show this help message + +Environment: + NO_UPDATE_NOTIFIER=1 Disable update checks + WORKOS_EMULATE_DISABLE_UPDATE_CHECK=1 Disable update checks `); } function parseArgs(argv: string[]): CliArgs { - const parsed: CliArgs = { port: DEFAULT_PORT, json: false, help: false, interactive: false, validateConfig: false }; + const parsed: CliArgs = { + port: DEFAULT_PORT, + json: false, + help: false, + version: false, + interactive: false, + validateConfig: false, + }; for (let i = 0; i < argv.length; i++) { const arg = argv[i]; @@ -54,6 +69,11 @@ function parseArgs(argv: string[]): CliArgs { continue; } + if (arg === '--version' || arg === '-v') { + parsed.version = true; + continue; + } + if (arg === '--interactive' || arg === '-i') { parsed.interactive = true; continue; @@ -155,6 +175,10 @@ async function main(): Promise { printHelp(); return; } + if (argv.version) { + console.log(VERSION); + return; + } const seedConfig = argv.seed ? loadSeedFile(argv.seed) : autoDetectSeedFile(); @@ -196,6 +220,15 @@ async function main(): Promise { printBanner(emulator); } + if (shouldCheckForUpdates({ json: argv.json })) { + void checkForUpdates().then((update) => { + if (!update) return; + console.error(chalk.yellow(`Update available: ${update.currentVersion} → ${update.latestVersion}`)); + console.error(chalk.dim(update.notice)); + console.error(); + }); + } + const shutdown = () => { if (!argv.json) console.log(`\n${chalk.dim('Shutting down...')}`); emulator.close().then(() => process.exit(0)); diff --git a/src/core/error-hooks-integration.spec.ts b/src/core/error-hooks-integration.spec.ts index a7a7759..490bb3a 100644 --- a/src/core/error-hooks-integration.spec.ts +++ b/src/core/error-hooks-integration.spec.ts @@ -1,7 +1,7 @@ /** * Integration tests for error hooks with actual API failures */ -import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { describe, it, expect, beforeAll, afterAll } from 'bun:test'; import { createEmulator, type Emulator } from '../index.js'; describe('Error Hooks Integration Tests', () => { @@ -37,7 +37,7 @@ describe('Error Hooks Integration Tests', () => { }); expect(res.status).toBe(422); - const data = await res.json(); + const data = (await res.json()) as any; expect(data.message).toBe('Validation failed'); expect(data.code).toBe('unprocessable_entity'); expect(data.errors).toHaveLength(1); @@ -58,7 +58,7 @@ describe('Error Hooks Integration Tests', () => { }); expect(res.status).toBe(500); - const data = await res.json(); + const data = (await res.json()) as any; expect(data.message).toBe('Internal Server Error'); expect(data.code).toBe('server_error'); @@ -226,7 +226,7 @@ describe('Error Hooks Integration Tests', () => { body: JSON.stringify({ name: 'Test Org 4' }), }); expect(res4.status).toBe(429); - const data = await res4.json(); + const data = (await res4.json()) as any; expect(data.code).toBe('rate_limit_exceeded'); expect(data.retry_after).toBeGreaterThan(0); diff --git a/src/core/error-hooks.spec.ts b/src/core/error-hooks.spec.ts index e0827af..bc72626 100644 --- a/src/core/error-hooks.spec.ts +++ b/src/core/error-hooks.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from './index.js'; import { workosPlugin } from '../workos/index.js'; import { addErrorHook, getErrorHooks, removeErrorHook } from './error-hooks.js'; @@ -37,7 +37,7 @@ describe('Error hooks middleware', () => { }); expect(res.status).toBe(422); - const body = await res.json(); + const body = (await res.json()) as any; expect(body.message).toBe('Validation failed'); expect(body.code).toBe('unprocessable_entity'); }); @@ -51,7 +51,7 @@ describe('Error hooks middleware', () => { const res = await req('/user_management/users'); expect(res.status).toBe(500); - const body = await res.json(); + const body = (await res.json()) as any; expect(body.message).toBe('Internal Server Error'); expect(body.code).toBe('server_error'); }); @@ -183,7 +183,7 @@ describe('Error hooks middleware', () => { method: 'POST', body: JSON.stringify({ email: 'bad' }), }); - const body = await res.json(); + const body = (await res.json()) as any; expect(body.errors).toHaveLength(1); expect(body.errors[0].field).toBe('email'); }); diff --git a/src/core/id.spec.ts b/src/core/id.spec.ts index ed87cf6..60b959b 100644 --- a/src/core/id.spec.ts +++ b/src/core/id.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { generateId, resetIdState, ID_PREFIXES } from './id.js'; beforeEach(() => { diff --git a/src/core/jwt.spec.ts b/src/core/jwt.spec.ts index 2129aa9..e33e47e 100644 --- a/src/core/jwt.spec.ts +++ b/src/core/jwt.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, setSystemTime, afterEach } from 'bun:test'; import { JWTManager } from './jwt.js'; describe('JWTManager', () => { @@ -9,7 +9,7 @@ describe('JWTManager', () => { }); afterEach(() => { - vi.useRealTimers(); + setSystemTime(); }); it('signs a token and verifies it', () => { @@ -52,12 +52,11 @@ describe('JWTManager', () => { }); it('throws on expired token', () => { - vi.useFakeTimers(); - vi.setSystemTime(new Date('2020-01-01T00:00:00Z')); + setSystemTime(new Date('2020-01-01T00:00:00Z')); const token = jwt.sign({ sub: 'user_01ABC', aud: 'client_01XYZ' }, { expiresIn: 60 }); - vi.setSystemTime(new Date('2020-01-01T00:02:00Z')); + setSystemTime(new Date('2020-01-01T00:02:00Z')); expect(() => jwt.verify(token)).toThrow('Token has expired'); }); diff --git a/src/core/pagination.spec.ts b/src/core/pagination.spec.ts index b2b4716..f6f667f 100644 --- a/src/core/pagination.spec.ts +++ b/src/core/pagination.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { cursorPaginate, type Entity } from './pagination.js'; interface TestItem extends Entity { diff --git a/src/core/store.spec.ts b/src/core/store.spec.ts index 2f35a53..4dad70a 100644 --- a/src/core/store.spec.ts +++ b/src/core/store.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, setSystemTime } from 'bun:test'; import { Collection, Store, type Entity } from './store.js'; interface User extends Entity { @@ -31,12 +31,11 @@ describe('Collection', () => { }); it('update merges data and updates updated_at; delete removes item', () => { - vi.useFakeTimers(); - vi.setSystemTime(new Date('2020-01-01T00:00:00.000Z')); + setSystemTime(new Date('2020-01-01T00:00:00.000Z')); const inserted = col.insert({ name: 'bob' }); const createdAt = inserted.created_at; - vi.setSystemTime(new Date('2020-01-02T00:00:00.000Z')); + setSystemTime(new Date('2020-01-02T00:00:00.000Z')); const updated = col.update(inserted.id, { name: 'robert', status: 'active' }); expect(updated).toBeDefined(); expect(updated!.name).toBe('robert'); @@ -47,7 +46,7 @@ describe('Collection', () => { expect(col.delete(inserted.id)).toBe(true); expect(col.get(inserted.id)).toBeUndefined(); - vi.useRealTimers(); + setSystemTime(); }); it('update returns undefined for nonexistent ID', () => { @@ -210,5 +209,5 @@ describe('Store', () => { }); afterEach(() => { - vi.useRealTimers(); + setSystemTime(); }); diff --git a/src/e2e.spec.ts b/src/e2e.spec.ts index a9921da..e74afb5 100644 --- a/src/e2e.spec.ts +++ b/src/e2e.spec.ts @@ -6,12 +6,26 @@ * creation and authentication outcome delivers a signed webhook whose name and * payload match the OpenAPI spec (via the generated EVENT_DATA_REQUIREMENTS). */ -import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import { describe, it, expect, beforeAll, afterAll } from 'bun:test'; import { createServer, type Server } from 'node:http'; import { createHmac, randomBytes } from 'node:crypto'; import { createEmulator, type Emulator } from './index.js'; import { EVENT_DATA_REQUIREMENTS } from './workos/generated/events.js'; +/** Poll `fn` until it stops throwing or the timeout elapses (bun:test has no vi.waitFor). */ +async function waitFor(fn: () => T | Promise, opts: { timeout?: number; interval?: number } = {}): Promise { + const { timeout = 5000, interval = 50 } = opts; + const deadline = Date.now() + timeout; + for (;;) { + try { + return await fn(); + } catch (err) { + if (Date.now() >= deadline) throw err; + } + await new Promise((r) => setTimeout(r, interval)); + } +} + let webhookSecret = ''; interface ReceivedWebhook { @@ -71,7 +85,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { /** Deliveries are fire-and-forget — poll until the named webhook arrives past the cursor. */ function waitForWebhook(event: string, opts?: { after?: number; timeout?: number }): Promise { - return vi.waitFor( + return waitFor( () => { const hit = receiver.received.slice(opts?.after ?? 0).find((w) => w.event === event); if (!hit) { @@ -128,7 +142,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { body: JSON.stringify({ email, password: 'correct horse battery staple', first_name: 'Alice' }), }); expect(res.status).toBe(201); - userId = (await res.json()).id; + userId = ((await res.json()) as any).id; const webhook = await waitForWebhook('user.created', { after: cursor }); expect(webhook.data.email).toBe(email); @@ -144,7 +158,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { method: 'POST', body: JSON.stringify({ name: 'E2E Story Org' }), }); - const org = await orgRes.json(); + const org = (await orgRes.json()) as any; await api('/user_management/organization_memberships', { method: 'POST', @@ -194,7 +208,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { body: JSON.stringify({ grant_type: 'authorization_code', code, client_id: 'client_e2e' }), }); expect(authRes.status).toBe(200); - const auth = await authRes.json(); + const auth = (await authRes.json()) as any; expect(auth.access_token).toBeTruthy(); expect(auth.refresh_token).toBeTruthy(); expect(auth.user.email).toBe(email); @@ -321,7 +335,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { }), }); expect(factorRes.status).toBe(201); - const factor = await factorRes.json(); + const factor = (await factorRes.json()) as any; // Step 2: Authenticate with password - should trigger MFA challenge const passwordRes = await fetch(`${emulator.url}/user_management/authenticate`, { @@ -330,7 +344,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { body: JSON.stringify({ grant_type: 'password', email, password: 'an even better passphrase' }), }); expect(passwordRes.status).toBe(403); - const passwordChallenge = await passwordRes.json(); + const passwordChallenge = (await passwordRes.json()) as any; expect(passwordChallenge.code).toBe('mfa_challenge'); expect(passwordChallenge.pending_authentication_token).toBeTruthy(); expect(passwordChallenge.authentication_challenge).toBeTruthy(); @@ -360,7 +374,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { }), }); expect(factorRes.status).toBe(201); - const factor = await factorRes.json(); + const factor = (await factorRes.json()) as any; // Step 2: Authenticate with password to trigger MFA challenge const passwordRes = await fetch(`${emulator.url}/user_management/authenticate`, { @@ -369,7 +383,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { body: JSON.stringify({ grant_type: 'password', email, password: 'an even better passphrase' }), }); expect(passwordRes.status).toBe(403); - const passwordChallenge = await passwordRes.json(); + const passwordChallenge = (await passwordRes.json()) as any; const pendingToken = passwordChallenge.pending_authentication_token as string; const challengeId = passwordChallenge.authentication_challenge.id as string; @@ -397,7 +411,7 @@ describe('end-to-end login flow (workos.com/docs story)', () => { }), }); expect(mfaRes.status).toBe(200); - const mfaAuth = await mfaRes.json(); + const mfaAuth = (await mfaRes.json()) as any; expect(mfaAuth.access_token).toBeTruthy(); expect(mfaAuth.refresh_token).toBeTruthy(); diff --git a/src/install-method.spec.ts b/src/install-method.spec.ts new file mode 100644 index 0000000..59a2264 --- /dev/null +++ b/src/install-method.spec.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from 'bun:test'; +import { detectInstallMethod, upgradeNotice } from './install-method.js'; + +describe('install method detection', () => { + it('detects npm from a package entrypoint even when Node came from Homebrew', () => { + expect( + detectInstallMethod([ + '/opt/homebrew/Cellar/node/24.0.0/bin/node', + '/opt/homebrew/lib/node_modules/@workos/emulate/dist/cli.js', + ]), + ).toBe('npm'); + }); + + it('detects npm on Windows', () => { + expect(detectInstallMethod(['C:\\Users\\test\\npm\\node_modules\\@workos\\emulate\\dist\\cli.js'])).toBe('npm'); + }); + + it('detects macOS and Linux Homebrew installations', () => { + expect(detectInstallMethod(['/opt/homebrew/Cellar/workos-emulate/0.4.0/bin/workos-emulate'])).toBe('homebrew'); + expect(detectInstallMethod(['/home/linuxbrew/.linuxbrew/Cellar/workos-emulate/0.4.0/bin/workos-emulate'])).toBe( + 'homebrew', + ); + }); + + it('treats an arbitrary standalone executable as a direct download', () => { + expect(detectInstallMethod(['/usr/local/bin/workos-emulate'])).toBe('download'); + }); +}); + +describe('upgrade notice', () => { + it('matches each installation channel', () => { + expect(upgradeNotice('npm')).toBe('Upgrade: npm install -g @workos/emulate@latest'); + expect(upgradeNotice('homebrew')).toBe('Upgrade: brew upgrade workos/tap/workos-emulate'); + expect(upgradeNotice('download')).toContain('https://github.com/workos/emulate/releases/latest'); + }); +}); diff --git a/src/install-method.ts b/src/install-method.ts new file mode 100644 index 0000000..553a39c --- /dev/null +++ b/src/install-method.ts @@ -0,0 +1,60 @@ +import { realpathSync } from 'node:fs'; + +export type InstallMethod = 'homebrew' | 'npm' | 'download'; + +const RELEASES_URL = 'https://github.com/workos/emulate/releases/latest'; + +function normalizePath(path: string): string { + return path.replaceAll('\\', '/'); +} + +function runtimePaths(): string[] { + const originalPaths = [process.argv[1], process.execPath].filter((path): path is string => Boolean(path)); + const paths = [...originalPaths]; + + for (const path of originalPaths) { + try { + paths.push(realpathSync(path)); + } catch { + // The original path remains useful when a launcher or symlink cannot be resolved. + } + } + + return [...new Set(paths)]; +} + +/** + * Infer how the CLI was installed from its entrypoint and executable paths. + * + * npm takes precedence because a Node installed by Homebrew can execute a + * globally installed npm package. Resolving argv[1] exposes the package's real + * node_modules path even when the command itself is a global bin symlink. + */ +export function detectInstallMethod(paths: string[] = runtimePaths()): InstallMethod { + const normalized = paths.map(normalizePath); + + if (normalized.some((path) => path.includes('/node_modules/'))) { + return 'npm'; + } + + if ( + normalized.some( + (path) => path.includes('/Cellar/') || path.includes('/opt/homebrew/') || path.includes('/.linuxbrew/'), + ) + ) { + return 'homebrew'; + } + + return 'download'; +} + +export function upgradeNotice(method: InstallMethod): string { + switch (method) { + case 'homebrew': + return 'Upgrade: brew upgrade workos/tap/workos-emulate'; + case 'npm': + return 'Upgrade: npm install -g @workos/emulate@latest'; + case 'download': + return `Download: ${RELEASES_URL}`; + } +} diff --git a/src/version-check.spec.ts b/src/version-check.spec.ts new file mode 100644 index 0000000..02fe7d3 --- /dev/null +++ b/src/version-check.spec.ts @@ -0,0 +1,124 @@ +import { describe, expect, it } from 'bun:test'; +import { checkForUpdates, shouldCheckForUpdates } from './version-check.js'; + +function response(status: number, options: { body?: unknown; location?: string } = {}): Response { + return new Response(options.body === undefined ? null : JSON.stringify(options.body), { + status, + headers: { + ...(options.body === undefined ? {} : { 'Content-Type': 'application/json' }), + ...(options.location ? { Location: options.location } : {}), + }, + }); +} + +describe('checkForUpdates', () => { + it('uses the npm registry for npm installations', async () => { + const calls: string[] = []; + const update = await checkForUpdates({ + currentVersion: '0.3.0', + installMethod: 'npm', + fetch: async (input) => { + calls.push(String(input)); + return response(200, { body: { version: '0.4.0' } }); + }, + }); + + expect(calls).toEqual(['https://registry.npmjs.org/@workos%2Femulate/latest']); + expect(update).toEqual({ + currentVersion: '0.3.0', + latestVersion: '0.4.0', + installMethod: 'npm', + notice: 'Upgrade: npm install -g @workos/emulate@latest', + }); + }); + + it('requires checksums before announcing a GitHub binary release', async () => { + const calls: string[] = []; + const update = await checkForUpdates({ + currentVersion: '0.3.0', + installMethod: 'download', + fetch: async (input) => { + calls.push(String(input)); + if (calls.length === 1) { + return response(302, { location: 'https://github.com/workos/emulate/releases/tag/v0.4.0' }); + } + return response(200); + }, + }); + + expect(calls).toEqual([ + 'https://github.com/workos/emulate/releases/latest', + 'https://github.com/workos/emulate/releases/download/v0.4.0/checksums.txt', + ]); + expect(update?.latestVersion).toBe('0.4.0'); + expect(update?.notice).toContain('/releases/latest'); + }); + + it('stays quiet while binary assets are incomplete', async () => { + let call = 0; + const update = await checkForUpdates({ + currentVersion: '0.3.0', + installMethod: 'homebrew', + fetch: async () => { + call++; + return call === 1 + ? response(302, { location: 'https://github.com/workos/emulate/releases/tag/v0.4.0' }) + : response(404); + }, + }); + + expect(update).toBeUndefined(); + }); + + it('stays quiet when current, ahead, invalid, or offline', async () => { + const npmResponse = (version: string) => async () => response(200, { body: { version } }); + + expect( + await checkForUpdates({ + currentVersion: '0.4.0', + installMethod: 'npm', + fetch: npmResponse('0.4.0'), + }), + ).toBeUndefined(); + expect( + await checkForUpdates({ + currentVersion: '0.5.0', + installMethod: 'npm', + fetch: npmResponse('0.4.0'), + }), + ).toBeUndefined(); + expect( + await checkForUpdates({ + currentVersion: 'development', + installMethod: 'npm', + fetch: npmResponse('0.4.0'), + }), + ).toBeUndefined(); + expect( + await checkForUpdates({ + currentVersion: '0.3.0', + installMethod: 'npm', + fetch: async () => { + throw new Error('offline'); + }, + }), + ).toBeUndefined(); + }); +}); + +describe('shouldCheckForUpdates', () => { + const base = { json: false, stderrIsTTY: true, env: {}, entryPath: '/usr/local/bin/workos-emulate' }; + + it('checks in an interactive human invocation', () => { + expect(shouldCheckForUpdates(base)).toBe(true); + }); + + it('skips JSON, non-TTY, CI, opt-out, and source development', () => { + expect(shouldCheckForUpdates({ ...base, json: true })).toBe(false); + expect(shouldCheckForUpdates({ ...base, stderrIsTTY: false })).toBe(false); + expect(shouldCheckForUpdates({ ...base, env: { CI: 'true' } })).toBe(false); + expect(shouldCheckForUpdates({ ...base, env: { NO_UPDATE_NOTIFIER: '1' } })).toBe(false); + expect(shouldCheckForUpdates({ ...base, env: { WORKOS_EMULATE_DISABLE_UPDATE_CHECK: 'true' } })).toBe(false); + expect(shouldCheckForUpdates({ ...base, entryPath: '/repo/src/cli.ts' })).toBe(false); + }); +}); diff --git a/src/version-check.ts b/src/version-check.ts new file mode 100644 index 0000000..c2a8c2e --- /dev/null +++ b/src/version-check.ts @@ -0,0 +1,117 @@ +import { lt, valid } from 'semver'; +import { detectInstallMethod, type InstallMethod, upgradeNotice } from './install-method.js'; +import { VERSION } from './version.js'; + +const NPM_LATEST_URL = 'https://registry.npmjs.org/@workos%2Femulate/latest'; +const GITHUB_LATEST_URL = 'https://github.com/workos/emulate/releases/latest'; +const GITHUB_DOWNLOAD_BASE = 'https://github.com/workos/emulate/releases/download'; +const DEFAULT_TIMEOUT_MS = 1_000; + +export interface AvailableUpdate { + currentVersion: string; + latestVersion: string; + installMethod: InstallMethod; + notice: string; +} + +type Fetcher = (input: string | URL | Request, init?: RequestInit) => Promise; + +interface UpdateCheckOptions { + currentVersion?: string; + installMethod?: InstallMethod; + fetch?: Fetcher; + timeoutMs?: number; +} + +interface ShouldCheckOptions { + json: boolean; + stderrIsTTY?: boolean; + env?: NodeJS.ProcessEnv; + entryPath?: string; +} + +function isEnabledEnvironmentValue(value: string | undefined): boolean { + return value === '1' || value?.toLowerCase() === 'true'; +} + +export function shouldCheckForUpdates({ + json, + stderrIsTTY = Boolean(process.stderr.isTTY), + env = process.env, + entryPath = process.argv[1] ?? '', +}: ShouldCheckOptions): boolean { + if (json || !stderrIsTTY || isEnabledEnvironmentValue(env.CI)) return false; + if (isEnabledEnvironmentValue(env.NO_UPDATE_NOTIFIER)) return false; + if (isEnabledEnvironmentValue(env.WORKOS_EMULATE_DISABLE_UPDATE_CHECK)) return false; + + // Source-mode development should not compare an unreleased checkout with production. + return !entryPath.replaceAll('\\', '/').endsWith('/src/cli.ts'); +} + +async function latestNpmVersion(fetcher: Fetcher, signal: AbortSignal): Promise { + const response = await fetcher(NPM_LATEST_URL, { + headers: { Accept: 'application/json' }, + signal, + }); + if (!response.ok) return undefined; + + const payload: unknown = await response.json(); + if (typeof payload !== 'object' || payload === null || !('version' in payload)) return undefined; + return typeof payload.version === 'string' ? payload.version : undefined; +} + +async function latestReadyBinaryVersion(fetcher: Fetcher, signal: AbortSignal): Promise { + const response = await fetcher(GITHUB_LATEST_URL, { + method: 'HEAD', + redirect: 'manual', + signal, + }); + + const location = response.headers.get('location') ?? ''; + const match = /\/releases\/tag\/([^/?#]+)/.exec(location); + if (!match) return undefined; + + const tag = decodeURIComponent(match[1]); + const version = tag.replace(/^v/, ''); + if (!valid(version)) return undefined; + + // release-please makes the release public before the binary workflow runs. + // Gate the notice on checksums.txt so users are never sent to incomplete assets. + const checksumResponse = await fetcher(`${GITHUB_DOWNLOAD_BASE}/${encodeURIComponent(tag)}/checksums.txt`, { + method: 'HEAD', + redirect: 'follow', + signal, + }); + return checksumResponse.ok ? version : undefined; +} + +/** + * Return an available update for the running installation channel. + * Network, timeout, registry, and parsing errors are intentionally silent. + */ +export async function checkForUpdates(options: UpdateCheckOptions = {}): Promise { + const currentVersion = options.currentVersion ?? VERSION; + const installMethod = options.installMethod ?? detectInstallMethod(); + const fetcher = options.fetch ?? globalThis.fetch; + + if (!valid(currentVersion)) return undefined; + + try { + const signal = AbortSignal.timeout(options.timeoutMs ?? DEFAULT_TIMEOUT_MS); + const latestVersion = + installMethod === 'npm' + ? await latestNpmVersion(fetcher, signal) + : await latestReadyBinaryVersion(fetcher, signal); + + if (!latestVersion || !valid(latestVersion) || !lt(currentVersion, latestVersion)) return undefined; + + return { + currentVersion, + latestVersion, + installMethod, + notice: upgradeNotice(installMethod), + }; + } catch { + return undefined; + } +} diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 0000000..457ca26 --- /dev/null +++ b/src/version.ts @@ -0,0 +1,3 @@ +import pkg from '../package.json' with { type: 'json' }; + +export const VERSION: string = pkg.version; diff --git a/src/workos/concurrent-webhooks.spec.ts b/src/workos/concurrent-webhooks.spec.ts index 2a6ee63..200609f 100644 --- a/src/workos/concurrent-webhooks.spec.ts +++ b/src/workos/concurrent-webhooks.spec.ts @@ -1,7 +1,7 @@ /** * Tests for concurrent webhook delivery scenarios */ -import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { describe, it, expect, beforeAll, afterAll } from 'bun:test'; import { createServer, type Server } from 'node:http'; import { createEmulator, type Emulator } from '../index.js'; @@ -197,7 +197,7 @@ describe('Concurrent Webhook Delivery', () => { password: 'password123', }), }); - const user = await res.json(); + const user = (await res.json()) as any; createdUserIds.push(user.id); } diff --git a/src/workos/event-bus.spec.ts b/src/workos/event-bus.spec.ts index 9819bdf..cd55522 100644 --- a/src/workos/event-bus.spec.ts +++ b/src/workos/event-bus.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, spyOn, type Mock } from 'bun:test'; import { createHmac } from 'node:crypto'; import { Store } from '../core/store.js'; import { getWorkOSStore } from './store.js'; @@ -7,12 +7,20 @@ import { EventBus } from './event-bus.js'; describe('EventBus', () => { let store: Store; let bus: EventBus; + let fetchSpy: Mock | undefined; beforeEach(() => { store = new Store(); bus = new EventBus(store); }); + // bun test runs every file in one process: restore here so a failing + // assertion can never leak a mocked fetch into later spec files. + afterEach(() => { + fetchSpy?.mockRestore(); + fetchSpy = undefined; + }); + it('stores events on emit', () => { const ws = getWorkOSStore(store); bus.emit({ event: 'user.created', data: { id: 'user_1', email: 'test@example.com' } }); @@ -84,7 +92,7 @@ describe('EventBus', () => { let receivedSignature: string | undefined; // Mock fetch to capture the delivery - const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce(new Response('ok')); + fetchSpy = spyOn(globalThis, 'fetch').mockResolvedValueOnce(new Response('ok')); ws.webhookEndpoints.insert({ object: 'webhook_endpoint', @@ -101,7 +109,7 @@ describe('EventBus', () => { // Wait for async delivery await new Promise((resolve) => setTimeout(resolve, 50)); - expect(fetchSpy).toHaveBeenCalledOnce(); + expect(fetchSpy).toHaveBeenCalledTimes(1); const [, init] = fetchSpy.mock.calls[0]; receivedBody = init!.body as string; receivedSignature = (init!.headers as Record)['WorkOS-Signature']; @@ -114,17 +122,16 @@ describe('EventBus', () => { const [, timestamp, hash] = match; const expectedHash = createHmac('sha256', secret).update(`${timestamp}.${receivedBody}`).digest('hex'); expect(hash).toBe(expectedHash); - - fetchSpy.mockRestore(); }); it('does not block when webhook delivery times out', async () => { const ws = getWorkOSStore(store); // Mock fetch to simulate a slow endpoint - const fetchSpy = vi - .spyOn(globalThis, 'fetch') - .mockImplementation(() => new Promise((resolve) => setTimeout(() => resolve(new Response('ok')), 10000))); + fetchSpy = spyOn(globalThis, 'fetch').mockImplementation( + // Cast: Bun types `fetch` with a `preconnect` property the mock closure doesn't need. + (() => new Promise((resolve) => setTimeout(() => resolve(new Response('ok')), 10000))) as unknown as typeof fetch, + ); ws.webhookEndpoints.insert({ object: 'webhook_endpoint', @@ -144,7 +151,5 @@ describe('EventBus', () => { // Should complete in under 100ms (not waiting for 10s fetch) expect(elapsed).toBeLessThan(100); expect(ws.events.all()).toHaveLength(1); - - fetchSpy.mockRestore(); }); }); diff --git a/src/workos/interactive-auth.spec.ts b/src/workos/interactive-auth.spec.ts index 2dd01cc..78d7f55 100644 --- a/src/workos/interactive-auth.spec.ts +++ b/src/workos/interactive-auth.spec.ts @@ -1,7 +1,7 @@ /** * Tests for interactive auth mode (HTML login pages) */ -import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { describe, it, expect, beforeAll, afterAll } from 'bun:test'; import { createEmulator, type Emulator } from '../index.js'; describe('Interactive Auth Mode', () => { diff --git a/src/workos/response-shapes.spec.ts b/src/workos/response-shapes.spec.ts index b5155db..88b6563 100644 --- a/src/workos/response-shapes.spec.ts +++ b/src/workos/response-shapes.spec.ts @@ -15,7 +15,7 @@ * exact sets. Closing a divergence (emit the field) forces deleting its ledger * entry, and any *new* divergence fails the build — drift can't accrue silently. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { Store } from '../core/index.js'; import { getWorkOSStore } from './store.js'; import { diff --git a/src/workos/routes/api-keys.spec.ts b/src/workos/routes/api-keys.spec.ts index d840dc5..ebe15d8 100644 --- a/src/workos/routes/api-keys.spec.ts +++ b/src/workos/routes/api-keys.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/audit-logs.spec.ts b/src/workos/routes/audit-logs.spec.ts index b66c82a..9d8542e 100644 --- a/src/workos/routes/audit-logs.spec.ts +++ b/src/workos/routes/audit-logs.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/auth-challenges.spec.ts b/src/workos/routes/auth-challenges.spec.ts index 6497eea..70f1821 100644 --- a/src/workos/routes/auth-challenges.spec.ts +++ b/src/workos/routes/auth-challenges.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/auth.spec.ts b/src/workos/routes/auth.spec.ts index c31886a..33c03bf 100644 --- a/src/workos/routes/auth.spec.ts +++ b/src/workos/routes/auth.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/authorization-checks.spec.ts b/src/workos/routes/authorization-checks.spec.ts index 421bf7a..2305e7f 100644 --- a/src/workos/routes/authorization-checks.spec.ts +++ b/src/workos/routes/authorization-checks.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/authorization-org-roles.spec.ts b/src/workos/routes/authorization-org-roles.spec.ts index 09870af..acb80f0 100644 --- a/src/workos/routes/authorization-org-roles.spec.ts +++ b/src/workos/routes/authorization-org-roles.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/authorization-permissions.spec.ts b/src/workos/routes/authorization-permissions.spec.ts index 4a4553f..f8eaff0 100644 --- a/src/workos/routes/authorization-permissions.spec.ts +++ b/src/workos/routes/authorization-permissions.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/authorization-resources.spec.ts b/src/workos/routes/authorization-resources.spec.ts index fdf56de..b4d210f 100644 --- a/src/workos/routes/authorization-resources.spec.ts +++ b/src/workos/routes/authorization-resources.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/authorization-roles.spec.ts b/src/workos/routes/authorization-roles.spec.ts index 486844f..0dc606b 100644 --- a/src/workos/routes/authorization-roles.spec.ts +++ b/src/workos/routes/authorization-roles.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/config.spec.ts b/src/workos/routes/config.spec.ts index 0ea7fa8..1906045 100644 --- a/src/workos/routes/config.spec.ts +++ b/src/workos/routes/config.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/connect.spec.ts b/src/workos/routes/connect.spec.ts index 47a7905..caf1189 100644 --- a/src/workos/routes/connect.spec.ts +++ b/src/workos/routes/connect.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/connections.spec.ts b/src/workos/routes/connections.spec.ts index 2d1c930..db2ca95 100644 --- a/src/workos/routes/connections.spec.ts +++ b/src/workos/routes/connections.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/data-integrations.spec.ts b/src/workos/routes/data-integrations.spec.ts index 17aa325..d43128f 100644 --- a/src/workos/routes/data-integrations.spec.ts +++ b/src/workos/routes/data-integrations.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/directories.spec.ts b/src/workos/routes/directories.spec.ts index 616a018..33ff11f 100644 --- a/src/workos/routes/directories.spec.ts +++ b/src/workos/routes/directories.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap, type Store } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/events.spec.ts b/src/workos/routes/events.spec.ts index ace3475..ceba038 100644 --- a/src/workos/routes/events.spec.ts +++ b/src/workos/routes/events.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin, getWorkOSStore } from '../index.js'; diff --git a/src/workos/routes/feature-flags.spec.ts b/src/workos/routes/feature-flags.spec.ts index 783b840..81b29ef 100644 --- a/src/workos/routes/feature-flags.spec.ts +++ b/src/workos/routes/feature-flags.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap, type Store } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/invitations.spec.ts b/src/workos/routes/invitations.spec.ts index 2e7b3cd..cb6236e 100644 --- a/src/workos/routes/invitations.spec.ts +++ b/src/workos/routes/invitations.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/legacy-mfa.spec.ts b/src/workos/routes/legacy-mfa.spec.ts index e61969a..110c51f 100644 --- a/src/workos/routes/legacy-mfa.spec.ts +++ b/src/workos/routes/legacy-mfa.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/memberships.spec.ts b/src/workos/routes/memberships.spec.ts index 4c08d78..79699bb 100644 --- a/src/workos/routes/memberships.spec.ts +++ b/src/workos/routes/memberships.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { formatMembership } from '../helpers.js'; diff --git a/src/workos/routes/oauth.spec.ts b/src/workos/routes/oauth.spec.ts index 16cad30..a58e924 100644 --- a/src/workos/routes/oauth.spec.ts +++ b/src/workos/routes/oauth.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin, seedFromConfig } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/organizations.spec.ts b/src/workos/routes/organizations.spec.ts index 09dd982..079e2e0 100644 --- a/src/workos/routes/organizations.spec.ts +++ b/src/workos/routes/organizations.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/password-reset.spec.ts b/src/workos/routes/password-reset.spec.ts index 9dbbe62..568f588 100644 --- a/src/workos/routes/password-reset.spec.ts +++ b/src/workos/routes/password-reset.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/pipes.spec.ts b/src/workos/routes/pipes.spec.ts index d712b62..7738656 100644 --- a/src/workos/routes/pipes.spec.ts +++ b/src/workos/routes/pipes.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin, seedFromConfig } from '../index.js'; diff --git a/src/workos/routes/portal.spec.ts b/src/workos/routes/portal.spec.ts index 70d110c..fce5ae5 100644 --- a/src/workos/routes/portal.spec.ts +++ b/src/workos/routes/portal.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/radar.spec.ts b/src/workos/routes/radar.spec.ts index 523f09e..90d6cb0 100644 --- a/src/workos/routes/radar.spec.ts +++ b/src/workos/routes/radar.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap, type Store } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/sessions.spec.ts b/src/workos/routes/sessions.spec.ts index 13710b5..a582c65 100644 --- a/src/workos/routes/sessions.spec.ts +++ b/src/workos/routes/sessions.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; @@ -44,6 +44,10 @@ describe('Session routes', () => { organization_id: null, ip_address: null, user_agent: null, + auth_method: 'password', + status: 'active', + expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), + ended_at: null, }); const res = await app.request( @@ -78,6 +82,10 @@ describe('Session routes', () => { organization_id: null, ip_address: null, user_agent: null, + auth_method: 'password', + status: 'active', + expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), + ended_at: null, }); const res = await app.request(`/user_management/sessions/logout?session_id=${session.id}`); diff --git a/src/workos/routes/sso.spec.ts b/src/workos/routes/sso.spec.ts index fef4883..e56bdb4 100644 --- a/src/workos/routes/sso.spec.ts +++ b/src/workos/routes/sso.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/user-features.spec.ts b/src/workos/routes/user-features.spec.ts index 7d810b8..9e2faa5 100644 --- a/src/workos/routes/user-features.spec.ts +++ b/src/workos/routes/user-features.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; import { getWorkOSStore } from '../store.js'; diff --git a/src/workos/routes/users.spec.ts b/src/workos/routes/users.spec.ts index 658f074..471213e 100644 --- a/src/workos/routes/users.spec.ts +++ b/src/workos/routes/users.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/webhook-endpoints.spec.ts b/src/workos/routes/webhook-endpoints.spec.ts index 0cc6f34..af4ba3a 100644 --- a/src/workos/routes/webhook-endpoints.spec.ts +++ b/src/workos/routes/webhook-endpoints.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/routes/widgets.spec.ts b/src/workos/routes/widgets.spec.ts index ce3df86..895d1df 100644 --- a/src/workos/routes/widgets.spec.ts +++ b/src/workos/routes/widgets.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { createServer, type ApiKeyMap } from '../../core/index.js'; import { workosPlugin } from '../index.js'; diff --git a/src/workos/seed-m2m.spec.ts b/src/workos/seed-m2m.spec.ts index bcfd308..f0d51df 100644 --- a/src/workos/seed-m2m.spec.ts +++ b/src/workos/seed-m2m.spec.ts @@ -4,7 +4,7 @@ * pinned client_id/secret) and API keys in seed config so a dockerized local * dev environment has usable credentials on startup. */ -import { describe, it, expect, afterEach } from 'vitest'; +import { describe, it, expect, afterEach } from 'bun:test'; import { createEmulator, type Emulator } from '../index.js'; import { validateSeedConfig } from './config-validator.js'; diff --git a/src/workos/seed-memberships.spec.ts b/src/workos/seed-memberships.spec.ts index c2a9aef..d687d5b 100644 --- a/src/workos/seed-memberships.spec.ts +++ b/src/workos/seed-memberships.spec.ts @@ -4,7 +4,7 @@ * don't resolve to a seeded user — a dangling membership could not serialize (the * membership serializer requires a resolvable embedded user). */ -import { describe, it, expect, afterEach } from 'vitest'; +import { describe, it, expect, afterEach } from 'bun:test'; import { createEmulator, type Emulator } from '../index.js'; import { validateSeedConfig } from './config-validator.js'; diff --git a/src/workos/seed-pinned-ids.spec.ts b/src/workos/seed-pinned-ids.spec.ts index 6473286..c006ff3 100644 --- a/src/workos/seed-pinned-ids.spec.ts +++ b/src/workos/seed-pinned-ids.spec.ts @@ -5,7 +5,7 @@ * the restart-minted id churns duplicate rows. These tests prove a pinned id is what the * API returns, what a login token carries, and what a webhook delivers. */ -import { describe, it, expect, afterEach } from 'vitest'; +import { describe, it, expect, afterEach } from 'bun:test'; import { createServer, type Server } from 'node:http'; import { createEmulator, type Emulator } from '../index.js'; import { validateSeedConfig } from './config-validator.js'; diff --git a/src/workos/webhook-signer.spec.ts b/src/workos/webhook-signer.spec.ts index d29ee50..8f5fff2 100644 --- a/src/workos/webhook-signer.spec.ts +++ b/src/workos/webhook-signer.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { createHmac } from 'node:crypto'; import { signWebhookPayload } from './webhook-signer.js'; diff --git a/tsconfig.tests.json b/tsconfig.tests.json new file mode 100644 index 0000000..fbbb13d --- /dev/null +++ b/tsconfig.tests.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + "rootDir": ".", + "types": ["bun", "node"] + }, + "include": ["src/**/*.spec.ts", "scripts/**/*.spec.ts", "src/**/*.test-utils.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index ee4b3ed..0000000 --- a/vitest.config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - globals: true, - environment: 'node', - include: ['src/**/*.spec.ts', 'scripts/**/*.spec.ts'], - coverage: { - provider: 'v8', - reporter: ['text', 'json', 'html'], - exclude: ['**/*.d.ts', '**/node_modules/**', '**/dist/**'], - }, - }, -});