diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index c304dc5..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint", "prettier"], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended" - ], - "rules": { - "@typescript-eslint/explicit-function-return-type": "warn", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], - "prettier/prettier": "error" - }, - "env": { - "node": true - } -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8027a22..961acc0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,41 +7,26 @@ on: branches: [main] jobs: - test: + node: runs-on: ubuntu-latest strategy: matrix: - node-version: [23.x] + node-version: [24, 25] steps: - - uses: actions/checkout@v4 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} + - uses: actions/checkout@v6 - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 10 - - - name: Get pnpm store directory - id: pnpm-cache - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + uses: pnpm/action-setup@v4 - - uses: actions/cache@v3 - name: Setup pnpm cache + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v6 with: - path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} - key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - pnpm-store-${{ runner.os }}- + node-version: ${{ matrix.node-version }} + cache: pnpm - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - name: Type check run: pnpm typecheck @@ -54,3 +39,18 @@ jobs: - name: Build run: pnpm build + + bun: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - name: Use Bun + uses: oven-sh/setup-bun@v2 + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Test Bun providers + run: bun run test:bun diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0f116cc..af88d02 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,77 +1,87 @@ name: Publish to NPM on: - workflow_dispatch: - inputs: - version: - description: "Version to publish (e.g., 1.0.0)" - required: true - type: string + release: + types: + - published + +permissions: + contents: read + id-token: write jobs: - publish: + verify-ci: + name: Verify CI passed runs-on: ubuntu-latest permissions: - contents: write - id-token: write + actions: read + contents: read steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} + - name: Verify CI passed for the release commit + env: + GH_TOKEN: ${{ github.token }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + run: | + run_id="$(gh run list \ + --workflow ci.yml \ + --branch "$DEFAULT_BRANCH" \ + --commit "${{ github.sha }}" \ + --event push \ + --status completed \ + --json databaseId,conclusion \ + --jq 'map(select(.conclusion == "success"))[0].databaseId // ""')" - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "23.x" - registry-url: "https://registry.npmjs.org" + if [ -z "$run_id" ]; then + echo "No successful CI run found for ${{ github.sha }} on $DEFAULT_BRANCH." + echo "Run CI successfully before publishing this release." + exit 1 + fi + + echo "Found successful CI run: $run_id" + + publish: + name: Publish to npm + runs-on: ubuntu-latest + needs: verify-ci + + steps: + - uses: actions/checkout@v6 - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4 + + - name: Setup Node.js 24 + uses: actions/setup-node@v6 with: - version: 10 + node-version: 24 + registry-url: "https://registry.npmjs.org" + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile - - name: Setup pnpm cache + - name: Validate release tag run: | - mkdir -p ~/.pnpm-store - echo "STORE_PATH=~/.pnpm-store" >> $GITHUB_ENV + package_version="$(node -p "require('./package.json').version")" + release_version="${GITHUB_REF_NAME#v}" - - uses: actions/cache@v3 - name: Setup pnpm cache - with: - path: ~/.pnpm-store - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- + if [ "$package_version" != "$release_version" ]; then + echo "Release tag v$release_version does not match package.json version $package_version." + exit 1 + fi - - name: Install dependencies - run: pnpm install + - name: Type check + run: pnpm typecheck + + - name: Lint + run: pnpm lint - name: Test - run: pnpm test + run: pnpm test:coverage - name: Build run: pnpm build - - name: Validate version - run: | - if ! [[ "${{ github.event.inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then - echo "Invalid version format. Please use semantic versioning (e.g., 1.0.0 or 1.0.0-beta.1)" - exit 1 - fi - - - name: Update package version - run: | - npm version ${{ github.event.inputs.version }} --no-git-tag-version - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git - git add package.json - git commit -m "release: ${{ github.event.inputs.version }}" - git tag v${{ github.event.inputs.version }} - git push origin main --tags - - name: Publish to NPM shell: bash - run: pnpm publish --no-git-checks - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm publish --provenance --access public diff --git a/.gitignore b/.gitignore index e6d113e..0fb6d13 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ build/Release # Dependency directories node_modules/ +.pnpm-store/ jspm_packages/ # Snowpack dependency directory (https://snowpack.dev/) @@ -136,4 +137,7 @@ dist .pnp.* # OS -.DS_Store \ No newline at end of file +.DS_Store + +# Example databases +*.sqlite diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..1635f24 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +minimum-release-age=10080 \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index a2d42ed..0000000 --- a/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "semi": true, - "trailingComma": "es5", - "singleQuote": true, - "printWidth": 100, - "tabWidth": 2, - "useTabs": false, - "endOfLine": "lf" -} diff --git a/LICENSE b/LICENSE index 19d04b1..e064636 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2025 Sandrino Di Mattia +Copyright (c) 2026 Sandrino Di Mattia Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index def2342..725adae 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](https://www.typescriptlang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -A lightweight SQLite migration system for Node.js, built with TypeScript. Manage your SQLite database schema changes with ease and confidence. +A lightweight SQLite migration system for Node.js and Bun, built with TypeScript. Manage your SQLite database schema changes with ease and confidence. ## Features @@ -14,15 +14,18 @@ A lightweight SQLite migration system for Node.js, built with TypeScript. Manage - 🔄 Supports migrations and rollbacks - 📊 Migration status tracking - 🔐 Transaction-safe migrations +- 🧩 Works with Node 24+ `node:sqlite`, Bun `bun:sqlite`, Bun `SQL`, optional `better-sqlite3`, and compatible SQLite clients ## Installation +Requires Node.js 24+ or Bun. + ```bash -npm install sqlite-up better-sqlite3 +npm install sqlite-up # or -yarn add sqlite-up better-sqlite3 +yarn add sqlite-up # or -pnpm add sqlite-up better-sqlite3 +pnpm add sqlite-up ``` ## Quick Start @@ -36,10 +39,10 @@ mkdir migrations 2. Create your first migration file `migrations/001_create_users.ts`: ```typescript -import { Database } from 'better-sqlite3'; +import type { SqliteDatabase } from 'sqlite-up'; -export const up = (db: Database): void => { - db.exec(` +export const up = async (db: SqliteDatabase): Promise => { + await db.exec(` CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL UNIQUE, @@ -49,19 +52,19 @@ export const up = (db: Database): void => { `); }; -export const down = (db: Database): void => { - db.exec('DROP TABLE users'); +export const down = async (db: SqliteDatabase): Promise => { + await db.exec('DROP TABLE users'); }; ``` 3. Use the migrator in your code: ```typescript -import { Database } from 'better-sqlite3'; +import { DatabaseSync } from 'node:sqlite'; import { Migrator } from 'sqlite-up'; async function main() { - const db = new Database('myapp.db'); + const db = new DatabaseSync('myapp.db'); const migrator = new Migrator({ db, @@ -80,6 +83,57 @@ async function main() { main().catch(console.error); ``` +### Bun + +The same migrator accepts Bun's synchronous `bun:sqlite` database: + +```typescript +import { Database } from 'bun:sqlite'; +import { Migrator } from 'sqlite-up'; + +const db = new Database('myapp.db', { create: true }); +const migrator = new Migrator({ + db, + migrationsDir: './migrations', +}); + +await migrator.apply(); +``` + +It also accepts Bun's Promise-based `SQL` SQLite client: + +```typescript +import { SQL } from 'bun'; +import { Migrator } from 'sqlite-up'; + +const sql = new SQL('sqlite://myapp.db'); +const migrator = new Migrator({ + db: sql, + migrationsDir: './migrations', +}); + +await migrator.apply(); +``` + +When using Bun `SQL`, write migration files as `async` functions and `await` database calls. + +### better-sqlite3 + +If your project already uses `better-sqlite3`, pass its database instance directly. `sqlite-up` does not install it or require it as a peer dependency, so install `better-sqlite3` in your application if you use this provider. + +```typescript +import Database from 'better-sqlite3'; +import { Migrator } from 'sqlite-up'; + +const db = new Database('myapp.db'); +const migrator = new Migrator({ + db, + migrationsDir: './migrations', +}); + +await migrator.apply(); +``` + ## API Reference ### `Migrator` @@ -90,7 +144,7 @@ The main class for managing migrations. ```typescript interface MigratorOptions { - db: Database; // better-sqlite3 database instance + db: MigratorDatabase; // Node DatabaseSync, Bun Database, Bun SQL, better-sqlite3, or compatible SQLite instance migrationsDir: string; // Directory containing migration files migrationsTable?: string; // Optional: Table name for tracking migrations (default: 'schema_migrations') migrationsLockTable?: string; // Optional: Table name for migration locks (default: 'schema_migrations_lock') @@ -169,7 +223,7 @@ console.log('Migration Plan:', plan); // Example output: // Migration Plan: { // nextBatch: 2, -// pending: ['003_add_email_index.ts'] +// pendingMigrations: ['003_add_email_index.ts'] // } ``` @@ -192,52 +246,60 @@ await migrator.apply(); ##### Transaction Safety -All migrations are run within a transaction. If any part of a migration fails, the entire migration is rolled back: +All pending migrations in one `apply()` call run in a single transaction. If any part of a migration fails, the entire batch is rolled back: ```typescript -export const up = (db: Database): void => { +import type { SqliteDatabase } from 'sqlite-up'; + +export const up = async (db: SqliteDatabase): Promise => { // Both operations will be in the same transaction - db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY)'); - db.exec('CREATE INDEX idx_user_id ON users(id)'); + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY)'); + await db.exec('CREATE INDEX idx_user_id ON users(id)'); // If any operation fails, the entire migration is rolled back // and the database remains in its previous state }; ``` +For synchronous SQLite clients such as Node `DatabaseSync`, Bun `Database`, `better-sqlite3`, and compatible `exec`/`prepare` clients, `sqlite-up` uses explicit `BEGIN IMMEDIATE` transactions so async migration functions are still awaited before commit or rollback. For Bun `SQL`, `sqlite-up` uses Bun SQL's native async transaction support when available. + ## Migration Files Migration files should be TypeScript or JavaScript files that export `up` and `down` functions: ```typescript -import { Database } from 'better-sqlite3'; +import type { SqliteDatabase } from 'sqlite-up'; -export const up = (db: Database): void => { +export const up = async (db: SqliteDatabase): Promise => { // Migration code here }; -export const down = (db: Database): void => { +export const down = async (db: SqliteDatabase): Promise => { // Rollback code here }; ``` Files should be named using the format: `XXX_description.ts` where XXX is a sequence number (e.g., `001_`, `002_`). +The migrator loads migration files with dynamic `import()`. Bun can load TypeScript migrations directly. In Node.js, run your migration script with a TypeScript runtime such as `tsx`, or compile migrations to JavaScript and use `.js` migration files. You can also customize loaded extensions with `fileExtensions`; `.d.ts` files are always ignored. + ## Error Handling ```typescript import { - SqliteUpError, // Base error class + MigrationError, // Base error class MigrationFileError, // Issues with migration files MigrationLockError, // Locking-related errors MigrationExecutionError, // Errors during migration execution } from 'sqlite-up'; -try { - await migrator.apply(); -} catch (error) { - if (error instanceof MigrationLockError) { - console.error('Migration failed, a different process is holding the lock:', error.message); +const result = await migrator.apply(); + +if (!result.success) { + if (result.error instanceof MigrationLockError) { + console.error('Migration failed, a different process is holding the lock:', result.error.message); + } else { + console.error('Migration failed:', result.error?.message); } } ``` @@ -251,13 +313,27 @@ The library provides specific error classes for different scenarios: ## Examples -Check out the [example directory](https://github.com/sandrinodimattia/sqlite-up/tree/main/example) for complete working examples. +Check out the [examples directory](https://github.com/sandrinodimattia/sqlite-up/tree/main/examples) for complete working examples. ## FAQ -### When running migrations as part of Vitest I get the following error: TypeError: Unknown file extension ".ts" +### When running migrations as part of Vitest I get `TypeError: Unknown file extension ".ts"` -This happens due to how module resolution works in Vitest. To work around this, you can add a `setupFile` to your `vitest.setup.ts` file: +This happens when a migration file is dynamically imported at runtime but the process loading it is not configured to handle TypeScript. Vitest can transform test files, but dynamically imported migration files may still need to be inside Vitest's transform path or loaded through a TypeScript-aware runtime. + +If your tests use TypeScript migration files, run the tests with Vitest as the test runner and keep the migrations in a location Vitest can transform. If the migrations are generated into a temporary directory or loaded by a helper process that runs plain Node.js, either write the test migrations as `.js` files or run that helper through a TypeScript loader such as `tsx` or `ts-node/esm`. + +```bash +pnpm exec vitest run + +# or, for a standalone migration helper used by tests +pnpm exec tsx migrate.ts + +# or, with ts-node's ESM loader +node --loader ts-node/esm migrate.ts +``` + +If you prefer to register the ESM loader from Vitest setup, add a setup file: ```typescript import { defineConfig } from 'vitest/config'; @@ -265,29 +341,32 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { environment: 'node', - reporters: ['verbose'], - include: ['src/**/*.test.ts'], - coverage: { - reporter: ['text', 'json', 'html'], - }, setupFiles: ['./vitest.setup.ts'], }, }); ``` -Then in your `vitest.setup.ts` file, register the TypeScript loader: +Then register the TypeScript loader in `vitest.setup.ts`: ```typescript import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; -// Register TypeScript loader register('ts-node/esm', pathToFileURL('./')); +``` + +### Why do I get `TypeError: Unknown file extension ".ts"` in Node.js? + +`sqlite-up` loads migrations with dynamic `import()`, so Node.js needs a loader that understands TypeScript migration files. Run your migration entry point with a TypeScript runtime such as `tsx`, use an ESM loader such as `ts-node/esm`, or compile migrations to JavaScript before running them with plain Node.js. -// This will ensure .ts files are properly loaded -process.env.NODE_OPTIONS = '--loader ts-node/esm'; +```bash +pnpm exec tsx migrate.ts +# or +node --loader ts-node/esm migrate.ts ``` +For production deployments that run plain Node.js, prefer compiled `.js` migrations and point `migrationsDir` at the compiled migration output. + ## Contributing ### Development @@ -299,12 +378,24 @@ pnpm install # Run tests pnpm test +# Run Bun provider tests +pnpm test:bun + # Run tests with coverage pnpm test:coverage +# Type check +pnpm typecheck + # Build the project pnpm build +# Check formatting and lint rules +pnpm check + +# Apply safe and unsafe Biome fixes locally +pnpm check:fix + # Lint the code pnpm lint diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..45f1cd9 --- /dev/null +++ b/biome.json @@ -0,0 +1,81 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "root": true, + "css": { + "parser": { + "tailwindDirectives": true + } + }, + "formatter": { + "attributePosition": "auto", + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 120 + }, + "javascript": { + "formatter": { + "arrowParentheses": "always", + "bracketSameLine": false, + "bracketSpacing": true, + "jsxQuoteStyle": "single", + "quoteProperties": "asNeeded", + "quoteStyle": "single", + "semicolons": "always", + "trailingCommas": "es5" + } + }, + "json": { + "formatter": { + "trailingCommas": "none" + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "a11y": { + "noLabelWithoutControl": "off", + "useButtonType": "off", + "noSvgWithoutTitle": "off", + "useMediaCaption": "off", + "useKeyWithClickEvents": "off", + "useSemanticElements": "off", + "useAltText": "warn" + }, + "correctness": { + "noUnsafeOptionalChaining": "off", + "useImportExtensions": "off", + "useExhaustiveDependencies": "warn" + }, + "security": { + "noDangerouslySetInnerHtml": "off" + }, + "complexity": { + "useLiteralKeys": "error" + }, + "style": { + "noNonNullAssertion": "off", + "noParameterAssign": "off", + "useImportType": "error" + }, + "suspicious": { + "noExplicitAny": "off", + "noAssignInExpressions": "off", + "noArrayIndexKey": "off", + "noMisleadingCharacterClass": "off" + } + } + }, + "assist": { + "actions": { + "source": { + "organizeImports": "on" + } + } + }, + "files": { + "includes": ["**", "!!.agents", "!!.claude", "!!.pnpm-store", "!!coverage", "!!dist", "!!node_modules"] + } +} diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..9050416 --- /dev/null +++ b/bun.lock @@ -0,0 +1,533 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "sqlite-up", + "devDependencies": { + "@biomejs/biome": "^2.4.13", + "@types/better-sqlite3": "^7.6.13", + "@types/bun": "^1.3.13", + "@types/node": "^25.6.0", + "@vitest/coverage-v8": "^4.1.5", + "better-sqlite3": "^12.9.0", + "husky": "^9.1.7", + "jsdoc-lint": "0.4.0", + "lint-staged": "^16.4.0", + "tsup": "^8.5.1", + "tsx": "^4.21.0", + "typescript": "^6.0.3", + "vitest": "^4.1.5", + }, + }, + }, + "packages": { + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], + + "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "7.27.1", "@babel/helper-validator-identifier": "7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="], + + "@biomejs/biome": ["@biomejs/biome@2.4.13", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.13", "@biomejs/cli-darwin-x64": "2.4.13", "@biomejs/cli-linux-arm64": "2.4.13", "@biomejs/cli-linux-arm64-musl": "2.4.13", "@biomejs/cli-linux-x64": "2.4.13", "@biomejs/cli-linux-x64-musl": "2.4.13", "@biomejs/cli-win32-arm64": "2.4.13", "@biomejs/cli-win32-x64": "2.4.13" }, "bin": { "biome": "bin/biome" } }, "sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.13", "", { "os": "win32", "cpu": "x64" }, "sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.7", "", { "os": "android", "cpu": "arm64" }, "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.7", "", { "os": "android", "cpu": "x64" }, "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.7", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.7", "", { "os": "linux", "cpu": "arm" }, "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.7", "", { "os": "linux", "cpu": "ia32" }, "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.7", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.7", "", { "os": "linux", "cpu": "s390x" }, "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.7", "", { "os": "none", "cpu": "x64" }, "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.7", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.7", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.7", "", { "os": "sunos", "cpu": "x64" }, "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "3.1.2", "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.2", "", { "os": "android", "cpu": "arm" }, "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.60.2", "", { "os": "android", "cpu": "arm64" }, "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.60.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.60.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.60.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.60.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.60.2", "", { "os": "linux", "cpu": "arm" }, "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.60.2", "", { "os": "linux", "cpu": "arm" }, "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.60.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.60.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.60.2", "", { "os": "linux", "cpu": "none" }, "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.60.2", "", { "os": "linux", "cpu": "none" }, "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.60.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.60.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.60.2", "", { "os": "linux", "cpu": "none" }, "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.60.2", "", { "os": "linux", "cpu": "none" }, "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.60.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.60.2", "", { "os": "linux", "cpu": "x64" }, "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.60.2", "", { "os": "linux", "cpu": "x64" }, "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.60.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.60.2", "", { "os": "none", "cpu": "arm64" }, "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.60.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.60.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.60.2", "", { "os": "win32", "cpu": "x64" }, "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.2", "", { "os": "win32", "cpu": "x64" }, "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA=="], + + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + + "@types/better-sqlite3": ["@types/better-sqlite3@7.6.13", "", { "dependencies": { "@types/node": "25.6.0" } }, "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA=="], + + "@types/bun": ["@types/bun@1.3.13", "", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="], + + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "4.0.2", "assertion-error": "2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "7.19.2" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.5", "", { "dependencies": { "@bcoe/v8-coverage": "1.0.2", "@vitest/utils": "4.1.5", "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.1.0", "tinyrainbow": "3.1.0" }, "peerDependencies": { "vitest": "4.1.5" } }, "sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A=="], + + "@vitest/expect": ["@vitest/expect@4.1.5", "", { "dependencies": { "@standard-schema/spec": "1.1.0", "@types/chai": "5.2.3", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "chai": "6.2.2", "tinyrainbow": "3.1.0" } }, "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw=="], + + "@vitest/mocker": ["@vitest/mocker@4.1.5", "", { "dependencies": { "@vitest/spy": "4.1.5", "estree-walker": "3.0.3", "magic-string": "0.30.21" }, "optionalDependencies": { "vite": "6.0.11" } }, "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@4.1.5", "", { "dependencies": { "tinyrainbow": "3.1.0" } }, "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g=="], + + "@vitest/runner": ["@vitest/runner@4.1.5", "", { "dependencies": { "@vitest/utils": "4.1.5", "pathe": "2.0.3" } }, "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ=="], + + "@vitest/snapshot": ["@vitest/snapshot@4.1.5", "", { "dependencies": { "@vitest/pretty-format": "4.1.5", "@vitest/utils": "4.1.5", "magic-string": "0.30.21", "pathe": "2.0.3" } }, "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ=="], + + "@vitest/spy": ["@vitest/spy@4.1.5", "", {}, "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ=="], + + "@vitest/utils": ["@vitest/utils@4.1.5", "", { "dependencies": { "@vitest/pretty-format": "4.1.5", "convert-source-map": "2.0.0", "tinyrainbow": "3.1.0" } }, "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug=="], + + "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], + + "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "1.1.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], + + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + + "ast-v8-to-istanbul": ["ast-v8-to-istanbul@1.0.0", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.31", "estree-walker": "3.0.3", "js-tokens": "10.0.0" } }, "sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "better-sqlite3": ["better-sqlite3@12.9.0", "", { "dependencies": { "bindings": "1.5.0", "prebuild-install": "7.1.3" } }, "sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ=="], + + "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], + + "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "5.7.1", "inherits": "2.0.4", "readable-stream": "3.6.2" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], + + "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "1.5.1", "ieee754": "1.2.1" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + + "bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="], + + "bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "0.2.5" }, "peerDependencies": { "esbuild": "0.27.7" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="], + + "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + + "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], + + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "4.1.2" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + + "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + + "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "5.1.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], + + "cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "8.0.0", "string-width": "8.2.1" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="], + + "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], + + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + + "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + + "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], + + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + + "es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], + + "esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "1.0.8" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + + "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], + + "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + + "fdir": ["fdir@6.5.0", "", { "optionalDependencies": { "picomatch": "4.0.4" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="], + + "fix-dts-default-cjs-exports": ["fix-dts-default-cjs-exports@1.0.1", "", { "dependencies": { "magic-string": "0.30.21", "mlly": "1.8.2", "rollup": "4.60.2" } }, "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg=="], + + "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + + "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], + + "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], + + "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], + + "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "1.5.0" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], + + "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "3.2.2", "make-dir": "4.0.0", "supports-color": "7.2.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], + + "istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "2.0.2", "istanbul-lib-report": "3.0.1" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="], + + "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="], + + "js-tokens": ["js-tokens@10.0.0", "", {}, "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q=="], + + "jsdoc-lint": ["jsdoc-lint@0.4.0", "", { "dependencies": { "typescript": "^6.0.3" }, "bin": { "jsdoc-lint": "dist/cli/index.js" } }, "sha512-k6DzgaDMMYaD1AGzT0iK0hsTkzhr2MYDD880n7S9vQfhNkWt4cbsVt6dmPawRwdYODiGuwOdRKdVV85dzXltUg=="], + + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "lint-staged": ["lint-staged@16.4.0", "", { "dependencies": { "commander": "14.0.3", "listr2": "9.0.5", "picomatch": "4.0.4", "string-argv": "0.3.2", "tinyexec": "1.1.1", "yaml": "2.8.3" }, "bin": { "lint-staged": "bin/lint-staged.js" } }, "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw=="], + + "listr2": ["listr2@9.0.5", "", { "dependencies": { "cli-truncate": "5.2.0", "colorette": "2.0.20", "eventemitter3": "5.0.4", "log-update": "6.1.0", "rfdc": "1.4.1", "wrap-ansi": "9.0.2" } }, "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g=="], + + "load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="], + + "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "7.3.0", "cli-cursor": "5.0.0", "slice-ansi": "7.1.2", "strip-ansi": "7.2.0", "wrap-ansi": "9.0.2" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "magicast": ["magicast@0.5.2", "", { "dependencies": { "@babel/parser": "7.29.2", "@babel/types": "7.29.0", "source-map-js": "1.2.1" } }, "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ=="], + + "make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "7.7.4" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="], + + "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], + + "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], + + "mlly": ["mlly@1.8.2", "", { "dependencies": { "acorn": "8.16.0", "pathe": "2.0.3", "pkg-types": "1.3.1", "ufo": "1.6.3" } }, "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "1.3.0", "object-assign": "4.1.1", "thenify-all": "1.6.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="], + + "node-abi": ["node-abi@3.89.0", "", { "dependencies": { "semver": "7.7.4" } }, "sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1.0.2" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "5.0.1" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + + "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], + + "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "0.1.8", "mlly": "1.8.2", "pathe": "2.0.3" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + + "postcss": ["postcss@8.5.12", "", { "dependencies": { "nanoid": "3.3.11", "picocolors": "1.1.1", "source-map-js": "1.2.1" } }, "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA=="], + + "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "3.1.3" }, "optionalDependencies": { "postcss": "8.5.12", "tsx": "4.21.0", "yaml": "2.8.3" } }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], + + "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "2.1.2", "expand-template": "2.0.3", "github-from-package": "0.0.0", "minimist": "1.2.8", "mkdirp-classic": "0.5.3", "napi-build-utils": "2.0.0", "node-abi": "3.89.0", "pump": "3.0.4", "rc": "1.2.8", "simple-get": "4.0.1", "tar-fs": "2.1.4", "tunnel-agent": "0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], + + "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "1.4.5", "once": "1.4.0" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], + + "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "0.6.0", "ini": "1.3.8", "minimist": "1.2.8", "strip-json-comments": "2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], + + "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "2.0.4", "string_decoder": "1.3.0", "util-deprecate": "1.0.2" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + + "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "7.0.0", "signal-exit": "4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], + + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "rollup": ["rollup@4.60.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.2", "@rollup/rollup-android-arm64": "4.60.2", "@rollup/rollup-darwin-arm64": "4.60.2", "@rollup/rollup-darwin-x64": "4.60.2", "@rollup/rollup-freebsd-arm64": "4.60.2", "@rollup/rollup-freebsd-x64": "4.60.2", "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", "@rollup/rollup-linux-arm-musleabihf": "4.60.2", "@rollup/rollup-linux-arm64-gnu": "4.60.2", "@rollup/rollup-linux-arm64-musl": "4.60.2", "@rollup/rollup-linux-loong64-gnu": "4.60.2", "@rollup/rollup-linux-loong64-musl": "4.60.2", "@rollup/rollup-linux-ppc64-gnu": "4.60.2", "@rollup/rollup-linux-ppc64-musl": "4.60.2", "@rollup/rollup-linux-riscv64-gnu": "4.60.2", "@rollup/rollup-linux-riscv64-musl": "4.60.2", "@rollup/rollup-linux-s390x-gnu": "4.60.2", "@rollup/rollup-linux-x64-gnu": "4.60.2", "@rollup/rollup-linux-x64-musl": "4.60.2", "@rollup/rollup-openbsd-x64": "4.60.2", "@rollup/rollup-openharmony-arm64": "4.60.2", "@rollup/rollup-win32-arm64-msvc": "4.60.2", "@rollup/rollup-win32-ia32-msvc": "4.60.2", "@rollup/rollup-win32-x64-gnu": "4.60.2", "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "2.3.3" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ=="], + + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="], + + "simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "6.0.0", "once": "1.4.0", "simple-concat": "1.0.1" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="], + + "slice-ansi": ["slice-ansi@8.0.0", "", { "dependencies": { "ansi-styles": "6.2.3", "is-fullwidth-code-point": "5.1.0" } }, "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg=="], + + "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "std-env": ["std-env@4.1.0", "", {}, "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ=="], + + "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], + + "string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "1.5.0", "strip-ansi": "7.2.0" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + + "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + + "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + + "sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "0.3.13", "commander": "4.1.1", "lines-and-columns": "1.2.4", "mz": "2.7.0", "pirates": "4.0.7", "tinyglobby": "0.2.16", "ts-interface-checker": "0.1.13" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "1.1.4", "mkdirp-classic": "0.5.3", "pump": "3.0.4", "tar-stream": "2.2.0" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="], + + "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "4.1.0", "end-of-stream": "1.4.5", "fs-constants": "1.0.0", "inherits": "2.0.4", "readable-stream": "3.6.2" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + + "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "1.3.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], + + "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": "3.3.1" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], + + "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "6.5.0", "picomatch": "4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], + + "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], + + "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], + + "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], + + "tsup": ["tsup@8.5.1", "", { "dependencies": { "bundle-require": "5.1.0", "cac": "6.7.14", "chokidar": "4.0.3", "consola": "3.4.2", "debug": "4.4.3", "esbuild": "0.27.7", "fix-dts-default-cjs-exports": "1.0.1", "joycon": "3.1.1", "picocolors": "1.1.1", "postcss-load-config": "6.0.1", "resolve-from": "5.0.0", "rollup": "4.60.2", "source-map": "0.7.6", "sucrase": "3.35.1", "tinyexec": "0.3.2", "tinyglobby": "0.2.16", "tree-kill": "1.2.2" }, "optionalDependencies": { "postcss": "8.5.12", "typescript": "6.0.3" }, "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing=="], + + "tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "0.27.7", "get-tsconfig": "4.14.0" }, "optionalDependencies": { "fsevents": "2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="], + + "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="], + + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], + + "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "vite": ["vite@6.0.11", "", { "dependencies": { "esbuild": "0.24.2", "postcss": "8.5.12", "rollup": "4.60.2" }, "optionalDependencies": { "@types/node": "25.6.0", "fsevents": "2.3.3", "tsx": "4.21.0", "yaml": "2.8.3" }, "bin": { "vite": "bin/vite.js" } }, "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg=="], + + "vitest": ["vitest@4.1.5", "", { "dependencies": { "@vitest/expect": "4.1.5", "@vitest/mocker": "4.1.5", "@vitest/pretty-format": "4.1.5", "@vitest/runner": "4.1.5", "@vitest/snapshot": "4.1.5", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "es-module-lexer": "2.1.0", "expect-type": "1.3.0", "magic-string": "0.30.21", "obug": "2.1.1", "pathe": "2.0.3", "picomatch": "4.0.4", "std-env": "4.1.0", "tinybench": "2.9.0", "tinyexec": "1.1.1", "tinyglobby": "0.2.16", "tinyrainbow": "3.1.0", "why-is-node-running": "2.3.0" }, "optionalDependencies": { "@types/node": "25.6.0", "@vitest/coverage-v8": "4.1.5" }, "peerDependencies": { "vite": "6.0.11" }, "bin": { "vitest": "vitest.mjs" } }, "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg=="], + + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "6.2.3", "string-width": "7.2.0", "strip-ansi": "7.2.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], + + "log-update/slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "6.2.3", "is-fullwidth-code-point": "5.1.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="], + + "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + + "tsup/tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + + "vite/esbuild": ["esbuild@0.24.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.24.2", "@esbuild/android-arm": "0.24.2", "@esbuild/android-arm64": "0.24.2", "@esbuild/android-x64": "0.24.2", "@esbuild/darwin-arm64": "0.24.2", "@esbuild/darwin-x64": "0.24.2", "@esbuild/freebsd-arm64": "0.24.2", "@esbuild/freebsd-x64": "0.24.2", "@esbuild/linux-arm": "0.24.2", "@esbuild/linux-arm64": "0.24.2", "@esbuild/linux-ia32": "0.24.2", "@esbuild/linux-loong64": "0.24.2", "@esbuild/linux-mips64el": "0.24.2", "@esbuild/linux-ppc64": "0.24.2", "@esbuild/linux-riscv64": "0.24.2", "@esbuild/linux-s390x": "0.24.2", "@esbuild/linux-x64": "0.24.2", "@esbuild/netbsd-arm64": "0.24.2", "@esbuild/netbsd-x64": "0.24.2", "@esbuild/openbsd-arm64": "0.24.2", "@esbuild/openbsd-x64": "0.24.2", "@esbuild/sunos-x64": "0.24.2", "@esbuild/win32-arm64": "0.24.2", "@esbuild/win32-ia32": "0.24.2", "@esbuild/win32-x64": "0.24.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA=="], + + "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "10.6.0", "get-east-asian-width": "1.5.0", "strip-ansi": "7.2.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="], + + "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="], + + "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.24.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg=="], + + "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.24.2", "", { "os": "android", "cpu": "x64" }, "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw=="], + + "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.24.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA=="], + + "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.24.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA=="], + + "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.24.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg=="], + + "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.24.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q=="], + + "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA=="], + + "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg=="], + + "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.24.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw=="], + + "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ=="], + + "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw=="], + + "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.24.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw=="], + + "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q=="], + + "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.24.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw=="], + + "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q=="], + + "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.24.2", "", { "os": "none", "cpu": "arm64" }, "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw=="], + + "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.24.2", "", { "os": "none", "cpu": "x64" }, "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw=="], + + "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.24.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A=="], + + "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.24.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA=="], + + "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.24.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig=="], + + "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.24.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ=="], + + "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.24.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="], + + "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="], + } +} diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index 643234e..0000000 --- a/eslint.config.js +++ /dev/null @@ -1,29 +0,0 @@ -import eslint from '@eslint/js'; -import tseslint from '@typescript-eslint/eslint-plugin'; -import tseslintParser from '@typescript-eslint/parser'; -import prettier from 'eslint-plugin-prettier'; - -export default [ - eslint.configs.recommended, - { - files: ['src/*.ts'], - languageOptions: { - parser: tseslintParser, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - }, - }, - plugins: { - '@typescript-eslint': tseslint, - prettier: prettier, - }, - rules: { - ...tseslint.configs['recommended'].rules, - '@typescript-eslint/explicit-function-return-type': 'warn', - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], - 'prettier/prettier': 'error', - }, - }, -]; diff --git a/example/README.md b/example/README.md deleted file mode 100644 index a816eaf..0000000 --- a/example/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# sqlite-up Example - -Simple example of how to use `sqlite-up` with TypeScript. In order to run this you'll need to build the library first. - -```bash -pnpm run build -pnpm exec tsx index.ts -``` diff --git a/example/index.ts b/example/index.ts deleted file mode 100644 index 91fdb3d..0000000 --- a/example/index.ts +++ /dev/null @@ -1,87 +0,0 @@ -import path from 'path'; -import { fileURLToPath } from 'url'; -import SQLiteDatabase from 'better-sqlite3'; - -import { Migrator, MigrationResult, MigrationPlan } from '../dist/index.js'; - -async function main() { - // Get the current directory path - const __dirname = path.dirname(fileURLToPath(import.meta.url)); - - // 1. Open the SQLite database - const db = new SQLiteDatabase(path.join(__dirname, 'mydatabase.sqlite')); - db.pragma('foreign_keys = ON'); - - // 2. Initialize the Migrator - const migrator = new Migrator({ - db, - migrationsDir: path.join(__dirname, 'migrations'), - // Optional overrides: - // migrationsTable: 'schema_migrations', - // migrationsLockTable: 'schema_migrations_lock', - }); - - // 3. Attach event listeners for logging - migrator.on('migration:applied', function (name: string, batch: number): void { - console.log(`✅ Migration Applied: "${name}" in batch ${batch}`); - }); - migrator.on('migration:rollback', function (name: string, batch: number): void { - console.log(`🔄 Migration Rolled Back: "${name}" from batch ${batch}`); - }); - - // 4. Check migration status - const statusBefore = await migrator.status(); - console.log('----------------------------------------'); - console.log('Migration Status:', statusBefore); - - // 5. Plan pending migrations - try { - console.log('----------------------------------------'); - console.log('Generating migration plan...'); - const plan: MigrationPlan = await migrator.plan(); - if (plan.pendingMigrations.length === 0) { - console.log('No pending migrations to apply.'); - } else { - console.log(`Upcoming Batch: ${plan.nextBatch}`); - console.log('Pending Migrations:'); - plan.pendingMigrations.forEach((migration, index) => { - console.log(` ${index + 1}. ${migration}`); - }); - } - } catch (err) { - console.error('Failed to generate migration plan:', err); - process.exit(1); - } - - // 6. Apply all pending migrations - console.log('----------------------------------------'); - console.log('Applying pending migrations...'); - const upResult: MigrationResult = await migrator.apply(); - if (!upResult.success) { - console.error('Migration up failed:', upResult.error); - process.exit(1); // Exit if migration failed - } - - // 7. Check migration status - const statusAfter = await migrator.status(); - console.log('----------------------------------------'); - console.log('Migration Status:', statusAfter); - - // 8. (Optional) Rollback the last batch of migrations - // console.log('----------------------------------------'); - // console.log('Rolling back last batch of migrations...'); - // const rollbackResult: MigrationResult = await migrator.rollback(); - // if (rollbackResult.success) { - // console.log('Migrations rolled back:', rollbackResult.appliedMigrations); - // } else { - // console.error('Rollback failed:', rollbackResult.error); - // } - - // 9. Close the database connection when done - db.close(); -} - -main().catch((err) => { - console.error('An unexpected error occurred:', err); - process.exit(1); -}); diff --git a/example/migrations/001_users_table.ts b/example/migrations/001_users_table.ts deleted file mode 100644 index 70b4177..0000000 --- a/example/migrations/001_users_table.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Database } from 'better-sqlite3'; - -export function up(db: Database): void { - db.exec(` - CREATE TABLE users ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - username TEXT NOT NULL UNIQUE, - email TEXT NOT NULL UNIQUE, - created_at TEXT NOT NULL - ); - `); -} - -export function down(db: Database): void { - db.exec(`DROP TABLE IF EXISTS users;`); -} diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..07bca1d --- /dev/null +++ b/examples/README.md @@ -0,0 +1,29 @@ +# sqlite-up Examples + +Each supported SQLite provider has its own self-contained example folder with a dedicated `README.md`, entry point, and migrations. + +Build the library from the repository root first: + +```bash +pnpm run build +``` + +Then install and run the provider example you want: + +```bash +cd examples/node-sqlite +pnpm install +pnpm start + +cd ../better-sqlite3 +pnpm install +pnpm start + +cd ../bun-sqlite +bun install +bun start + +cd ../bun-sql +bun install +bun start +``` diff --git a/examples/better-sqlite3/README.md b/examples/better-sqlite3/README.md new file mode 100644 index 0000000..cbb8d6a --- /dev/null +++ b/examples/better-sqlite3/README.md @@ -0,0 +1,17 @@ +# better-sqlite3 Example + +This example uses `better-sqlite3`. + +Build the library from the repository root first: + +```bash +pnpm run build +``` + +Then install and run this example: + +```bash +cd examples/better-sqlite3 +pnpm install +pnpm start +``` diff --git a/examples/better-sqlite3/index.ts b/examples/better-sqlite3/index.ts new file mode 100644 index 0000000..9f24764 --- /dev/null +++ b/examples/better-sqlite3/index.ts @@ -0,0 +1,37 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import Database from 'better-sqlite3'; + +import { type MigrationPlan, type MigrationResult, Migrator } from 'sqlite-up'; + +async function main() { + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const db = new Database(path.join(__dirname, 'better-sqlite3.sqlite')); + db.exec('PRAGMA foreign_keys = ON'); + + const migrator = new Migrator({ + db, + migrationsDir: path.join(__dirname, 'migrations'), + }); + + migrator.on('migration:applied', (name: string, batch: number): void => { + console.log(`Migration applied: "${name}" in batch ${batch}`); + }); + + const plan: MigrationPlan = await migrator.plan(); + console.log('Migration plan:', plan); + + const result: MigrationResult = await migrator.apply(); + if (!result.success) { + console.error('Migration failed:', result.error); + process.exit(1); + } + + console.log('Migration status:', await migrator.status()); + db.close(); +} + +main().catch((err) => { + console.error('An unexpected error occurred:', err); + process.exit(1); +}); diff --git a/examples/better-sqlite3/migrations/001_users_table.ts b/examples/better-sqlite3/migrations/001_users_table.ts new file mode 100644 index 0000000..f7763dd --- /dev/null +++ b/examples/better-sqlite3/migrations/001_users_table.ts @@ -0,0 +1,16 @@ +import type { SqliteDatabase } from 'sqlite-up'; + +export async function up(db: SqliteDatabase): Promise { + await db.exec(` + CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at TEXT NOT NULL + ); + `); +} + +export async function down(db: SqliteDatabase): Promise { + await db.exec(`DROP TABLE IF EXISTS users;`); +} diff --git a/example/migrations/002_add_age.ts b/examples/better-sqlite3/migrations/002_add_age.ts similarity index 57% rename from example/migrations/002_add_age.ts rename to examples/better-sqlite3/migrations/002_add_age.ts index 60e15ce..59a77f8 100644 --- a/example/migrations/002_add_age.ts +++ b/examples/better-sqlite3/migrations/002_add_age.ts @@ -1,14 +1,14 @@ -import { Database } from 'better-sqlite3'; +import type { SqliteDatabase } from 'sqlite-up'; -export function up(db: Database): void { - db.exec(` +export async function up(db: SqliteDatabase): Promise { + await db.exec(` ALTER TABLE users ADD COLUMN age INTEGER DEFAULT 0; `); } -export function down(db: Database): void { +export async function down(db: SqliteDatabase): Promise { // SQLite does not support DROP COLUMN directly. To remove a column: - db.exec(` + await db.exec(` CREATE TABLE users_backup ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, @@ -16,10 +16,10 @@ export function down(db: Database): void { created_at TEXT NOT NULL ); `); - db.exec(` + await db.exec(` INSERT INTO users_backup (id, username, email, created_at) SELECT id, username, email, created_at FROM users; `); - db.exec(`DROP TABLE users;`); - db.exec(`ALTER TABLE users_backup RENAME TO users;`); + await db.exec(`DROP TABLE users;`); + await db.exec(`ALTER TABLE users_backup RENAME TO users;`); } diff --git a/examples/better-sqlite3/package.json b/examples/better-sqlite3/package.json new file mode 100644 index 0000000..acf1659 --- /dev/null +++ b/examples/better-sqlite3/package.json @@ -0,0 +1,15 @@ +{ + "name": "@sqlite-up/example-better-sqlite3", + "private": true, + "type": "module", + "scripts": { + "start": "tsx index.ts" + }, + "dependencies": { + "better-sqlite3": "^12.9.0", + "sqlite-up": "link:../.." + }, + "devDependencies": { + "tsx": "^4.21.0" + } +} diff --git a/examples/bun-sql/README.md b/examples/bun-sql/README.md new file mode 100644 index 0000000..cf056f9 --- /dev/null +++ b/examples/bun-sql/README.md @@ -0,0 +1,17 @@ +# Bun SQL Example + +This example uses Bun's Promise-based `SQL` SQLite client. + +Build the library from the repository root first: + +```bash +pnpm run build +``` + +Then install and run this example: + +```bash +cd examples/bun-sql +bun install +bun start +``` diff --git a/examples/bun-sql/index.ts b/examples/bun-sql/index.ts new file mode 100644 index 0000000..82fc06e --- /dev/null +++ b/examples/bun-sql/index.ts @@ -0,0 +1,36 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { SQL } from 'bun'; + +import { type MigrationPlan, type MigrationResult, Migrator } from 'sqlite-up'; + +async function main() { + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const sql = new SQL(`sqlite://${path.join(__dirname, 'bun-sql.sqlite')}`); + + const migrator = new Migrator({ + db: sql, + migrationsDir: path.join(__dirname, 'migrations'), + }); + + migrator.on('migration:applied', (name: string, batch: number): void => { + console.log(`Migration applied: "${name}" in batch ${batch}`); + }); + + const plan: MigrationPlan = await migrator.plan(); + console.log('Migration plan:', plan); + + const result: MigrationResult = await migrator.apply(); + if (!result.success) { + console.error('Migration failed:', result.error); + process.exit(1); + } + + console.log('Migration status:', await migrator.status()); + sql.close(); +} + +main().catch((err) => { + console.error('An unexpected error occurred:', err); + process.exit(1); +}); diff --git a/examples/bun-sql/migrations/001_users_table.ts b/examples/bun-sql/migrations/001_users_table.ts new file mode 100644 index 0000000..f7763dd --- /dev/null +++ b/examples/bun-sql/migrations/001_users_table.ts @@ -0,0 +1,16 @@ +import type { SqliteDatabase } from 'sqlite-up'; + +export async function up(db: SqliteDatabase): Promise { + await db.exec(` + CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at TEXT NOT NULL + ); + `); +} + +export async function down(db: SqliteDatabase): Promise { + await db.exec(`DROP TABLE IF EXISTS users;`); +} diff --git a/examples/bun-sql/migrations/002_add_age.ts b/examples/bun-sql/migrations/002_add_age.ts new file mode 100644 index 0000000..59a77f8 --- /dev/null +++ b/examples/bun-sql/migrations/002_add_age.ts @@ -0,0 +1,25 @@ +import type { SqliteDatabase } from 'sqlite-up'; + +export async function up(db: SqliteDatabase): Promise { + await db.exec(` + ALTER TABLE users ADD COLUMN age INTEGER DEFAULT 0; + `); +} + +export async function down(db: SqliteDatabase): Promise { + // SQLite does not support DROP COLUMN directly. To remove a column: + await db.exec(` + CREATE TABLE users_backup ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at TEXT NOT NULL + ); + `); + await db.exec(` + INSERT INTO users_backup (id, username, email, created_at) + SELECT id, username, email, created_at FROM users; + `); + await db.exec(`DROP TABLE users;`); + await db.exec(`ALTER TABLE users_backup RENAME TO users;`); +} diff --git a/examples/bun-sql/package.json b/examples/bun-sql/package.json new file mode 100644 index 0000000..232dc09 --- /dev/null +++ b/examples/bun-sql/package.json @@ -0,0 +1,11 @@ +{ + "name": "@sqlite-up/example-bun-sql", + "private": true, + "type": "module", + "scripts": { + "start": "bun index.ts" + }, + "dependencies": { + "sqlite-up": "link:../.." + } +} diff --git a/examples/bun-sqlite/README.md b/examples/bun-sqlite/README.md new file mode 100644 index 0000000..4c414d5 --- /dev/null +++ b/examples/bun-sqlite/README.md @@ -0,0 +1,17 @@ +# Bun SQLite Example + +This example uses Bun's synchronous `bun:sqlite` database. + +Build the library from the repository root first: + +```bash +pnpm run build +``` + +Then install and run this example: + +```bash +cd examples/bun-sqlite +bun install +bun start +``` diff --git a/examples/bun-sqlite/index.ts b/examples/bun-sqlite/index.ts new file mode 100644 index 0000000..7aeebc2 --- /dev/null +++ b/examples/bun-sqlite/index.ts @@ -0,0 +1,37 @@ +import { Database } from 'bun:sqlite'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { type MigrationPlan, type MigrationResult, Migrator } from 'sqlite-up'; + +async function main() { + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const db = new Database(path.join(__dirname, 'bun-sqlite.sqlite'), { create: true }); + db.exec('PRAGMA foreign_keys = ON'); + + const migrator = new Migrator({ + db, + migrationsDir: path.join(__dirname, 'migrations'), + }); + + migrator.on('migration:applied', (name: string, batch: number): void => { + console.log(`Migration applied: "${name}" in batch ${batch}`); + }); + + const plan: MigrationPlan = await migrator.plan(); + console.log('Migration plan:', plan); + + const result: MigrationResult = await migrator.apply(); + if (!result.success) { + console.error('Migration failed:', result.error); + process.exit(1); + } + + console.log('Migration status:', await migrator.status()); + db.close(); +} + +main().catch((err) => { + console.error('An unexpected error occurred:', err); + process.exit(1); +}); diff --git a/examples/bun-sqlite/migrations/001_users_table.ts b/examples/bun-sqlite/migrations/001_users_table.ts new file mode 100644 index 0000000..f7763dd --- /dev/null +++ b/examples/bun-sqlite/migrations/001_users_table.ts @@ -0,0 +1,16 @@ +import type { SqliteDatabase } from 'sqlite-up'; + +export async function up(db: SqliteDatabase): Promise { + await db.exec(` + CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at TEXT NOT NULL + ); + `); +} + +export async function down(db: SqliteDatabase): Promise { + await db.exec(`DROP TABLE IF EXISTS users;`); +} diff --git a/examples/bun-sqlite/migrations/002_add_age.ts b/examples/bun-sqlite/migrations/002_add_age.ts new file mode 100644 index 0000000..59a77f8 --- /dev/null +++ b/examples/bun-sqlite/migrations/002_add_age.ts @@ -0,0 +1,25 @@ +import type { SqliteDatabase } from 'sqlite-up'; + +export async function up(db: SqliteDatabase): Promise { + await db.exec(` + ALTER TABLE users ADD COLUMN age INTEGER DEFAULT 0; + `); +} + +export async function down(db: SqliteDatabase): Promise { + // SQLite does not support DROP COLUMN directly. To remove a column: + await db.exec(` + CREATE TABLE users_backup ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at TEXT NOT NULL + ); + `); + await db.exec(` + INSERT INTO users_backup (id, username, email, created_at) + SELECT id, username, email, created_at FROM users; + `); + await db.exec(`DROP TABLE users;`); + await db.exec(`ALTER TABLE users_backup RENAME TO users;`); +} diff --git a/examples/bun-sqlite/package.json b/examples/bun-sqlite/package.json new file mode 100644 index 0000000..7354d2e --- /dev/null +++ b/examples/bun-sqlite/package.json @@ -0,0 +1,11 @@ +{ + "name": "@sqlite-up/example-bun-sqlite", + "private": true, + "type": "module", + "scripts": { + "start": "bun index.ts" + }, + "dependencies": { + "sqlite-up": "link:../.." + } +} diff --git a/examples/node-sqlite/README.md b/examples/node-sqlite/README.md new file mode 100644 index 0000000..0ab8766 --- /dev/null +++ b/examples/node-sqlite/README.md @@ -0,0 +1,17 @@ +# node:sqlite Example + +This example uses Node 24+ `node:sqlite`. + +Build the library from the repository root first: + +```bash +pnpm run build +``` + +Then install and run this example: + +```bash +cd examples/node-sqlite +pnpm install +pnpm start +``` diff --git a/examples/node-sqlite/index.ts b/examples/node-sqlite/index.ts new file mode 100644 index 0000000..45ee677 --- /dev/null +++ b/examples/node-sqlite/index.ts @@ -0,0 +1,40 @@ +import path from 'node:path'; +import { DatabaseSync } from 'node:sqlite'; +import { fileURLToPath } from 'node:url'; + +import { type MigrationPlan, type MigrationResult, Migrator } from 'sqlite-up'; + +async function main() { + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const db = new DatabaseSync(path.join(__dirname, 'node-sqlite.sqlite')); + db.exec('PRAGMA foreign_keys = ON'); + + const migrator = new Migrator({ + db, + migrationsDir: path.join(__dirname, 'migrations'), + }); + + migrator.on('migration:applied', (name: string, batch: number): void => { + console.log(`Migration applied: "${name}" in batch ${batch}`); + }); + + const plan: MigrationPlan = await migrator.plan(); + console.log('Migration plan:', plan); + + const result: MigrationResult = await migrator.apply(); + if (!result.success) { + console.error('Migration failed:', result.error); + process.exit(1); + } + + console.log('Migration status:', await migrator.status()); + + if (db.isOpen) { + db.close(); + } +} + +main().catch((err) => { + console.error('An unexpected error occurred:', err); + process.exit(1); +}); diff --git a/examples/node-sqlite/migrations/001_users_table.ts b/examples/node-sqlite/migrations/001_users_table.ts new file mode 100644 index 0000000..f7763dd --- /dev/null +++ b/examples/node-sqlite/migrations/001_users_table.ts @@ -0,0 +1,16 @@ +import type { SqliteDatabase } from 'sqlite-up'; + +export async function up(db: SqliteDatabase): Promise { + await db.exec(` + CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at TEXT NOT NULL + ); + `); +} + +export async function down(db: SqliteDatabase): Promise { + await db.exec(`DROP TABLE IF EXISTS users;`); +} diff --git a/examples/node-sqlite/migrations/002_add_age.ts b/examples/node-sqlite/migrations/002_add_age.ts new file mode 100644 index 0000000..59a77f8 --- /dev/null +++ b/examples/node-sqlite/migrations/002_add_age.ts @@ -0,0 +1,25 @@ +import type { SqliteDatabase } from 'sqlite-up'; + +export async function up(db: SqliteDatabase): Promise { + await db.exec(` + ALTER TABLE users ADD COLUMN age INTEGER DEFAULT 0; + `); +} + +export async function down(db: SqliteDatabase): Promise { + // SQLite does not support DROP COLUMN directly. To remove a column: + await db.exec(` + CREATE TABLE users_backup ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at TEXT NOT NULL + ); + `); + await db.exec(` + INSERT INTO users_backup (id, username, email, created_at) + SELECT id, username, email, created_at FROM users; + `); + await db.exec(`DROP TABLE users;`); + await db.exec(`ALTER TABLE users_backup RENAME TO users;`); +} diff --git a/examples/node-sqlite/package.json b/examples/node-sqlite/package.json new file mode 100644 index 0000000..e41daed --- /dev/null +++ b/examples/node-sqlite/package.json @@ -0,0 +1,17 @@ +{ + "name": "@sqlite-up/example-node-sqlite", + "private": true, + "type": "module", + "scripts": { + "start": "tsx index.ts" + }, + "dependencies": { + "sqlite-up": "link:../.." + }, + "devDependencies": { + "tsx": "^4.21.0" + }, + "engines": { + "node": ">=24.0.0" + } +} diff --git a/jsdoc.json b/jsdoc.json new file mode 100644 index 0000000..deb1bfa --- /dev/null +++ b/jsdoc.json @@ -0,0 +1,6 @@ +{ + "roots": ["."], + "excludePaths": ["node_modules", "dist", "coverage"], + "excludeFiles": ["\\.d\\.[cm]?ts$", "\\.test\\.[^.]+$", "\\.bun\\.test\\.[^.]+$"], + "includeExtensions": [".ts"] +} diff --git a/package.json b/package.json index cea4ac7..608ea37 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,28 @@ { "name": "sqlite-up", + "author": "Sandrino Di Mattia", "version": "0.4.0", - "description": "A lightweight SQLite migration system for Node.js", + "description": "A lightweight SQLite migration system for Node.js and Bun", + "type": "module", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/sandrinodimattia/sqlite-up.git" + }, + "bugs": { + "url": "https://github.com/sandrinodimattia/sqlite-up/issues" + }, + "homepage": "https://github.com/sandrinodimattia/sqlite-up#readme", + "engines": { + "node": ">=24.0.0" + }, + "packageManager": "pnpm@10.30.3", + "publishConfig": { + "access": "public" + }, "main": "./dist/index.js", - "module": "dist/index.mjs", + "module": "./dist/index.js", "types": "./dist/index.d.ts", - "type": "module", "exports": { ".": { "import": "./dist/index.js", @@ -14,55 +31,48 @@ }, "files": [ "dist", - "README.md", - "LICENSE" + "LICENSE", + "README.md" ], "scripts": { - "build": "tsup src/index.ts --format esm --dts --sourcemap", + "build": "tsup src/index.ts --format esm --sourcemap && tsc -p tsconfig.build.json", + "check": "biome check .", + "check:fix": "biome check --write --unsafe .", + "format": "biome format --write .", + "lint": "biome lint . && jsdoc-lint src", + "typecheck": "pnpm typecheck:src && pnpm typecheck:test", + "typecheck:src": "tsc --noEmit", + "typecheck:test": "tsc --noEmit -p tsconfig.test.json", "test": "vitest run", - "test:watch": "vitest", + "test:bun": "bun test ./src/*.bun.test.ts ./src/providers/*.bun.test.ts", "test:coverage": "vitest run --coverage", - "lint": "eslint \"**/*.ts\"", - "format": "prettier --write \"src/**/*.ts\"", + "test:node": "vitest run", + "test:watch": "vitest", "prepare": "husky install", - "prepublishOnly": "pnpm run build", - "typecheck": "tsc --noEmit" + "release": "node scripts/release.mjs", + "prepublishOnly": "pnpm run build" }, "keywords": [ - "sqlite", + "bun", "database", - "typescript", + "migrations", "node", - "migrations" + "sqlite", + "typescript" ], - "author": "Sandrino Di Mattia", - "license": "MIT", - "engines": { - "node": ">=23.0.0" - }, - "publishConfig": { - "access": "public" - }, "devDependencies": { - "@eslint/js": "^9.0.0", + "@biomejs/biome": "^2.4.13", "@types/better-sqlite3": "^7.6.13", - "@types/node": "^22.18.8", - "@typescript-eslint/eslint-plugin": "^8.46.0", - "@typescript-eslint/parser": "^8.46.0", - "@vitest/coverage-v8": "^3.2.4", - "better-sqlite3": "^11.10.0", - "eslint": "^9.37.0", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-prettier": "^5.5.4", + "@types/bun": "^1.3.13", + "@types/node": "^25.6.0", + "@vitest/coverage-v8": "^4.1.5", + "better-sqlite3": "^12.9.0", "husky": "^9.1.7", - "lint-staged": "^15.5.2", - "prettier": "^3.6.2", - "tsup": "^8.5.0", - "tsx": "^4.20.6", - "typescript": "^5.9.3", - "vitest": "^3.2.4" - }, - "peerDependencies": { - "better-sqlite3": ">=11.0.0" + "jsdoc-lint": "0.4.0", + "lint-staged": "^16.4.0", + "tsup": "^8.5.1", + "tsx": "^4.21.0", + "typescript": "^6.0.3", + "vitest": "^4.1.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 546fb9a..c551245 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,93 +8,134 @@ importers: .: devDependencies: - '@eslint/js': - specifier: ^9.0.0 - version: 9.37.0 + '@biomejs/biome': + specifier: ^2.4.13 + version: 2.4.13 '@types/better-sqlite3': specifier: ^7.6.13 version: 7.6.13 + '@types/bun': + specifier: ^1.3.13 + version: 1.3.13 '@types/node': - specifier: ^22.18.8 - version: 22.18.8 - '@typescript-eslint/eslint-plugin': - specifier: ^8.46.0 - version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) - '@typescript-eslint/parser': - specifier: ^8.46.0 - version: 8.46.0(eslint@9.37.0)(typescript@5.9.3) + specifier: ^25.6.0 + version: 25.6.0 '@vitest/coverage-v8': - specifier: ^3.2.4 - version: 3.2.4(vitest@3.2.4(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1)) + specifier: ^4.1.5 + version: 4.1.5(vitest@4.1.5) better-sqlite3: - specifier: ^11.10.0 - version: 11.10.0 - eslint: - specifier: ^9.37.0 - version: 9.37.0 - eslint-config-prettier: - specifier: ^10.1.8 - version: 10.1.8(eslint@9.37.0) - eslint-plugin-prettier: - specifier: ^5.5.4 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0))(eslint@9.37.0)(prettier@3.6.2) + specifier: ^12.9.0 + version: 12.9.0 husky: specifier: ^9.1.7 version: 9.1.7 + jsdoc-lint: + specifier: 0.4.0 + version: 0.4.0 lint-staged: - specifier: ^15.5.2 - version: 15.5.2 - prettier: - specifier: ^3.6.2 - version: 3.6.2 + specifier: ^16.4.0 + version: 16.4.0 tsup: - specifier: ^8.5.0 - version: 8.5.0(postcss@8.5.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + specifier: ^8.5.1 + version: 8.5.1(postcss@8.5.12)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) tsx: - specifier: ^4.20.6 - version: 4.20.6 + specifier: ^4.21.0 + version: 4.21.0 typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 vitest: - specifier: ^3.2.4 - version: 3.2.4(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1) + specifier: ^4.1.5 + version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(vite@6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3)) packages: - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.5': - resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==} + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.26.5': - resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} + '@biomejs/biome@2.4.13': + resolution: {integrity: sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.4.13': + resolution: {integrity: sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.4.13': + resolution: {integrity: sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.4.13': + resolution: {integrity: sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-arm64@2.4.13': + resolution: {integrity: sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-linux-x64-musl@2.4.13': + resolution: {integrity: sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-x64@2.4.13': + resolution: {integrity: sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-win32-arm64@2.4.13': + resolution: {integrity: sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.4.13': + resolution: {integrity: sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@esbuild/aix-ppc64@0.24.2': resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.10': - resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -105,8 +146,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.10': - resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -117,8 +158,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.10': - resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -129,8 +170,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.10': - resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -141,8 +182,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.10': - resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -153,8 +194,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.10': - resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -165,8 +206,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.10': - resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -177,8 +218,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.10': - resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -189,8 +230,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.10': - resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -201,8 +242,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.10': - resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -213,8 +254,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.10': - resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -225,8 +266,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.10': - resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -237,8 +278,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.10': - resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -249,8 +290,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.10': - resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -261,8 +302,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.10': - resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -273,8 +314,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.10': - resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -285,8 +326,8 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.10': - resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -297,8 +338,8 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.25.10': - resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -309,8 +350,8 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.10': - resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -321,8 +362,8 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.25.10': - resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -333,14 +374,14 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.10': - resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.10': - resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -351,8 +392,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.10': - resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -363,8 +404,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.10': - resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -375,8 +416,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.10': - resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -387,237 +428,174 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.10': - resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.4.0': - resolution: {integrity: sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.16.0': - resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.37.0': - resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.4.0': - resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@pkgr/core@0.2.9': - resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - - '@rollup/rollup-android-arm-eabi@4.52.4': - resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} + '@rollup/rollup-android-arm-eabi@4.60.2': + resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.4': - resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} + '@rollup/rollup-android-arm64@4.60.2': + resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.4': - resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} + '@rollup/rollup-darwin-arm64@4.60.2': + resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.4': - resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} + '@rollup/rollup-darwin-x64@4.60.2': + resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.4': - resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} + '@rollup/rollup-freebsd-arm64@4.60.2': + resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.4': - resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} + '@rollup/rollup-freebsd-x64@4.60.2': + resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': - resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} cpu: [arm] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.52.4': - resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} cpu: [arm] os: [linux] + libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.52.4': - resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} + '@rollup/rollup-linux-arm64-gnu@4.60.2': + resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} cpu: [arm64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.52.4': - resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} + '@rollup/rollup-linux-arm64-musl@4.60.2': + resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} cpu: [arm64] os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} + cpu: [loong64] + os: [linux] + libc: [glibc] - '@rollup/rollup-linux-loong64-gnu@4.52.4': - resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} + '@rollup/rollup-linux-loong64-musl@4.60.2': + resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} cpu: [loong64] os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] - '@rollup/rollup-linux-ppc64-gnu@4.52.4': - resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} + '@rollup/rollup-linux-ppc64-musl@4.60.2': + resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} cpu: [ppc64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.52.4': - resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} cpu: [riscv64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.52.4': - resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} + '@rollup/rollup-linux-riscv64-musl@4.60.2': + resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} cpu: [riscv64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.52.4': - resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} + '@rollup/rollup-linux-s390x-gnu@4.60.2': + resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} cpu: [s390x] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.52.4': - resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} + '@rollup/rollup-linux-x64-gnu@4.60.2': + resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} cpu: [x64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.52.4': - resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} + '@rollup/rollup-linux-x64-musl@4.60.2': + resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} cpu: [x64] os: [linux] + libc: [musl] - '@rollup/rollup-openharmony-arm64@4.52.4': - resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} + '@rollup/rollup-openbsd-x64@4.60.2': + resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.2': + resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.52.4': - resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} + '@rollup/rollup-win32-arm64-msvc@4.60.2': + resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.4': - resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} + '@rollup/rollup-win32-ia32-msvc@4.60.2': + resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.4': - resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} + '@rollup/rollup-win32-x64-gnu@4.60.2': + resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.52.4': - resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} + '@rollup/rollup-win32-x64-msvc@4.60.2': + resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} cpu: [x64] os: [win32] + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@types/better-sqlite3@7.6.13': resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/bun@1.3.13': + resolution: {integrity: sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -625,163 +603,80 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@22.18.8': - resolution: {integrity: sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==} - - '@typescript-eslint/eslint-plugin@8.46.0': - resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.46.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@8.46.0': - resolution: {integrity: sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.46.0': - resolution: {integrity: sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@8.46.0': - resolution: {integrity: sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.46.0': - resolution: {integrity: sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.46.0': - resolution: {integrity: sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@8.46.0': - resolution: {integrity: sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.46.0': - resolution: {integrity: sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} - '@typescript-eslint/utils@8.46.0': - resolution: {integrity: sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vitest/coverage-v8@4.1.5': + resolution: {integrity: sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/visitor-keys@8.46.0': - resolution: {integrity: sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@vitest/coverage-v8@3.2.4': - resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} - peerDependencies: - '@vitest/browser': 3.2.4 - vitest: 3.2.4 + '@vitest/browser': 4.1.5 + vitest: 4.1.5 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/expect@4.1.5': + resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==} - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + '@vitest/mocker@4.1.5': + resolution: {integrity: sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/pretty-format@4.1.5': + resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==} - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/runner@4.1.5': + resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==} - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/snapshot@4.1.5': + resolution: {integrity: sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==} - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vitest/spy@4.1.5': + resolution: {integrity: sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==} - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@vitest/utils@4.1.5': + resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-escapes@7.0.0: - resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} engines: {node: '>=18'} - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-v8-to-istanbul@0.3.5: - resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + ast-v8-to-istanbul@1.0.0: + resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - better-sqlite3@11.10.0: - resolution: {integrity: sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==} + better-sqlite3@12.9.0: + resolution: {integrity: sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} @@ -789,19 +684,12 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bun-types@1.3.13: + resolution: {integrity: sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA==} + bundle-require@5.1.0: resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -812,26 +700,10 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -843,50 +715,30 @@ packages: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} - cli-truncate@4.0.0: - resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} - engines: {node: '>=18'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} + engines: {node: '>=20'} colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - consola@3.4.0: - resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} @@ -901,156 +753,51 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@10.4.0: - resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} esbuild@0.24.2: resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} engines: {node: '>=18'} hasBin: true - esbuild@0.25.10: - resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} hasBin: true - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-config-prettier@10.1.8: - resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-plugin-prettier@5.5.4: - resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.37.0: - resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1060,35 +807,12 @@ packages: picomatch: optional: true - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - fix-dts-default-cjs-exports@1.0.1: resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.2: - resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} - - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -1097,39 +821,16 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - get-east-asian-width@1.3.0: - resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-tsconfig@4.10.0: - resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1137,10 +838,6 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} engines: {node: '>=18'} @@ -1149,59 +846,16 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - - is-fullwidth-code-point@5.0.0: - resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} engines: {node: '>=18'} - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -1210,44 +864,22 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@5.0.6: - resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} - engines: {node: '>=10'} - - istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + jsdoc-lint@0.4.0: + resolution: {integrity: sha512-k6DzgaDMMYaD1AGzT0iK0hsTkzhr2MYDD880n7S9vQfhNkWt4cbsVt6dmPawRwdYODiGuwOdRKdVV85dzXltUg==} + engines: {node: '>=24'} hasBin: true - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -1255,67 +887,33 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@15.5.2: - resolution: {integrity: sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==} - engines: {node: '>=18.12.0'} + lint-staged@16.4.0: + resolution: {integrity: sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==} + engines: {node: '>=20.17'} hasBin: true - listr2@8.2.5: - resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} - engines: {node: '>=18.0.0'} + listr2@9.0.5: + resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} + engines: {node: '>=20.0.0'} load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - log-update@6.1.0: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magic-string@0.30.19: - resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} - - magicast@0.3.5: - resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} @@ -1324,25 +922,14 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1350,100 +937,44 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true napi-build-utils@2.0.0: resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - node-abi@3.73.0: - resolution: {integrity: sha512-z8iYzQGBu35ZkTQ9mtR8RqugJZ9RCLn8fv3d7LsgDBzOijGQP3RdKTX4LA7LXw03ZhU5z0l4xfhIMgSES31+cg==} + node-abi@3.89.0: + resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} engines: {node: '>=10'} - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - onetime@7.0.0: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} pkg-types@1.3.1: @@ -1467,37 +998,18 @@ packages: yaml: optional: true - postcss@8.5.1: - resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} + postcss@8.5.12: + resolution: {integrity: sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==} engines: {node: ^10 || ^12 || >=14} prebuild-install@7.1.3: resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. hasBin: true - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} - engines: {node: '>=14'} - hasBin: true - - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} @@ -1507,14 +1019,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readdirp@4.1.1: - resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -1526,42 +1034,22 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rollup@4.52.4: - resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} + rollup@4.60.2: + resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -1575,72 +1063,53 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - - slice-ansi@7.1.0: - resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string-width@8.2.1: + resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} + engines: {node: '>=20'} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} - - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true @@ -1648,21 +1117,13 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} - engines: {node: ^14.18.0 || >=16.0.0} - - tar-fs@2.1.2: - resolution: {integrity: sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==} + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} - test-exclude@7.0.1: - resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} - engines: {node: '>=18'} - thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -1676,44 +1137,27 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - tsup@8.5.0: - resolution: {integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==} + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -1731,40 +1175,28 @@ packages: typescript: optional: true - tsx@4.20.6: - resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} hasBin: true tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - vite@6.0.11: resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -1805,26 +1237,39 @@ packages: yaml: optional: true - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vitest@4.1.5: + resolution: {integrity: sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.5 + '@vitest/browser-preview': 4.1.5 + '@vitest/browser-webdriverio': 4.1.5 + '@vitest/coverage-istanbul': 4.1.5 + '@vitest/coverage-v8': 4.1.5 + '@vitest/ui': 4.1.5 happy-dom: '*' jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true - '@types/debug': + '@opentelemetry/api': optional: true '@types/node': optional: true - '@vitest/browser': + '@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 @@ -1833,618 +1278,418 @@ packages: jsdom: optional: true - webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - - whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} engines: {node: '>=18'} wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} engines: {node: '>= 14.6'} hasBin: true - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - snapshots: - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - - '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.28.5': {} - '@babel/parser@7.26.5': + '@babel/parser@7.29.2': dependencies: - '@babel/types': 7.26.5 + '@babel/types': 7.29.0 - '@babel/types@7.26.5': + '@babel/types@7.29.0': dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 '@bcoe/v8-coverage@1.0.2': {} + '@biomejs/biome@2.4.13': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.4.13 + '@biomejs/cli-darwin-x64': 2.4.13 + '@biomejs/cli-linux-arm64': 2.4.13 + '@biomejs/cli-linux-arm64-musl': 2.4.13 + '@biomejs/cli-linux-x64': 2.4.13 + '@biomejs/cli-linux-x64-musl': 2.4.13 + '@biomejs/cli-win32-arm64': 2.4.13 + '@biomejs/cli-win32-x64': 2.4.13 + + '@biomejs/cli-darwin-arm64@2.4.13': + optional: true + + '@biomejs/cli-darwin-x64@2.4.13': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.4.13': + optional: true + + '@biomejs/cli-linux-arm64@2.4.13': + optional: true + + '@biomejs/cli-linux-x64-musl@2.4.13': + optional: true + + '@biomejs/cli-linux-x64@2.4.13': + optional: true + + '@biomejs/cli-win32-arm64@2.4.13': + optional: true + + '@biomejs/cli-win32-x64@2.4.13': + optional: true + '@esbuild/aix-ppc64@0.24.2': optional: true - '@esbuild/aix-ppc64@0.25.10': + '@esbuild/aix-ppc64@0.27.7': optional: true '@esbuild/android-arm64@0.24.2': optional: true - '@esbuild/android-arm64@0.25.10': + '@esbuild/android-arm64@0.27.7': optional: true '@esbuild/android-arm@0.24.2': optional: true - '@esbuild/android-arm@0.25.10': + '@esbuild/android-arm@0.27.7': optional: true '@esbuild/android-x64@0.24.2': optional: true - '@esbuild/android-x64@0.25.10': + '@esbuild/android-x64@0.27.7': optional: true '@esbuild/darwin-arm64@0.24.2': optional: true - '@esbuild/darwin-arm64@0.25.10': + '@esbuild/darwin-arm64@0.27.7': optional: true '@esbuild/darwin-x64@0.24.2': optional: true - '@esbuild/darwin-x64@0.25.10': + '@esbuild/darwin-x64@0.27.7': optional: true '@esbuild/freebsd-arm64@0.24.2': optional: true - '@esbuild/freebsd-arm64@0.25.10': + '@esbuild/freebsd-arm64@0.27.7': optional: true '@esbuild/freebsd-x64@0.24.2': optional: true - '@esbuild/freebsd-x64@0.25.10': + '@esbuild/freebsd-x64@0.27.7': optional: true '@esbuild/linux-arm64@0.24.2': optional: true - '@esbuild/linux-arm64@0.25.10': + '@esbuild/linux-arm64@0.27.7': optional: true '@esbuild/linux-arm@0.24.2': optional: true - '@esbuild/linux-arm@0.25.10': + '@esbuild/linux-arm@0.27.7': optional: true '@esbuild/linux-ia32@0.24.2': optional: true - '@esbuild/linux-ia32@0.25.10': + '@esbuild/linux-ia32@0.27.7': optional: true '@esbuild/linux-loong64@0.24.2': optional: true - '@esbuild/linux-loong64@0.25.10': + '@esbuild/linux-loong64@0.27.7': optional: true '@esbuild/linux-mips64el@0.24.2': optional: true - '@esbuild/linux-mips64el@0.25.10': + '@esbuild/linux-mips64el@0.27.7': optional: true '@esbuild/linux-ppc64@0.24.2': optional: true - '@esbuild/linux-ppc64@0.25.10': + '@esbuild/linux-ppc64@0.27.7': optional: true '@esbuild/linux-riscv64@0.24.2': optional: true - '@esbuild/linux-riscv64@0.25.10': + '@esbuild/linux-riscv64@0.27.7': optional: true '@esbuild/linux-s390x@0.24.2': optional: true - '@esbuild/linux-s390x@0.25.10': + '@esbuild/linux-s390x@0.27.7': optional: true '@esbuild/linux-x64@0.24.2': optional: true - '@esbuild/linux-x64@0.25.10': + '@esbuild/linux-x64@0.27.7': optional: true '@esbuild/netbsd-arm64@0.24.2': optional: true - '@esbuild/netbsd-arm64@0.25.10': + '@esbuild/netbsd-arm64@0.27.7': optional: true '@esbuild/netbsd-x64@0.24.2': optional: true - '@esbuild/netbsd-x64@0.25.10': + '@esbuild/netbsd-x64@0.27.7': optional: true '@esbuild/openbsd-arm64@0.24.2': optional: true - '@esbuild/openbsd-arm64@0.25.10': + '@esbuild/openbsd-arm64@0.27.7': optional: true '@esbuild/openbsd-x64@0.24.2': optional: true - '@esbuild/openbsd-x64@0.25.10': + '@esbuild/openbsd-x64@0.27.7': optional: true - '@esbuild/openharmony-arm64@0.25.10': + '@esbuild/openharmony-arm64@0.27.7': optional: true '@esbuild/sunos-x64@0.24.2': optional: true - '@esbuild/sunos-x64@0.25.10': + '@esbuild/sunos-x64@0.27.7': optional: true '@esbuild/win32-arm64@0.24.2': optional: true - '@esbuild/win32-arm64@0.25.10': + '@esbuild/win32-arm64@0.27.7': optional: true '@esbuild/win32-ia32@0.24.2': optional: true - '@esbuild/win32-ia32@0.25.10': + '@esbuild/win32-ia32@0.27.7': optional: true '@esbuild/win32-x64@0.24.2': optional: true - '@esbuild/win32-x64@0.25.10': + '@esbuild/win32-x64@0.27.7': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0)': - dependencies: - eslint: 9.37.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/config-array@0.21.0': - dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.3 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.4.0': + '@jridgewell/gen-mapping@0.3.13': dependencies: - '@eslint/core': 0.16.0 - - '@eslint/core@0.16.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.1': - dependencies: - ajv: 6.12.6 - debug: 4.4.3 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.37.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.4.0': - dependencies: - '@eslint/core': 0.16.0 - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@istanbuljs/schema@0.1.3': {} - - '@jridgewell/gen-mapping@0.3.8': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + '@rollup/rollup-android-arm-eabi@4.60.2': + optional: true - '@pkgjs/parseargs@0.11.0': + '@rollup/rollup-android-arm64@4.60.2': optional: true - '@pkgr/core@0.2.9': {} + '@rollup/rollup-darwin-arm64@4.60.2': + optional: true - '@rollup/rollup-android-arm-eabi@4.52.4': + '@rollup/rollup-darwin-x64@4.60.2': optional: true - '@rollup/rollup-android-arm64@4.52.4': + '@rollup/rollup-freebsd-arm64@4.60.2': optional: true - '@rollup/rollup-darwin-arm64@4.52.4': + '@rollup/rollup-freebsd-x64@4.60.2': optional: true - '@rollup/rollup-darwin-x64@4.52.4': + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': optional: true - '@rollup/rollup-freebsd-arm64@4.52.4': + '@rollup/rollup-linux-arm-musleabihf@4.60.2': optional: true - '@rollup/rollup-freebsd-x64@4.52.4': + '@rollup/rollup-linux-arm64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + '@rollup/rollup-linux-arm64-musl@4.60.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.4': + '@rollup/rollup-linux-loong64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.4': + '@rollup/rollup-linux-loong64-musl@4.60.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.4': + '@rollup/rollup-linux-ppc64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.4': + '@rollup/rollup-linux-ppc64-musl@4.60.2': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.4': + '@rollup/rollup-linux-riscv64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.4': + '@rollup/rollup-linux-riscv64-musl@4.60.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.4': + '@rollup/rollup-linux-s390x-gnu@4.60.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.4': + '@rollup/rollup-linux-x64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.4': + '@rollup/rollup-linux-x64-musl@4.60.2': optional: true - '@rollup/rollup-linux-x64-musl@4.52.4': + '@rollup/rollup-openbsd-x64@4.60.2': optional: true - '@rollup/rollup-openharmony-arm64@4.52.4': + '@rollup/rollup-openharmony-arm64@4.60.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.4': + '@rollup/rollup-win32-arm64-msvc@4.60.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.4': + '@rollup/rollup-win32-ia32-msvc@4.60.2': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.4': + '@rollup/rollup-win32-x64-gnu@4.60.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.4': + '@rollup/rollup-win32-x64-msvc@4.60.2': optional: true + '@standard-schema/spec@1.1.0': {} + '@types/better-sqlite3@7.6.13': dependencies: - '@types/node': 22.18.8 + '@types/node': 25.6.0 - '@types/chai@5.2.2': + '@types/bun@1.3.13': + dependencies: + bun-types: 1.3.13 + + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/deep-eql@4.0.2': {} '@types/estree@1.0.8': {} - '@types/json-schema@7.0.15': {} - - '@types/node@22.18.8': - dependencies: - undici-types: 6.21.0 - - '@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.46.0(eslint@9.37.0)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0)(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.0 - eslint: 9.37.0 - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.46.0(eslint@9.37.0)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.0 - debug: 4.4.0 - eslint: 9.37.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.46.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - debug: 4.4.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.46.0': - dependencies: - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/visitor-keys': 8.46.0 - - '@typescript-eslint/tsconfig-utils@8.46.0(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@typescript-eslint/type-utils@8.46.0(eslint@9.37.0)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0)(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.37.0 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.46.0': {} - - '@typescript-eslint/typescript-estree@8.46.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.46.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/visitor-keys': 8.46.0 - debug: 4.4.0 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.46.0(eslint@9.37.0)(typescript@5.9.3)': + '@types/node@25.6.0': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) - eslint: 9.37.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color + undici-types: 7.19.2 - '@typescript-eslint/visitor-keys@8.46.0': + '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': dependencies: - '@typescript-eslint/types': 8.46.0 - eslint-visitor-keys: 4.2.1 - - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1))': - dependencies: - '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - ast-v8-to-istanbul: 0.3.5 - debug: 4.4.3 + '@vitest/utils': 4.1.5 + ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.1.7 - magic-string: 0.30.17 - magicast: 0.3.5 - std-env: 3.9.0 - test-exclude: 7.0.1 - tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1) - transitivePeerDependencies: - - supports-color + istanbul-reports: 3.2.0 + magicast: 0.5.2 + obug: 2.1.1 + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(vite@6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3)) - '@vitest/expect@3.2.4': + '@vitest/expect@4.1.5': dependencies: - '@types/chai': 5.2.2 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.3.3 - tinyrainbow: 2.0.0 + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.5 + '@vitest/utils': 4.1.5 + chai: 6.2.2 + tinyrainbow: 3.1.0 - '@vitest/mocker@3.2.4(vite@6.0.11(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1))': + '@vitest/mocker@4.1.5(vite@6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: - '@vitest/spy': 3.2.4 + '@vitest/spy': 4.1.5 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.21 optionalDependencies: - vite: 6.0.11(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1) + vite: 6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/pretty-format@3.2.4': + '@vitest/pretty-format@4.1.5': dependencies: - tinyrainbow: 2.0.0 + tinyrainbow: 3.1.0 - '@vitest/runner@3.2.4': + '@vitest/runner@4.1.5': dependencies: - '@vitest/utils': 3.2.4 + '@vitest/utils': 4.1.5 pathe: 2.0.3 - strip-literal: 3.1.0 - '@vitest/snapshot@3.2.4': + '@vitest/snapshot@4.1.5': dependencies: - '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.17 + '@vitest/pretty-format': 4.1.5 + '@vitest/utils': 4.1.5 + magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@3.2.4': - dependencies: - tinyspy: 4.0.4 + '@vitest/spy@4.1.5': {} - '@vitest/utils@3.2.4': + '@vitest/utils@4.1.5': dependencies: - '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 - tinyrainbow: 2.0.0 + '@vitest/pretty-format': 4.1.5 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 + acorn@8.16.0: {} - ansi-escapes@7.0.0: + ansi-escapes@7.3.0: dependencies: environment: 1.1.0 - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 + ansi-regex@6.2.2: {} - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} any-promise@1.3.0: {} - argparse@2.0.1: {} - assertion-error@2.0.1: {} - ast-v8-to-istanbul@0.3.5: + ast-v8-to-istanbul@1.0.0: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 - js-tokens: 9.0.1 - - balanced-match@1.0.2: {} + js-tokens: 10.0.0 base64-js@1.5.1: {} - better-sqlite3@11.10.0: + better-sqlite3@12.9.0: dependencies: bindings: 1.5.0 prebuild-install: 7.1.3 @@ -2459,53 +1704,27 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - buffer@5.7.1: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - bundle-require@5.1.0(esbuild@0.25.10): - dependencies: - esbuild: 0.25.10 - load-tsconfig: 0.2.5 - - cac@6.7.14: {} - - callsites@3.1.0: {} - - chai@5.3.3: + bun-types@1.3.13: dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + '@types/node': 25.6.0 - chalk@4.1.2: + bundle-require@5.1.0(esbuild@0.27.7): dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 + esbuild: 0.27.7 + load-tsconfig: 0.2.5 - chalk@5.4.1: {} + cac@6.7.14: {} - check-error@2.1.1: {} + chai@6.2.2: {} chokidar@4.0.3: dependencies: - readdirp: 4.1.1 + readdirp: 4.1.2 chownr@1.1.4: {} @@ -2513,38 +1732,22 @@ snapshots: dependencies: restore-cursor: 5.1.0 - cli-truncate@4.0.0: - dependencies: - slice-ansi: 5.0.0 - string-width: 7.2.0 - - color-convert@2.0.1: + cli-truncate@5.2.0: dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} + slice-ansi: 8.0.0 + string-width: 8.2.1 colorette@2.0.20: {} - commander@13.1.0: {} + commander@14.0.3: {} commander@4.1.1: {} - concat-map@0.0.1: {} - confbox@0.1.8: {} - consola@3.4.0: {} + consola@3.4.2: {} - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.4.0: - dependencies: - ms: 2.1.3 + convert-source-map@2.0.0: {} debug@4.4.3: dependencies: @@ -2554,29 +1757,19 @@ snapshots: dependencies: mimic-response: 3.1.0 - deep-eql@5.0.2: {} - deep-extend@0.6.0: {} - deep-is@0.1.4: {} - - detect-libc@2.0.3: {} + detect-libc@2.1.2: {} - eastasianwidth@0.2.0: {} + emoji-regex@10.6.0: {} - emoji-regex@10.4.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - end-of-stream@1.4.4: + end-of-stream@1.4.5: dependencies: once: 1.4.0 environment@1.1.0: {} - es-module-lexer@1.7.0: {} + es-module-lexer@2.1.0: {} esbuild@0.24.2: optionalDependencies: @@ -2606,276 +1799,85 @@ snapshots: '@esbuild/win32-ia32': 0.24.2 '@esbuild/win32-x64': 0.24.2 - esbuild@0.25.10: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.10 - '@esbuild/android-arm': 0.25.10 - '@esbuild/android-arm64': 0.25.10 - '@esbuild/android-x64': 0.25.10 - '@esbuild/darwin-arm64': 0.25.10 - '@esbuild/darwin-x64': 0.25.10 - '@esbuild/freebsd-arm64': 0.25.10 - '@esbuild/freebsd-x64': 0.25.10 - '@esbuild/linux-arm': 0.25.10 - '@esbuild/linux-arm64': 0.25.10 - '@esbuild/linux-ia32': 0.25.10 - '@esbuild/linux-loong64': 0.25.10 - '@esbuild/linux-mips64el': 0.25.10 - '@esbuild/linux-ppc64': 0.25.10 - '@esbuild/linux-riscv64': 0.25.10 - '@esbuild/linux-s390x': 0.25.10 - '@esbuild/linux-x64': 0.25.10 - '@esbuild/netbsd-arm64': 0.25.10 - '@esbuild/netbsd-x64': 0.25.10 - '@esbuild/openbsd-arm64': 0.25.10 - '@esbuild/openbsd-x64': 0.25.10 - '@esbuild/openharmony-arm64': 0.25.10 - '@esbuild/sunos-x64': 0.25.10 - '@esbuild/win32-arm64': 0.25.10 - '@esbuild/win32-ia32': 0.25.10 - '@esbuild/win32-x64': 0.25.10 - - escape-string-regexp@4.0.0: {} - - eslint-config-prettier@10.1.8(eslint@9.37.0): - dependencies: - eslint: 9.37.0 - - eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0))(eslint@9.37.0)(prettier@3.6.2): - dependencies: - eslint: 9.37.0 - prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 + esbuild@0.27.7: optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@9.37.0) - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.37.0: - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.4.0 - '@eslint/core': 0.16.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.37.0 - '@eslint/plugin-kit': 0.4.0 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 - esutils@2.0.3: {} - - eventemitter3@5.0.1: {} - - execa@8.0.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 + eventemitter3@5.0.4: {} expand-template@2.0.3: {} - expect-type@1.2.2: {} + expect-type@1.3.0: {} - fast-deep-equal@3.1.3: {} - - fast-diff@1.3.0: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fdir@6.5.0(picomatch@4.0.3): + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: - picomatch: 4.0.3 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 + picomatch: 4.0.4 file-uri-to-path@1.0.0: {} - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.19 - mlly: 1.8.0 - rollup: 4.52.4 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.2 - keyv: 4.5.4 - - flatted@3.3.2: {} - - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 + magic-string: 0.30.21 + mlly: 1.8.2 + rollup: 4.60.2 fs-constants@1.0.0: {} fsevents@2.3.3: optional: true - get-east-asian-width@1.3.0: {} - - get-stream@8.0.1: {} + get-east-asian-width@1.5.0: {} - get-tsconfig@4.10.0: + get-tsconfig@4.14.0: dependencies: resolve-pkg-maps: 1.0.0 github-from-package@0.0.0: {} - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.4.5: - dependencies: - foreground-child: 3.3.0 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - - globals@14.0.0: {} - - graphemer@1.4.0: {} - has-flag@4.0.0: {} html-escaper@2.0.2: {} - human-signals@5.0.0: {} - husky@9.1.7: {} ieee754@1.2.1: {} - ignore@5.3.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.0: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - inherits@2.0.4: {} ini@1.3.8: {} - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-fullwidth-code-point@4.0.0: {} - - is-fullwidth-code-point@5.0.0: - dependencies: - get-east-asian-width: 1.3.0 - - is-glob@4.0.3: + is-fullwidth-code-point@5.1.0: dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-stream@3.0.0: {} - - isexe@2.0.0: {} + get-east-asian-width: 1.5.0 istanbul-lib-coverage@3.2.2: {} @@ -2885,151 +1887,79 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@5.0.6: - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.3 - istanbul-lib-coverage: 3.2.2 - transitivePeerDependencies: - - supports-color - - istanbul-reports@3.1.7: + istanbul-reports@3.2.0: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - joycon@3.1.1: {} - js-tokens@9.0.1: {} - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} + js-tokens@10.0.0: {} - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: + jsdoc-lint@0.4.0: dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 + typescript: 6.0.3 lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} - lint-staged@15.5.2: + lint-staged@16.4.0: dependencies: - chalk: 5.4.1 - commander: 13.1.0 - debug: 4.4.0 - execa: 8.0.1 - lilconfig: 3.1.3 - listr2: 8.2.5 - micromatch: 4.0.8 - pidtree: 0.6.0 + commander: 14.0.3 + listr2: 9.0.5 + picomatch: 4.0.4 string-argv: 0.3.2 - yaml: 2.8.1 - transitivePeerDependencies: - - supports-color + tinyexec: 1.1.1 + yaml: 2.8.3 - listr2@8.2.5: + listr2@9.0.5: dependencies: - cli-truncate: 4.0.0 + cli-truncate: 5.2.0 colorette: 2.0.20 - eventemitter3: 5.0.1 + eventemitter3: 5.0.4 log-update: 6.1.0 rfdc: 1.4.1 - wrap-ansi: 9.0.0 + wrap-ansi: 9.0.2 load-tsconfig@0.2.5: {} - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - lodash.sortby@4.7.0: {} - log-update@6.1.0: dependencies: - ansi-escapes: 7.0.0 + ansi-escapes: 7.3.0 cli-cursor: 5.0.0 - slice-ansi: 7.1.0 - strip-ansi: 7.1.0 - wrap-ansi: 9.0.0 - - loupe@3.2.1: {} + slice-ansi: 7.1.2 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 - lru-cache@10.4.3: {} - - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - - magic-string@0.30.19: + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magicast@0.3.5: + magicast@0.5.2: dependencies: - '@babel/parser': 7.26.5 - '@babel/types': 7.26.5 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 source-map-js: 1.2.1 make-dir@4.0.0: dependencies: - semver: 7.6.3 - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mimic-fn@4.0.0: {} + semver: 7.7.4 mimic-function@5.0.1: {} mimic-response@3.1.0: {} - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - minimist@1.2.8: {} - minipass@7.1.2: {} - mkdirp-classic@0.5.3: {} - mlly@1.8.0: + mlly@1.8.2: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.6.1 + ufo: 1.6.3 ms@2.1.3: {} @@ -3039,134 +1969,74 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nanoid@3.3.8: {} + nanoid@3.3.11: {} napi-build-utils@2.0.0: {} - natural-compare@1.4.0: {} - - node-abi@3.73.0: - dependencies: - semver: 7.6.3 - - npm-run-path@5.3.0: + node-abi@3.89.0: dependencies: - path-key: 4.0.0 + semver: 7.7.4 object-assign@4.1.1: {} + obug@2.1.1: {} + once@1.4.0: dependencies: wrappy: 1.0.2 - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - onetime@7.0.0: dependencies: mimic-function: 5.0.1 - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - package-json-from-dist@1.0.1: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - pathe@2.0.3: {} - pathval@2.0.1: {} - picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@4.0.4: {} - picomatch@4.0.3: {} - - pidtree@0.6.0: {} - - pirates@4.0.6: {} + pirates@4.0.7: {} pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.8.0 + mlly: 1.8.2 pathe: 2.0.3 - postcss-load-config@6.0.1(postcss@8.5.1)(tsx@4.20.6)(yaml@2.8.1): + postcss-load-config@6.0.1(postcss@8.5.12)(tsx@4.21.0)(yaml@2.8.3): dependencies: lilconfig: 3.1.3 optionalDependencies: - postcss: 8.5.1 - tsx: 4.20.6 - yaml: 2.8.1 + postcss: 8.5.12 + tsx: 4.21.0 + yaml: 2.8.3 - postcss@8.5.1: + postcss@8.5.12: dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 prebuild-install@7.1.3: dependencies: - detect-libc: 2.0.3 + detect-libc: 2.1.2 expand-template: 2.0.3 github-from-package: 0.0.0 minimist: 1.2.8 mkdirp-classic: 0.5.3 napi-build-utils: 2.0.0 - node-abi: 3.73.0 - pump: 3.0.2 + node-abi: 3.89.0 + pump: 3.0.4 rc: 1.2.8 simple-get: 4.0.1 - tar-fs: 2.1.2 + tar-fs: 2.1.4 tunnel-agent: 0.6.0 - prelude-ls@1.2.1: {} - - prettier-linter-helpers@1.0.0: + pump@3.0.4: dependencies: - fast-diff: 1.3.0 - - prettier@3.6.2: {} - - pump@3.0.2: - dependencies: - end-of-stream: 1.4.4 + end-of-stream: 1.4.5 once: 1.4.0 - punycode@2.3.1: {} - - queue-microtask@1.2.3: {} - rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -3180,9 +2050,7 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readdirp@4.1.1: {} - - resolve-from@4.0.0: {} + readdirp@4.1.2: {} resolve-from@5.0.0: {} @@ -3193,53 +2061,42 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 - reusify@1.1.0: {} - rfdc@1.4.1: {} - rollup@4.52.4: + rollup@4.60.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.4 - '@rollup/rollup-android-arm64': 4.52.4 - '@rollup/rollup-darwin-arm64': 4.52.4 - '@rollup/rollup-darwin-x64': 4.52.4 - '@rollup/rollup-freebsd-arm64': 4.52.4 - '@rollup/rollup-freebsd-x64': 4.52.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 - '@rollup/rollup-linux-arm-musleabihf': 4.52.4 - '@rollup/rollup-linux-arm64-gnu': 4.52.4 - '@rollup/rollup-linux-arm64-musl': 4.52.4 - '@rollup/rollup-linux-loong64-gnu': 4.52.4 - '@rollup/rollup-linux-ppc64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-musl': 4.52.4 - '@rollup/rollup-linux-s390x-gnu': 4.52.4 - '@rollup/rollup-linux-x64-gnu': 4.52.4 - '@rollup/rollup-linux-x64-musl': 4.52.4 - '@rollup/rollup-openharmony-arm64': 4.52.4 - '@rollup/rollup-win32-arm64-msvc': 4.52.4 - '@rollup/rollup-win32-ia32-msvc': 4.52.4 - '@rollup/rollup-win32-x64-gnu': 4.52.4 - '@rollup/rollup-win32-x64-msvc': 4.52.4 + '@rollup/rollup-android-arm-eabi': 4.60.2 + '@rollup/rollup-android-arm64': 4.60.2 + '@rollup/rollup-darwin-arm64': 4.60.2 + '@rollup/rollup-darwin-x64': 4.60.2 + '@rollup/rollup-freebsd-arm64': 4.60.2 + '@rollup/rollup-freebsd-x64': 4.60.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.2 + '@rollup/rollup-linux-arm-musleabihf': 4.60.2 + '@rollup/rollup-linux-arm64-gnu': 4.60.2 + '@rollup/rollup-linux-arm64-musl': 4.60.2 + '@rollup/rollup-linux-loong64-gnu': 4.60.2 + '@rollup/rollup-linux-loong64-musl': 4.60.2 + '@rollup/rollup-linux-ppc64-gnu': 4.60.2 + '@rollup/rollup-linux-ppc64-musl': 4.60.2 + '@rollup/rollup-linux-riscv64-gnu': 4.60.2 + '@rollup/rollup-linux-riscv64-musl': 4.60.2 + '@rollup/rollup-linux-s390x-gnu': 4.60.2 + '@rollup/rollup-linux-x64-gnu': 4.60.2 + '@rollup/rollup-linux-x64-musl': 4.60.2 + '@rollup/rollup-openbsd-x64': 4.60.2 + '@rollup/rollup-openharmony-arm64': 4.60.2 + '@rollup/rollup-win32-arm64-msvc': 4.60.2 + '@rollup/rollup-win32-ia32-msvc': 4.60.2 + '@rollup/rollup-win32-x64-gnu': 4.60.2 + '@rollup/rollup-win32-x64-msvc': 4.60.2 fsevents: 2.3.3 - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - safe-buffer@5.2.1: {} - semver@7.6.3: {} - - semver@7.7.3: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} + semver@7.7.4: {} siginfo@2.0.0: {} @@ -3253,107 +2110,76 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 - slice-ansi@5.0.0: + slice-ansi@7.1.2: dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 - slice-ansi@7.1.0: + slice-ansi@8.0.0: dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 5.0.0 + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 source-map-js@1.2.1: {} - source-map@0.8.0-beta.0: - dependencies: - whatwg-url: 7.1.0 + source-map@0.7.6: {} stackback@0.0.2: {} - std-env@3.9.0: {} + std-env@4.1.0: {} string-argv@0.3.2: {} - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: + string-width@7.2.0: dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + emoji-regex: 10.6.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 - string-width@7.2.0: + string-width@8.2.1: dependencies: - emoji-regex: 10.4.0 - get-east-asian-width: 1.3.0 - strip-ansi: 7.1.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 - strip-ansi@6.0.1: + strip-ansi@7.2.0: dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - - strip-final-newline@3.0.0: {} + ansi-regex: 6.2.2 strip-json-comments@2.0.1: {} - strip-json-comments@3.1.1: {} - - strip-literal@3.1.0: + sucrase@3.35.1: dependencies: - js-tokens: 9.0.1 - - sucrase@3.35.0: - dependencies: - '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 + tinyglobby: 0.2.16 ts-interface-checker: 0.1.13 supports-color@7.2.0: dependencies: has-flag: 4.0.0 - synckit@0.11.11: - dependencies: - '@pkgr/core': 0.2.9 - - tar-fs@2.1.2: + tar-fs@2.1.4: dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 - pump: 3.0.2 + pump: 3.0.4 tar-stream: 2.2.0 tar-stream@2.2.0: dependencies: bl: 4.1.0 - end-of-stream: 1.4.4 + end-of-stream: 1.4.5 fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 - test-exclude@7.0.1: - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 10.4.5 - minimatch: 9.0.5 - thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -3366,65 +2192,51 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinypool@1.1.1: {} - - tinyrainbow@2.0.0: {} + tinyexec@1.1.1: {} - tinyspy@4.0.4: {} - - to-regex-range@5.0.1: + tinyglobby@0.2.16: dependencies: - is-number: 7.0.0 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 - tr46@1.0.1: - dependencies: - punycode: 2.3.1 + tinyrainbow@3.1.0: {} tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - ts-interface-checker@0.1.13: {} - tsup@8.5.0(postcss@8.5.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): + tsup@8.5.1(postcss@8.5.12)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3): dependencies: - bundle-require: 5.1.0(esbuild@0.25.10) + bundle-require: 5.1.0(esbuild@0.27.7) cac: 6.7.14 chokidar: 4.0.3 - consola: 3.4.0 - debug: 4.4.0 - esbuild: 0.25.10 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.27.7 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(postcss@8.5.1)(tsx@4.20.6)(yaml@2.8.1) + postcss-load-config: 6.0.1(postcss@8.5.12)(tsx@4.21.0)(yaml@2.8.3) resolve-from: 5.0.0 - rollup: 4.52.4 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 + rollup: 4.60.2 + source-map: 0.7.6 + sucrase: 3.35.1 tinyexec: 0.3.2 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 tree-kill: 1.2.2 optionalDependencies: - postcss: 8.5.1 - typescript: 5.9.3 + postcss: 8.5.12 + typescript: 6.0.3 transitivePeerDependencies: - jiti - supports-color - tsx - yaml - tsx@4.20.6: + tsx@4.21.0: dependencies: - esbuild: 0.25.10 - get-tsconfig: 4.10.0 + esbuild: 0.27.7 + get-tsconfig: 4.14.0 optionalDependencies: fsevents: 2.3.3 @@ -3432,134 +2244,64 @@ snapshots: dependencies: safe-buffer: 5.2.1 - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - typescript@5.9.3: {} - - ufo@1.6.1: {} + typescript@6.0.3: {} - undici-types@6.21.0: {} + ufo@1.6.3: {} - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 + undici-types@7.19.2: {} util-deprecate@1.0.2: {} - vite-node@3.2.4(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1): - dependencies: - cac: 6.7.14 - debug: 4.4.3 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 6.0.11(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vite@6.0.11(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1): + vite@6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: esbuild: 0.24.2 - postcss: 8.5.1 - rollup: 4.52.4 + postcss: 8.5.12 + rollup: 4.60.2 optionalDependencies: - '@types/node': 22.18.8 + '@types/node': 25.6.0 fsevents: 2.3.3 - tsx: 4.20.6 - yaml: 2.8.1 - - vitest@3.2.4(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1): - dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.0.11(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.3.3 - debug: 4.4.3 - expect-type: 1.2.2 - magic-string: 0.30.17 + tsx: 4.21.0 + yaml: 2.8.3 + + vitest@4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(vite@6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3)): + dependencies: + '@vitest/expect': 4.1.5 + '@vitest/mocker': 4.1.5(vite@6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.5 + '@vitest/runner': 4.1.5 + '@vitest/snapshot': 4.1.5 + '@vitest/spy': 4.1.5 + '@vitest/utils': 4.1.5 + es-module-lexer: 2.1.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: 3.9.0 + picomatch: 4.0.4 + std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.15 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 - vite: 6.0.11(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.18.8)(tsx@4.20.6)(yaml@2.8.1) + tinyexec: 1.1.1 + tinyglobby: 0.2.16 + tinyrainbow: 3.1.0 + vite: 6.0.11(@types/node@25.6.0)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.18.8 + '@types/node': 25.6.0 + '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) transitivePeerDependencies: - - jiti - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - webidl-conversions@4.0.2: {} - - whatwg-url@7.1.0: - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 stackback: 0.0.2 - word-wrap@1.2.5: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: + wrap-ansi@9.0.2: dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrap-ansi@9.0.0: - dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 7.2.0 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 wrappy@1.0.2: {} - yaml@2.8.1: {} - - yocto-queue@0.1.0: {} + yaml@2.8.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f2721cf..5e27d53 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,6 @@ onlyBuiltDependencies: - better-sqlite3 - esbuild + +minimumReleaseAgeExclude: + - jsdoc-lint@0.4.0 diff --git a/scripts/release.mjs b/scripts/release.mjs new file mode 100644 index 0000000..d3dec60 --- /dev/null +++ b/scripts/release.mjs @@ -0,0 +1,148 @@ +import { spawn } from 'node:child_process'; +import process from 'node:process'; + +/** + * Parses CLI arguments for the release helper. + * + * @param {string[]} args CLI arguments after the script path. + * @returns {{ dryRun: boolean, version: string }} Parsed release options. + */ +export function parseReleaseArgs(args) { + const dryRun = args.includes('--dry-run'); + const positionalArgs = args.filter((arg) => arg !== '--dry-run' && arg !== '--'); + const version = positionalArgs[0]; + + if (!version || positionalArgs.length !== 1) { + throw new Error('Usage: pnpm run release -- [--dry-run]'); + } + + if (!/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u.test(version)) { + throw new Error('Version must be plain semver like 0.2.0, without a leading "v".'); + } + + return { dryRun, version }; +} + +/** + * Creates the ordered command plan used by the release helper. + * + * @param {string} version Plain semver version. + * @returns {[string, string[]][]} Command plan. + */ +export function createReleasePlan(version) { + const tagName = `v${version}`; + + return [ + ['git', ['status', '--porcelain']], + ['git', ['branch', '--show-current']], + ['gh', ['auth', 'status']], + ['git', ['fetch', '--tags', 'origin']], + ['git', ['rev-parse', '--verify', tagName]], + ['gh', ['release', 'view', tagName]], + ['pnpm', ['run', 'build']], + ['npm', ['version', version, '--no-git-tag-version']], + ['git', ['add', 'package.json', 'pnpm-lock.yaml']], + ['git', ['commit', '-m', `chore: release ${version}`]], + ['git', ['push']], + ['gh', ['release', 'create', tagName, '--target', 'main', '--title', tagName, '--generate-notes']], + ]; +} + +/** + * Runs the release flow. + * + * @param {{ dryRun: boolean, log?: (message: string) => void, run?: typeof runCommand, version: string }} options + * Release options. + * @returns {Promise} Resolves when the release flow finishes. + */ +export async function release({ dryRun, log = console.log, run = runCommand, version }) { + const plan = createReleasePlan(version); + + for (const [command, args] of plan) { + const isMutation = isMutatingCommand(command, args); + if (dryRun && isMutation) { + log(`[dry-run] ${formatCommand(command, args)}`); + continue; + } + + log(formatCommand(command, args)); + const result = await run(command, args); + + if (command === 'git' && args.join(' ') === 'status --porcelain' && result.stdout.trim()) { + throw new Error('Working tree must be clean before releasing.'); + } + + if (command === 'git' && args.join(' ') === 'branch --show-current' && result.stdout.trim() !== 'main') { + throw new Error('Releases must be created from main.'); + } + + if (command === 'git' && args[0] === 'rev-parse' && result.status === 0) { + throw new Error(`Tag ${args[2]} already exists.`); + } + + if (command === 'gh' && args[0] === 'release' && args[1] === 'view' && result.status === 0) { + throw new Error(`GitHub release ${args[2]} already exists.`); + } + + const expectedMissingResource = + (command === 'git' && args[0] === 'rev-parse') || + (command === 'gh' && args[0] === 'release' && args[1] === 'view'); + + if (result.status !== 0 && !expectedMissingResource) { + throw new Error(`Command failed: ${formatCommand(command, args)}`); + } + } +} + +/** + * Runs a child process and captures stdout. + * + * @param {string} command Executable name. + * @param {string[]} args Executable arguments. + * @returns {Promise<{ status: number, stdout: string }>} Command result. + */ +function runCommand(command, args) { + return new Promise((resolve) => { + const child = spawn(command, args, { stdio: ['ignore', 'pipe', 'inherit'] }); + const stdout = []; + + child.stdout.setEncoding('utf8'); + child.stdout.on('data', (chunk) => stdout.push(chunk)); + child.on('close', (status) => resolve({ status: status ?? 1, stdout: stdout.join('') })); + }); +} + +/** + * Checks whether a planned command changes repository or GitHub state. + * + * @param {string} command Executable name. + * @param {string[]} args Executable arguments. + * @returns {boolean} True when the command mutates state. + */ +function isMutatingCommand(command, args) { + return ( + (command === 'npm' && args[0] === 'version') || + (command === 'git' && ['add', 'commit', 'push'].includes(args[0])) || + (command === 'gh' && args[0] === 'release' && args[1] === 'create') + ); +} + +/** + * Formats a command for logging. + * + * @param {string} command Executable name. + * @param {string[]} args Executable arguments. + * @returns {string} Shell-like command string. + */ +function formatCommand(command, args) { + return [command, ...args].join(' '); +} + +if (process.argv[1] && import.meta.url === new URL(process.argv[1], 'file:').href) { + try { + await release(parseReleaseArgs(process.argv.slice(2))); + } catch (error) { + console.error(error instanceof Error ? error.message : String(error)); + process.exitCode = 1; + } +} diff --git a/src/index.bun.test.ts b/src/index.bun.test.ts new file mode 100644 index 0000000..7f887a0 --- /dev/null +++ b/src/index.bun.test.ts @@ -0,0 +1,547 @@ +import { Database, type SQLQueryBindings } from 'bun:sqlite'; +import { afterEach, describe, expect, it } from 'bun:test'; +import { promises as fs } from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { SQL } from 'bun'; + +import { MigrationError, MigrationExecutionError, MigrationFileError, MigrationLockError, Migrator } from './index'; +import type { MigratorDatabase } from './types'; + +type BunMigratorTestProvider = { + name: string; + createDatabase: () => { + db: MigratorDatabase; + close: () => unknown; + all: (sql: string, params?: SQLQueryBindings[]) => Promise; + get: (sql: string, params?: SQLQueryBindings[]) => Promise; + run: (sql: string, params?: SQLQueryBindings[]) => Promise; + }; +}; + +const providers: BunMigratorTestProvider[] = [ + { + name: 'Bun synchronous SQLite', + createDatabase: () => { + const db = new Database(':memory:'); + + return { + db, + close: () => db.close(), + all: async (sql: string, params: SQLQueryBindings[] = []) => db.query(sql).all(...params) as T[], + get: async (sql: string, params: SQLQueryBindings[] = []) => db.query(sql).get(...params) as T | undefined, + run: async (sql: string, params: SQLQueryBindings[] = []) => db.query(sql).run(...params), + }; + }, + }, + { + name: 'Bun SQL SQLite', + createDatabase: () => { + const sql = new SQL(':memory:'); + + return { + db: sql, + close: () => sql.close(), + all: async (query: string, params: SQLQueryBindings[] = []) => + (await sql.unsafe(query, params.length > 0 ? params : undefined)) as T[], + get: async (query: string, params: SQLQueryBindings[] = []) => { + const rows = (await sql.unsafe(query, params.length > 0 ? params : undefined)) as T[]; + return rows[0]; + }, + run: async (query: string, params: SQLQueryBindings[] = []) => + sql.unsafe(query, params.length > 0 ? params : undefined), + }; + }, + }, +]; + +async function createTempMigrationsDir( + prefix = 'sqlite-up-bun-index-' +): Promise<{ tempDir: string; migrationsDir: string }> { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), prefix)); + const migrationsDir = path.join(tempDir, 'migrations'); + await fs.mkdir(migrationsDir); + return { tempDir, migrationsDir }; +} + +async function writeMigration(migrationsDir: string, name: string, body: string): Promise { + await fs.writeFile(path.join(migrationsDir, name), body); +} + +async function writeUserAndPostMigrations(migrationsDir: string): Promise { + await writeMigration( + migrationsDir, + '001_users.ts', + ` + export async function up(db) { + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + await db.exec('DROP TABLE users'); + } + ` + ); + + await writeMigration( + migrationsDir, + '002_posts.ts', + ` + export async function up(db) { + await db.exec('CREATE TABLE posts (id INTEGER PRIMARY KEY, user_id INTEGER)'); + } + export async function down(db) { + await db.exec('DROP TABLE posts'); + } + ` + ); +} + +describe('Migrator with Bun providers', () => { + const cleanup: Array<() => unknown> = []; + const tempDirs: string[] = []; + + afterEach(async () => { + for (const close of cleanup.splice(0)) { + close(); + } + + for (const tempDir of tempDirs.splice(0)) { + await fs.rm(tempDir, { recursive: true, force: true }); + } + }); + + for (const provider of providers) { + describe(provider.name, () => { + async function createContext(options: { seedDefaultMigrations?: boolean } = {}) { + const { tempDir, migrationsDir } = await createTempMigrationsDir(); + tempDirs.push(tempDir); + + const database = provider.createDatabase(); + cleanup.push(database.close); + + if (options.seedDefaultMigrations) { + await writeUserAndPostMigrations(migrationsDir); + } + + return { + ...database, + migrationsDir, + migrator: new Migrator({ + db: database.db, + migrationsDir, + }), + }; + } + + it('creates required tables', async () => { + const { get, migrator } = await createContext(); + + await migrator.status(); + + await expect( + get("SELECT name FROM sqlite_master WHERE type='table' AND name='schema_migrations'") + ).resolves.toBeDefined(); + await expect( + get("SELECT name FROM sqlite_master WHERE type='table' AND name='schema_migrations_lock'") + ).resolves.toBeDefined(); + }); + + it('allows custom table names', async () => { + const { db, get, migrationsDir } = await createContext(); + const migrator = new Migrator({ + db, + migrationsDir, + migrationsTable: 'custom_migrations', + migrationsLockTable: 'custom_lock', + }); + + await migrator.status(); + + await expect( + get("SELECT name FROM sqlite_master WHERE type='table' AND name='custom_migrations'") + ).resolves.toBeDefined(); + await expect( + get("SELECT name FROM sqlite_master WHERE type='table' AND name='custom_lock'") + ).resolves.toBeDefined(); + }); + + it('loads migrations in correct order', async () => { + const { migrationsDir, migrator } = await createContext(); + await writeMigration( + migrationsDir, + '002_second.ts', + ` + export async function up(db) { await db.exec('CREATE TABLE second (id INTEGER PRIMARY KEY)'); } + export async function down(db) { await db.exec('DROP TABLE second'); } + ` + ); + await writeMigration( + migrationsDir, + '001_first.ts', + ` + export async function up(db) { await db.exec('CREATE TABLE first (id INTEGER PRIMARY KEY)'); } + export async function down(db) { await db.exec('DROP TABLE first'); } + ` + ); + + const plan = await migrator.plan(); + + expect(plan.pendingMigrations).toEqual(['001_first.ts', '002_second.ts']); + }); + + it('throws on invalid migration files', async () => { + const { migrationsDir, migrator } = await createContext(); + await writeMigration(migrationsDir, 'invalid.ts', 'export const invalid = true;'); + + await expect(migrator.plan()).rejects.toThrow(MigrationFileError); + }); + + it('throws on syntax errors in migration files', async () => { + const { migrationsDir, migrator } = await createContext(); + await writeMigration(migrationsDir, 'syntax_error.ts', 'export const up = function( {'); + + await expect(migrator.plan()).rejects.toThrow(MigrationFileError); + }); + + it('handles missing migration directories', async () => { + const { db } = provider.createDatabase(); + cleanup.push(() => (db as { close?: () => unknown }).close?.()); + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'sqlite-up-bun-missing-')); + tempDirs.push(tempDir); + + const migrator = new Migrator({ + db, + migrationsDir: path.join(tempDir, 'missing'), + }); + + await expect(migrator.plan()).rejects.toThrow(MigrationFileError); + }); + + it('applies migrations successfully', async () => { + const { all, migrator } = await createContext({ seedDefaultMigrations: true }); + + const result = await migrator.apply(); + + expect(result.success).toBe(true); + expect(result.appliedMigrations).toEqual(['001_users.ts', '002_posts.ts']); + await expect( + all("SELECT name FROM sqlite_master WHERE type='table' AND name IN ('users', 'posts')") + ).resolves.toHaveLength(2); + }); + + it('returns migration errors and rolls back partial batches', async () => { + const { all, migrationsDir, migrator } = await createContext(); + await writeMigration( + migrationsDir, + '001_success.ts', + ` + export async function up(db) { + await db.exec('CREATE TABLE success (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + await db.exec('DROP TABLE success'); + } + ` + ); + await writeMigration( + migrationsDir, + '002_fail.ts', + ` + export async function up(db) { + await db.exec('INVALID SQL'); + } + export async function down(db) {} + ` + ); + + const result = await migrator.apply(); + + expect(result.success).toBe(false); + expect(result.error).toBeInstanceOf(MigrationExecutionError); + expect(result.appliedMigrations).toEqual([]); + await expect( + all("SELECT name FROM sqlite_master WHERE type='table' AND name = 'success'") + ).resolves.toHaveLength(0); + }); + + it('does not emit applied events when the migration transaction fails', async () => { + const { migrationsDir, migrator } = await createContext({ seedDefaultMigrations: true }); + await writeMigration( + migrationsDir, + '003_error.ts', + ` + export async function up(db) { + await db.exec('INVALID SQL'); + } + export async function down(db) {} + ` + ); + const events: string[] = []; + migrator.on('migration:applied', (name) => events.push(String(name))); + + const result = await migrator.apply(); + + expect(result.success).toBe(false); + expect(events).toEqual([]); + }); + + it('rolls back migrations', async () => { + const { all, migrator } = await createContext({ seedDefaultMigrations: true }); + + await migrator.apply(); + const result = await migrator.rollback(); + + expect(result.success).toBe(true); + expect(result.appliedMigrations).toEqual(['002_posts.ts', '001_users.ts']); + await expect( + all("SELECT name FROM sqlite_master WHERE type='table' AND name IN ('users', 'posts')") + ).resolves.toHaveLength(0); + }); + + it('does not report or emit rolled back migrations when rollback transaction fails', async () => { + const { all, migrationsDir, migrator } = await createContext(); + await writeMigration( + migrationsDir, + '001_users.ts', + ` + export async function up(db) { + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + throw new Error('Rollback failed'); + } + ` + ); + await writeMigration( + migrationsDir, + '002_posts.ts', + ` + export async function up(db) { + await db.exec('CREATE TABLE posts (id INTEGER PRIMARY KEY, user_id INTEGER)'); + } + export async function down(db) { + await db.exec('DROP TABLE posts'); + } + ` + ); + const events: string[] = []; + migrator.on('migration:rollback', (name) => events.push(String(name))); + + await migrator.apply(); + const result = await migrator.rollback(); + + expect(result.success).toBe(false); + expect(result.appliedMigrations).toEqual([]); + expect(events).toEqual([]); + await expect( + all("SELECT name FROM sqlite_master WHERE type='table' AND name IN ('users', 'posts')") + ).resolves.toHaveLength(2); + }); + + it('handles concurrent migration locks', async () => { + const { migrator, run } = await createContext({ seedDefaultMigrations: true }); + + await migrator.status(); + await run('UPDATE schema_migrations_lock SET locked = 1 WHERE id = 1'); + const result = await migrator.apply(); + + expect(result.success).toBe(false); + expect(result.error).toBeInstanceOf(MigrationLockError); + expect(result.appliedMigrations).toEqual([]); + }); + + it('releases locks after errors', async () => { + const { get, migrationsDir, migrator } = await createContext(); + await writeMigration( + migrationsDir, + '001_error.ts', + ` + export async function up() { throw new Error('Simulated error'); } + export async function down() {} + ` + ); + + await migrator.apply(); + + const lockStatus = await get<{ locked: number }>('SELECT locked FROM schema_migrations_lock WHERE id = 1'); + expect(lockStatus?.locked).toBe(0); + }); + + it('records and removes migrations', async () => { + const { all, migrator } = await createContext({ seedDefaultMigrations: true }); + + await migrator.apply(); + const records = await all<{ batch: number }>('SELECT * FROM schema_migrations ORDER BY batch ASC'); + expect(records).toHaveLength(2); + expect(records[0]?.batch).toBe(1); + + await migrator.rollback(); + await expect(all('SELECT * FROM schema_migrations')).resolves.toHaveLength(0); + }); + + it('reports status and creates plans', async () => { + const { migrator } = await createContext({ seedDefaultMigrations: true }); + + const initialStatus = await migrator.status(); + expect(initialStatus.currentBatch).toBe(0); + expect(initialStatus.pending).toBe(2); + expect(initialStatus.applied).toEqual([]); + + const plan = await migrator.plan(); + expect(plan.nextBatch).toBe(1); + expect(plan.pendingMigrations).toEqual(['001_users.ts', '002_posts.ts']); + + await migrator.apply(); + + const finalStatus = await migrator.status(); + expect(finalStatus.currentBatch).toBe(1); + expect(finalStatus.pending).toBe(0); + expect(finalStatus.applied).toHaveLength(2); + + const emptyPlan = await migrator.plan(); + expect(emptyPlan.nextBatch).toBe(2); + expect(emptyPlan.pendingMigrations).toEqual([]); + }); + + it('emits events for apply and rollback operations', async () => { + const { migrator } = await createContext({ seedDefaultMigrations: true }); + const events: string[] = []; + migrator.on('migration:applied', (name) => events.push(`applied:${name}`)); + migrator.on('migration:rollback', (name) => events.push(`rolledback:${name}`)); + migrator.on('error', (error) => events.push(`error:${error.message}`)); + + await migrator.apply(); + await migrator.rollback(); + + expect(events).toContain('applied:001_users.ts'); + expect(events).toContain('applied:002_posts.ts'); + expect(events).toContain('rolledback:002_posts.ts'); + expect(events).toContain('rolledback:001_users.ts'); + expect(events.some((event) => event.startsWith('error:'))).toBe(false); + }); + + it('handles empty migrations directories', async () => { + const { migrator } = await createContext(); + + const status = await migrator.status(); + const plan = await migrator.plan(); + + expect(status.pending).toBe(0); + expect(plan.pendingMigrations).toEqual([]); + }); + + it('handles large batches of migrations', async () => { + const { get, migrationsDir, migrator } = await createContext(); + for (let i = 1; i <= 10; i++) { + const num = i.toString().padStart(3, '0'); + await writeMigration( + migrationsDir, + `${num}_table.ts`, + ` + export async function up(db) { + await db.exec('CREATE TABLE table_${num} (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + await db.exec('DROP TABLE table_${num}'); + } + ` + ); + } + + const result = await migrator.apply(); + const tables = await get<{ count: number }>( + "SELECT count(*) as count FROM sqlite_master WHERE type='table' AND name LIKE 'table_%'" + ); + + expect(result.success).toBe(true); + expect(result.appliedMigrations).toHaveLength(10); + expect(tables?.count).toBe(10); + }); + + it('respects supported file extensions', async () => { + const { db, migrationsDir, migrator } = await createContext(); + await writeMigration( + migrationsDir, + '001_users.ts', + ` + export async function up(db) { + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + await db.exec('DROP TABLE users'); + } + ` + ); + await writeMigration( + migrationsDir, + '002_posts.js', + ` + export async function up(db) { + await db.exec('CREATE TABLE posts (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + await db.exec('DROP TABLE posts'); + } + ` + ); + await writeMigration( + migrationsDir, + '003_comments.mjs', + ` + export async function up(db) { + await db.exec('CREATE TABLE comments (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + await db.exec('DROP TABLE comments'); + } + ` + ); + await writeMigration(migrationsDir, '004_types.d.ts', 'export interface User { id: number; }'); + + expect((await migrator.plan()).pendingMigrations).toEqual(['001_users.ts', '002_posts.js']); + expect( + ( + await new Migrator({ + db, + migrationsDir, + fileExtensions: ['mjs'], + }).plan() + ).pendingMigrations + ).toEqual(['003_comments.mjs']); + expect( + ( + await new Migrator({ + db, + migrationsDir, + fileExtensions: ['ts'], + }).plan() + ).pendingMigrations + ).toEqual(['001_users.ts']); + }); + }); + } + + it('returns initialization errors from apply', async () => { + const { tempDir, migrationsDir } = await createTempMigrationsDir(); + tempDirs.push(tempDir); + await writeUserAndPostMigrations(migrationsDir); + + const migrator = new Migrator({ + db: { + exec: () => { + throw new Error('Database error'); + }, + prepare: () => { + throw new Error('Database error'); + }, + } as unknown as MigratorDatabase, + migrationsDir, + }); + + const result = await migrator.apply(); + + expect(result.success).toBe(false); + expect(result.error).toBeInstanceOf(MigrationError); + expect(result.appliedMigrations).toEqual([]); + }); +}); diff --git a/src/index.test.ts b/src/index.test.ts index b5a631e..14d9452 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1,19 +1,16 @@ -import os from 'os'; -import path from 'path'; -import { promises as fs } from 'fs'; -import SQLiteDatabase, { Database } from 'better-sqlite3'; -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; - -import { - MigrationFileError, - MigrationLockError, - MigrationExecutionError, - MigrationError, -} from './errors'; +import { promises as fs } from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { DatabaseSync } from 'node:sqlite'; +import Database from 'better-sqlite3'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { MigrationError, MigrationExecutionError, MigrationFileError, MigrationLockError } from './errors'; import { Migrator } from './index'; +import type { SqliteDatabase } from './types'; describe('Migrator', () => { - let db: Database; + let db: DatabaseSync; let migrationsDir: string; let migrator: Migrator; let tempDir: string; @@ -25,7 +22,7 @@ describe('Migrator', () => { await fs.mkdir(migrationsDir); // Create in-memory database - db = new SQLiteDatabase(':memory:'); + db = new DatabaseSync(':memory:'); migrator = new Migrator({ db, @@ -35,7 +32,7 @@ describe('Migrator', () => { afterEach(async () => { // Close database - if (db.open) { + if (db.isOpen) { db.close(); } @@ -56,9 +53,7 @@ describe('Migrator', () => { // Check lock table const lockTable = db - .prepare( - "SELECT name FROM sqlite_master WHERE type='table' AND name='schema_migrations_lock'" - ) + .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='schema_migrations_lock'") .get(); expect(lockTable).toBeDefined(); }); @@ -78,9 +73,7 @@ describe('Migrator', () => { .get(); expect(migrationsTable).toBeDefined(); - const lockTable = db - .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='custom_lock'") - .get(); + const lockTable = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='custom_lock'").get(); expect(lockTable).toBeDefined(); }); }); @@ -174,6 +167,49 @@ describe('Migrator', () => { expect(tables).toHaveLength(2); }); + it('should support better-sqlite3 databases', async () => { + db.close(); + await fs.rm(migrationsDir, { recursive: true, force: true }); + await fs.mkdir(migrationsDir); + + await fs.writeFile( + path.join(migrationsDir, '001_success.ts'), + ` + export async function up(db) { + await db.exec('CREATE TABLE success (id INTEGER PRIMARY KEY)'); + } + export async function down(db) { + await db.exec('DROP TABLE success'); + } + ` + ); + + await fs.writeFile( + path.join(migrationsDir, '002_fail.ts'), + ` + export async function up(db) { + await db.exec('INVALID SQL'); + } + export async function down(db) {} + ` + ); + + const betterDb = new Database(':memory:'); + migrator = new Migrator({ + db: betterDb, + migrationsDir, + }); + + const result = await migrator.apply(); + expect(result.success).toBe(false); + expect(result.error).toBeInstanceOf(MigrationExecutionError); + + const table = betterDb.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = 'success'").get(); + expect(table).toBeUndefined(); + + betterDb.close(); + }); + it('should handle migration errors', async () => { await fs.writeFile( path.join(migrationsDir, '003_error.ts'), @@ -192,6 +228,26 @@ describe('Migrator', () => { }); }); + it('should not emit applied events when the migration transaction fails', async () => { + await fs.writeFile( + path.join(migrationsDir, '003_error.ts'), + ` + export function up(db) { + db.exec('INVALID SQL'); + } + export function down(db) {} + ` + ); + + const appliedSpy = vi.fn(); + migrator.on('migration:applied', appliedSpy); + + const result = await migrator.apply(); + + expect(result.success).toBe(false); + expect(appliedSpy).not.toHaveBeenCalled(); + }); + it('should rollback migrations', async () => { // First apply migrations await migrator.apply(); @@ -208,6 +264,36 @@ describe('Migrator', () => { expect(tables).toHaveLength(0); }); + it('should not report or emit rolled back migrations when rollback transaction fails', async () => { + await fs.writeFile( + path.join(migrationsDir, '001_users.ts'), + ` + export function up(db) { + db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY)'); + } + export function down(db) { + throw new Error('Rollback failed'); + } + ` + ); + + await migrator.apply(); + + const rollbackSpy = vi.fn(); + migrator.on('migration:rollback', rollbackSpy); + + const result = await migrator.rollback(); + + expect(result.success).toBe(false); + expect(result.appliedMigrations).toEqual([]); + expect(rollbackSpy).not.toHaveBeenCalled(); + + const tables = db + .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name IN ('users', 'posts')") + .all(); + expect(tables).toHaveLength(2); + }); + it('should handle concurrent migrations', async () => { // Initialize tables await migrator.status(); @@ -240,9 +326,7 @@ describe('Migrator', () => { expect(result.error).toBeInstanceOf(MigrationExecutionError); // Verify transaction was rolled back - const table = db - .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='test'") - .get(); + const table = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='test'").get(); expect(table).toBeUndefined(); }); @@ -469,9 +553,9 @@ describe('Migrator', () => { await migrator.apply(); // Verify lock is released - const lockStatus = db - .prepare(`SELECT locked FROM schema_migrations_lock WHERE id = 1`) - .get() as { locked: number }; + const lockStatus = db.prepare(`SELECT locked FROM schema_migrations_lock WHERE id = 1`).get() as { + locked: number; + }; expect(lockStatus.locked).toBe(0); }); }); @@ -561,9 +645,7 @@ describe('Migrator', () => { expect(result.appliedMigrations).toHaveLength(0); // No migrations should have been applied in the transaction - const tables = db - .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = 'success'") - .all(); + const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = 'success'").all(); expect(tables).toHaveLength(0); }); }); @@ -592,9 +674,7 @@ describe('Migrator', () => { // Verify all tables were created const tables = db - .prepare( - "SELECT count(*) as count FROM sqlite_master WHERE type='table' AND name LIKE 'table_%'" - ) + .prepare("SELECT count(*) as count FROM sqlite_master WHERE type='table' AND name LIKE 'table_%'") .get() as { count: number }; expect(tables.count).toBe(10); }); @@ -606,7 +686,7 @@ describe('Migrator', () => { prepare: () => { throw new Error('Database error'); }, - } as unknown as Database; + } as unknown as SqliteDatabase; const errorMigrator = new Migrator({ db: invalidDb, @@ -639,7 +719,7 @@ describe('Migrator', () => { transaction: () => { throw new Error('Transaction error'); }, - } as unknown as Database; + } as unknown as SqliteDatabase; const errorMigrator = new Migrator({ db: errorDb, diff --git a/src/index.ts b/src/index.ts index 13a8a37..152b859 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,44 +1,72 @@ -import path from 'path'; -import { promises as fs } from 'fs'; -import { EventEmitter } from 'events'; - -import { Database } from 'better-sqlite3'; - -import { +import { EventEmitter } from 'node:events'; +import { promises as fs } from 'node:fs'; +import path from 'node:path'; +import { MigrationError, MigrationExecutionError, MigrationFileError, MigrationLockError } from './errors.js'; +import { createSqliteProvider, type SqliteProvider } from './providers/index.js'; +import type { + MaybePromise, Migration, MigrationPlan, MigrationRecord, MigrationResult, - MigratorOptions, MigrationStatus, -} from './types'; -import { - MigrationExecutionError, - MigrationFileError, - MigrationLockError, - MigrationError, -} from './errors.js'; + MigratorOptions, + SqliteDatabase, +} from './types.js'; /** * Migration provider for SQLite databases. * @example - * const db = new Database('database.db'); + * const db = new DatabaseSync('database.db'); * const migrator = new Migrator({ db, migrationsDir: 'migrations' }); * await migrator.apply(); */ export class Migrator extends EventEmitter { - private db: Database; + /** + * Driver-specific provider normalized to the sqlite-up database surface. + */ + private provider: SqliteProvider; + + /** + * Database handle used by migrations and internal bookkeeping queries. + */ + private db: SqliteDatabase; + + /** + * Directory where migration modules are loaded from. + */ private migrationsDir: string; + + /** + * Table that records successfully applied migrations. + */ private migrationsTable: string; + + /** + * Table that stores the single-row migration lock. + */ private lockTable: string; + + /** + * Migration modules loaded from disk in execution order. + */ private migrations: Migration[] = []; + + /** + * Whether internal tables and migration files have already been initialized. + */ private initialized = false; + + /** + * File extensions considered when loading migration modules. + */ private fileExtensions: string[]; constructor(options: MigratorOptions) { super(); - this.db = options.db; + this.provider = createSqliteProvider(options.db); + this.db = this.provider.db; this.migrationsDir = options.migrationsDir; this.migrationsTable = options.migrationsTable ?? 'schema_migrations'; this.lockTable = options.migrationsLockTable ?? 'schema_migrations_lock'; @@ -66,7 +94,7 @@ export class Migrator extends EventEmitter { private async initTables(): Promise { try { // Create the migrations table if it doesn't exist - this.db.exec(` + await this.db.exec(` CREATE TABLE IF NOT EXISTS ${this.migrationsTable} ( name TEXT PRIMARY KEY, executed_at TEXT NOT NULL, -- ISO string @@ -75,7 +103,7 @@ export class Migrator extends EventEmitter { `); // Create the lock table if it doesn't exist - this.db.exec(` + await this.db.exec(` CREATE TABLE IF NOT EXISTS ${this.lockTable} ( id INTEGER PRIMARY KEY CHECK (id = 1), locked INTEGER NOT NULL DEFAULT 0 @@ -83,7 +111,7 @@ export class Migrator extends EventEmitter { `); // Ensure exactly one row in the lock table (id=1) - this.db.exec(` + await this.db.exec(` INSERT OR IGNORE INTO ${this.lockTable} (id, locked) VALUES (1, 0) `); @@ -118,25 +146,20 @@ export class Migrator extends EventEmitter { const fullPath = path.join(this.migrationsDir, file); let imported: { - up: (db: Database) => void; - down: (db: Database) => void; + up: (db: SqliteDatabase) => MaybePromise; + down: (db: SqliteDatabase) => MaybePromise; }; try { // Dynamic import (ESM) imported = await import(fullPath); } catch (err) { - throw new MigrationFileError( - `Error loading migration "${file}": ${String(err)}`, - err as Error - ); + throw new MigrationFileError(`Error loading migration "${file}": ${String(err)}`, err as Error); } const { up, down } = imported; if (typeof up !== 'function' || typeof down !== 'function') { - throw new MigrationFileError( - `Migration "${file}" must export "up" and "down" functions.` - ); + throw new MigrationFileError(`Migration "${file}" must export "up" and "down" functions.`); } loadedMigrations.push({ name: file, up, down }); @@ -145,9 +168,7 @@ export class Migrator extends EventEmitter { // Only update migrations array after all files are loaded successfully this.migrations = loadedMigrations; } catch (err) { - throw err instanceof MigrationFileError - ? err - : new MigrationFileError('Failed to load migrations', err as Error); + throw err instanceof MigrationFileError ? err : new MigrationFileError('Failed to load migrations', err as Error); } } @@ -155,21 +176,19 @@ export class Migrator extends EventEmitter { * Acquire a lock to prevent concurrent migrations. * Throws an error if the lock is already held. */ - private acquireLock(): void { - const transaction = this.db.transaction(() => { - const row = this.db.prepare(`SELECT locked FROM ${this.lockTable} WHERE id = 1`).get() as { - locked: number; - }; - - if (row.locked === 1) { - throw new MigrationLockError('Migration lock already held by another process.'); - } + private async acquireLock(): Promise { + try { + await this.runTransaction(async () => { + const row = (await this.db.prepare(`SELECT locked FROM ${this.lockTable} WHERE id = 1`).get()) as { + locked: number; + }; - this.db.prepare(`UPDATE ${this.lockTable} SET locked = 1 WHERE id = 1`).run(); - }); + if (row.locked === 1) { + throw new MigrationLockError('Migration lock already held by another process.'); + } - try { - transaction(); + await this.db.prepare(`UPDATE ${this.lockTable} SET locked = 1 WHERE id = 1`).run(); + }); } catch (err) { if (err instanceof MigrationLockError) { throw err; @@ -182,9 +201,9 @@ export class Migrator extends EventEmitter { /** * Release the migration lock. */ - private releaseLock(): void { + private async releaseLock(): Promise { try { - this.db.prepare(`UPDATE ${this.lockTable} SET locked = 0 WHERE id = 1`).run(); + await this.db.prepare(`UPDATE ${this.lockTable} SET locked = 0 WHERE id = 1`).run(); } catch (err) { throw new MigrationLockError('Failed to release migration lock', err as Error); } @@ -193,19 +212,19 @@ export class Migrator extends EventEmitter { /** * Get the highest batch number. */ - private getCurrentBatch(): number { - const row = this.db - .prepare(`SELECT MAX(batch) as batch FROM ${this.migrationsTable}`) - .get() as { batch: number | null }; + private async getCurrentBatch(): Promise { + const row = (await this.db.prepare(`SELECT MAX(batch) as batch FROM ${this.migrationsTable}`).get()) as { + batch: number | null; + }; return row?.batch ?? 0; } /** * Insert a record for an applied migration. */ - private recordMigration(name: string, batch: number): void { + private async recordMigration(name: string, batch: number): Promise { const executedAt = new Date().toISOString(); - this.db + await this.db .prepare( ` INSERT INTO ${this.migrationsTable} (name, executed_at, batch) @@ -218,8 +237,8 @@ export class Migrator extends EventEmitter { /** * Delete a record for a migration that is being rolled back. */ - private removeMigration(name: string, batch: number): void { - this.db + private async removeMigration(name: string, batch: number): Promise { + await this.db .prepare( ` DELETE FROM ${this.migrationsTable} @@ -233,9 +252,8 @@ export class Migrator extends EventEmitter { * Run SQL operations in a transaction. * @param fn The function to run in the transaction. */ - private runTransaction(fn: () => void): void { - const transaction = this.db.transaction(fn); - transaction(); + private async runTransaction(fn: () => MaybePromise): Promise { + await this.provider.transaction(fn); } /** @@ -256,7 +274,7 @@ export class Migrator extends EventEmitter { // Acquire lock try { - this.acquireLock(); + await this.acquireLock(); } catch (err) { return { success: false, @@ -267,15 +285,14 @@ export class Migrator extends EventEmitter { const appliedMigrations: string[] = []; try { - const currentBatch = this.getCurrentBatch(); + const currentBatch = await this.getCurrentBatch(); const nextBatch = currentBatch + 1; // Determine pending migrations: not present in schema_migrations const appliedNames = new Set( - this.db - .prepare(`SELECT name FROM ${this.migrationsTable}`) - .all() - .map((row) => (row as { name: string }).name) + (await this.db.prepare(`SELECT name FROM ${this.migrationsTable}`).all()).map( + (row) => (row as { name: string }).name + ) ); // Get pending migrations, if any @@ -285,24 +302,25 @@ export class Migrator extends EventEmitter { } // Perform the migration - this.runTransaction(() => { + await this.runTransaction(async () => { for (const migration of pendingMigrations) { try { // Apply migration - migration.up(this.db); + await migration.up(this.db); // Record migration - this.recordMigration(migration.name, nextBatch); + await this.recordMigration(migration.name, nextBatch); appliedMigrations.push(migration.name); - this.emit('migration:applied', migration.name, nextBatch); } catch (err) { - throw new MigrationExecutionError( - `Failed to rollback migration "${migration.name}"`, - err as Error - ); + throw new MigrationExecutionError(`Failed to apply migration "${migration.name}"`, err as Error); } } }); + + for (const migrationName of appliedMigrations) { + this.emit('migration:applied', migrationName, nextBatch); + } + return { success: true, appliedMigrations }; } catch (error) { const err = @@ -311,7 +329,7 @@ export class Migrator extends EventEmitter { : new MigrationExecutionError('Migration failed', error as Error); return { success: false, error: err, appliedMigrations: [] }; } finally { - this.releaseLock(); + await this.releaseLock(); } } @@ -333,7 +351,7 @@ export class Migrator extends EventEmitter { // Acquire lock try { - this.acquireLock(); + await this.acquireLock(); } catch (err) { return { success: false, @@ -345,13 +363,13 @@ export class Migrator extends EventEmitter { const appliedMigrations: string[] = []; try { // Check if there are migrations to rollback - const currentBatch = this.getCurrentBatch(); + const currentBatch = await this.getCurrentBatch(); if (currentBatch === 0) { return { success: true, appliedMigrations }; } // Get migrations in the last batch, sorted descending - const rows = this.db + const rows = (await this.db .prepare( ` SELECT name @@ -360,7 +378,7 @@ export class Migrator extends EventEmitter { ORDER BY name DESC ` ) - .all(currentBatch) as { name: string }[]; + .all(currentBatch)) as { name: string }[]; // No migrations found in the last batch if (rows.length === 0) { @@ -368,7 +386,7 @@ export class Migrator extends EventEmitter { } // Perform the rollback - this.runTransaction(() => { + await this.runTransaction(async () => { for (const row of rows) { const migration = this.migrations.find((m) => m.name === row.name); if (!migration) { @@ -377,31 +395,31 @@ export class Migrator extends EventEmitter { try { // Revert migration - migration.down(this.db); + await migration.down(this.db); // Remove migration record - this.removeMigration(migration.name, currentBatch); + await this.removeMigration(migration.name, currentBatch); appliedMigrations.push(migration.name); - this.emit('migration:rollback', migration.name, currentBatch); } catch (err) { - throw new MigrationExecutionError( - `Failed to rollback migration "${migration.name}"`, - err as Error - ); + throw new MigrationExecutionError(`Failed to rollback migration "${migration.name}"`, err as Error); } } }); + for (const migrationName of appliedMigrations) { + this.emit('migration:rollback', migrationName, currentBatch); + } + return { success: true, appliedMigrations }; } catch (error) { const err = error instanceof MigrationExecutionError ? error : new MigrationExecutionError('Rollback failed', error as Error); - return { success: false, error: err, appliedMigrations }; + return { success: false, error: err, appliedMigrations: [] }; } finally { - this.releaseLock(); + await this.releaseLock(); } } @@ -416,10 +434,10 @@ export class Migrator extends EventEmitter { await this.init(); try { - const currentBatch = this.getCurrentBatch(); + const currentBatch = await this.getCurrentBatch(); // Get all applied migrations - const rows = this.db + const rows = (await this.db .prepare( ` SELECT name, executed_at, batch @@ -427,7 +445,7 @@ export class Migrator extends EventEmitter { ORDER BY batch ASC, name ASC ` ) - .all() as MigrationRecord[]; + .all()) as MigrationRecord[]; // Determine pending migrations const appliedNames = new Set(rows.map((r) => r.name)); @@ -451,20 +469,17 @@ export class Migrator extends EventEmitter { await this.init(); try { - const currentBatch = this.getCurrentBatch(); + const currentBatch = await this.getCurrentBatch(); const nextBatch = currentBatch + 1; // Determine pending migrations: not present in schema_migrations const appliedNames = new Set( - this.db - .prepare(`SELECT name FROM ${this.migrationsTable}`) - .all() - .map((row) => (row as { name: string }).name) + (await this.db.prepare(`SELECT name FROM ${this.migrationsTable}`).all()).map( + (row) => (row as { name: string }).name + ) ); - const pendingMigrations = this.migrations - .filter((m) => !appliedNames.has(m.name)) - .map((m) => m.name); + const pendingMigrations = this.migrations.filter((m) => !appliedNames.has(m.name)).map((m) => m.name); return { nextBatch, @@ -476,4 +491,24 @@ export class Migrator extends EventEmitter { } } -export { MigratorOptions, MigrationResult, MigrationRecord, MigrationPlan, MigrationStatus }; +export { + MigrationError, + MigrationExecutionError, + MigrationFileError, + MigrationLockError, +} from './errors.js'; +export type { + BunSqliteDatabase, + MaybePromise, + Migration, + MigrationPlan, + MigrationRecord, + MigrationResult, + MigrationStatus, + MigratorDatabase, + MigratorOptions, + SqliteDatabase, + SqliteRunResult, + SqliteStatement, + SqliteTransaction, +} from './types.js'; diff --git a/src/providers/better-sqlite3.test.ts b/src/providers/better-sqlite3.test.ts new file mode 100644 index 0000000..4b4bfd7 --- /dev/null +++ b/src/providers/better-sqlite3.test.ts @@ -0,0 +1,44 @@ +import Database from 'better-sqlite3'; +import { describe, expect, it, vi } from 'vitest'; + +import { createBetterSqlite3Provider, isBetterSqlite3Database } from './better-sqlite3'; + +describe('better-sqlite3 provider', () => { + it('supports better-sqlite3 as an optional runtime database', async () => { + const db = new Database(':memory:'); + const provider = createBetterSqlite3Provider(db); + + expect(isBetterSqlite3Database(db)).toBe(true); + + await expect( + provider.transaction(async () => { + await provider.db.exec('CREATE TABLE success (id INTEGER PRIMARY KEY)'); + await provider.db.exec('INVALID SQL'); + }) + ).rejects.toThrow(); + + const table = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='success'").get(); + expect(table).toBeUndefined(); + + db.close(); + }); + + it('does not use better-sqlite3 native transactions for async migration callbacks', async () => { + const db = new Database(':memory:'); + const transactionSpy = vi.spyOn(db, 'transaction'); + const provider = createBetterSqlite3Provider(db); + + await expect( + provider.transaction(async () => { + await provider.db.exec('CREATE TABLE success (id INTEGER PRIMARY KEY)'); + await Promise.resolve(); + await provider.db.exec('INVALID SQL'); + }) + ).rejects.toThrow(); + + expect(transactionSpy).not.toHaveBeenCalled(); + expect(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='success'").get()).toBeUndefined(); + + db.close(); + }); +}); diff --git a/src/providers/better-sqlite3.ts b/src/providers/better-sqlite3.ts new file mode 100644 index 0000000..c29b80d --- /dev/null +++ b/src/providers/better-sqlite3.ts @@ -0,0 +1,31 @@ +import type { SqliteDatabase } from '../types.js'; +import { createManualTransactionProvider } from './manual-transaction.js'; +import type { SqliteProvider } from './types.js'; + +/** + * Structural database shape used to identify better-sqlite3 connections. + */ +export type BetterSqlite3Database = SqliteDatabase & { + transaction?: unknown; + open?: boolean; +}; + +/** + * Checks whether a value looks like a better-sqlite3 database instance. + */ +export function isBetterSqlite3Database(db: unknown): db is BetterSqlite3Database { + const candidate = db as Partial; + return ( + typeof candidate.exec === 'function' && + typeof candidate.prepare === 'function' && + typeof candidate.transaction === 'function' && + typeof candidate.open === 'boolean' + ); +} + +/** + * Creates a sqlite-up provider for better-sqlite3 database instances. + */ +export function createBetterSqlite3Provider(db: BetterSqlite3Database): SqliteProvider { + return createManualTransactionProvider(db); +} diff --git a/src/providers/bun-sql.bun.test.ts b/src/providers/bun-sql.bun.test.ts new file mode 100644 index 0000000..bb3806c --- /dev/null +++ b/src/providers/bun-sql.bun.test.ts @@ -0,0 +1,71 @@ +import { afterEach, describe, expect, it } from 'bun:test'; +import { promises as fs } from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { SQL } from 'bun'; +import { Migrator } from '../index'; +import { createBunSqlProvider, isBunSqlDatabase } from './bun-sql'; + +async function createMigrationsDir(): Promise { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'sqlite-up-bun-sql-')); + const migrationsDir = path.join(tempDir, 'migrations'); + await fs.mkdir(migrationsDir); + + await fs.writeFile( + path.join(migrationsDir, '001_users.ts'), + ` + export async function up(db) { + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)'); + await db.prepare('INSERT INTO users (name) VALUES (?)').run('Ada'); + } + + export async function down(db) { + await db.exec('DROP TABLE users'); + } + ` + ); + + return migrationsDir; +} + +describe('Bun SQL provider', () => { + const tempDirs: string[] = []; + + afterEach(async () => { + for (const tempDir of tempDirs.splice(0)) { + await fs.rm(tempDir, { recursive: true, force: true }); + } + }); + + it('runs migrations with Bun SQL SQLite', async () => { + const migrationsDir = await createMigrationsDir(); + tempDirs.push(path.dirname(migrationsDir)); + + const sql = new SQL(':memory:'); + const migrator = new Migrator({ db: sql, migrationsDir }); + + const result = await migrator.apply(); + + expect(result.success).toBe(true); + expect(result.appliedMigrations).toEqual(['001_users.ts']); + expect(await sql.unsafe>('SELECT name FROM users')).toEqual([{ name: 'Ada' }]); + + sql.close(); + }); + + it('uses Bun SQL begin for transactions', async () => { + const sql = new SQL(':memory:'); + const provider = createBunSqlProvider(sql); + + expect(isBunSqlDatabase(sql)).toBe(true); + + await provider.db.exec('CREATE TABLE users (name TEXT NOT NULL)'); + await provider.transaction(async () => { + await provider.db.prepare('INSERT INTO users (name) VALUES (?)').run('Ada'); + }); + + expect(await sql.unsafe>('SELECT name FROM users')).toEqual([{ name: 'Ada' }]); + + sql.close(); + }); +}); diff --git a/src/providers/bun-sql.test.ts b/src/providers/bun-sql.test.ts new file mode 100644 index 0000000..82d177d --- /dev/null +++ b/src/providers/bun-sql.test.ts @@ -0,0 +1,70 @@ +import { DatabaseSync } from 'node:sqlite'; +import { describe, expect, it } from 'vitest'; + +import { createBunSqlProvider, isBunSqlDatabase } from './bun-sql'; + +type SqliteParameter = null | number | bigint | string | NodeJS.ArrayBufferView; + +interface BunSqlLikeDatabase { + unsafe(sql: string, params?: unknown[]): Promise; + begin(fn: (tx: BunSqlLikeDatabase) => Promise | Result): Promise; + close(): void; + readonly beginCalls: number; +} + +function createBunSqlLikeDatabase(): BunSqlLikeDatabase { + const sqlite = new DatabaseSync(':memory:'); + let beginCalls = 0; + + const createClient = (): BunSqlLikeDatabase => ({ + unsafe: async (sql: string, params: unknown[] = []) => { + const statement = sqlite.prepare(sql); + const bindParams = params as SqliteParameter[]; + const normalized = sql.trim().toLowerCase(); + if (normalized.startsWith('select') || normalized.startsWith('pragma') || normalized.startsWith('with')) { + return statement.all(...bindParams); + } + + statement.run(...bindParams); + return []; + }, + begin: async (fn: (tx: BunSqlLikeDatabase) => Promise | Result) => { + beginCalls += 1; + sqlite.exec('BEGIN'); + try { + const result = await fn(createClient()); + sqlite.exec('COMMIT'); + return result; + } catch (err) { + sqlite.exec('ROLLBACK'); + throw err; + } + }, + close: () => sqlite.close(), + get beginCalls() { + return beginCalls; + }, + }); + + return createClient(); +} + +describe('bun-sql provider', () => { + it('adapts Bun SQL unsafe/begin to the migration database surface', async () => { + const sql = createBunSqlLikeDatabase(); + const provider = createBunSqlProvider(sql); + + expect(isBunSqlDatabase(sql)).toBe(true); + + await provider.db.exec('CREATE TABLE users (name TEXT NOT NULL)'); + await provider.transaction(async () => { + await provider.db.prepare('INSERT INTO users (name) VALUES (?)').run('Ada'); + }); + + const rows = await provider.db.prepare('SELECT name FROM users').all(); + expect(rows).toEqual([{ name: 'Ada' }]); + expect(sql.beginCalls).toBe(1); + + sql.close(); + }); +}); diff --git a/src/providers/bun-sql.ts b/src/providers/bun-sql.ts new file mode 100644 index 0000000..b4125ad --- /dev/null +++ b/src/providers/bun-sql.ts @@ -0,0 +1,119 @@ +import type { BunSqliteDatabase, MaybePromise, SqliteDatabase, SqliteTransaction } from '../types.js'; +import type { SqliteProvider } from './types.js'; + +/** + * SQLite database facade whose transactions may complete asynchronously. + */ +interface AsyncTransactionalSqliteDatabase extends SqliteDatabase { + /** + * Creates a transaction runner that can await asynchronous transaction work. + */ + transaction( + fn: (...args: Args) => MaybePromise + ): SqliteTransaction; +} + +/** + * Executes SQL through Bun SQL and normalizes empty parameter lists. + */ +async function executeBunSql(client: BunSqliteDatabase, sql: string, params: unknown[] = []): Promise { + return await client.unsafe(sql, params.length > 0 ? params : undefined); +} + +/** + * Checks whether a value looks like Bun's Promise-based SQL client for SQLite. + */ +export function isBunSqlDatabase(db: unknown): db is BunSqliteDatabase { + const candidate = db as Partial; + return typeof candidate.unsafe === 'function' && typeof (candidate as Partial).exec !== 'function'; +} + +/** + * Creates a sqlite-up provider for Bun SQL SQLite clients. + */ +export function createBunSqlProvider(rootClient: BunSqliteDatabase): SqliteProvider { + let activeClient = rootClient; + + const db: AsyncTransactionalSqliteDatabase = { + /** + * Executes a SQL statement through the currently active Bun SQL client. + */ + exec: async (sql: string) => { + await executeBunSql(activeClient, sql); + }, + + /** + * Creates a prepared-statement facade backed by Bun SQL unsafe execution. + */ + prepare: (sql: string) => ({ + /** + * Runs the statement and returns all rows. + */ + all: (...params: unknown[]) => executeBunSql(activeClient, sql, params), + + /** + * Runs the statement and returns the first row. + */ + get: async (...params: unknown[]) => { + const rows = await executeBunSql(activeClient, sql, params); + return rows[0]; + }, + + /** + * Runs the statement for side effects and returns the driver result. + */ + run: (...params: unknown[]) => executeBunSql(activeClient, sql, params), + }), + + /** + * Creates a transaction runner using Bun SQL native transactions when available. + */ + transaction: (fn: (...args: Args) => MaybePromise) => { + /** + * Executes the transaction callback with the active transaction client. + */ + const run = async (...args: Args): Promise => { + if (typeof rootClient.begin === 'function') { + return await rootClient.begin(async (tx) => { + const previousClient = activeClient; + activeClient = tx; + + try { + return await fn(...args); + } finally { + activeClient = previousClient; + } + }); + } + + await db.exec('BEGIN'); + try { + const result = await fn(...args); + await db.exec('COMMIT'); + return result; + } catch (err) { + try { + await db.exec('ROLLBACK'); + } catch { + // Preserve the original transaction failure. + } + throw err; + } + }; + + return run; + }, + }; + + return { + db, + + /** + * Runs migration work inside the Bun SQL transaction facade. + */ + transaction: async (fn: () => MaybePromise) => { + const transaction = db.transaction(fn); + await transaction(); + }, + }; +} diff --git a/src/providers/bun-sqlite.bun.test.ts b/src/providers/bun-sqlite.bun.test.ts new file mode 100644 index 0000000..3b5130c --- /dev/null +++ b/src/providers/bun-sqlite.bun.test.ts @@ -0,0 +1,97 @@ +import { Database } from 'bun:sqlite'; +import { afterEach, describe, expect, it } from 'bun:test'; +import { promises as fs } from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { Migrator } from '../index'; +import { createBunSqliteProvider, isBunSqliteDatabase } from './bun-sqlite'; + +async function createMigrationsDir(): Promise { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'sqlite-up-bun-sqlite-')); + const migrationsDir = path.join(tempDir, 'migrations'); + await fs.mkdir(migrationsDir); + + await fs.writeFile( + path.join(migrationsDir, '001_users.ts'), + ` + export async function up(db) { + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)'); + await db.prepare('INSERT INTO users (name) VALUES (?)').run('Ada'); + } + + export async function down(db) { + await db.exec('DROP TABLE users'); + } + ` + ); + + return migrationsDir; +} + +describe('bun:sqlite provider', () => { + const tempDirs: string[] = []; + + afterEach(async () => { + for (const tempDir of tempDirs.splice(0)) { + await fs.rm(tempDir, { recursive: true, force: true }); + } + }); + + it('runs migrations with Bun Database', async () => { + const migrationsDir = await createMigrationsDir(); + tempDirs.push(path.dirname(migrationsDir)); + + const db = new Database(':memory:'); + const migrator = new Migrator({ db, migrationsDir }); + + const result = await migrator.apply(); + + expect(result.success).toBe(true); + expect(result.appliedMigrations).toEqual(['001_users.ts']); + expect(db.query('SELECT name FROM users').get()).toEqual({ name: 'Ada' }); + + db.close(); + }); + + it('uses transactional rollback with Bun Database', async () => { + const db = new Database(':memory:'); + const provider = createBunSqliteProvider(db); + + expect(isBunSqliteDatabase(db)).toBe(true); + + await expect( + provider.transaction(async () => { + await provider.db.exec('CREATE TABLE rolled_back (id INTEGER PRIMARY KEY)'); + await provider.db.exec('INVALID SQL'); + }) + ).rejects.toThrow(); + + expect(db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'rolled_back'").get()).toBeNull(); + + db.close(); + }); + + it('does not use Bun native transactions for async migration callbacks', async () => { + const db = new Database(':memory:'); + const nativeTransaction = db.transaction.bind(db); + let nativeTransactionCalls = 0; + db.transaction = ((...args: Parameters) => { + nativeTransactionCalls += 1; + return nativeTransaction(...args); + }) as typeof db.transaction; + const provider = createBunSqliteProvider(db); + + await expect( + provider.transaction(async () => { + await provider.db.exec('CREATE TABLE success (id INTEGER PRIMARY KEY)'); + await Promise.resolve(); + await provider.db.exec('INVALID SQL'); + }) + ).rejects.toThrow(); + + expect(nativeTransactionCalls).toBe(0); + expect(db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'success'").get()).toBeNull(); + + db.close(); + }); +}); diff --git a/src/providers/bun-sqlite.test.ts b/src/providers/bun-sqlite.test.ts new file mode 100644 index 0000000..9da5e6b --- /dev/null +++ b/src/providers/bun-sqlite.test.ts @@ -0,0 +1,37 @@ +import { DatabaseSync } from 'node:sqlite'; +import { describe, expect, it } from 'vitest'; + +import { createBunSqliteProvider, isBunSqliteDatabase } from './bun-sqlite'; + +function createBunSqliteLikeDatabase() { + const sqlite = new DatabaseSync(':memory:'); + const db = { + exec: (sql: string) => sqlite.exec(sql), + prepare: (sql: string) => sqlite.prepare(sql), + query: (sql: string) => sqlite.prepare(sql), + close: () => sqlite.close(), + }; + + return db; +} + +describe('bun-sqlite provider', () => { + it('detects Bun synchronous SQLite shape and rolls back failed transactions', async () => { + const db = createBunSqliteLikeDatabase(); + const provider = createBunSqliteProvider(db); + + expect(isBunSqliteDatabase(db)).toBe(true); + + await expect( + provider.transaction(async () => { + await provider.db.exec('CREATE TABLE success (id INTEGER PRIMARY KEY)'); + await provider.db.exec('INVALID SQL'); + }) + ).rejects.toThrow(); + + const table = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='success'").get(); + expect(table).toBeUndefined(); + + db.close(); + }); +}); diff --git a/src/providers/bun-sqlite.ts b/src/providers/bun-sqlite.ts new file mode 100644 index 0000000..1c6cdad --- /dev/null +++ b/src/providers/bun-sqlite.ts @@ -0,0 +1,29 @@ +import type { SqliteDatabase, SqliteStatement } from '../types.js'; +import { createManualTransactionProvider } from './manual-transaction.js'; +import type { SqliteProvider } from './types.js'; + +/** + * Structural database shape used to identify Bun's synchronous SQLite client. + */ +export type BunSqliteSyncDatabase = SqliteDatabase & { + query?: (sql: string) => SqliteStatement; +}; + +/** + * Checks whether a value looks like a Bun SQLite database instance. + */ +export function isBunSqliteDatabase(db: unknown): db is BunSqliteSyncDatabase { + const candidate = db as Partial; + return ( + typeof candidate.exec === 'function' && + typeof candidate.prepare === 'function' && + typeof candidate.query === 'function' + ); +} + +/** + * Creates a sqlite-up provider for Bun SQLite database instances. + */ +export function createBunSqliteProvider(db: BunSqliteSyncDatabase): SqliteProvider { + return createManualTransactionProvider(db); +} diff --git a/src/providers/index.ts b/src/providers/index.ts new file mode 100644 index 0000000..da5dede --- /dev/null +++ b/src/providers/index.ts @@ -0,0 +1,52 @@ +import type { MigratorDatabase, SqliteDatabase } from '../types.js'; +import { createBetterSqlite3Provider, isBetterSqlite3Database } from './better-sqlite3.js'; +import { createBunSqlProvider, isBunSqlDatabase } from './bun-sql.js'; +import { createBunSqliteProvider, isBunSqliteDatabase } from './bun-sqlite.js'; +import { createManualTransactionProvider } from './manual-transaction.js'; +import { createNodeSqliteProvider, isNodeSqliteDatabase } from './node-sqlite.js'; +import type { SqliteProvider } from './types.js'; + +/** + * Checks for the minimal SQLite database surface sqlite-up can use directly. + */ +function isSqliteDatabase(db: unknown): db is SqliteDatabase { + const candidate = db as Partial; + return typeof candidate.exec === 'function' && typeof candidate.prepare === 'function'; +} + +/** + * Creates the best provider adapter for a supported SQLite database client. + */ +export function createSqliteProvider(db: MigratorDatabase): SqliteProvider { + if (isBunSqlDatabase(db)) { + return createBunSqlProvider(db); + } + + if (isBunSqliteDatabase(db)) { + return createBunSqliteProvider(db); + } + + if (isBetterSqlite3Database(db)) { + return createBetterSqlite3Provider(db); + } + + if (isNodeSqliteDatabase(db)) { + return createNodeSqliteProvider(db); + } + + if (isSqliteDatabase(db)) { + return createManualTransactionProvider(db); + } + + if (typeof db === 'object' && db !== null) { + return createManualTransactionProvider(db as SqliteDatabase); + } + + throw new TypeError('Unsupported SQLite database provider.'); +} + +export { createBetterSqlite3Provider, isBetterSqlite3Database } from './better-sqlite3.js'; +export { createBunSqlProvider, isBunSqlDatabase } from './bun-sql.js'; +export { createBunSqliteProvider, isBunSqliteDatabase } from './bun-sqlite.js'; +export { createNodeSqliteProvider, isNodeSqliteDatabase } from './node-sqlite.js'; +export type { SqliteProvider } from './types.js'; diff --git a/src/providers/manual-transaction.test.ts b/src/providers/manual-transaction.test.ts new file mode 100644 index 0000000..34bbdef --- /dev/null +++ b/src/providers/manual-transaction.test.ts @@ -0,0 +1,45 @@ +import { describe, expect, it } from 'vitest'; + +import type { SqliteDatabase, SqliteStatement } from '../types'; +import { createManualTransactionProvider } from './manual-transaction'; + +describe('manual transaction provider', () => { + it('starts write transactions with immediate locking', async () => { + const execCalls: string[] = []; + const db: SqliteDatabase = { + exec: (sql: string) => { + execCalls.push(sql); + }, + prepare: () => { + throw new Error('prepare should not be called'); + }, + }; + + const provider = createManualTransactionProvider(db); + + await provider.transaction(() => {}); + + expect(execCalls).toEqual(['BEGIN IMMEDIATE', 'COMMIT']); + }); + + it('rolls back async failures in one SQL transaction', async () => { + const execCalls: string[] = []; + const db: SqliteDatabase = { + exec: (sql: string) => { + execCalls.push(sql); + }, + prepare: () => ({}) as SqliteStatement, + }; + + const provider = createManualTransactionProvider(db); + + await expect( + provider.transaction(async () => { + await Promise.resolve(); + throw new Error('after await'); + }) + ).rejects.toThrow('after await'); + + expect(execCalls).toEqual(['BEGIN IMMEDIATE', 'ROLLBACK']); + }); +}); diff --git a/src/providers/manual-transaction.ts b/src/providers/manual-transaction.ts new file mode 100644 index 0000000..aa6165d --- /dev/null +++ b/src/providers/manual-transaction.ts @@ -0,0 +1,29 @@ +import type { MaybePromise, SqliteDatabase } from '../types.js'; +import type { SqliteProvider } from './types.js'; + +/** + * Creates a provider that wraps migration work in explicit SQL transactions. + */ +export function createManualTransactionProvider(db: SqliteDatabase): SqliteProvider { + return { + db, + + /** + * Runs the callback between BEGIN IMMEDIATE and COMMIT, rolling back on failure. + */ + transaction: async (fn: () => MaybePromise): Promise => { + await db.exec('BEGIN IMMEDIATE'); + try { + await fn(); + await db.exec('COMMIT'); + } catch (err) { + try { + await db.exec('ROLLBACK'); + } catch { + // Preserve the original transaction failure. + } + throw err; + } + }, + }; +} diff --git a/src/providers/node-sqlite.test.ts b/src/providers/node-sqlite.test.ts new file mode 100644 index 0000000..82fa313 --- /dev/null +++ b/src/providers/node-sqlite.test.ts @@ -0,0 +1,25 @@ +import { DatabaseSync } from 'node:sqlite'; +import { describe, expect, it } from 'vitest'; + +import { createNodeSqliteProvider, isNodeSqliteDatabase } from './node-sqlite'; + +describe('node-sqlite provider', () => { + it('detects Node DatabaseSync and rolls back failed transactions', async () => { + const db = new DatabaseSync(':memory:'); + const provider = createNodeSqliteProvider(db); + + expect(isNodeSqliteDatabase(db)).toBe(true); + + await expect( + provider.transaction(async () => { + await provider.db.exec('CREATE TABLE success (id INTEGER PRIMARY KEY)'); + await provider.db.exec('INVALID SQL'); + }) + ).rejects.toThrow(); + + const table = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='success'").get(); + expect(table).toBeUndefined(); + + db.close(); + }); +}); diff --git a/src/providers/node-sqlite.ts b/src/providers/node-sqlite.ts new file mode 100644 index 0000000..cc1f920 --- /dev/null +++ b/src/providers/node-sqlite.ts @@ -0,0 +1,29 @@ +import type { SqliteDatabase } from '../types.js'; +import { createManualTransactionProvider } from './manual-transaction.js'; +import type { SqliteProvider } from './types.js'; + +/** + * Structural database shape used to identify Node's node:sqlite DatabaseSync. + */ +export type NodeSqliteDatabase = SqliteDatabase & { + isOpen?: boolean; +}; + +/** + * Checks whether a value looks like a node:sqlite database instance. + */ +export function isNodeSqliteDatabase(db: unknown): db is NodeSqliteDatabase { + const candidate = db as Partial; + return ( + typeof candidate.exec === 'function' && + typeof candidate.prepare === 'function' && + typeof candidate.isOpen === 'boolean' + ); +} + +/** + * Creates a sqlite-up provider for node:sqlite database instances. + */ +export function createNodeSqliteProvider(db: NodeSqliteDatabase): SqliteProvider { + return createManualTransactionProvider(db); +} diff --git a/src/providers/types.ts b/src/providers/types.ts new file mode 100644 index 0000000..3f53b17 --- /dev/null +++ b/src/providers/types.ts @@ -0,0 +1,16 @@ +import type { MaybePromise, SqliteDatabase } from '../types.js'; + +/** + * Adapter that normalizes driver-specific SQLite behavior for the migrator. + */ +export interface SqliteProvider { + /** + * Database facade used by migration code. + */ + db: SqliteDatabase; + + /** + * Runs migration bookkeeping and user migration code atomically. + */ + transaction(fn: () => MaybePromise): Promise; +} diff --git a/src/types.ts b/src/types.ts index 3cc78b9..26ac968 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,105 @@ -import { Database } from 'better-sqlite3'; +/** + * A value or a promise for that value. + */ +export type MaybePromise = T | Promise; + +/** + * Result returned by SQLite statement execution. + */ +export interface SqliteRunResult { + /** + * Number of rows changed by the statement, when reported by the driver. + */ + changes?: number | bigint; + + /** + * Last inserted row identifier, when reported by the driver. + */ + lastInsertRowid?: number | bigint; +} + +/** + * Minimal prepared statement surface used by sqlite-up. + * Compatible with Node's `node:sqlite`, Bun's `bun:sqlite`, Bun SQL, and + * similar SQLite clients. + */ +export interface SqliteStatement { + /** + * Runs the prepared statement and returns all result rows. + */ + all(...params: unknown[]): MaybePromise; + + /** + * Runs the prepared statement and returns the first result row. + */ + get(...params: unknown[]): MaybePromise; + + /** + * Runs the prepared statement for side effects and returns the driver result. + */ + run(...params: unknown[]): MaybePromise; +} + +/** + * Transaction function returned by SQLite drivers that provide native + * async-compatible transaction wrappers. + */ +export interface SqliteTransaction { + (...args: Args): MaybePromise; + + /** + * Runs the transaction with deferred locking semantics when supported. + */ + deferred?: (...args: Args) => MaybePromise; + + /** + * Runs the transaction with immediate locking semantics when supported. + */ + immediate?: (...args: Args) => MaybePromise; + + /** + * Runs the transaction with exclusive locking semantics when supported. + */ + exclusive?: (...args: Args) => MaybePromise; +} + +/** + * Minimal SQLite database surface passed to migration files. + * Node 24+ `DatabaseSync`, Bun `Database`, better-sqlite3 `Database`, + * and Bun SQL adapters are structurally compatible with this interface. + */ +export interface SqliteDatabase { + /** + * Executes one or more SQL statements without returning result rows. + */ + exec(sql: string): MaybePromise; + + /** + * Prepares a SQL statement for repeated execution. + */ + prepare(sql: string): SqliteStatement; +} + +/** + * Structural subset of Bun's Promise-based SQL client when configured for SQLite. + * sqlite-up wraps this into the `SqliteDatabase` migration surface. + */ +export interface BunSqliteDatabase { + /** + * Executes raw SQL through Bun SQL and returns all result rows. + */ + unsafe(sql: string, params?: unknown[]): PromiseLike | unknown[]; + + /** + * Runs a callback inside a Bun SQL transaction when supported. + */ + begin?(fn: (tx: BunSqliteDatabase) => MaybePromise): MaybePromise; +} + +/** + * Database instances accepted by `Migrator`. + */ +export type MigratorDatabase = SqliteDatabase | BunSqliteDatabase; /** * Options for initializing the Migrator. @@ -7,7 +108,7 @@ export interface MigratorOptions { /** * SQLite database instance */ - db: Database; + db: MigratorDatabase; /** * Directory containing migration files @@ -43,12 +144,12 @@ export interface Migration { /** * Function to apply the migration */ - up: (db: Database) => void; + up: (db: SqliteDatabase) => MaybePromise; /** * Function to revert the migration */ - down: (db: Database) => void; + down: (db: SqliteDatabase) => MaybePromise; } /** diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..d6b31dc --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,34 @@ +{ + // Inherit shared TypeScript compiler options + "extends": "./tsconfig.json", + + // TypeScript compiler options + "compilerOptions": { + // Specify the root directory of input files + "rootDir": "src", + + // Redirect output structure to the directory + "outDir": "dist", + + // Only emit .d.ts declaration files + "emitDeclarationOnly": true, + + // Generate .d.ts declaration files + "declaration": true, + + // Create sourcemaps for d.ts files + "declarationMap": true, + + // Disable JavaScript source maps for build output + "sourceMap": false, + + // Allow TypeScript to emit build output + "noEmit": false + }, + + // Specify files to include in compilation + "include": ["src/**/*.ts"], + + // Specify files to exclude from compilation + "exclude": ["node_modules", "dist", "**/*.test.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index 7bbaa07..2378105 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,47 +3,71 @@ "compilerOptions": { // Specify ECMAScript target version "target": "ES2020", + // Specify module code generation "module": "ESNext", + // List of library files to be included in the compilation "lib": ["ES2020"], + // Specify module resolution strategy - "moduleResolution": "node", + "moduleResolution": "bundler", + + // Include Node.js built-in module types + "types": ["node"], + // Specify the root directory of input files "rootDir": ".", + // Redirect output structure to the directory "outDir": "dist", + // Enable all strict type checking options "strict": true, + // Enable strict null checks "strictNullChecks": true, + // Enable strict checking of function types "strictFunctionTypes": true, + // Enable strict 'bind', 'call', and 'apply' methods on functions "strictBindCallApply": true, + // Enable strict checking of property initialization in classes "strictPropertyInitialization": true, + // Raise error on 'this' expressions with an implied 'any' type "noImplicitThis": true, + // Parse in strict mode and emit "use strict" for each source file "alwaysStrict": true, + // Enables emit interoperability between CommonJS and ES Modules "esModuleInterop": true, + // Generate .d.ts declaration files "declaration": true, + // Create sourcemaps for d.ts files "declarationMap": true, + // Generate corresponding .map file "sourceMap": true, + // Skip type checking of declaration files "skipLibCheck": true, + // Ensure consistent casing in file names "forceConsistentCasingInFileNames": true, + // Allow importing JSON modules "resolveJsonModule": true }, + // Specify files to include in compilation "include": ["src/**/*"], + // Specify files to exclude from compilation "exclude": ["node_modules", "dist", "**/*.test.ts"] } diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..5180fc1 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,25 @@ +{ + // Inherit shared TypeScript compiler options + "extends": "./tsconfig.json", + + // TypeScript compiler options + "compilerOptions": { + // Disable .d.ts declaration file generation + "declaration": false, + + // Disable sourcemaps for d.ts files + "declarationMap": false, + + // Disable emitting build output during tests + "noEmit": true, + + // Include Node.js, Vitest, and Bun global types + "types": ["node", "vitest", "bun"] + }, + + // Specify files to include in compilation + "include": ["src/**/*.ts"], + + // Specify files to exclude from compilation + "exclude": ["node_modules", "dist"] +} diff --git a/vitest.config.ts b/vitest.config.ts index dbed5f5..197127c 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,9 +1,10 @@ -import { defineConfig } from 'vitest/config'; +import { configDefaults, defineConfig } from 'vitest/config'; export default defineConfig({ test: { globals: true, environment: 'node', + exclude: [...configDefaults.exclude, '**/*.bun.test.ts'], coverage: { reporter: ['text', 'json', 'html'], exclude: ['node_modules/', 'test/**/*'],