From 2756e626923aacff134bb4d587c2e4e68cc603ca Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:07:59 +0530 Subject: [PATCH 01/16] chore(security): add supply chain risk mitigations --- .npmrc | 8 ++++++++ AGENTS.md | 15 +++++++++++++++ CLAUDE.md | 1 + package.json | 5 ++++- 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .npmrc create mode 100644 AGENTS.md create mode 120000 CLAUDE.md diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..ce911b3 --- /dev/null +++ b/.npmrc @@ -0,0 +1,8 @@ +save-exact=true +# 7 days in minutes +minimum-release-age=10080 +ignore-scripts=true +# Block transitive deps that resolve to git/tarball URLs instead of the registry +block-exotic-subdeps=true +# Refuse to install a package whose trust level dropped vs. prior versions +trust-policy=no-downgrade diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..353463a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,15 @@ +## Supply Chain Config — Do Not Modify Without Approval + +This repo enforces strict install-time supply chain defenses: + +- Exact pinned versions (no `~`/`^`). +- `minimumReleaseAge` of 7 days (pnpm: minutes, bun: seconds). +- Install/lifecycle scripts disabled by default; only packages in + `onlyBuiltDependencies` (pnpm) or `trustedDependencies` (bun) may run them. +- pnpm: `block-exotic-subdeps=true`, `trust-policy=no-downgrade`. +- bun: Socket security scanner enabled in `bunfig.toml`. + +**Never disable, loosen, or bypass these settings** — including adding packages +to the script allow-list, shortening `minimumReleaseAge`, or setting +`dangerouslyAllowAllBuilds` — without explicit confirmation from the user in +the current conversation. A prior approval does not carry over. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/package.json b/package.json index b5d422c..40c7fa0 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,8 @@ "zod" ], "license": "MIT", - "packageManager": "pnpm@10.16.1" + "packageManager": "pnpm@10.16.1", + "pnpm": { + "onlyBuiltDependencies": [] + } } From 7760a0ec2574410483b516f4d7dc992338b25fe0 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:52:39 +0530 Subject: [PATCH 02/16] chore: add supply chain settings to pnpm-workspace.yaml --- pnpm-workspace.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b425d4e..e2f9633 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,9 @@ +ignoreScripts: true +minimumReleaseAge: 10080 +blockExoticSubdeps: true +trustPolicy: no-downgrade +onlyBuiltDependencies: [] + packages: - 'packages/*' - 'playground/*' From 04d394a679d53932de1e1421e5e71683406905f1 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 18:38:29 +0530 Subject: [PATCH 03/16] feat!: modernize tooling and migrate to Standard Schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace Zod with Standard Schema interface for event validation, enabling any compliant validator (zod 3.24+, valibot, arktype, etc.). - Build: vite → tsdown with dual ESM+CJS output - Lint/Format: eslint+prettier → oxlint+oxfmt (root-level via turbo) - Test: add vitest with happy-dom (18 tests across core + react) - CI/CD: GitHub Actions with OIDC NPM provenance, changesets - Deps: remove react-use, type-fest; add pnpm catalog for versions - Config: tsconfig.base.json, commitlint, husky hooks, .node-version - Delete playground/ (to be replaced by TanStack Start example) BREAKING CHANGE: EventMap now uses StandardSchemaV1 instead of z.ZodTypeAny. All schema validation uses the Standard Schema protocol. --- .changeset/config.json | 11 + .github/workflows/ci.yml | 36 + .github/workflows/release.yml | 36 + .gitignore | 3 + .husky/commit-msg | 1 + .husky/pre-commit | 3 + .node-version | 1 + .npmrc | 6 - .oxlintrc.json | 11 + .prettierrc | 3 - .zed/settings.json | 68 + AGENTS.md | 45 +- commitlint.config.js | 1 + package.json | 37 +- packages/core/README.md | 92 - packages/core/package.json | 46 +- packages/core/src/index.ts | 377 +- packages/core/tests/index.test.ts | 371 ++ packages/core/tests/setup.ts | 1 + packages/core/tsconfig.json | 21 +- packages/core/tsconfig.node.json | 9 - packages/core/tsdown.config.ts | 16 + packages/core/vite.config.ts | 23 - packages/core/vitest.config.ts | 13 + packages/react/.eslintrc.cjs | 18 - packages/react/README.md | 150 - packages/react/index.html | 13 - packages/react/package.json | 60 +- packages/react/public/vite.svg | 1 - packages/react/src/index.ts | 108 +- packages/react/tests/react.test.ts | 128 + packages/react/tests/setup.ts | 1 + packages/react/tsconfig.json | 25 +- packages/react/tsconfig.node.json | 10 - packages/react/tsdown.config.ts | 16 + packages/react/vite.config.ts | 23 - packages/react/vitest.config.ts | 13 + playground/playground-common/package.json | 35 - playground/playground-common/src/index.ts | 20 - playground/playground-common/tsconfig.json | 21 - .../playground-common/tsconfig.node.json | 9 - playground/playground-common/vite.config.ts | 23 - playground/playground-react/.eslintrc.cjs | 18 - playground/playground-react/.gitignore | 24 - playground/playground-react/README.md | 27 - playground/playground-react/index.html | 13 - playground/playground-react/package.json | 32 - playground/playground-react/public/vite.svg | 1 - playground/playground-react/src/App.tsx | 96 - playground/playground-react/src/main.tsx | 4 - playground/playground-react/src/vite-env.d.ts | 1 - playground/playground-react/tsconfig.json | 25 - .../playground-react/tsconfig.node.json | 10 - playground/playground-react/vite.config.ts | 7 - playground/playground-vanilla/.gitignore | 24 - playground/playground-vanilla/index.html | 56 - playground/playground-vanilla/package.json | 20 - playground/playground-vanilla/public/vite.svg | 1 - playground/playground-vanilla/src/main.ts | 66 - playground/playground-vanilla/tsconfig.json | 23 - pnpm-lock.yaml | 4216 ++++++++++------- pnpm-workspace.yaml | 21 +- tsconfig.base.json | 22 + turbo.json | 28 +- 64 files changed, 3597 insertions(+), 3043 deletions(-) create mode 100644 .changeset/config.json create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100755 .husky/commit-msg create mode 100755 .husky/pre-commit create mode 100644 .node-version create mode 100644 .oxlintrc.json delete mode 100644 .prettierrc create mode 100644 .zed/settings.json create mode 100644 commitlint.config.js delete mode 100644 packages/core/README.md create mode 100644 packages/core/tests/index.test.ts create mode 100644 packages/core/tests/setup.ts delete mode 100644 packages/core/tsconfig.node.json create mode 100644 packages/core/tsdown.config.ts delete mode 100644 packages/core/vite.config.ts create mode 100644 packages/core/vitest.config.ts delete mode 100644 packages/react/.eslintrc.cjs delete mode 100644 packages/react/README.md delete mode 100644 packages/react/index.html delete mode 100644 packages/react/public/vite.svg create mode 100644 packages/react/tests/react.test.ts create mode 100644 packages/react/tests/setup.ts delete mode 100644 packages/react/tsconfig.node.json create mode 100644 packages/react/tsdown.config.ts delete mode 100644 packages/react/vite.config.ts create mode 100644 packages/react/vitest.config.ts delete mode 100644 playground/playground-common/package.json delete mode 100644 playground/playground-common/src/index.ts delete mode 100644 playground/playground-common/tsconfig.json delete mode 100644 playground/playground-common/tsconfig.node.json delete mode 100644 playground/playground-common/vite.config.ts delete mode 100644 playground/playground-react/.eslintrc.cjs delete mode 100644 playground/playground-react/.gitignore delete mode 100644 playground/playground-react/README.md delete mode 100644 playground/playground-react/index.html delete mode 100644 playground/playground-react/package.json delete mode 100644 playground/playground-react/public/vite.svg delete mode 100644 playground/playground-react/src/App.tsx delete mode 100644 playground/playground-react/src/main.tsx delete mode 100644 playground/playground-react/src/vite-env.d.ts delete mode 100644 playground/playground-react/tsconfig.json delete mode 100644 playground/playground-react/tsconfig.node.json delete mode 100644 playground/playground-react/vite.config.ts delete mode 100644 playground/playground-vanilla/.gitignore delete mode 100644 playground/playground-vanilla/index.html delete mode 100644 playground/playground-vanilla/package.json delete mode 100644 playground/playground-vanilla/public/vite.svg delete mode 100644 playground/playground-vanilla/src/main.ts delete mode 100644 playground/playground-vanilla/tsconfig.json create mode 100644 tsconfig.base.json diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..d09c689 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [["@izod/core", "@izod/react"]], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4832d84 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: pnpm/action-setup@5d445ecbfcb90fdf1556a629d018c79e97ff973b # v6.0.6 + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 24.15.0 + cache: pnpm + + - run: pnpm install --frozen-lockfile + + - run: pnpm run lint + - run: pnpm run format:check + - run: pnpm run typecheck + - run: pnpm run test + - run: pnpm run test:coverage + - run: pnpm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..9b4d4f1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,36 @@ +name: Release + +on: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + +permissions: + contents: write + pull-requests: write + id-token: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: pnpm/action-setup@5d445ecbfcb90fdf1556a629d018c79e97ff973b # v6.0.6 + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 24.15.0 + registry-url: "https://registry.npmjs.org" + + - run: pnpm install --frozen-lockfile + + - uses: changesets/action@d94a5c301145045a0960133674e003b265942a22 # v1.8.0 + with: + publish: pnpm run release + version: pnpm run version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_CONFIG_PROVENANCE: true diff --git a/.gitignore b/.gitignore index a547bf3..66539d2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ dist dist-ssr *.local +# Turbo +.turbo + # Editor directories and files .vscode/* !.vscode/extensions.json diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..2e6b87e --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +pnpm exec commitlint --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..1def0ee --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,3 @@ +pnpm run lint +pnpm run format:check +pnpm run test diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..5bf4400 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +24.15.0 diff --git a/.npmrc b/.npmrc index ce911b3..682460b 100644 --- a/.npmrc +++ b/.npmrc @@ -1,8 +1,2 @@ save-exact=true -# 7 days in minutes -minimum-release-age=10080 ignore-scripts=true -# Block transitive deps that resolve to git/tarball URLs instead of the registry -block-exotic-subdeps=true -# Refuse to install a package whose trust level dropped vs. prior versions -trust-policy=no-downgrade diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000..2293d68 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,11 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "react", "unicorn", "oxc"], + "categories": { + "correctness": "error" + }, + "rules": {}, + "env": { + "builtin": true + } +} diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 544138b..0000000 --- a/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "singleQuote": true -} diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..caeb94d --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,68 @@ +{ + "file_scan_exclusions": ["**/*.gen.ts"], + "lsp": { + "oxlint": { + "initialization_options": { + "settings": { + "configPath": ".oxlintrc.json", + "run": "onType" + } + } + }, + "oxfmt": { + "initialization_options": { + "settings": { + "run": "onSave", + "configPath": ".oxfmtrc.json" + } + } + } + }, + "languages": { + "TypeScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "TSX": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JavaScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSON": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSONC": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "HTML": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "CSS": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "YAML": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "Markdown": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + } + } +} diff --git a/AGENTS.md b/AGENTS.md index 353463a..e25d3a5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,13 +1,50 @@ +# izod + +Type-safe iframe communication using the Standard Schema interface for runtime validation. + +## Commands + +- `pnpm run build` — build all packages with tsdown (via turbo) +- `pnpm run test` — run tests with vitest (via turbo) +- `pnpm run test:coverage` — run tests with coverage +- `pnpm run typecheck` — type-check with tsc (via turbo) +- `pnpm run lint` — oxlint across the repo +- `pnpm run format` — oxfmt across the repo +- `pnpm run format:check` — check formatting + +## Conventions + +- TypeScript strict mode, target ES2022 +- No single-character variable names — use descriptive names +- No nested ternaries +- Conventional Commits enforced via commitlint +- Exact pinned dependency versions (no `~`/`^`), managed via pnpm catalog +- oxlint for linting, oxfmt for formatting (no eslint/prettier) +- Vitest for testing with happy-dom environment +- Turborepo for monorepo orchestration + +## Architecture + +- `packages/core/` — `@izod/core`: iframe communication engine (no React dependency) + - `createChild()` — parent-side iframe creation and handshake + - `connectToParent()` — child-side connection to parent window + - Uses Standard Schema interface for event data validation +- `packages/react/` — `@izod/react`: React hooks wrapper around core + - `child.useCreate()` — hook for parent component to create child iframe + - `parent.useConnect()` — hook for child component to connect to parent +- `examples/` — TanStack Start demo app (workspace package, not published) +- All event schemas accept any Standard Schema compliant validator (zod 3.24+, valibot, arktype, etc.) +- React is a peer dependency of `@izod/react` only + ## Supply Chain Config — Do Not Modify Without Approval This repo enforces strict install-time supply chain defenses: - Exact pinned versions (no `~`/`^`). -- `minimumReleaseAge` of 7 days (pnpm: minutes, bun: seconds). +- `minimumReleaseAge` of 7 days (pnpm: minutes). - Install/lifecycle scripts disabled by default; only packages in - `onlyBuiltDependencies` (pnpm) or `trustedDependencies` (bun) may run them. -- pnpm: `block-exotic-subdeps=true`, `trust-policy=no-downgrade`. -- bun: Socket security scanner enabled in `bunfig.toml`. + `onlyBuiltDependencies` (in `pnpm-workspace.yaml`) may run them. +- `blockExoticSubdeps: true`, `trustPolicy: no-downgrade` (in `pnpm-workspace.yaml`). **Never disable, loosen, or bypass these settings** — including adding packages to the script allow-list, shortening `minimumReleaseAge`, or setting diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..fa584fb --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1 @@ +export default { extends: ["@commitlint/config-conventional"] }; diff --git a/package.json b/package.json index 40c7fa0..86d8a89 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,29 @@ { "name": "izod-monorepo", - "private": false, - "version": "1.0.0", + "private": true, "type": "module", "scripts": { + "build": "turbo run build", "dev": "turbo run dev", - "build": "turbo run build" + "test": "turbo run test", + "test:coverage": "turbo run test:coverage", + "typecheck": "turbo run typecheck", + "lint": "oxlint .", + "lint:fix": "oxlint --fix .", + "format": "oxfmt .", + "format:check": "oxfmt --check .", + "changeset": "changeset", + "version": "changeset version", + "release": "turbo run build && changeset publish", + "prepare": "husky" }, "devDependencies": { - "prettier": "3.0.1", + "@changesets/cli": "2.31.0", + "@commitlint/cli": "20.5.3", + "@commitlint/config-conventional": "20.5.3", + "husky": "9.1.7", + "oxfmt": "0.47.0", + "oxlint": "1.62.0", "turbo": "2.5.6" }, "repository": { @@ -19,15 +34,9 @@ "author": { "name": "Soumyajit Pathak" }, - "keywords": [ - "react", - "iframe", - "typescript", - "zod" - ], "license": "MIT", - "packageManager": "pnpm@10.16.1", - "pnpm": { - "onlyBuiltDependencies": [] - } + "engines": { + "node": ">=24.15.0" + }, + "packageManager": "pnpm@11.0.9" } diff --git a/packages/core/README.md b/packages/core/README.md deleted file mode 100644 index 46fed73..0000000 --- a/packages/core/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# @izod/core - -> NOTE: This is very early stage, documentation is not complete and breaking API changes likely ahead. Please use at your own risk. Lock your version in case you use. (Even though I will adhere to semver for updates) - -![Bundle Size](https://img.shields.io/bundlephobia/minzip/@izod/core) ![npm version](https://badgen.net/npm/v/@izod/core) ![types](https://badgen.net/npm/types/@izod/core) - -`izod` leverages [zod](https://github.com/colinhacks/zod) to provide a type safe Promise oriented API to manage iframe communication. - -## Installation - -```sh -npm i zod @izod/core -``` - -## Usage - -```ts -// common.ts - -import { z } from 'zod'; -import type { EventMap } from '@izod/core'; - -export const parentOriginEvents = { - askQuestion: z.object({ - question: z.string(), - }), - shout: z.object({ - message: z.string(), - }), -} as const satisfies EventMap; - -export const childOriginEvents = { - answerQuestion: z.object({ - answer: z.string(), - }), - whisper: z.object({ - message: z.string(), - }), -} as const satisfies EventMap; -``` - -```ts -// parent.html - -import { createChild } from '@izod/core'; - -// create the child instance (not mounted until handshake is executed) -const child = createChild({ - container: document.body, // required - url: 'http://127.0.0.1:3010', // required - inboundEvents: childOriginEvents, // optional - outboundEvents: parentOriginEvents, // optional - handshakeOptions: { - // optional - maxHandshakeRequests: 10, // default 5 - handshakeRetryInterval: 100, // default 1000 - }, -}); - -// perfect time to setup event listeners so that they are ready once the handshake is over -// type safe event listeners for events coming from the child -child.on('whisper', (data) => { - console.log(`Child whispered: ${data.message}`); -}); - -const childApi = await child.executeHandshake(); - -// type safe event emitters -childApi.emit('shout', { message: 'Hello' }); -``` - -```ts -// child.html - -import { connectToParent } from '@izod/core'; - -// sets the boilerplate -const parent = connectToParent({ - inboundEvents: parentOriginEvents, // optional - outboundEvents: childOriginEvents, // optional -}); - -// type safe event listeners for events coming from the parent -parent.on('shout', (data) => { - console.log(`Parent shouted: ${data.message}`); -}); - -const parentApi = await parent.executeHandshake(); - -// type safe event emitters -parentApi.emit('whisper', { message: 'Hi' }); -``` diff --git a/packages/core/package.json b/packages/core/package.json index b917e9e..20d444d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,39 +1,42 @@ { "name": "@izod/core", - "private": false, - "version": "1.1.1", + "version": "2.0.0", "type": "module", "sideEffects": false, "files": [ "dist" ], - "module": "./dist/index.es.js", + "main": "./dist/index.cjs", + "module": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { - "import": "./dist/index.es.js", - "types": "./dist/index.d.ts" + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./package.json": { + "default": "./package.json" } }, "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "preview": "vite preview" - }, - "devDependencies": { - "@types/node": "20.4.8", - "typescript": "5.8.2", - "vite": "4.4.5", - "vite-plugin-dts": "3.5.1", - "zod": "3.24.2" - }, - "peerDependencies": { - "zod": "^2.0.0 || ^3.0.0" + "build": "tsdown", + "dev": "tsdown --watch", + "test": "vitest run", + "test:coverage": "vitest run --coverage", + "typecheck": "tsc --noEmit" }, "dependencies": { "crelt": "1.0.6", - "nanoid": "5.1.5", - "type-fest": "4.37.0" + "nanoid": "5.1.5" + }, + "devDependencies": { + "@standard-schema/spec": "catalog:", + "@vitest/coverage-v8": "catalog:", + "happy-dom": "catalog:", + "tsdown": "catalog:", + "typescript": "catalog:", + "vitest": "catalog:" }, "repository": { "type": "git", @@ -46,7 +49,8 @@ "keywords": [ "iframe", "typescript", - "zod" + "standard-schema", + "postmessage" ], "license": "MIT" } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 017a6cf..28286c0 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,105 +1,163 @@ -import { z } from 'zod'; -import crelt from 'crelt'; -import { nanoid } from 'nanoid'; +import type { StandardSchemaV1 } from "@standard-schema/spec"; +import crelt from "crelt"; +import { nanoid } from "nanoid"; -export const eventContentType = 'application/x-izod+json' as const; +export type { StandardSchemaV1 } from "@standard-schema/spec"; + +export const eventContentType = "application/x-izod+json" as const; const createLogger = (enabled: boolean = false): typeof console.info => enabled ? console.info.bind(console) : () => {}; export const messageTypes = { - 'handshake-request': 'handshake-request', - 'handshake-reply': 'handshake-reply', - 'child-originated-event': 'child-originated-event', - 'parent-originated-event': 'parent-originated-event', + "handshake-request": "handshake-request", + "handshake-reply": "handshake-reply", + "child-originated-event": "child-originated-event", + "parent-originated-event": "parent-originated-event", } as const; export const errorCauses = { - handshake_request_invalid: 'handshake_request_invalid', - handshake_request_timeout: 'handshake_request_timeout', - event_name_invalid: 'event_name_invalid', - event_data_invalid: 'event_data_invalid', + handshake_request_invalid: "handshake_request_invalid", + handshake_request_timeout: "handshake_request_timeout", + event_name_invalid: "event_name_invalid", + event_data_invalid: "event_data_invalid", } as const; -const wildcardOrigin = '*'; +const wildcardOrigin = "*"; function resolveOrigin(url?: string) { if (!url) { return wildcardOrigin; } - const a = document.createElement('a'); - a.href = url; + const anchor = document.createElement("a"); + anchor.href = url; const protocol = - a.protocol.length > 4 ? a.protocol : window.location.protocol; - const host = a.host.length - ? a.port === '80' || a.port === '443' - ? a.hostname - : a.host + anchor.protocol.length > 4 ? anchor.protocol : window.location.protocol; + const host = anchor.host.length + ? anchor.port === "80" || anchor.port === "443" + ? anchor.hostname + : anchor.host : window.location.host; - return a.origin || `${protocol}//${host}`; + return anchor.origin || `${protocol}//${host}`; } export function generateUniqueId(namespace?: string) { - return `${namespace ?? 'anon'}__${nanoid()}`; + return `${namespace ?? "anon"}__${nanoid()}`; +} + +function validateSync( + schema: T, + data: unknown, +): + | { success: true; data: StandardSchemaV1.InferOutput } + | { success: false; error: string } { + const result = schema["~standard"].validate(data); + if (result instanceof Promise) { + throw new TypeError("Schema validation must be synchronous"); + } + if (result.issues) { + return { success: false, error: JSON.stringify(result.issues, null, 2) }; + } + return { success: true, data: result.value as StandardSchemaV1.InferOutput }; +} + +interface BaseMessageData { + contentType: typeof eventContentType; + namespace?: string; + id: string; +} + +function isBaseMessageData(data: unknown): data is BaseMessageData { + if (typeof data !== "object" || data === null) return false; + const record = data as Record; + return ( + record["contentType"] === eventContentType && typeof record["id"] === "string" + ); } -const baseMessageDataSchema = z.object({ - contentType: z.literal(eventContentType), - namespace: z.string().optional(), - id: z.string(), -}); - -const HandshakeRequestMessageDataSchema = baseMessageDataSchema.extend({ - messageType: z.literal(messageTypes['handshake-request']), -}); -export type HandshakeRequestMessageData = z.infer< - typeof HandshakeRequestMessageDataSchema ->; - -const HandshakeReplyMessageDataSchema = baseMessageDataSchema.extend({ - messageType: z.literal(messageTypes['handshake-reply']), -}); -export type HandshakeReplyMessageData = z.infer< - typeof HandshakeReplyMessageDataSchema ->; - -const baseMessageDataEventPayloadSchema = baseMessageDataSchema.extend({ - event: z.object({ - name: z.string(), - data: z.any(), - }), -}); - -const ParentOriginatedMessageDataEventPayloadSchema = - baseMessageDataEventPayloadSchema.extend({ - messageType: z.literal(messageTypes['parent-originated-event']), - }); -export type ParentOriginatedMessageDataEventPayload = z.infer< - typeof ParentOriginatedMessageDataEventPayloadSchema ->; - -const ChildOriginatedMessageDataEventPayloadSchema = - baseMessageDataEventPayloadSchema.extend({ - messageType: z.literal(messageTypes['child-originated-event']), - }); -export type ChildOriginatedMessageDataEventPayload = z.infer< - typeof ChildOriginatedMessageDataEventPayloadSchema ->; +export interface HandshakeRequestMessageData extends BaseMessageData { + messageType: typeof messageTypes["handshake-request"]; +} + +function isHandshakeRequest( + data: unknown, +): data is HandshakeRequestMessageData { + if (!isBaseMessageData(data)) return false; + return ( + "messageType" in data && + data.messageType === messageTypes["handshake-request"] + ); +} + +export interface HandshakeReplyMessageData extends BaseMessageData { + messageType: typeof messageTypes["handshake-reply"]; +} + +function isHandshakeReply(data: unknown): data is HandshakeReplyMessageData { + if (!isBaseMessageData(data)) return false; + return ( + "messageType" in data && + data.messageType === messageTypes["handshake-reply"] + ); +} + +interface EventPayload { + name: string; + data: unknown; +} + +function isEventPayload(data: unknown): data is EventPayload { + if (typeof data !== "object" || data === null) return false; + const record = data as Record; + return typeof record["name"] === "string" && "data" in record; +} + +export interface ParentOriginatedMessageDataEventPayload extends BaseMessageData { + messageType: typeof messageTypes["parent-originated-event"]; + event: EventPayload; +} + +function isParentOriginatedEvent( + data: unknown, +): data is ParentOriginatedMessageDataEventPayload { + if (!isBaseMessageData(data)) return false; + if (!("messageType" in data) || !("event" in data)) return false; + return ( + data.messageType === messageTypes["parent-originated-event"] && + isEventPayload(data.event) + ); +} + +export interface ChildOriginatedMessageDataEventPayload extends BaseMessageData { + messageType: typeof messageTypes["child-originated-event"]; + event: EventPayload; +} + +function isChildOriginatedEvent( + data: unknown, +): data is ChildOriginatedMessageDataEventPayload { + if (!isBaseMessageData(data)) return false; + if (!("messageType" in data) || !("event" in data)) return false; + return ( + data.messageType === messageTypes["child-originated-event"] && + isEventPayload(data.event) + ); +} function isWhitelistedMessage(message: MessageEvent, allowedOrigin: string) { if (allowedOrigin === wildcardOrigin) { return true; } - if (typeof allowedOrigin === 'string' && message.origin !== allowedOrigin) { + if (typeof allowedOrigin === "string" && message.origin !== allowedOrigin) { return false; } return true; } -export type EventMap = Record; +export type EventMap = Record; export interface HandshakeOptions { maxHandshakeRequests?: number; @@ -115,13 +173,14 @@ export interface CreateChildParams< url?: string; namespace?: string; iframeAttributes?: { - [attr: string]: any; + [attr: string]: unknown; }; inboundEvents?: IE; outboundEvents?: OE; handshakeOptions?: HandshakeOptions; enableLogging?: boolean; } + export function createChild< IE extends EventMap, OE extends EventMap, @@ -136,8 +195,8 @@ export function createChild< handshakeOptions = {}, enableLogging, }: CreateChildParams) { - const parent = window; - const iframe = crelt('iframe', iframeAttributes as any) as HTMLIFrameElement; + const parentWindow = window; + const iframe = crelt("iframe", iframeAttributes as object) as HTMLIFrameElement; if (url) { iframe.src = url; } @@ -147,9 +206,9 @@ export function createChild< const log = createLogger(enableLogging); function destroy() { - log('Destroying child iframe'); + log("Destroying child iframe"); - parent.removeEventListener('message', handleEventsFromChild, false); + parentWindow.removeEventListener("message", handleEventsFromChild, false); return iframe.remove(); } @@ -158,29 +217,34 @@ export function createChild< symbol, { eventName: InboundEventName; - handler: (data: any) => void; + handler: (data: unknown) => void; } >(); function on( eventName: E, - handler: (data: z.infer) => void | Promise, + handler: ( + data: StandardSchemaV1.InferOutput, + ) => void | Promise, ) { const listenerId = Symbol(); listeners.set(listenerId, { eventName, handler, }); - log('Parent Frame Inbound Event Listener added:', eventName); + log("Parent Frame Inbound Event Listener added:", eventName); return () => { - log('Parent Frame Inbound Event Listener removed:', eventName); + log("Parent Frame Inbound Event Listener removed:", eventName); listeners.delete(listenerId); }; } - function emit(eventName: E, data: z.infer) { + function emit( + eventName: E, + data: StandardSchemaV1.InferInput, + ) { const eventSchema = outboundEvents[eventName]; if (!eventSchema) { throw new Error( @@ -191,12 +255,10 @@ export function createChild< ); } - const dataParseResult = eventSchema.safeParse(data); + const dataParseResult = validateSync(eventSchema, data); if (!dataParseResult.success) { throw new Error( - `Parent Originated Event "${eventName.toString()}" data is invalid: ${ - dataParseResult.error.message - }`, + `Parent Originated Event "${eventName.toString()}" data is invalid: ${dataParseResult.error}`, { cause: errorCauses.event_data_invalid, }, @@ -208,7 +270,7 @@ export function createChild< data: dataParseResult.data, }; - log('Parent Originated Event sent:', { + log("Parent Originated Event sent:", { namespace, event, }); @@ -216,7 +278,7 @@ export function createChild< iframe.contentWindow?.postMessage( { contentType: eventContentType, - messageType: messageTypes['parent-originated-event'], + messageType: messageTypes["parent-originated-event"], namespace, id: generateUniqueId(namespace), event: { @@ -231,7 +293,7 @@ export function createChild< function handleEventsFromChild(event: MessageEvent) { if (!isWhitelistedMessage(event, childOrigin)) { log( - 'Child Originated Event ignored due to non-whitelisted origin:', + "Child Originated Event ignored due to non-whitelisted origin:", childOrigin, event.origin, ); @@ -241,7 +303,7 @@ export function createChild< if (namespace && event.data.namespace !== namespace) { log( - 'Child Originated Event ignored due to namespace mismatch:', + "Child Originated Event ignored due to namespace mismatch:", namespace, event.data.namespace, ); @@ -249,26 +311,23 @@ export function createChild< return; } - const messageData = ChildOriginatedMessageDataEventPayloadSchema.safeParse( - event.data, - ); - if (!messageData.success) { - log('Child Originated Event ignored due to invalid message data:', event); + if (!isChildOriginatedEvent(event.data)) { + log("Child Originated Event ignored due to invalid message data:", event); return; } - log('Child Originated Event accepted:', event); + log("Child Originated Event accepted:", event); - const { event: eventData } = messageData.data; + const { event: eventData } = event.data; const { name, data } = eventData; Array.from(listeners.values()) .filter(({ eventName }) => eventName === name) .forEach(({ handler, eventName }) => { - const dataParseResult = inboundEvents[eventName]?.safeParse(data); - if (dataParseResult?.success) { - log('Child Originated Event Listener Handler invoked:', { + const dataParseResult = validateSync(inboundEvents[eventName]!, data); + if (dataParseResult.success) { + log("Child Originated Event Listener Handler invoked:", { eventName, data: dataParseResult.data, }); @@ -281,7 +340,7 @@ export function createChild< function executeHandshake() { return new Promise<{ destroy: typeof destroy; - parent: typeof parent; + parent: typeof parentWindow; iframe: typeof iframe; childOrigin: typeof childOrigin; on: typeof on; @@ -298,11 +357,11 @@ export function createChild< function handleHandshakeReply( event: MessageEvent, ) { - log('Handleshake Reply Event received:', event); + log("Handshake Reply Event received:", event); if (!isWhitelistedMessage(event, childOrigin)) { log( - 'Handshake Reply Event ignored due to non-whitelisted origin:', + "Handshake Reply Event ignored due to non-whitelisted origin:", childOrigin, event.origin, ); @@ -312,7 +371,7 @@ export function createChild< if (namespace && event.data.namespace !== namespace) { log( - 'Handshake Reply Event ignored due to namespace mismatch:', + "Handshake Reply Event ignored due to namespace mismatch:", namespace, event.data.namespace, ); @@ -320,23 +379,27 @@ export function createChild< return; } - if (!HandshakeReplyMessageDataSchema.safeParse(event.data).success) { + if (!isHandshakeReply(event.data)) { log( - 'Handshake Reply Event ignored due to invalid message data:', + "Handshake Reply Event ignored due to invalid message data:", event, ); return; } - log('Handshake Reply Event accepted:', event); + log("Handshake Reply Event accepted:", event); clearInterval(handshakeRetryIntervalTimer); - parent.removeEventListener('message', handleHandshakeReply, false); + parentWindow.removeEventListener( + "message", + handleHandshakeReply, + false, + ); const api = { destroy, - parent, + parent: parentWindow, iframe, childOrigin, on, @@ -345,7 +408,7 @@ export function createChild< return resolve(api); } - parent.addEventListener('message', handleHandshakeReply, false); + parentWindow.addEventListener("message", handleHandshakeReply, false); function sendHandshakeRequest() { handshakeAttempt++; @@ -353,14 +416,14 @@ export function createChild< iframe.contentWindow?.postMessage( { contentType: eventContentType, - messageType: messageTypes['handshake-request'], + messageType: messageTypes["handshake-request"], namespace, id: generateUniqueId(namespace), } satisfies HandshakeRequestMessageData, childOrigin, ); - log('Handshake Request Sent: Attempt ', handshakeAttempt); + log("Handshake Request Sent: Attempt ", handshakeAttempt); if (handshakeAttempt === finalHandshakeOptions.maxHandshakeRequests) { clearInterval(handshakeRetryIntervalTimer); @@ -375,8 +438,8 @@ export function createChild< } } - function handleIframeLoad(event: Event) { - log('Iframe Load Event Listener received:', event); + function handleIframeLoad(loadEvent: Event) { + log("Iframe Load Event Listener received:", loadEvent); sendHandshakeRequest(); handshakeRetryIntervalTimer = setInterval( @@ -385,7 +448,7 @@ export function createChild< ); } - iframe.addEventListener('load', handleIframeLoad, false); + iframe.addEventListener("load", handleIframeLoad, false); container.appendChild(iframe); @@ -393,7 +456,7 @@ export function createChild< }); } - parent.addEventListener('message', handleEventsFromChild, false); + parentWindow.addEventListener("message", handleEventsFromChild, false); return { executeHandshake, @@ -410,6 +473,7 @@ export interface ConnectToParentParams< outboundEvents?: OE; enableLogging?: boolean; } + export function connectToParent( { namespace, @@ -427,30 +491,35 @@ export function connectToParent( symbol, { eventName: InboundEventName; - handler: (data: any) => void; + handler: (data: unknown) => void; } >(); function on( eventName: E, - handler: (data: z.infer) => void | Promise, + handler: ( + data: StandardSchemaV1.InferOutput, + ) => void | Promise, ) { const listenerId = Symbol(); listeners.set(listenerId, { eventName, handler, }); - log('Child Frame Inbound Event Listener added:', eventName); + log("Child Frame Inbound Event Listener added:", eventName); return () => { - log('Child Frame Inbound Event Listener removed:', eventName); + log("Child Frame Inbound Event Listener removed:", eventName); listeners.delete(listenerId); }; } function createEmitter(parentOrigin: string) { - function emit(eventName: E, data: z.infer) { + function emit( + eventName: E, + data: StandardSchemaV1.InferInput, + ) { const eventSchema = outboundEvents[eventName]; if (!eventSchema) { throw new Error( @@ -461,12 +530,10 @@ export function connectToParent( ); } - const dataParseResult = eventSchema.safeParse(data); + const dataParseResult = validateSync(eventSchema, data); if (!dataParseResult.success) { throw new Error( - `Child Originated Event "${eventName.toString()}" data is invalid: ${ - dataParseResult.error.message - }`, + `Child Originated Event "${eventName.toString()}" data is invalid: ${dataParseResult.error}`, { cause: errorCauses.event_data_invalid, }, @@ -478,15 +545,15 @@ export function connectToParent( data: dataParseResult.data, }; - log('Child Originated Event Sent:', { + log("Child Originated Event Sent:", { namespace, event, }); - parent.postMessage( + parentRef.postMessage( { contentType: eventContentType, - messageType: messageTypes['child-originated-event'], + messageType: messageTypes["child-originated-event"], namespace, event, id: generateUniqueId(namespace), @@ -498,12 +565,12 @@ export function connectToParent( return emit; } - const parent = child.parent; + const parentRef = child.parent; function executeHandshake() { return new Promise<{ child: typeof child; - parent: typeof parent; + parent: typeof parentRef; parentOrigin: string; on: typeof on; emit: ReturnType; @@ -511,14 +578,14 @@ export function connectToParent( function handleHandshakeRequest( event: MessageEvent, ) { - log('Handshake Request Event Listener received:', event); + log("Handshake Request Event Listener received:", event); if ( event.source instanceof MessagePort || isEventSourceServiceWorker(event) ) { log( - 'Handshake Request Event Listener ignored due to invalid source type:', + "Handshake Request Event Listener ignored due to invalid source type:", event.source, ); @@ -527,7 +594,7 @@ export function connectToParent( if (namespace && event.data.namespace !== namespace) { log( - 'Handshake Request Event Listener ignored due to namespace mismatch:', + "Handshake Request Event Listener ignored due to namespace mismatch:", namespace, event.data.namespace, ); @@ -535,63 +602,64 @@ export function connectToParent( return; } - if (!HandshakeRequestMessageDataSchema.safeParse(event.data).success) { + if (!isHandshakeRequest(event.data)) { reject( - new Error('Invalid handshake request message data', { + new Error("Invalid handshake request message data", { cause: errorCauses.handshake_request_invalid, }), ); return; } - child.removeEventListener('message', handleHandshakeRequest, false); + child.removeEventListener("message", handleHandshakeRequest, false); const parentOrigin = event.origin; - function handleEventsFromParent(event: MessageEvent) { - if (!isWhitelistedMessage(event, parentOrigin)) { + function handleEventsFromParent(parentEvent: MessageEvent) { + if (!isWhitelistedMessage(parentEvent, parentOrigin)) { log( - 'Parent Originated Event ignored due to non-whitelisted origin:', + "Parent Originated Event ignored due to non-whitelisted origin:", parentOrigin, - event.origin, + parentEvent.origin, ); return; } - if (namespace && event.data.namespace !== namespace) { + if (namespace && parentEvent.data.namespace !== namespace) { log( - 'Parent Originated Event ignored due to namespace mismatch:', + "Parent Originated Event ignored due to namespace mismatch:", namespace, - event.data.namespace, + parentEvent.data.namespace, ); return; } - const messageData = - ParentOriginatedMessageDataEventPayloadSchema.safeParse(event.data); - if (!messageData.success) { + if (!isParentOriginatedEvent(parentEvent.data)) { log( - 'Parent Originated Event ignored due to invalid message data:', - event, + "Parent Originated Event ignored due to invalid message data:", + parentEvent, ); return; } - log('Parent Originated Event accepted:', event); + log("Parent Originated Event accepted:", parentEvent); - const { event: eventData } = messageData.data; + const { event: eventData } = parentEvent.data; const { name, data } = eventData; Array.from(listeners.values()) .filter(({ eventName }) => eventName === name) .forEach(({ handler, eventName }) => { - const dataParseResult = inboundEvents[eventName]?.safeParse(data); - if (dataParseResult?.success) { + const dataParseResult = validateSync( + inboundEvents[eventName]!, + data, + ); + if (dataParseResult.success) { log( - 'Parent Originated Event Listener Handler invoked:', + "Parent Originated Event Listener Handler invoked:", eventName, ); @@ -599,14 +667,14 @@ export function connectToParent( } }); } - child.addEventListener('message', handleEventsFromParent, false); + child.addEventListener("message", handleEventsFromParent, false); - log('Handshake Reply sent:', parentOrigin); + log("Handshake Reply sent:", parentOrigin); - parent.postMessage( + parentRef.postMessage( { contentType: eventContentType, - messageType: messageTypes['handshake-reply'], + messageType: messageTypes["handshake-reply"], namespace, id: generateUniqueId(namespace), } satisfies HandshakeReplyMessageData, @@ -615,7 +683,7 @@ export function connectToParent( const api = { child, - parent, + parent: parentRef, parentOrigin, on, emit: createEmitter(parentOrigin), @@ -623,9 +691,9 @@ export function connectToParent( return resolve(api); } - child.addEventListener('message', handleHandshakeRequest, false); + child.addEventListener("message", handleHandshakeRequest, false); - log('Handshake Request Listener added'); + log("Handshake Request Listener added"); }); } @@ -636,7 +704,6 @@ export function connectToParent( } function isEventSourceServiceWorker(event: MessageEvent) { - // ServiceWorker is not available in Private Browsing Mode in Firefox try { return event.source instanceof ServiceWorker; } catch { diff --git a/packages/core/tests/index.test.ts b/packages/core/tests/index.test.ts new file mode 100644 index 0000000..81f64ee --- /dev/null +++ b/packages/core/tests/index.test.ts @@ -0,0 +1,371 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import type { StandardSchemaV1 } from "@standard-schema/spec"; +import { + createChild, + connectToParent, + errorCauses, + eventContentType, + messageTypes, +} from "../src/index.js"; + +function createMockSchema( + validateFn: ( + value: unknown, + ) => StandardSchemaV1.Result, +): StandardSchemaV1 { + return { + "~standard": { + version: 1, + vendor: "test", + validate: validateFn, + }, + }; +} + +function createPassthroughSchema(): StandardSchemaV1 { + return createMockSchema((value) => ({ value: value as T })); +} + +function createFailingSchema( + issues: StandardSchemaV1.Issue[], +): StandardSchemaV1 { + return createMockSchema(() => ({ issues })); +} + +function createAsyncSchema(): StandardSchemaV1 { + return { + "~standard": { + version: 1, + vendor: "test", + validate: () => Promise.resolve({ value: "async" }), + }, + } as unknown as StandardSchemaV1; +} + +describe("createChild", () => { + let container: HTMLElement; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("returns executeHandshake and on functions", () => { + const result = createChild({ container }); + expect(result).toHaveProperty("executeHandshake"); + expect(result).toHaveProperty("on"); + expect(typeof result.executeHandshake).toBe("function"); + expect(typeof result.on).toBe("function"); + }); + + it("creates an iframe in the container", () => { + createChild({ container, url: "https://example.com" }); + expect(container.querySelector("iframe")).toBeNull(); + + createChild({ container, url: "https://example.com" }).executeHandshake(); + const iframe = container.querySelector("iframe"); + expect(iframe).not.toBeNull(); + expect(iframe?.src).toBe("https://example.com/"); + }); + + it("registers an event listener on subscribe", () => { + const handler = vi.fn(); + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { on } = createChild({ container, inboundEvents }); + const unsubscribe = on("testEvent", handler); + expect(typeof unsubscribe).toBe("function"); + }); + + it("unsubscribe removes the listener", () => { + const handler = vi.fn(); + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { on } = createChild({ container, inboundEvents }); + const unsubscribe = on("testEvent", handler); + unsubscribe(); + }); +}); + +describe("connectToParent", () => { + it("returns executeHandshake and on functions", () => { + const result = connectToParent(); + expect(result).toHaveProperty("executeHandshake"); + expect(result).toHaveProperty("on"); + expect(typeof result.executeHandshake).toBe("function"); + expect(typeof result.on).toBe("function"); + }); + + it("registers an event listener on subscribe", () => { + const handler = vi.fn(); + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { on } = connectToParent({ inboundEvents }); + const unsubscribe = on("testEvent", handler); + expect(typeof unsubscribe).toBe("function"); + }); +}); + +describe("Standard Schema validation", () => { + let container: HTMLElement; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("throws on invalid event name in emit", () => { + const outboundEvents = { + validEvent: createPassthroughSchema(), + }; + + const { executeHandshake } = createChild({ container, outboundEvents }); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector("iframe")!; + const postMessageSpy = vi.fn(); + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: postMessageSpy }, + }); + + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + id: "test-id", + }, + }), + ); + + return handshakePromise.then((api) => { + expect(() => + (api.emit as (name: string, data: unknown) => void)( + "invalidEvent", + "data", + ), + ).toThrow("not defined in the outboundEvents map"); + }); + }); + + it("throws on invalid data for emit", () => { + const issues: StandardSchemaV1.Issue[] = [ + { message: "invalid data" }, + ]; + const outboundEvents = { + testEvent: createFailingSchema(issues), + }; + + const { executeHandshake } = createChild({ container, outboundEvents }); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector("iframe")!; + const postMessageSpy = vi.fn(); + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: postMessageSpy }, + }); + + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + id: "test-id", + }, + }), + ); + + return handshakePromise.then((api) => { + try { + api.emit("testEvent", "bad-data"); + expect.unreachable("should have thrown"); + } catch (error) { + expect(error).toBeInstanceOf(Error); + expect((error as Error).cause).toBe(errorCauses.event_data_invalid); + } + }); + }); + + it("throws TypeError for async schemas", () => { + const outboundEvents = { + testEvent: createAsyncSchema(), + }; + + const { executeHandshake } = createChild({ container, outboundEvents }); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector("iframe")!; + const postMessageSpy = vi.fn(); + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: postMessageSpy }, + }); + + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + id: "test-id", + }, + }), + ); + + return handshakePromise.then((api) => { + expect(() => api.emit("testEvent", "data")).toThrow(TypeError); + expect(() => api.emit("testEvent", "data")).toThrow( + "Schema validation must be synchronous", + ); + }); + }); + + it("emits valid data successfully", () => { + const outboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { executeHandshake } = createChild({ container, outboundEvents }); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector("iframe")!; + const postMessageSpy = vi.fn(); + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: postMessageSpy }, + }); + + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + id: "test-id", + }, + }), + ); + + return handshakePromise.then((api) => { + api.emit("testEvent", "hello"); + expect(postMessageSpy).toHaveBeenCalledWith( + expect.objectContaining({ + contentType: eventContentType, + messageType: messageTypes["parent-originated-event"], + event: expect.objectContaining({ + name: "testEvent", + data: "hello", + }), + }), + expect.any(String), + ); + }); + }); +}); + +describe("handshake", () => { + let container: HTMLElement; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("resolves on valid handshake reply", async () => { + const { executeHandshake } = createChild({ + container, + url: "https://example.com", + }); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector("iframe")!; + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: vi.fn() }, + }); + + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + id: "reply-id", + }, + origin: "https://example.com", + }), + ); + + const api = await handshakePromise; + expect(api).toHaveProperty("destroy"); + expect(api).toHaveProperty("on"); + expect(api).toHaveProperty("emit"); + expect(api).toHaveProperty("iframe"); + expect(api).toHaveProperty("childOrigin"); + }); + + it("rejects after max handshake attempts", async () => { + const { executeHandshake } = createChild({ + container, + handshakeOptions: { + maxHandshakeRequests: 1, + handshakeRetryInterval: 10, + }, + }); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector("iframe")!; + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: vi.fn() }, + }); + + iframe.dispatchEvent(new Event("load")); + + await expect(handshakePromise).rejects.toThrow("Handshake failed after"); + }); + + it("filters messages by namespace", async () => { + const { executeHandshake } = createChild({ + container, + namespace: "test-ns", + }); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector("iframe")!; + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: vi.fn() }, + }); + + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + namespace: "wrong-ns", + id: "reply-id", + }, + }), + ); + + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + namespace: "test-ns", + id: "reply-id-2", + }, + }), + ); + + const api = await handshakePromise; + expect(api).toHaveProperty("on"); + }); +}); diff --git a/packages/core/tests/setup.ts b/packages/core/tests/setup.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/core/tests/setup.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 3d0a51a..5a24989 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,21 +1,8 @@ { + "extends": "../../tsconfig.base.json", "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": false, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "ESNext", - "moduleResolution": "Node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" + "outDir": "dist", + "rootDir": "src" }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + "include": ["src"] } diff --git a/packages/core/tsconfig.node.json b/packages/core/tsconfig.node.json deleted file mode 100644 index 9d31e2a..0000000 --- a/packages/core/tsconfig.node.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/packages/core/tsdown.config.ts b/packages/core/tsdown.config.ts new file mode 100644 index 0000000..376214a --- /dev/null +++ b/packages/core/tsdown.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: { index: "src/index.ts" }, + format: ["esm", "cjs"], + dts: true, + clean: true, + treeshake: true, + target: "es2022", + platform: "neutral", + outputOptions: (options, format) => + format === "cjs" ? { ...options, exports: "named" } : options, + deps: { + neverBundle: ["crelt", "nanoid", "@standard-schema/spec"], + }, +}); diff --git a/packages/core/vite.config.ts b/packages/core/vite.config.ts deleted file mode 100644 index 9680b36..0000000 --- a/packages/core/vite.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import path from 'path'; -import { defineConfig } from 'vite'; -import dts from 'vite-plugin-dts'; - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - dts({ - insertTypesEntry: true, - }), - ], - build: { - lib: { - entry: path.resolve(__dirname, 'src/index.ts'), - name: 'IzodCore', - formats: ['es'], - fileName: (format) => `index.${format}.js`, - }, - rollupOptions: { - external: ['zod'], - }, - }, -}); diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts new file mode 100644 index 0000000..d373090 --- /dev/null +++ b/packages/core/vitest.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "happy-dom", + setupFiles: ["./tests/setup.ts"], + coverage: { + provider: "v8", + include: ["src/**"], + reporter: ["text", "json-summary"], + }, + }, +}); diff --git a/packages/react/.eslintrc.cjs b/packages/react/.eslintrc.cjs deleted file mode 100644 index d6c9537..0000000 --- a/packages/react/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, -} diff --git a/packages/react/README.md b/packages/react/README.md deleted file mode 100644 index c5cdb8a..0000000 --- a/packages/react/README.md +++ /dev/null @@ -1,150 +0,0 @@ -# @izod/react - -> NOTE: This is very early stage, documentation is not complete and breaking API changes likely ahead. Please use at your own risk. Lock your version in case you use. (Even though I will adhere to semver for updates) - -![Bundle Size](https://img.shields.io/bundlephobia/minzip/@izod/react) ![npm version](https://badgen.net/npm/v/@izod/react) ![types](https://badgen.net/npm/types/@izod/react) - -`izod` leverages [zod](https://github.com/colinhacks/zod) to provide a type safe Promise oriented API to manage iframe communication. - -This is the react adapter built on top of `@izod/core` - -## Installation - -```sh -npm i zod @izod/core @izod/react -``` - -## Usage - -```ts -// common.ts - -import { z } from 'zod'; -import type { EventMap } from '@izod/core'; - -export const parentOriginEvents = { - askQuestion: z.object({ - question: z.string(), - }), - shout: z.object({ - message: z.string(), - }), -} as const satisfies EventMap; - -export const childOriginEvents = { - answerQuestion: z.object({ - answer: z.string(), - }), - whisper: z.object({ - message: z.string(), - }), -} as const satisfies EventMap; -``` - -```tsx -// parent.tsx - -import { child } from '@izod/react'; - -function Parent() { - // accepts all the parameters that `createChild` from @izod/core does - // `api` is the same that is returned from `connectToParent.executeHandshake` from @izod/core - // `on` can be used to attach event listeners - const { on, api, executeHandshake } = child.useCreate({ - container: document.body, // required - url: 'http://127.0.0.1:3010', // required - inboundEvents: parentOriginEvents, // optional - outboundEvents: childOriginEvents, // optional - handshakeOptions: { - // optional - maxHandshakeRequests: 10, // default 5 - handshakeRetryInterval: 100, // default 1000 - }, - onHandshakeComplete(api) { - // callback called when handshake is successful - }, - onHandshakeError(error) { - // callback called when handshake fails - }, - // remove the iframe on component unmount - destroyOnUnmount: false, // default false - optional - }); - - // `child.useEventListener` takes care of this boilerplate for you but is not fully type safe as of now - // to add event listeners - // prefer this over `onHandshakeComplete` for attaching event listeners - useEffect(() => { - if (api) { - // function is returned from `.on` that can be called to unsubscribe - const off = on('askQuestion', (data) => { - console.log('Question: ', data.question); - }); - - // return that from the useEffect for cleanup - return off; - } - }, [api]); - - const ranOnce = useRef(false); - useEffect(() => { - if (ranOnce.current) { - return; - } - - executeHandshake(); - ranOnce.current = true; - }, []); - - const shout = () => { - api.emit('shout', { message: 'Hello' }); - }; -} -``` - -```tsx -// child.tsx - -import { parent } from '@izod/react'; - -function Child() { - // `api` is the same that is returned from `connectToParent.executeHandshake` from @izod/core - const { on, api, executeHandshake } = parent.useConnect({ - inboundEvents: parentOriginEvents, - outboundEvents: childOriginEvents, - onHandshakeComplete(api) { - // callback called when handshake is successful - }, - onHandshakeError(error) { - // callback called when handshake fails - }, - }); - - // `parent.useEventListener` takes care of this boilerplate for you but is not fully type safe as of now - // to add event listeners - useEffect(() => { - // function is returned from `.on` that can be called to unsubscribe - if (api) { - const off = api.on('shout', (data) => { - console.log(`Parent shouted: ${data.message}`); - }); - - // return that from the useEffect for cleanup - return off; - } - }, [api]); - - const ranOnce = useRef(false); - useEffect(() => { - if (ranOnce.current) { - return; - } - - executeHandshake(); - ranOnce.current = true; - }, []); - - const whisper = () => { - api.emit('whisper', { message: 'Hi' }); - }; -} -``` diff --git a/packages/react/index.html b/packages/react/index.html deleted file mode 100644 index e4b78ea..0000000 --- a/packages/react/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + React + TS - - -
- - - diff --git a/packages/react/package.json b/packages/react/package.json index 133cefb..ad4e390 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,50 +1,49 @@ { "name": "@izod/react", - "private": false, - "version": "1.1.0", + "version": "2.0.0", "type": "module", "sideEffects": false, "files": [ "dist" ], - "module": "./dist/index.es.js", + "main": "./dist/index.cjs", + "module": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { - "import": "./dist/index.es.js", - "types": "./dist/index.d.ts" + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./package.json": { + "default": "./package.json" } }, "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" - }, - "dependencies": { - "react-use": "17.6.0" + "build": "tsdown", + "dev": "tsdown --watch", + "test": "vitest run", + "test:coverage": "vitest run --coverage", + "typecheck": "tsc --noEmit" }, "peerDependencies": { - "zod": "^2.0.0 || ^3.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "@izod/core": "1.1.0" + "@izod/core": "workspace:*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "devDependencies": { "@izod/core": "workspace:*", - "@types/react": "18.2.15", - "@types/react-dom": "18.2.7", - "@typescript-eslint/eslint-plugin": "6.0.0", - "@typescript-eslint/parser": "6.0.0", - "@vitejs/plugin-react": "4.0.3", - "eslint": "8.45.0", - "eslint-plugin-react-hooks": "4.6.0", - "eslint-plugin-react-refresh": "0.4.3", - "typescript": "5.8.2", - "vite": "4.4.5", - "vite-plugin-dts": "3.5.1", - "zod": "3.24.2", - "react": "18.2.0", - "react-dom": "18.2.0" + "@standard-schema/spec": "catalog:", + "@testing-library/jest-dom": "catalog:", + "@testing-library/react": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@vitest/coverage-v8": "catalog:", + "happy-dom": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", + "tsdown": "catalog:", + "typescript": "catalog:", + "vitest": "catalog:" }, "repository": { "type": "git", @@ -58,7 +57,8 @@ "react", "iframe", "typescript", - "zod" + "standard-schema", + "hooks" ], "license": "MIT" } diff --git a/packages/react/public/vite.svg b/packages/react/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/packages/react/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index bf1094b..b35727a 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,35 +1,62 @@ import { createChild, - EventMap, + type EventMap, type CreateChildParams, type ConnectToParentParams, connectToParent, -} from '@izod/core'; -import { useEffect, useRef } from 'react'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; +} from "@izod/core"; +import { useEffect, useRef, useState, useCallback } from "react"; + +type AsyncState = + | { loading: false; value: undefined; error: undefined } + | { loading: true; value: undefined; error: undefined } + | { loading: false; value: T; error: undefined } + | { loading: false; value: undefined; error: Error }; + +function useAsyncCallback(asyncFn: () => Promise) { + const [state, setState] = useState>({ + loading: false, + value: undefined, + error: undefined, + }); + + const execute = useCallback(() => { + setState({ loading: true, value: undefined, error: undefined }); + asyncFn().then( + (value) => + setState({ loading: false, value, error: undefined }), + (error: unknown) => + setState({ + loading: false, + value: undefined, + error: error instanceof Error ? error : new Error(String(error)), + }), + ); + }, [asyncFn]); + + return [state, execute] as const; +} -// a typescript trick to get the strictly inferred return type of a function with generics -class CreateChildHandshakeWrapper< +type CreateChildHandshakeResult< IE extends EventMap, OE extends EventMap, T extends HTMLElement | Element, -> { - wrapped = (params: CreateChildParams) => - createChild(params)['executeHandshake'](); -} +> = Awaited< + ReturnType>["executeHandshake"]> +>; + interface UseChildIframeParams< IE extends EventMap, OE extends EventMap, T extends HTMLElement | Element, > extends CreateChildParams { onHandshakeComplete?: ( - api: NonNullable< - Awaited['wrapped']>> - >, + api: CreateChildHandshakeResult, ) => void; onHandshakeError?: (error: Error) => void; destroyOnUnmount?: boolean; } + function useCreateChildIframe< IE extends EventMap, OE extends EventMap, @@ -40,11 +67,13 @@ function useCreateChildIframe< destroyOnUnmount, ...props }: UseChildIframeParams) { - const child = useRef(createChild(props)); - const [handshakeState, executeHandshake] = useAsyncFn( - child.current.executeHandshake, + const childRef = useRef(createChild(props)); + const executeHandshakeFn = useCallback( + () => childRef.current.executeHandshake(), [], ); + const [handshakeState, executeHandshake] = + useAsyncCallback(executeHandshakeFn); const onHandshakeCompleteCallbackRef = useRef(onHandshakeComplete); @@ -52,13 +81,13 @@ function useCreateChildIframe< useRef(onHandshakeError); const destroyOnUnmountRef = useRef(destroyOnUnmount ?? true); - const apiRef = useRef(); + const apiRef = useRef(undefined); useEffect(() => { const api = apiRef.current; - const destroyOnUnmount = destroyOnUnmountRef.current; + const shouldDestroy = destroyOnUnmountRef.current; return () => { - if (destroyOnUnmount && api) { + if (shouldDestroy && api) { api.destroy(); } }; @@ -74,9 +103,9 @@ function useCreateChildIframe< onHandshakeSettledEffectRan.current = true; apiRef.current = handshakeState.value; - const onHandshakeComplete = onHandshakeCompleteCallbackRef.current; - if (onHandshakeComplete) { - onHandshakeComplete(handshakeState.value); + const callback = onHandshakeCompleteCallbackRef.current; + if (callback) { + callback(handshakeState.value); } } else if (handshakeState.error) { onHandshakeSettledEffectRan.current = true; @@ -88,7 +117,7 @@ function useCreateChildIframe< }, [handshakeState]); return { - on: child.current.on, + on: childRef.current.on, executeHandshake, api: handshakeState.value, isHandshakeComplete: handshakeState.value !== undefined, @@ -101,22 +130,21 @@ export const child = { useCreate: useCreateChildIframe, } as const; -class ConnectToParentHandshakeWrapper< +type ConnectToParentHandshakeResult< IE extends EventMap, OE extends EventMap, -> { - wrapped = (params: ConnectToParentParams) => - connectToParent(params).executeHandshake(); -} +> = Awaited< + ReturnType>["executeHandshake"]> +>; + interface UseParentParams extends ConnectToParentParams { onHandshakeComplete?: ( - api: NonNullable< - Awaited['wrapped']>> - >, + api: ConnectToParentHandshakeResult, ) => void; onHandshakeError?: (error: Error) => void; } + function useConnectToParent( { onHandshakeComplete, @@ -124,18 +152,20 @@ function useConnectToParent( ...props }: UseParentParams = {} as UseParentParams, ) { - const parent = useRef(connectToParent(props)); - const [handshakeState, executeHandshake] = useAsyncFn( - parent.current.executeHandshake, + const parentRef = useRef(connectToParent(props)); + const executeHandshakeFn = useCallback( + () => parentRef.current.executeHandshake(), [], ); + const [handshakeState, executeHandshake] = + useAsyncCallback(executeHandshakeFn); const onHandshakeCompleteCallbackRef = useRef(onHandshakeComplete); const onHandshakeErrorCallbackRef = useRef(onHandshakeError); - const apiRef = useRef(); + const apiRef = useRef(undefined); const onHandshakeSettledEffectRan = useRef(false); useEffect(() => { @@ -147,9 +177,9 @@ function useConnectToParent( onHandshakeSettledEffectRan.current = true; apiRef.current = handshakeState.value; - const onHandshakeComplete = onHandshakeCompleteCallbackRef.current; - if (onHandshakeComplete) { - onHandshakeComplete(handshakeState.value); + const callback = onHandshakeCompleteCallbackRef.current; + if (callback) { + callback(handshakeState.value); } } else if (handshakeState.error) { onHandshakeSettledEffectRan.current = true; @@ -162,7 +192,7 @@ function useConnectToParent( return { executeHandshake, - on: parent.current.on, + on: parentRef.current.on, api: handshakeState.value, isHandshakeComplete: handshakeState.value !== undefined, isHandshakePending: handshakeState.loading, diff --git a/packages/react/tests/react.test.ts b/packages/react/tests/react.test.ts new file mode 100644 index 0000000..edb0a6a --- /dev/null +++ b/packages/react/tests/react.test.ts @@ -0,0 +1,128 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { renderHook, act, cleanup } from "@testing-library/react"; +import type { StandardSchemaV1 } from "@standard-schema/spec"; +import { eventContentType, messageTypes } from "@izod/core"; +import { child, parent } from "../src/index.js"; + +function createPassthroughSchema(): StandardSchemaV1 { + return { + "~standard": { + version: 1, + vendor: "test", + validate: (value: unknown) => ({ value: value as T }), + }, + }; +} + +describe("child.useCreate", () => { + let container: HTMLElement; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + return () => { + cleanup(); + container.remove(); + }; + }); + + it("returns expected API shape", () => { + const { result } = renderHook(() => + child.useCreate({ container }), + ); + + expect(result.current).toHaveProperty("on"); + expect(result.current).toHaveProperty("executeHandshake"); + expect(result.current).toHaveProperty("api"); + expect(result.current).toHaveProperty("isHandshakeComplete"); + expect(result.current).toHaveProperty("isHandshakePending"); + expect(result.current).toHaveProperty("handshakeError"); + + expect(typeof result.current.on).toBe("function"); + expect(typeof result.current.executeHandshake).toBe("function"); + expect(result.current.isHandshakeComplete).toBe(false); + expect(result.current.isHandshakePending).toBe(false); + }); + + it("can register event listeners", () => { + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { result } = renderHook(() => + child.useCreate({ container, inboundEvents }), + ); + + const handler = vi.fn(); + const unsubscribe = result.current.on("testEvent", handler); + expect(typeof unsubscribe).toBe("function"); + unsubscribe(); + }); + + it("calls onHandshakeComplete callback on success", async () => { + const onHandshakeComplete = vi.fn(); + + const { result } = renderHook(() => + child.useCreate({ + container, + onHandshakeComplete, + }), + ); + + act(() => { + result.current.executeHandshake(); + }); + + const iframe = container.querySelector("iframe")!; + Object.defineProperty(iframe, "contentWindow", { + value: { postMessage: vi.fn() }, + }); + + await act(async () => { + window.dispatchEvent( + new MessageEvent("message", { + data: { + contentType: eventContentType, + messageType: messageTypes["handshake-reply"], + id: "test-id", + }, + }), + ); + }); + + expect(onHandshakeComplete).toHaveBeenCalled(); + }); +}); + +describe("parent.useConnect", () => { + it("returns expected API shape", () => { + const { result } = renderHook(() => parent.useConnect()); + + expect(result.current).toHaveProperty("on"); + expect(result.current).toHaveProperty("executeHandshake"); + expect(result.current).toHaveProperty("api"); + expect(result.current).toHaveProperty("isHandshakeComplete"); + expect(result.current).toHaveProperty("isHandshakePending"); + expect(result.current).toHaveProperty("handshakeError"); + + expect(typeof result.current.on).toBe("function"); + expect(typeof result.current.executeHandshake).toBe("function"); + expect(result.current.isHandshakeComplete).toBe(false); + expect(result.current.isHandshakePending).toBe(false); + }); + + it("can register event listeners", () => { + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { result } = renderHook(() => + parent.useConnect({ inboundEvents }), + ); + + const handler = vi.fn(); + const unsubscribe = result.current.on("testEvent", handler); + expect(typeof unsubscribe).toBe("function"); + unsubscribe(); + }); +}); diff --git a/packages/react/tests/setup.ts b/packages/react/tests/setup.ts new file mode 100644 index 0000000..f149f27 --- /dev/null +++ b/packages/react/tests/setup.ts @@ -0,0 +1 @@ +import "@testing-library/jest-dom/vitest"; diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index a7fc6fb..5a24989 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -1,25 +1,8 @@ { + "extends": "../../tsconfig.base.json", "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "outDir": "dist", + "rootDir": "src" }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + "include": ["src"] } diff --git a/packages/react/tsconfig.node.json b/packages/react/tsconfig.node.json deleted file mode 100644 index 42872c5..0000000 --- a/packages/react/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/packages/react/tsdown.config.ts b/packages/react/tsdown.config.ts new file mode 100644 index 0000000..72cf858 --- /dev/null +++ b/packages/react/tsdown.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: { index: "src/index.ts" }, + format: ["esm", "cjs"], + dts: true, + clean: true, + treeshake: true, + target: "es2022", + platform: "neutral", + outputOptions: (options, format) => + format === "cjs" ? { ...options, exports: "named" } : options, + deps: { + neverBundle: ["react", "react-dom", "@izod/core", "@standard-schema/spec"], + }, +}); diff --git a/packages/react/vite.config.ts b/packages/react/vite.config.ts deleted file mode 100644 index f2833cd..0000000 --- a/packages/react/vite.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import path from 'path'; -import { defineConfig } from 'vite'; -import dts from 'vite-plugin-dts'; - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - dts({ - insertTypesEntry: true, - }), - ], - build: { - lib: { - entry: path.resolve(__dirname, 'src/index.ts'), - name: 'IzodReact', - formats: ['es'], - fileName: (format) => `index.${format}.js`, - }, - rollupOptions: { - external: ['react', 'react-dom', 'react-use', 'zod'], - }, - }, -}); diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts new file mode 100644 index 0000000..d373090 --- /dev/null +++ b/packages/react/vitest.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "happy-dom", + setupFiles: ["./tests/setup.ts"], + coverage: { + provider: "v8", + include: ["src/**"], + reporter: ["text", "json-summary"], + }, + }, +}); diff --git a/playground/playground-common/package.json b/playground/playground-common/package.json deleted file mode 100644 index e99e7bb..0000000 --- a/playground/playground-common/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@izod/playground-common", - "private": false, - "version": "1.0.0", - "type": "module", - "sideEffects": false, - "files": [ - "dist" - ], - "module": "./dist/index.es.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "import": "./dist/index.es.js", - "types": "./dist/index.d.ts" - } - }, - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "preview": "vite preview" - }, - "peerDependencies": { - "@izod/core": "workspace:*", - "zod": "^2.0.0 || ^3.0.0" - }, - "devDependencies": { - "@izod/core": "workspace:*", - "@types/node": "20.4.8", - "typescript": "5.8.2", - "vite": "4.4.5", - "vite-plugin-dts": "3.5.1", - "zod": "3.24.2" - } -} diff --git a/playground/playground-common/src/index.ts b/playground/playground-common/src/index.ts deleted file mode 100644 index 95f7cbc..0000000 --- a/playground/playground-common/src/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { z } from 'zod'; -import type { EventMap } from '@izod/core'; - -export const parentOriginEvents = { - askQuestion: z.object({ - question: z.string(), - }), - shout: z.object({ - message: z.string(), - }), -} as const satisfies EventMap; - -export const childOriginEvents = { - answerQuestion: z.object({ - answer: z.string(), - }), - whisper: z.object({ - message: z.string(), - }), -} as const satisfies EventMap; diff --git a/playground/playground-common/tsconfig.json b/playground/playground-common/tsconfig.json deleted file mode 100644 index 3d0a51a..0000000 --- a/playground/playground-common/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": false, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "ESNext", - "moduleResolution": "Node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] -} diff --git a/playground/playground-common/tsconfig.node.json b/playground/playground-common/tsconfig.node.json deleted file mode 100644 index 9d31e2a..0000000 --- a/playground/playground-common/tsconfig.node.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/playground/playground-common/vite.config.ts b/playground/playground-common/vite.config.ts deleted file mode 100644 index 3215b1b..0000000 --- a/playground/playground-common/vite.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import path from 'path'; -import { defineConfig } from 'vite'; -import dts from 'vite-plugin-dts'; - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - dts({ - insertTypesEntry: true, - }), - ], - build: { - lib: { - entry: path.resolve(__dirname, 'src/index.ts'), - name: 'IzodPlaygroundCommon', - formats: ['es'], - fileName: (format) => `index.${format}.js`, - }, - rollupOptions: { - external: ['zod'], - }, - }, -}); diff --git a/playground/playground-react/.eslintrc.cjs b/playground/playground-react/.eslintrc.cjs deleted file mode 100644 index d6c9537..0000000 --- a/playground/playground-react/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, -} diff --git a/playground/playground-react/.gitignore b/playground/playground-react/.gitignore deleted file mode 100644 index a547bf3..0000000 --- a/playground/playground-react/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/playground/playground-react/README.md b/playground/playground-react/README.md deleted file mode 100644 index 1ebe379..0000000 --- a/playground/playground-react/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json'], - tsconfigRootDir: __dirname, - }, -``` - -- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` -- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list diff --git a/playground/playground-react/index.html b/playground/playground-react/index.html deleted file mode 100644 index e4b78ea..0000000 --- a/playground/playground-react/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + React + TS - - -
- - - diff --git a/playground/playground-react/package.json b/playground/playground-react/package.json deleted file mode 100644 index 2825290..0000000 --- a/playground/playground-react/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@izod/playground-react", - "private": false, - "version": "1.0.0", - "type": "module", - "scripts": { - "dev": "vite --port 3010", - "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" - }, - "dependencies": { - "react": "18.2.0", - "react-dom": "18.2.0", - "zod": "3.24.2", - "@izod/core": "workspace:*", - "@izod/react": "workspace:*", - "@izod/playground-common": "workspace:*" - }, - "devDependencies": { - "@types/react": "18.2.15", - "@types/react-dom": "18.2.7", - "@typescript-eslint/eslint-plugin": "6.0.0", - "@typescript-eslint/parser": "6.0.0", - "@vitejs/plugin-react": "4.0.3", - "eslint": "8.45.0", - "eslint-plugin-react-hooks": "4.6.0", - "eslint-plugin-react-refresh": "0.4.3", - "typescript": "5.8.2", - "vite": "4.4.5" - } -} diff --git a/playground/playground-react/public/vite.svg b/playground/playground-react/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/playground/playground-react/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/playground/playground-react/src/App.tsx b/playground/playground-react/src/App.tsx deleted file mode 100644 index 580470c..0000000 --- a/playground/playground-react/src/App.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { parent } from '@izod/react'; -import { childOriginEvents, parentOriginEvents } from '@izod/playground-common'; -import { useEffect, useRef, useState } from 'react'; - -function App() { - const { executeHandshake, on, api } = parent.useConnect({ - inboundEvents: parentOriginEvents, - outboundEvents: childOriginEvents, - onHandshakeComplete(api) { - api.on('askQuestion', (data) => { - console.log('Question: ', data.question); - }); - }, - }); - - const [data, setData] = useState([]); - - const ranOnce = useRef(false); - useEffect(() => { - if (!ranOnce.current) { - on('askQuestion', (data) => { - setData((prev) => [...prev, `Question: ${data.question}`]); - }); - - on('shout', (data) => { - setData((prev) => [...prev, `Message: ${data.message}`]); - }); - - executeHandshake(); - ranOnce.current = true; - } - }, [executeHandshake, on]); - - const [input, setInput] = useState(''); - const [type, setType] = - useState('answerQuestion'); - - return ( -
-
{ - event.preventDefault(); - - api?.emit( - type, - type === 'answerQuestion' - ? { - answer: input, - } - : { - message: input, - }, - ); - - setInput(''); - }} - > -
- setInput(event.target.value)} - /> -
- -
- -
- - -
- - {data.map((item, index) => ( -

{item}

- ))} -
- ); -} - -export default App; diff --git a/playground/playground-react/src/main.tsx b/playground/playground-react/src/main.tsx deleted file mode 100644 index dee6b69..0000000 --- a/playground/playground-react/src/main.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import ReactDOM from 'react-dom/client'; -import App from './App'; - -ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/playground/playground-react/src/vite-env.d.ts b/playground/playground-react/src/vite-env.d.ts deleted file mode 100644 index 11f02fe..0000000 --- a/playground/playground-react/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/playground/playground-react/tsconfig.json b/playground/playground-react/tsconfig.json deleted file mode 100644 index a7fc6fb..0000000 --- a/playground/playground-react/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] -} diff --git a/playground/playground-react/tsconfig.node.json b/playground/playground-react/tsconfig.node.json deleted file mode 100644 index 42872c5..0000000 --- a/playground/playground-react/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/playground/playground-react/vite.config.ts b/playground/playground-react/vite.config.ts deleted file mode 100644 index 5a33944..0000000 --- a/playground/playground-react/vite.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [react()], -}) diff --git a/playground/playground-vanilla/.gitignore b/playground/playground-vanilla/.gitignore deleted file mode 100644 index a547bf3..0000000 --- a/playground/playground-vanilla/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/playground/playground-vanilla/index.html b/playground/playground-vanilla/index.html deleted file mode 100644 index 4c11e20..0000000 --- a/playground/playground-vanilla/index.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - Vite + TS - - - - -
-
-
-
- -
-
- - - - - -
- - -
- -
-
Messages from child
-
-
-
-
-
- - - diff --git a/playground/playground-vanilla/package.json b/playground/playground-vanilla/package.json deleted file mode 100644 index cd60da5..0000000 --- a/playground/playground-vanilla/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@izod/playground-vanilla", - "private": false, - "version": "1.0.0", - "type": "module", - "scripts": { - "dev": "vite --port 3020", - "build": "tsc && vite build", - "preview": "vite preview" - }, - "dependencies": { - "zod": "3.24.2", - "@izod/core": "workspace:*", - "@izod/playground-common": "workspace:*" - }, - "devDependencies": { - "typescript": "5.8.2", - "vite": "4.4.5" - } -} diff --git a/playground/playground-vanilla/public/vite.svg b/playground/playground-vanilla/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/playground/playground-vanilla/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/playground/playground-vanilla/src/main.ts b/playground/playground-vanilla/src/main.ts deleted file mode 100644 index b02c7e0..0000000 --- a/playground/playground-vanilla/src/main.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { createChild } from '@izod/core'; -import { childOriginEvents, parentOriginEvents } from '@izod/playground-common'; - -async function main() { - const container = document.getElementById('child-container'); - - if (container) { - const child = createChild({ - container, - url: 'http://localhost:3010', - inboundEvents: childOriginEvents, - outboundEvents: parentOriginEvents, - handshakeOptions: { - handshakeRetryInterval: 100, - }, - }); - - child.on('whisper', (data) => { - const p = document.createElement('p'); - p.textContent = data.message; - childMessageList?.appendChild(p); - }); - child.on('answerQuestion', (data) => { - const p = document.createElement('p'); - p.textContent = data.answer; - childMessageList?.appendChild(p); - }); - - const api = await child.executeHandshake(); - - const childMessageList = document.getElementById('child-message-list'); - - const parentControlPanelForm = document.getElementById( - 'parent-control-panel-form', - ) as HTMLFormElement; - parentControlPanelForm.addEventListener( - 'submit', - (event) => { - event.preventDefault(); - const textInput = document.getElementById( - 'parent-control-panel-input', - ) as HTMLInputElement; - const text = textInput.value; - - const questionRadio = document.querySelector( - 'input[id="parent-control-panel-question-radio"]', - ) as HTMLInputElement; - - const shoutRadio = document.querySelector( - 'input[id="parent-control-panel-shout-radio"]', - ) as HTMLInputElement; - - if (questionRadio.checked) { - api.emit('askQuestion', { question: text }); - } else if (shoutRadio.checked) { - api.emit('shout', { message: text }); - } - - textInput.value = ''; - }, - false, - ); - } -} - -main(); diff --git a/playground/playground-vanilla/tsconfig.json b/playground/playground-vanilla/tsconfig.json deleted file mode 100644 index 75abdef..0000000 --- a/playground/playground-vanilla/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e3cc6b8..b6f7087 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,13 +4,67 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + default: + '@standard-schema/spec': + specifier: 1.1.0 + version: 1.1.0 + '@testing-library/jest-dom': + specifier: 6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: 16.3.2 + version: 16.3.2 + '@types/react': + specifier: 19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3 + '@vitest/coverage-v8': + specifier: 4.1.5 + version: 4.1.5 + happy-dom: + specifier: 20.9.0 + version: 20.9.0 + react: + specifier: 19.2.5 + version: 19.2.5 + react-dom: + specifier: 19.2.5 + version: 19.2.5 + tsdown: + specifier: 0.21.10 + version: 0.21.10 + typescript: + specifier: 6.0.3 + version: 6.0.3 + vitest: + specifier: 4.1.5 + version: 4.1.5 + importers: .: devDependencies: - prettier: - specifier: 3.0.1 - version: 3.0.1 + '@changesets/cli': + specifier: 2.31.0 + version: 2.31.0(@types/node@25.6.0) + '@commitlint/cli': + specifier: 20.5.3 + version: 20.5.3(@types/node@25.6.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3) + '@commitlint/config-conventional': + specifier: 20.5.3 + version: 20.5.3 + husky: + specifier: 9.1.7 + version: 9.1.7 + oxfmt: + specifier: 0.47.0 + version: 0.47.0 + oxlint: + specifier: 1.62.0 + version: 1.62.0 turbo: specifier: 2.5.6 version: 2.5.6 @@ -23,941 +77,1059 @@ importers: nanoid: specifier: 5.1.5 version: 5.1.5 - type-fest: - specifier: 4.37.0 - version: 4.37.0 devDependencies: - '@types/node': - specifier: 20.4.8 - version: 20.4.8 + '@standard-schema/spec': + specifier: 'catalog:' + version: 1.1.0 + '@vitest/coverage-v8': + specifier: 'catalog:' + version: 4.1.5(vitest@4.1.5) + happy-dom: + specifier: 'catalog:' + version: 20.9.0 + tsdown: + specifier: 'catalog:' + version: 0.21.10(typescript@6.0.3) typescript: - specifier: 5.8.2 - version: 5.8.2 - vite: - specifier: 4.4.5 - version: 4.4.5(@types/node@20.4.8) - vite-plugin-dts: - specifier: 3.5.1 - version: 3.5.1(@types/node@20.4.8)(rollup@3.27.2)(typescript@5.8.2)(vite@4.4.5(@types/node@20.4.8)) - zod: - specifier: 3.24.2 - version: 3.24.2 + specifier: 'catalog:' + version: 6.0.3 + vitest: + specifier: 'catalog:' + version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) packages/react: - dependencies: - react-use: - specifier: 17.6.0 - version: 17.6.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) devDependencies: '@izod/core': specifier: workspace:* version: link:../core + '@standard-schema/spec': + specifier: 'catalog:' + version: 1.1.0 + '@testing-library/jest-dom': + specifier: 'catalog:' + version: 6.9.1 + '@testing-library/react': + specifier: 'catalog:' + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@types/react': - specifier: 18.2.15 - version: 18.2.15 + specifier: 'catalog:' + version: 19.2.14 '@types/react-dom': - specifier: 18.2.7 - version: 18.2.7 - '@typescript-eslint/eslint-plugin': - specifier: 6.0.0 - version: 6.0.0(@typescript-eslint/parser@6.0.0(eslint@8.45.0)(typescript@5.8.2))(eslint@8.45.0)(typescript@5.8.2) - '@typescript-eslint/parser': - specifier: 6.0.0 - version: 6.0.0(eslint@8.45.0)(typescript@5.8.2) - '@vitejs/plugin-react': - specifier: 4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.4.8)) - eslint: - specifier: 8.45.0 - version: 8.45.0 - eslint-plugin-react-hooks: - specifier: 4.6.0 - version: 4.6.0(eslint@8.45.0) - eslint-plugin-react-refresh: - specifier: 0.4.3 - version: 0.4.3(eslint@8.45.0) - react: - specifier: 18.2.0 - version: 18.2.0 - react-dom: - specifier: 18.2.0 - version: 18.2.0(react@18.2.0) - typescript: - specifier: 5.8.2 - version: 5.8.2 - vite: - specifier: 4.4.5 - version: 4.4.5(@types/node@20.4.8) - vite-plugin-dts: - specifier: 3.5.1 - version: 3.5.1(@types/node@20.4.8)(rollup@3.27.2)(typescript@5.8.2)(vite@4.4.5(@types/node@20.4.8)) - zod: - specifier: 3.24.2 - version: 3.24.2 - - playground/playground-common: - devDependencies: - '@izod/core': - specifier: workspace:* - version: link:../../packages/core - '@types/node': - specifier: 20.4.8 - version: 20.4.8 - typescript: - specifier: 5.8.2 - version: 5.8.2 - vite: - specifier: 4.4.5 - version: 4.4.5(@types/node@20.4.8) - vite-plugin-dts: - specifier: 3.5.1 - version: 3.5.1(@types/node@20.4.8)(rollup@3.27.2)(typescript@5.8.2)(vite@4.4.5(@types/node@20.4.8)) - zod: - specifier: 3.24.2 - version: 3.24.2 - - playground/playground-react: - dependencies: - '@izod/core': - specifier: workspace:* - version: link:../../packages/core - '@izod/playground-common': - specifier: workspace:* - version: link:../playground-common - '@izod/react': - specifier: workspace:* - version: link:../../packages/react + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.14) + '@vitest/coverage-v8': + specifier: 'catalog:' + version: 4.1.5(vitest@4.1.5) + happy-dom: + specifier: 'catalog:' + version: 20.9.0 react: - specifier: 18.2.0 - version: 18.2.0 + specifier: 'catalog:' + version: 19.2.5 react-dom: - specifier: 18.2.0 - version: 18.2.0(react@18.2.0) - zod: - specifier: 3.24.2 - version: 3.24.2 - devDependencies: - '@types/react': - specifier: 18.2.15 - version: 18.2.15 - '@types/react-dom': - specifier: 18.2.7 - version: 18.2.7 - '@typescript-eslint/eslint-plugin': - specifier: 6.0.0 - version: 6.0.0(@typescript-eslint/parser@6.0.0(eslint@8.45.0)(typescript@5.8.2))(eslint@8.45.0)(typescript@5.8.2) - '@typescript-eslint/parser': - specifier: 6.0.0 - version: 6.0.0(eslint@8.45.0)(typescript@5.8.2) - '@vitejs/plugin-react': - specifier: 4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.4.8)) - eslint: - specifier: 8.45.0 - version: 8.45.0 - eslint-plugin-react-hooks: - specifier: 4.6.0 - version: 4.6.0(eslint@8.45.0) - eslint-plugin-react-refresh: - specifier: 0.4.3 - version: 0.4.3(eslint@8.45.0) - typescript: - specifier: 5.8.2 - version: 5.8.2 - vite: - specifier: 4.4.5 - version: 4.4.5(@types/node@20.4.8) - - playground/playground-vanilla: - dependencies: - '@izod/core': - specifier: workspace:* - version: link:../../packages/core - '@izod/playground-common': - specifier: workspace:* - version: link:../playground-common - zod: - specifier: 3.24.2 - version: 3.24.2 - devDependencies: + specifier: 'catalog:' + version: 19.2.5(react@19.2.5) + tsdown: + specifier: 'catalog:' + version: 0.21.10(typescript@6.0.3) typescript: - specifier: 5.8.2 - version: 5.8.2 - vite: - specifier: 4.4.5 - version: 4.4.5(@types/node@20.4.8) + specifier: 'catalog:' + version: 6.0.3 + vitest: + specifier: 'catalog:' + version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) packages: - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} - '@ampproject/remapping@2.2.1': - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} - engines: {node: '>=6.0.0'} - - '@babel/code-frame@7.22.10': - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.22.9': - resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} - engines: {node: '>=6.9.0'} + '@babel/generator@8.0.0-rc.3': + resolution: {integrity: sha512-em37/13/nR320G4jab/nIIHZgc2Wz2y/D39lxnTyxB4/D/omPQncl/lSdlnJY1OhQcRGugTSIF2l/69o31C9dA==} + engines: {node: ^20.19.0 || >=22.12.0} - '@babel/core@7.22.10': - resolution: {integrity: sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.22.10': - resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} - engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@8.0.0-rc.4': + resolution: {integrity: sha512-dluR3v287dp6YPF57kyKKrHPKffUeuxH1zQcF1WD30TeFzWXhDiVi1U6PkqaDB0++H1PeCwRhmYl4DvoerlPIw==} + engines: {node: ^20.19.0 || >=22.12.0} - '@babel/helper-compilation-targets@7.22.10': - resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.22.5': - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} - engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@8.0.0-rc.3': + resolution: {integrity: sha512-8AWCJ2VJJyDFlGBep5GpaaQ9AAaE/FjAcrqI7jyssYhtL7WGV0DOKpJsQqM037xDbpRLHXsY8TwU7zDma7coOw==} + engines: {node: ^20.19.0 || >=22.12.0} - '@babel/helper-function-name@7.22.5': - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} - engines: {node: '>=6.9.0'} + '@babel/parser@7.29.3': + resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} + engines: {node: '>=6.0.0'} + hasBin: true - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} + '@babel/parser@8.0.0-rc.3': + resolution: {integrity: sha512-B20dvP3MfNc/XS5KKCHy/oyWl5IA6Cn9YjXRdDlCjNmUFrjvLXMNUfQq/QUy9fnG2gYkKKcrto2YaF9B32ToOQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true - '@babel/helper-module-imports@7.22.5': - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.22.9': - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.22.5': - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} + '@babel/types@8.0.0-rc.3': + resolution: {integrity: sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q==} + engines: {node: ^20.19.0 || >=22.12.0} - '@babel/helper-simple-access@7.22.5': - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} - '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} + '@changesets/apply-release-plan@7.1.1': + resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==} - '@babel/helper-string-parser@7.22.5': - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} - engines: {node: '>=6.9.0'} + '@changesets/assemble-release-plan@6.0.10': + resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==} - '@babel/helper-validator-identifier@7.22.5': - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} - engines: {node: '>=6.9.0'} + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@babel/helper-validator-option@7.22.5': - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} - engines: {node: '>=6.9.0'} + '@changesets/cli@2.31.0': + resolution: {integrity: sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==} + hasBin: true - '@babel/helpers@7.22.10': - resolution: {integrity: sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==} - engines: {node: '>=6.9.0'} + '@changesets/config@3.1.4': + resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==} - '@babel/highlight@7.22.10': - resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} - engines: {node: '>=6.9.0'} + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - '@babel/parser@7.22.10': - resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} - engines: {node: '>=6.0.0'} + '@changesets/get-dependents-graph@2.1.4': + resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==} + + '@changesets/get-release-plan@4.0.16': + resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@commitlint/cli@20.5.3': + resolution: {integrity: sha512-OJdL0EXWD5y9LPa0nr/geOwzaS8BsdaybKkcloB0JgsguGxNv2R+hC2FTPqrAcprg35zF33KOQerY0x8W1aesA==} + engines: {node: '>=v18'} hasBin: true - '@babel/plugin-transform-react-jsx-self@7.22.5': - resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} - engines: {node: '>=6.9.0'} + '@commitlint/config-conventional@20.5.3': + resolution: {integrity: sha512-j34Qqeaa152chJgz2ysyk0BCpHenJn1lV0Rx0VXf8k3ccQcED+48EZrzMvo9jLmJUyBrrBwvu89I+2er4gW7QQ==} + engines: {node: '>=v18'} + + '@commitlint/config-validator@20.5.0': + resolution: {integrity: sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==} + engines: {node: '>=v18'} + + '@commitlint/ensure@20.5.3': + resolution: {integrity: sha512-4i4AgNvH62owG9MwSiWKrle7HGNpBHHdLnWFIp5fTsHUYe5kRuh15t08L/0pdbbrRk8JKXQxxN4hZQcn+szkrw==} + engines: {node: '>=v18'} + + '@commitlint/execute-rule@20.0.0': + resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} + engines: {node: '>=v18'} + + '@commitlint/format@20.5.0': + resolution: {integrity: sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==} + engines: {node: '>=v18'} + + '@commitlint/is-ignored@20.5.0': + resolution: {integrity: sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==} + engines: {node: '>=v18'} + + '@commitlint/lint@20.5.3': + resolution: {integrity: sha512-M7JbWBNr2gXKaPc4i/KipsuW1gkDHpj35KPjWtKy3Z+2AQw5wu1gBi1LIO0uoaij67CqY4K8PxPZSGens4evCw==} + engines: {node: '>=v18'} + + '@commitlint/load@20.5.3': + resolution: {integrity: sha512-1FDZWuKyu98Myb8i7Tp31jPU2rZpOwAdYRyJcy2KoGg7Xk2A+bgHN8smhMaaNSNkmE8fwt53BokywZq8Gv/5XQ==} + engines: {node: '>=v18'} + + '@commitlint/message@20.4.3': + resolution: {integrity: sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==} + engines: {node: '>=v18'} + + '@commitlint/parse@20.5.0': + resolution: {integrity: sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==} + engines: {node: '>=v18'} + + '@commitlint/read@20.5.0': + resolution: {integrity: sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==} + engines: {node: '>=v18'} + + '@commitlint/resolve-extends@20.5.3': + resolution: {integrity: sha512-+ogW9v/u9JqpvAgTrLra/YTFo0KkjU6iNblF89pPsj4NebNc+DAWctsludwezI8YnsjBmfHpApSwcXprN/f/ew==} + engines: {node: '>=v18'} + + '@commitlint/rules@20.5.3': + resolution: {integrity: sha512-MPlMnb9D3wbszYMp+1hPtuhtPJndRo6I6yfkZVA4+jR8w7Kqp0u2u/Y+gzbaItx5Lltq5rw7FSZQWJMoXUC4NQ==} + engines: {node: '>=v18'} + + '@commitlint/to-lines@20.0.0': + resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==} + engines: {node: '>=v18'} + + '@commitlint/top-level@20.4.3': + resolution: {integrity: sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==} + engines: {node: '>=v18'} + + '@commitlint/types@20.5.0': + resolution: {integrity: sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==} + engines: {node: '>=v18'} + + '@conventional-changelog/git-client@2.7.0': + resolution: {integrity: sha512-j7A8/LBEQ+3rugMzPXoKYzyUPpw/0CBQCyvtTR7Lmu4olG4yRC/Tfkq79Mr3yuPs0SUitlO2HwGP3gitMJnRFw==} + engines: {node: '>=18'} peerDependencies: - '@babel/core': ^7.0.0-0 + conventional-commits-filter: ^5.0.0 + conventional-commits-parser: ^6.4.0 + peerDependenciesMeta: + conventional-commits-filter: + optional: true + conventional-commits-parser: + optional: true - '@babel/plugin-transform-react-jsx-source@7.22.5': - resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==} - engines: {node: '>=6.9.0'} + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@babel/runtime@7.22.10': - resolution: {integrity: sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==} - engines: {node: '>=6.9.0'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@babel/template@7.22.5': - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} - engines: {node: '>=6.9.0'} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} - '@babel/traverse@7.22.10': - resolution: {integrity: sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==} - engines: {node: '>=6.9.0'} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@babel/types@7.22.10': - resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} - engines: {node: '>=6.9.0'} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@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'} + + '@oxc-project/types@0.127.0': + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + + '@oxfmt/binding-android-arm-eabi@0.47.0': + resolution: {integrity: sha512-KrMQRdMi/upr81qT4ijK6X6BNp6jqpMY7FwILQnwIy9QLc3qpnhUx5rsCLGzn4ewsCQ0CNAspN2ogmP1GXLyLw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] + '@oxfmt/binding-android-arm64@0.47.0': + resolution: {integrity: sha512-r4ixS/PeUpAFKgrpDoZ5pSkthjZzVzKd95525Aazj+aOv9H4ulK5zYHGb7wFY5n5kZxHK8TbOJUZgoEb1ohddQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] os: [android] - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} + '@oxfmt/binding-darwin-arm64@0.47.0': + resolution: {integrity: sha512-CLWxiKpMl+195cm09CuaWEhJK0CirRkoMa07aR9+9AFPat2LfIKtwx1JqxZM0MTvcMe6+adlJNdVL6jdInvq3g==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} + '@oxfmt/binding-darwin-x64@0.47.0': + resolution: {integrity: sha512-Xq5fjTYDC50faUeLSm0rZdBqoTgleXEdD7NpJdARtQIczkCJn3xNjMUSQQkUmh4CtxkKTNL68lytcOK3e/osgg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} + '@oxfmt/binding-freebsd-x64@0.47.0': + resolution: {integrity: sha512-QOU9ZIJ52p5askcEC0QJvvr8trHAWoonul8bgISo6gYUL3s50zkqafBYcNAr9LJZQbsZtPfIWHk9+5+nUp1qJQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] + '@oxfmt/binding-linux-arm-gnueabihf@0.47.0': + resolution: {integrity: sha512-oJxDM1aBhPvz9gmElBv8UpxyiqhwfjcbrSxT5F0xtuUzY6dQI27/AQPIt3eu3Z5Yvn0kQl5R7MA3Z+MbnRvCBw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} + '@oxfmt/binding-linux-arm-musleabihf@0.47.0': + resolution: {integrity: sha512-g8Lh50VS4ibGz2q6v7r9UZY4D0dM16SdrFYOMzhqIoCwGcai8VMIRUAcqn1/jlCsOOzUXJ741+kCeJt0cofakQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] + '@oxfmt/binding-linux-arm64-gnu@0.47.0': + resolution: {integrity: sha512-YrNT1vQ0asaXoRbrvYENPqmBfOQ9Xr8enPNOULeYfg44VjCcrUowFy5QZr+WawE0zyP8cH9e9Gxxg0fDEFzhcg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] os: [linux] + libc: [glibc] - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] + '@oxfmt/binding-linux-arm64-musl@0.47.0': + resolution: {integrity: sha512-IxtQC/sbBi4ubbY+MdwdanRWrG9InQJVZqyMsBa5IUaQcnSg86gQme574HxXMC1p4bo4YhV99zQ+wNnGCvEgzw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] os: [linux] + libc: [musl] - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] + '@oxfmt/binding-linux-ppc64-gnu@0.47.0': + resolution: {integrity: sha512-EWXEhOMbWO0q6eJSbu0QLkU8cKi0ljlYLngeDs2Ocu/pm1rrLwyQiYzlFbdnMRURI4w9ndr1sI9rSbhlJ5o23Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] os: [linux] + libc: [glibc] - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] + '@oxfmt/binding-linux-riscv64-gnu@0.47.0': + resolution: {integrity: sha512-tZrjS11TUiDuEpRaqdk8K9F9xETRyKXfuZKmdeW+Gj7coBnm7+8sBEfyt033EAFEQSlkniAXvBLh+Qja2ioGBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] os: [linux] + libc: [glibc] - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} + '@oxfmt/binding-linux-riscv64-musl@0.47.0': + resolution: {integrity: sha512-KBFy+2CFKUCZzYwX2ZOPQKck1vjQbz+hextuc19G4r0WRJwadfAeuQMQRQvB+Ivc8brlbOVg7et8K7E467440g==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] + libc: [musl] - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} + '@oxfmt/binding-linux-s390x-gnu@0.47.0': + resolution: {integrity: sha512-REUPFKVGSiK99B+9eaPhluEVglzaoj/SMykNC5SUiV2RSsBfV5lWN7Y0iCIc251Wz3GaeAGZsJ/zj3gjarxdFg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} + '@oxfmt/binding-linux-x64-gnu@0.47.0': + resolution: {integrity: sha512-KVftVSVEDeIfRW3TIeLe3aNI/iY4m1fu5mDwHcisKMZSCMKLkrhFsjowC7o9RoqNPxbbglm2+/6KAKBIts2t0Q==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} + '@oxfmt/binding-linux-x64-musl@0.47.0': + resolution: {integrity: sha512-DTsmGEaA2860Aq5VUyDO8/MT9NFxwVL93RnRYmpMwK6DsSkThmvEpqoUDDljziEpAedMRG19SCogrNbINSbLUQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] - os: [openbsd] + os: [linux] + libc: [musl] - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] + '@oxfmt/binding-openharmony-arm64@0.47.0': + resolution: {integrity: sha512-8r5BDro7fLOBoq1JXHLVSs55OlrxQhEso4HVo0TcY7OXJUPYfjPoOaYL5us+yIwqyP9rQwN+rxuiNFSmaxSuOQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} + '@oxfmt/binding-win32-arm64-msvc@0.47.0': + resolution: {integrity: sha512-qtz/gzm8IjSPUlseZ0ofW8zyHLoZsuP5HTfcGGkWkUblB89JT8GNYH3ICqjbDsqsGqXum0/ZndXTFplSdXFIcg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} + '@oxfmt/binding-win32-ia32-msvc@0.47.0': + resolution: {integrity: sha512-5vIcdcIDE7nCx+MXN6sm8kbC4zajDB31E86rez4i45iHNH/2NjdKlJ720xcHTr3eeiMcttCGPHPhE1TjtBDGZw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} + '@oxfmt/binding-win32-x64-msvc@0.47.0': + resolution: {integrity: sha512-Sr59Y5ms54ONBjxFeWhVlGyQcHXxcl9DxC23f6yXlRkcos7LXBLoO+KDfxexjHIOZh7cWqrWduzvUjJ+pHp8cQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@oxlint/binding-android-arm-eabi@1.62.0': + resolution: {integrity: sha512-pKsthNECyvJh8lPTICz6VcwVy2jOqdhhsp1rlxCkhgZR47aKvXPmaRWQDv+zlXpRae4qm1MaaTnutkaOk5aofg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] - '@eslint-community/regexpp@4.6.2': - resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@oxlint/binding-android-arm64@1.62.0': + resolution: {integrity: sha512-b1AUNViByvgmR2xJDubvLIr+dSuu3uraG7bsAoKo+xrpspPvu6RIn6Fhr2JUhobfep3jwUTy18Huco6GkwdvGQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@eslint/eslintrc@2.1.1': - resolution: {integrity: sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@oxlint/binding-darwin-arm64@1.62.0': + resolution: {integrity: sha512-iG+Tvf70UJ6otfwFYIHk36Sjq9cpPP5YLxkoggANNRtzgi3Tj3g8q6Ybqi6AtkU3+yg9QwF7bDCkCS6bbL4PCg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - '@eslint/js@8.44.0': - resolution: {integrity: sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@oxlint/binding-darwin-x64@1.62.0': + resolution: {integrity: sha512-oOWI6YPPr5AJUx+yIDlxmuUbQjS5gZX3OH3QisawYvsZgLiQVvZtR0rPBcJTxLWqt2ClrWg0DlSrlUiG5SQNHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - '@humanwhocodes/config-array@0.11.10': - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead + '@oxlint/binding-freebsd-x64@1.62.0': + resolution: {integrity: sha512-dLP33T7VLCmLVv4cvjkVX+rmkcwNk2UfxmsZPNur/7BQHoQR60zJ7XLiRvNUawlzn0u8ngCa3itjEG73MAMa/w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} + '@oxlint/binding-linux-arm-gnueabihf@1.62.0': + resolution: {integrity: sha512-fl//LWNks6qo9chNY60UDYyIwtp7a5cEx4Y/rHPjaarhuwqx6jtbzEpD5V5AqmdL4a6Y5D8zeXg5HF2Cr0QmSQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@humanwhocodes/object-schema@1.2.1': - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - deprecated: Use @eslint/object-schema instead + '@oxlint/binding-linux-arm-musleabihf@1.62.0': + resolution: {integrity: sha512-i5vkAuxvueTODV3J2dL61/TXewDHhMFKvtD156cIsk7GsdfiAu7zW7kY0NJXhKeFHeiMZIh7eFNjkPYH6J47HQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} + '@oxlint/binding-linux-arm64-gnu@1.62.0': + resolution: {integrity: sha512-QwN19LLuIGuOjEflSeJkZmOTfBdBMlTmW8xbMf8TZhjd//cxVNYQPq75q7oKZBJc6hRx3gY7sX0Egc8cEIFZYg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] - '@jridgewell/resolve-uri@3.1.1': - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} + '@oxlint/binding-linux-arm64-musl@1.62.0': + resolution: {integrity: sha512-8eCy3FCDuWUM5hWujAv6heMvfZPbcCOU3SdQUAkixZLu5bSzOkNfirJiLGoQFO943xceOKkiQRMQNzH++jM3WA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} + '@oxlint/binding-linux-ppc64-gnu@1.62.0': + resolution: {integrity: sha512-NjQ7K7tpTPDe9J+yq8p/s/J0E7lRCkK2uDBDqvT4XIT6f4Z0tlnr59OBg/WcrmVHER1AbrcfyxhGTXgcG8ytWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@oxlint/binding-linux-riscv64-gnu@1.62.0': + resolution: {integrity: sha512-oKZed9gmSwze29dEt3/Wnsv6l/Ygw/FUst+8Kfpv2SGeS/glEoTGZAMQw37SVyzFV76UTHJN2snGgxK2t2+8ow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] - '@jridgewell/trace-mapping@0.3.19': - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + '@oxlint/binding-linux-riscv64-musl@1.62.0': + resolution: {integrity: sha512-gBjBxQ+9lGpAYq+ELqw0w8QXsBnkZclFc7GRX2r0LnEVn3ZTEqeIKpKcGjucmp76Q53bvJD0i4qBWBhcfhSfGA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] - '@microsoft/api-extractor-model@7.27.6': - resolution: {integrity: sha512-eiCnlayyum1f7fS2nA9pfIod5VCNR1G+Tq84V/ijDrKrOFVa598BLw145nCsGDMoFenV6ajNi2PR5WCwpAxW6Q==} + '@oxlint/binding-linux-s390x-gnu@1.62.0': + resolution: {integrity: sha512-Ew2Kxs9EQ9/mbAIJ2hvocMC0wsOu6YKzStI2eFBDt+Td5O8seVC/oxgRIHqCcl5sf5ratA1nozQBAuv7tphkHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] - '@microsoft/api-extractor@7.36.4': - resolution: {integrity: sha512-21UECq8C/8CpHT23yiqTBQ10egKUacIpxkPyYR7hdswo/M5yTWdBvbq+77YC9uPKQJOUfOD1FImBQ1DzpsdeQQ==} - hasBin: true + '@oxlint/binding-linux-x64-gnu@1.62.0': + resolution: {integrity: sha512-5z25jcAA0gfKyVwz71A0VXgaPlocPoTAxhlv/hgoK6tlCrfoNuw7haWbDHvGMfjXhdic4EqVXGRv5XsTqFnbRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] - '@microsoft/tsdoc-config@0.16.2': - resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + '@oxlint/binding-linux-x64-musl@1.62.0': + resolution: {integrity: sha512-IWpHmMB6ZDllPvqWDkG6AmXrN7JF5e/c4g/0PuURsmlK+vHoYZPB70rr4u1bn3I4LsKCSpqqfveyx6UCOC8wdg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] - '@microsoft/tsdoc@0.14.2': - resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + '@oxlint/binding-openharmony-arm64@1.62.0': + resolution: {integrity: sha512-fjlSxxrD5pA594vkyikCS9MnPRjQawW6/BLgyTYkO+73wwPlYjkcZ7LSd974l0Q2zkHQmu4DPvJFLYA7o8xrxQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@oxlint/binding-win32-arm64-msvc@1.62.0': + resolution: {integrity: sha512-EiFXr8loNS0Ul3Gu80+9nr1T8jRmnKocqmHHg16tj5ZqTgUXyb97l2rrspVHdDluyFn9JfR4PoJFdNzw4paHww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + '@oxlint/binding-win32-ia32-msvc@1.62.0': + resolution: {integrity: sha512-IgOFvL73li1bFgab+hThXYA0N2Xms2kV2MvZN95cebV+fmrZ9AVui1JSxfeeqRLo3CpPxKZlzhyq4G0cnaAvIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@oxlint/binding-win32-x64-msvc@1.62.0': + resolution: {integrity: sha512-6hMpyDWQ2zGA1OXFKBrdYMUveUCO8UJhkO6JdwZPd78xIdHZNhjx+pib+4fC2Cljuhjyl0QwA2F3df/bs4Bp6A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] - '@rollup/pluginutils@5.0.2': - resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@quansync/fs@1.0.0': + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} - '@rushstack/node-core-library@3.59.7': - resolution: {integrity: sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true + '@rolldown/binding-android-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@rushstack/rig-package@0.4.1': - resolution: {integrity: sha512-AGRwpqlXNSp9LhUSz4HKI9xCluqQDt/obsQFdv/NYIekF3pTTPzc+HbQsIsjVjYnJ3DcmxOREVMhvrMEjpiq6g==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - '@rushstack/ts-command-line@4.15.2': - resolution: {integrity: sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==} + '@rolldown/binding-darwin-x64@1.0.0-rc.17': + resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - '@types/argparse@1.0.38': - resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - '@types/estree@1.0.1': - resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] - '@types/js-cookie@2.2.7': - resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] - '@types/json-schema@7.0.12': - resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] - '@types/node@20.4.8': - resolution: {integrity: sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] - '@types/prop-types@15.7.5': - resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] - '@types/react-dom@18.2.7': - resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] - '@types/react@18.2.15': - resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==} + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] - '@types/scheduler@0.16.3': - resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] - '@types/semver@7.5.0': - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] - '@typescript-eslint/eslint-plugin@6.0.0': - resolution: {integrity: sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@rolldown/pluginutils@1.0.0-rc.17': + resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} - '@typescript-eslint/parser@6.0.0': - resolution: {integrity: sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@simple-libs/child-process-utils@1.0.2': + resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==} + engines: {node: '>=18'} - '@typescript-eslint/scope-manager@6.0.0': - resolution: {integrity: sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==} - engines: {node: ^16.0.0 || >=18.0.0} + '@simple-libs/stream-utils@1.2.0': + resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} + engines: {node: '>=18'} - '@typescript-eslint/type-utils@6.0.0': - resolution: {integrity: sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@typescript-eslint/types@6.0.0': - resolution: {integrity: sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==} - engines: {node: ^16.0.0 || >=18.0.0} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} - '@typescript-eslint/typescript-estree@6.0.0': - resolution: {integrity: sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==} - engines: {node: ^16.0.0 || >=18.0.0} + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} peerDependencies: - typescript: '*' + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 peerDependenciesMeta: - typescript: + '@types/react': + optional: true + '@types/react-dom': optional: true - '@typescript-eslint/utils@6.0.0': - resolution: {integrity: sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - '@typescript-eslint/visitor-keys@6.0.0': - resolution: {integrity: sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==} - engines: {node: ^16.0.0 || >=18.0.0} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - '@vitejs/plugin-react@4.0.3': - resolution: {integrity: sha512-pwXDog5nwwvSIzwrvYYmA2Ljcd/ZNlcsSG2Q9CNDBwnsd55UGAyr2doXtB5j+2uymRCnCfExlznzzSFbBRcoCg==} - engines: {node: ^14.18.0 || >=16.0.0} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: - vite: ^4.2.0 + '@types/react': ^19.2.0 - '@volar/language-core@1.10.0': - resolution: {integrity: sha512-ddyWwSYqcbEZNFHm+Z3NZd6M7Ihjcwl/9B5cZd8kECdimVXUFdFi60XHWD27nrWtUQIsUYIG7Ca1WBwV2u2LSQ==} + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} - '@volar/source-map@1.10.0': - resolution: {integrity: sha512-/ibWdcOzDGiq/GM1JU2eX8fH1bvAhl66hfe8yEgLEzg9txgr6qb5sQ/DEz5PcDL75tF5H5sCRRwn8Eu8ezi9mw==} + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} - '@volar/typescript@1.10.0': - resolution: {integrity: sha512-OtqGtFbUKYC0pLNIk3mHQp5xWnvL1CJIUc9VE39VdZ/oqpoBh5jKfb9uJ45Y4/oP/WYTrif/Uxl1k8VTPz66Gg==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@vue/compiler-core@3.3.4': - resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} + '@vitest/coverage-v8@4.1.5': + resolution: {integrity: sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==} + peerDependencies: + '@vitest/browser': 4.1.5 + vitest: 4.1.5 + peerDependenciesMeta: + '@vitest/browser': + optional: true - '@vue/compiler-dom@3.3.4': - resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} + '@vitest/expect@4.1.5': + resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==} - '@vue/language-core@1.8.8': - resolution: {integrity: sha512-i4KMTuPazf48yMdYoebTkgSOJdFraE4pQf0B+FTOFkbB+6hAfjrSou/UmYWRsWyZV6r4Rc6DDZdI39CJwL0rWw==} + '@vitest/mocker@4.1.5': + resolution: {integrity: sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==} peerDependencies: - typescript: '*' + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: - typescript: + msw: + optional: true + vite: optional: true - '@vue/reactivity@3.3.4': - resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} + '@vitest/pretty-format@4.1.5': + resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==} - '@vue/shared@3.3.4': - resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} + '@vitest/runner@4.1.5': + resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==} - '@vue/typescript@1.8.8': - resolution: {integrity: sha512-jUnmMB6egu5wl342eaUH236v8tdcEPXXkPgj+eI/F6JwW/lb+yAU6U07ZbQ3MVabZRlupIlPESB7ajgAGixhow==} + '@vitest/snapshot@4.1.5': + resolution: {integrity: sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==} - '@xobotyi/scrollbar-width@1.9.5': - resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} + '@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.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} - engines: {node: '>=0.4.0'} - hasBin: true + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + ast-kit@3.0.0-beta.1: + resolution: {integrity: sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==} + engines: {node: '>=20.19.0'} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + ast-v8-to-istanbul@1.0.0: + resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + birpc@4.0.0: + resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.21.10: - resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001519: - resolution: {integrity: sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colors@1.2.5: - resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==} - engines: {node: '>=0.1.90'} + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + + conventional-changelog-angular@8.3.1: + resolution: {integrity: sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==} + engines: {node: '>=18'} - commander@9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} + conventional-changelog-conventionalcommits@9.3.1: + resolution: {integrity: sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==} + engines: {node: '>=18'} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + conventional-commits-parser@6.4.0: + resolution: {integrity: sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==} + engines: {node: '>=18'} + hasBin: true + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + cosmiconfig-typescript-loader@6.3.0: + resolution: {integrity: sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==} + engines: {node: '>=v18'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=9' + typescript: '>=5' - copy-to-clipboard@3.3.3: - resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + cosmiconfig@9.0.1: + resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - css-in-js-utils@3.1.0: - resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - css-tree@1.1.3: - resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} - engines: {node: '>=8.0.0'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - csstype@3.1.2: - resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} - de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - electron-to-chromium@1.4.488: - resolution: {integrity: sha512-Dv4sTjiW7t/UWGL+H8ZkgIjtUAVZDgb/PwGWvMsCT7jipzUV/u5skbLXPFKb6iV0tiddVi/bcS2/kUrczeWgIQ==} - - error-stack-parser@2.1.4: - resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} - - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - - escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} - eslint-plugin-react-hooks@4.6.0: - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} + dts-resolver@2.1.3: + resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} + engines: {node: '>=20.19.0'} peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true - eslint-plugin-react-refresh@0.4.3: - resolution: {integrity: sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==} - peerDependencies: - eslint: '>=7' + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} - eslint-visitor-keys@3.4.2: - resolution: {integrity: sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} - eslint@8.45.0: - resolution: {integrity: sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + es-toolkit@1.46.1: + resolution: {integrity: sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==} - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + 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'} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + 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==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fast-shallow-equal@1.0.0: - resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - fastest-stable-stringify@2.0.2: - resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} - - fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + 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'} - - flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - - flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + + git-raw-commits@5.0.1: + resolution: {integrity: sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==} + engines: {node: '>=18'} + hasBin: true 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@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - - globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} - engines: {node: '>=8'} + global-directory@5.0.0: + resolution: {integrity: sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w==} + engines: {node: '>=20'} globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} @@ -966,64 +1138,67 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + happy-dom@20.9.0: + resolution: {integrity: sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==} + engines: {node: '>=20.0.0'} has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true - hyphenate-style-name@1.0.4: - resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} + husky@9.1.7: + resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} + engines: {node: '>=18'} + hasBin: true - ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-lazy@4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + import-without-cache@0.3.3: + resolution: {integrity: sha512-bDxwDdF04gm550DfZHgffvlX+9kUlcz32UD0AeBTmVPFiWkrexF2XVmiuFFbDhiFuP8fQkrkvI2KdSNPYWAXkQ==} + engines: {node: '>=20.19.0'} - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} - inline-style-prefixer@7.0.1: - resolution: {integrity: sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==} + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} - is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 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-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1032,113 +1207,192 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - jju@1.4.0: - resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} - js-cookie@2.2.1: - resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - 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==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} hasBin: true + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] - lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - mdn-data@2.0.14: - resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} - muggle-string@0.3.1: - resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - nano-css@5.6.2: - resolution: {integrity: sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==} - peerDependencies: - react: '*' - react-dom: '*' + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} - nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1147,162 +1401,191 @@ packages: engines: {node: ^18 || >=20} hasBin: true - natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + oxfmt@0.47.0: + resolution: {integrity: sha512-OFbkbzxKCpooQEnRmpTDnuwTX8KHXzZTQ4Df/hz85fpS67Pl+lxPEFvUtin56HIIS0B1k4X8oIzTXRZPufA2CA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + oxlint@1.62.0: + resolution: {integrity: sha512-1uFkg6HakjsGIpW9wNdeW4/2LOHW9MEkoWjZUTUfQtIHyLIZPYt00w3Sg+H3lH+206FgBPHBbW5dVE5l2ExECQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + oxlint-tsgolint: '>=0.18.0' + peerDependenciesMeta: + oxlint-tsgolint: + optional: true - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} - node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} - optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - postcss@8.4.27: - resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} - engines: {node: ^10 || ^12 || >=14} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} - prettier@3.0.1: - resolution: {integrity: sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==} - engines: {node: '>=14'} + postcss@8.5.13: + resolution: {integrity: sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==} + engines: {node: ^10 || ^12 || >=14} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} hasBin: true - punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} - engines: {node: '>=6'} + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - react-dom@18.2.0: - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + react-dom@19.2.5: + resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} peerDependencies: - react: ^18.2.0 + react: ^19.2.5 - react-refresh@0.14.0: - resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react@19.2.5: + resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} engines: {node: '>=0.10.0'} - react-universal-interface@0.6.2: - resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} - peerDependencies: - react: '*' - tslib: '*' + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} - react-use@17.6.0: - resolution: {integrity: sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==} - peerDependencies: - react: '*' - react-dom: '*' + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} - react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - regenerator-runtime@0.14.0: - resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} - - resize-observer-polyfill@1.5.1: - resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - resolve@1.19.0: - resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} - resolve@1.22.4: - resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} - hasBin: true + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true + rolldown-plugin-dts@0.23.2: + resolution: {integrity: sha512-PbSqLawLgZBGcOGT3yqWBGn4cX+wh2nt5FuBGdcMHyOhoukmjbhYAl8NT9sE4U38Cm9tqLOIQeOrvzeayM0DLQ==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@ts-macro/tsc': ^0.3.6 + '@typescript/native-preview': '>=7.0.0-dev.20260325.1' + rolldown: ^1.0.0-rc.12 + typescript: ^5.0.0 || ^6.0.0 + vue-tsc: ~3.2.0 + peerDependenciesMeta: + '@ts-macro/tsc': + optional: true + '@typescript/native-preview': + optional: true + typescript: + optional: true + vue-tsc: + optional: true - rollup@3.27.2: - resolution: {integrity: sha512-YGwmHf7h2oUHkVBT248x0yt6vZkYQ3/rvE5iQuVBh3WO8GcJ6BNeOkpoX1yMHIiBm18EMLjBPIoUDkhgnyxGOQ==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + rolldown@1.0.0-rc.17: + resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rtl-css-js@1.16.1: - resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - screenfull@5.2.0: - resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} - engines: {node: '>=0.10.0'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true - set-harmonic-interval@1.0.1: - resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} - engines: {node: '>=6.9'} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1311,93 +1594,114 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - - source-map@0.5.6: - resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - stack-generator@2.0.10: - resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} - - stackframe@1.3.4: - resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} - - stacktrace-gps@3.1.2: - resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - stacktrace-js@2.0.2: - resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} + 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'} strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - stylis@4.3.0: - resolution: {integrity: sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==} - - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - throttle-debounce@3.0.1: - resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} - engines: {node: '>=10'} + tinyexec@1.1.2: + resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} + engines: {node: '>=18'} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + tinypool@2.1.0: + resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} + engines: {node: ^20.0.0 || >=22.0.0} + + 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'} - toggle-selection@1.0.6: - resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true - ts-api-utils@1.0.1: - resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} - engines: {node: '>=16.13.0'} + tsdown@0.21.10: + resolution: {integrity: sha512-3wk73yBhZe/wX7REqSdivNQ84TDs1mJ+IlnzrrEREP70xlJ/AEIzqaI04l/TzMKVIdkTdC3CPaADn2Lk/0SkdA==} + engines: {node: '>=20.19.0'} + hasBin: true peerDependencies: - typescript: '>=4.2.0' - - ts-easing@0.2.0: - resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} + '@arethetypeswrong/core': ^0.18.1 + '@tsdown/css': 0.21.10 + '@tsdown/exe': 0.21.10 + '@vitejs/devtools': '*' + publint: ^0.3.0 + typescript: ^5.0.0 || ^6.0.0 + unplugin-unused: ^0.5.0 + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + '@tsdown/css': + optional: true + '@tsdown/exe': + optional: true + '@vitejs/devtools': + optional: true + publint: + optional: true + typescript: + optional: true + unplugin-unused: + optional: true - tslib@2.6.1: - resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} turbo-darwin-64@2.5.6: resolution: {integrity: sha512-3C1xEdo4aFwMJAPvtlPqz1Sw/+cddWIOmsalHFMrsqqydcptwBfu26WW2cDm3u93bUzMbBJ8k3zNKFqxJ9ei2A==} @@ -1433,1268 +1737,1493 @@ packages: resolution: {integrity: sha512-gxToHmi9oTBNB05UjUsrWf0OyN5ZXtD0apOarC1KIx232Vp3WimRNy3810QzeNSgyD5rsaIDXlxlbnOzlouo+w==} hasBin: true - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - type-fest@4.37.0: - resolution: {integrity: sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==} - engines: {node: '>=16'} - - typescript@5.0.4: - resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} - engines: {node: '>=12.20'} - hasBin: true - - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - update-browserslist-db@1.0.11: - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + unrun@0.2.37: + resolution: {integrity: sha512-AA7vDuYsgeSYVzJMm16UKA+aXFKhy7nFqW9z5l7q44K4ppFWZAMqYS58ePRZbugMLPH0fwwMzD5A8nP0avxwZQ==} + engines: {node: '>=20.19.0'} hasBin: true peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - validator@13.11.0: - resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} - engines: {node: '>= 0.10'} - - vite-plugin-dts@3.5.1: - resolution: {integrity: sha512-wrrIvRTWq9xL0HKOUvJyJ+wivEoLsZ2GU2I2000v5tAAUtu9gE+5OUmUJ9yNkmyYz3tSPedkkiXHeb5jnnSXhg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - typescript: '*' - vite: '*' + synckit: ^0.11.11 peerDependenciesMeta: - vite: + synckit: optional: true - vite@4.4.5: - resolution: {integrity: sha512-4m5kEtAWHYr0O1Fu7rZp64CfO1PsRGZlD3TAB32UmQlpd7qg15VF7ROqGN5CyqN7HFuwr7ICNM2+fDWRqFEKaA==} - engines: {node: ^14.18.0 || >=16.0.0} + vite@8.0.10: + resolution: {integrity: sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': '>= 14' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true - less: + '@vitejs/devtools': + optional: true + esbuild: optional: true - lightningcss: + jiti: + optional: true + less: optional: true sass: optional: true + sass-embedded: + optional: true stylus: optional: true sugarss: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true - vue-template-compiler@2.7.14: - resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} - - vue-tsc@1.8.8: - resolution: {integrity: sha512-bSydNFQsF7AMvwWsRXD7cBIXaNs/KSjvzWLymq/UtKE36697sboX4EccSHFVxvgdBlI1frYPc/VMKJNB7DFeDQ==} + 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: - typescript: '*' + '@edge-runtime/vm': '*' + '@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 + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - z-schema@5.0.5: - resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} - engines: {node: '>=8.0.0'} - hasBin: true + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} - zod@3.24.2: - resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} snapshots: - '@aashutoshrathi/word-wrap@1.2.6': {} + '@adobe/css-tools@4.4.4': {} - '@ampproject/remapping@2.2.1': + '@babel/code-frame@7.29.0': dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 - '@babel/code-frame@7.22.10': + '@babel/generator@8.0.0-rc.3': dependencies: - '@babel/highlight': 7.22.10 - chalk: 2.4.2 + '@babel/parser': 8.0.0-rc.3 + '@babel/types': 8.0.0-rc.3 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 - '@babel/compat-data@7.22.9': {} + '@babel/helper-string-parser@7.27.1': {} - '@babel/core@7.22.10': + '@babel/helper-string-parser@8.0.0-rc.4': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-identifier@8.0.0-rc.3': {} + + '@babel/parser@7.29.3': dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helpers': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + '@babel/types': 7.29.0 + + '@babel/parser@8.0.0-rc.3': + dependencies: + '@babel/types': 8.0.0-rc.3 + + '@babel/runtime@7.29.2': {} + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@babel/types@8.0.0-rc.3': + dependencies: + '@babel/helper-string-parser': 8.0.0-rc.4 + '@babel/helper-validator-identifier': 8.0.0-rc.3 + + '@bcoe/v8-coverage@1.0.2': {} - '@babel/generator@7.22.10': + '@changesets/apply-release-plan@7.1.1': dependencies: - '@babel/types': 7.22.10 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 + '@changesets/config': 3.1.4 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.4 + + '@changesets/assemble-release-plan@6.0.10': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.4 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.31.0(@types/node@25.6.0)': + dependencies: + '@changesets/apply-release-plan': 7.1.1 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.4 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/get-release-plan': 4.0.16 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@25.6.0) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' - '@babel/helper-compilation-targets@7.22.10': + '@changesets/config@3.1.4': dependencies: - '@babel/compat-data': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.10 - lru-cache: 5.1.1 - semver: 6.3.1 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 - '@babel/helper-environment-visitor@7.22.5': {} + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 - '@babel/helper-function-name@7.22.5': + '@changesets/get-dependents-graph@2.1.4': dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.10 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.4 - '@babel/helper-hoist-variables@7.22.5': + '@changesets/get-release-plan@4.0.16': dependencies: - '@babel/types': 7.22.10 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/config': 3.1.4 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 - '@babel/helper-module-imports@7.22.5': + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': dependencies: - '@babel/types': 7.22.10 + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 - '@babel/helper-module-transforms@7.22.9(@babel/core@7.22.10)': + '@changesets/logger@0.1.1': dependencies: - '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.5 + picocolors: 1.1.1 - '@babel/helper-plugin-utils@7.22.5': {} + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.1.1 - '@babel/helper-simple-access@7.22.5': + '@changesets/pre@2.0.2': dependencies: - '@babel/types': 7.22.10 + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 - '@babel/helper-split-export-declaration@7.22.6': + '@changesets/read@0.6.7': dependencies: - '@babel/types': 7.22.10 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 - '@babel/helper-string-parser@7.22.5': {} + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 - '@babel/helper-validator-identifier@7.22.5': {} + '@changesets/types@4.1.0': {} - '@babel/helper-validator-option@7.22.5': {} + '@changesets/types@6.1.0': {} - '@babel/helpers@7.22.10': + '@changesets/write@0.4.0': dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.3 + prettier: 2.8.8 + + '@commitlint/cli@20.5.3(@types/node@25.6.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3)': + dependencies: + '@commitlint/format': 20.5.0 + '@commitlint/lint': 20.5.3 + '@commitlint/load': 20.5.3(@types/node@25.6.0)(typescript@6.0.3) + '@commitlint/read': 20.5.0(conventional-commits-parser@6.4.0) + '@commitlint/types': 20.5.0 + tinyexec: 1.1.2 + yargs: 17.7.2 transitivePeerDependencies: - - supports-color + - '@types/node' + - conventional-commits-filter + - conventional-commits-parser + - typescript - '@babel/highlight@7.22.10': + '@commitlint/config-conventional@20.5.3': dependencies: - '@babel/helper-validator-identifier': 7.22.5 - chalk: 2.4.2 - js-tokens: 4.0.0 + '@commitlint/types': 20.5.0 + conventional-changelog-conventionalcommits: 9.3.1 + + '@commitlint/config-validator@20.5.0': + dependencies: + '@commitlint/types': 20.5.0 + ajv: 8.20.0 + + '@commitlint/ensure@20.5.3': + dependencies: + '@commitlint/types': 20.5.0 + es-toolkit: 1.46.1 + + '@commitlint/execute-rule@20.0.0': {} - '@babel/parser@7.22.10': + '@commitlint/format@20.5.0': dependencies: - '@babel/types': 7.22.10 + '@commitlint/types': 20.5.0 + picocolors: 1.1.1 - '@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.22.10)': + '@commitlint/is-ignored@20.5.0': dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@commitlint/types': 20.5.0 + semver: 7.7.4 - '@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.22.10)': + '@commitlint/lint@20.5.3': dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@commitlint/is-ignored': 20.5.0 + '@commitlint/parse': 20.5.0 + '@commitlint/rules': 20.5.3 + '@commitlint/types': 20.5.0 - '@babel/runtime@7.22.10': + '@commitlint/load@20.5.3(@types/node@25.6.0)(typescript@6.0.3)': dependencies: - regenerator-runtime: 0.14.0 + '@commitlint/config-validator': 20.5.0 + '@commitlint/execute-rule': 20.0.0 + '@commitlint/resolve-extends': 20.5.3 + '@commitlint/types': 20.5.0 + cosmiconfig: 9.0.1(typescript@6.0.3) + cosmiconfig-typescript-loader: 6.3.0(@types/node@25.6.0)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3) + es-toolkit: 1.46.1 + is-plain-obj: 4.1.0 + picocolors: 1.1.1 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/message@20.4.3': {} - '@babel/template@7.22.5': + '@commitlint/parse@20.5.0': dependencies: - '@babel/code-frame': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 + '@commitlint/types': 20.5.0 + conventional-changelog-angular: 8.3.1 + conventional-commits-parser: 6.4.0 - '@babel/traverse@7.22.10': + '@commitlint/read@20.5.0(conventional-commits-parser@6.4.0)': dependencies: - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 - debug: 4.3.4 - globals: 11.12.0 + '@commitlint/top-level': 20.4.3 + '@commitlint/types': 20.5.0 + git-raw-commits: 5.0.1(conventional-commits-parser@6.4.0) + minimist: 1.2.8 + tinyexec: 1.1.2 transitivePeerDependencies: - - supports-color + - conventional-commits-filter + - conventional-commits-parser + + '@commitlint/resolve-extends@20.5.3': + dependencies: + '@commitlint/config-validator': 20.5.0 + '@commitlint/types': 20.5.0 + es-toolkit: 1.46.1 + global-directory: 5.0.0 + import-meta-resolve: 4.2.0 + resolve-from: 5.0.0 + + '@commitlint/rules@20.5.3': + dependencies: + '@commitlint/ensure': 20.5.3 + '@commitlint/message': 20.4.3 + '@commitlint/to-lines': 20.0.0 + '@commitlint/types': 20.5.0 + + '@commitlint/to-lines@20.0.0': {} + + '@commitlint/top-level@20.4.3': + dependencies: + escalade: 3.2.0 + + '@commitlint/types@20.5.0': + dependencies: + conventional-commits-parser: 6.4.0 + picocolors: 1.1.1 + + '@conventional-changelog/git-client@2.7.0(conventional-commits-parser@6.4.0)': + dependencies: + '@simple-libs/child-process-utils': 1.0.2 + '@simple-libs/stream-utils': 1.2.0 + semver: 7.7.4 + optionalDependencies: + conventional-commits-parser: 6.4.0 + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@inquirer/external-editor@1.0.3(@types/node@25.6.0)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 25.6.0 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.29.2 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.29.2 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} - '@babel/types@7.22.10': + '@nodelib/fs.walk@1.2.8': dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@oxc-project/types@0.127.0': {} + + '@oxfmt/binding-android-arm-eabi@0.47.0': + optional: true + + '@oxfmt/binding-android-arm64@0.47.0': + optional: true + + '@oxfmt/binding-darwin-arm64@0.47.0': + optional: true + + '@oxfmt/binding-darwin-x64@0.47.0': + optional: true + + '@oxfmt/binding-freebsd-x64@0.47.0': + optional: true + + '@oxfmt/binding-linux-arm-gnueabihf@0.47.0': + optional: true + + '@oxfmt/binding-linux-arm-musleabihf@0.47.0': + optional: true + + '@oxfmt/binding-linux-arm64-gnu@0.47.0': + optional: true + + '@oxfmt/binding-linux-arm64-musl@0.47.0': + optional: true + + '@oxfmt/binding-linux-ppc64-gnu@0.47.0': + optional: true + + '@oxfmt/binding-linux-riscv64-gnu@0.47.0': + optional: true + + '@oxfmt/binding-linux-riscv64-musl@0.47.0': + optional: true - '@esbuild/android-arm64@0.18.20': + '@oxfmt/binding-linux-s390x-gnu@0.47.0': optional: true - '@esbuild/android-arm@0.18.20': + '@oxfmt/binding-linux-x64-gnu@0.47.0': optional: true - '@esbuild/android-x64@0.18.20': + '@oxfmt/binding-linux-x64-musl@0.47.0': optional: true - '@esbuild/darwin-arm64@0.18.20': + '@oxfmt/binding-openharmony-arm64@0.47.0': optional: true - '@esbuild/darwin-x64@0.18.20': + '@oxfmt/binding-win32-arm64-msvc@0.47.0': optional: true - '@esbuild/freebsd-arm64@0.18.20': + '@oxfmt/binding-win32-ia32-msvc@0.47.0': optional: true - '@esbuild/freebsd-x64@0.18.20': + '@oxfmt/binding-win32-x64-msvc@0.47.0': optional: true - '@esbuild/linux-arm64@0.18.20': + '@oxlint/binding-android-arm-eabi@1.62.0': optional: true - '@esbuild/linux-arm@0.18.20': + '@oxlint/binding-android-arm64@1.62.0': optional: true - '@esbuild/linux-ia32@0.18.20': + '@oxlint/binding-darwin-arm64@1.62.0': optional: true - '@esbuild/linux-loong64@0.18.20': + '@oxlint/binding-darwin-x64@1.62.0': optional: true - '@esbuild/linux-mips64el@0.18.20': + '@oxlint/binding-freebsd-x64@1.62.0': optional: true - '@esbuild/linux-ppc64@0.18.20': + '@oxlint/binding-linux-arm-gnueabihf@1.62.0': optional: true - '@esbuild/linux-riscv64@0.18.20': + '@oxlint/binding-linux-arm-musleabihf@1.62.0': optional: true - '@esbuild/linux-s390x@0.18.20': + '@oxlint/binding-linux-arm64-gnu@1.62.0': optional: true - '@esbuild/linux-x64@0.18.20': + '@oxlint/binding-linux-arm64-musl@1.62.0': optional: true - '@esbuild/netbsd-x64@0.18.20': + '@oxlint/binding-linux-ppc64-gnu@1.62.0': optional: true - '@esbuild/openbsd-x64@0.18.20': + '@oxlint/binding-linux-riscv64-gnu@1.62.0': optional: true - '@esbuild/sunos-x64@0.18.20': + '@oxlint/binding-linux-riscv64-musl@1.62.0': optional: true - '@esbuild/win32-arm64@0.18.20': + '@oxlint/binding-linux-s390x-gnu@1.62.0': optional: true - '@esbuild/win32-ia32@0.18.20': + '@oxlint/binding-linux-x64-gnu@1.62.0': optional: true - '@esbuild/win32-x64@0.18.20': + '@oxlint/binding-linux-x64-musl@1.62.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.45.0)': - dependencies: - eslint: 8.45.0 - eslint-visitor-keys: 3.4.2 + '@oxlint/binding-openharmony-arm64@1.62.0': + optional: true - '@eslint-community/regexpp@4.6.2': {} + '@oxlint/binding-win32-arm64-msvc@1.62.0': + optional: true - '@eslint/eslintrc@2.1.1': - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color + '@oxlint/binding-win32-ia32-msvc@1.62.0': + optional: true - '@eslint/js@8.44.0': {} + '@oxlint/binding-win32-x64-msvc@1.62.0': + optional: true - '@humanwhocodes/config-array@0.11.10': + '@quansync/fs@1.0.0': dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + quansync: 1.0.0 - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/object-schema@1.2.1': {} + '@rolldown/binding-android-arm64@1.0.0-rc.17': + optional: true - '@jridgewell/gen-mapping@0.3.3': - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + optional: true - '@jridgewell/resolve-uri@3.1.1': {} + '@rolldown/binding-darwin-x64@1.0.0-rc.17': + optional: true - '@jridgewell/set-array@1.1.2': {} + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + optional: true - '@jridgewell/sourcemap-codec@1.4.15': {} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + optional: true - '@jridgewell/trace-mapping@0.3.19': - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + optional: true - '@microsoft/api-extractor-model@7.27.6(@types/node@20.4.8)': - dependencies: - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.7(@types/node@20.4.8) - transitivePeerDependencies: - - '@types/node' + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + optional: true - '@microsoft/api-extractor@7.36.4(@types/node@20.4.8)': - dependencies: - '@microsoft/api-extractor-model': 7.27.6(@types/node@20.4.8) - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.7(@types/node@20.4.8) - '@rushstack/rig-package': 0.4.1 - '@rushstack/ts-command-line': 4.15.2 - colors: 1.2.5 - lodash: 4.17.21 - resolve: 1.22.4 - semver: 7.5.4 - source-map: 0.6.1 - typescript: 5.0.4 - transitivePeerDependencies: - - '@types/node' + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + optional: true - '@microsoft/tsdoc-config@0.16.2': - dependencies: - '@microsoft/tsdoc': 0.14.2 - ajv: 6.12.6 - jju: 1.4.0 - resolve: 1.19.0 + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + optional: true - '@microsoft/tsdoc@0.14.2': {} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + optional: true - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + optional: true - '@nodelib/fs.stat@2.0.5': {} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + optional: true - '@nodelib/fs.walk@1.2.8': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true - '@rollup/pluginutils@5.0.2(rollup@3.27.2)': - dependencies: - '@types/estree': 1.0.1 - estree-walker: 2.0.2 - picomatch: 2.3.1 - optionalDependencies: - rollup: 3.27.2 + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + optional: true - '@rushstack/node-core-library@3.59.7(@types/node@20.4.8)': - dependencies: - colors: 1.2.5 - fs-extra: 7.0.1 - import-lazy: 4.0.0 - jju: 1.4.0 - resolve: 1.22.4 - semver: 7.5.4 - z-schema: 5.0.5 - optionalDependencies: - '@types/node': 20.4.8 + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + optional: true - '@rushstack/rig-package@0.4.1': - dependencies: - resolve: 1.22.4 - strip-json-comments: 3.1.1 + '@rolldown/pluginutils@1.0.0-rc.17': {} - '@rushstack/ts-command-line@4.15.2': + '@simple-libs/child-process-utils@1.0.2': dependencies: - '@types/argparse': 1.0.38 - argparse: 1.0.10 - colors: 1.2.5 - string-argv: 0.3.2 - - '@types/argparse@1.0.38': {} - - '@types/estree@1.0.1': {} + '@simple-libs/stream-utils': 1.2.0 - '@types/js-cookie@2.2.7': {} + '@simple-libs/stream-utils@1.2.0': {} - '@types/json-schema@7.0.12': {} + '@standard-schema/spec@1.1.0': {} - '@types/node@20.4.8': {} - - '@types/prop-types@15.7.5': {} - - '@types/react-dom@18.2.7': + '@testing-library/dom@10.4.1': dependencies: - '@types/react': 18.2.15 + '@babel/code-frame': 7.29.0 + '@babel/runtime': 7.29.2 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 - '@types/react@18.2.15': + '@testing-library/jest-dom@6.9.1': dependencies: - '@types/prop-types': 15.7.5 - '@types/scheduler': 0.16.3 - csstype: 3.1.2 - - '@types/scheduler@0.16.3': {} - - '@types/semver@7.5.0': {} + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 - '@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0(eslint@8.45.0)(typescript@5.8.2))(eslint@8.45.0)(typescript@5.8.2)': + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: - '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.8.2) - '@typescript-eslint/scope-manager': 6.0.0 - '@typescript-eslint/type-utils': 6.0.0(eslint@8.45.0)(typescript@5.8.2) - '@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 6.0.0 - debug: 4.3.4 - eslint: 8.45.0 - grapheme-splitter: 1.0.4 - graphemer: 1.4.0 - ignore: 5.2.4 - natural-compare: 1.4.0 - natural-compare-lite: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.8.2) + '@babel/runtime': 7.29.2 + '@testing-library/dom': 10.4.1 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) optionalDependencies: - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@typescript-eslint/parser@6.0.0(eslint@8.45.0)(typescript@5.8.2)': + '@tybys/wasm-util@0.10.1': dependencies: - '@typescript-eslint/scope-manager': 6.0.0 - '@typescript-eslint/types': 6.0.0 - '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 6.0.0 - debug: 4.3.4 - eslint: 8.45.0 - optionalDependencies: - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color + tslib: 2.8.1 + optional: true - '@typescript-eslint/scope-manager@6.0.0': - dependencies: - '@typescript-eslint/types': 6.0.0 - '@typescript-eslint/visitor-keys': 6.0.0 + '@types/aria-query@5.0.4': {} - '@typescript-eslint/type-utils@6.0.0(eslint@8.45.0)(typescript@5.8.2)': + '@types/chai@5.2.3': dependencies: - '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.8.2) - '@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.8.2) - debug: 4.3.4 - eslint: 8.45.0 - ts-api-utils: 1.0.1(typescript@5.8.2) - optionalDependencies: - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 - '@typescript-eslint/types@6.0.0': {} + '@types/deep-eql@4.0.2': {} - '@typescript-eslint/typescript-estree@6.0.0(typescript@5.8.2)': - dependencies: - '@typescript-eslint/types': 6.0.0 - '@typescript-eslint/visitor-keys': 6.0.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.8.2) - optionalDependencies: - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@6.0.0(eslint@8.45.0)(typescript@5.8.2)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 6.0.0 - '@typescript-eslint/types': 6.0.0 - '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.8.2) - eslint: 8.45.0 - eslint-scope: 5.1.1 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - - typescript + '@types/estree@1.0.8': {} - '@typescript-eslint/visitor-keys@6.0.0': - dependencies: - '@typescript-eslint/types': 6.0.0 - eslint-visitor-keys: 3.4.2 + '@types/jsesc@2.5.1': {} + + '@types/node@12.20.55': {} - '@vitejs/plugin-react@4.0.3(vite@4.4.5(@types/node@20.4.8))': + '@types/node@25.6.0': dependencies: - '@babel/core': 7.22.10 - '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.10) - react-refresh: 0.14.0 - vite: 4.4.5(@types/node@20.4.8) - transitivePeerDependencies: - - supports-color + undici-types: 7.19.2 - '@volar/language-core@1.10.0': + '@types/react-dom@19.2.3(@types/react@19.2.14)': dependencies: - '@volar/source-map': 1.10.0 + '@types/react': 19.2.14 - '@volar/source-map@1.10.0': + '@types/react@19.2.14': dependencies: - muggle-string: 0.3.1 + csstype: 3.2.3 + + '@types/whatwg-mimetype@3.0.2': {} - '@volar/typescript@1.10.0': + '@types/ws@8.18.1': dependencies: - '@volar/language-core': 1.10.0 + '@types/node': 25.6.0 - '@vue/compiler-core@3.3.4': + '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': dependencies: - '@babel/parser': 7.22.10 - '@vue/shared': 3.3.4 - estree-walker: 2.0.2 - source-map-js: 1.0.2 + '@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 + vitest: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) - '@vue/compiler-dom@3.3.4': + '@vitest/expect@4.1.5': dependencies: - '@vue/compiler-core': 3.3.4 - '@vue/shared': 3.3.4 + '@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 - '@vue/language-core@1.8.8(typescript@5.8.2)': + '@vitest/mocker@4.1.5(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1))': dependencies: - '@volar/language-core': 1.10.0 - '@volar/source-map': 1.10.0 - '@vue/compiler-dom': 3.3.4 - '@vue/reactivity': 3.3.4 - '@vue/shared': 3.3.4 - minimatch: 9.0.3 - muggle-string: 0.3.1 - vue-template-compiler: 2.7.14 + '@vitest/spy': 4.1.5 + estree-walker: 3.0.3 + magic-string: 0.30.21 optionalDependencies: - typescript: 5.8.2 + vite: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) - '@vue/reactivity@3.3.4': + '@vitest/pretty-format@4.1.5': dependencies: - '@vue/shared': 3.3.4 + tinyrainbow: 3.1.0 - '@vue/shared@3.3.4': {} + '@vitest/runner@4.1.5': + dependencies: + '@vitest/utils': 4.1.5 + pathe: 2.0.3 - '@vue/typescript@1.8.8(typescript@5.8.2)': + '@vitest/snapshot@4.1.5': dependencies: - '@volar/typescript': 1.10.0 - '@vue/language-core': 1.8.8(typescript@5.8.2) - transitivePeerDependencies: - - typescript + '@vitest/pretty-format': 4.1.5 + '@vitest/utils': 4.1.5 + magic-string: 0.30.21 + pathe: 2.0.3 - '@xobotyi/scrollbar-width@1.9.5': {} + '@vitest/spy@4.1.5': {} - acorn-jsx@5.3.2(acorn@8.10.0): + '@vitest/utils@4.1.5': dependencies: - acorn: 8.10.0 - - acorn@8.10.0: {} + '@vitest/pretty-format': 4.1.5 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 - ajv@6.12.6: + ajv@8.20.0: 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 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 - ansi-regex@5.0.1: {} + ansi-colors@4.1.3: {} - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 + ansi-regex@5.0.1: {} ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + + ansis@4.2.0: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + array-ify@1.0.0: {} + array-union@2.1.0: {} - balanced-match@1.0.2: {} + assertion-error@2.0.1: {} - brace-expansion@1.1.11: + ast-kit@3.0.0-beta.1: dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 + '@babel/parser': 8.0.0-rc.3 + estree-walker: 3.0.3 + pathe: 2.0.3 - brace-expansion@2.0.1: + ast-v8-to-istanbul@1.0.0: dependencies: - balanced-match: 1.0.2 + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 - braces@3.0.2: + better-path-resolve@1.0.0: dependencies: - fill-range: 7.0.1 + is-windows: 1.0.2 + + birpc@4.0.0: {} - browserslist@4.21.10: + braces@3.0.3: dependencies: - caniuse-lite: 1.0.30001519 - electron-to-chromium: 1.4.488 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.10) + fill-range: 7.1.1 - callsites@3.1.0: {} + cac@7.0.0: {} - caniuse-lite@1.0.30001519: {} + callsites@3.1.0: {} - chalk@2.4.2: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 + chai@6.2.2: {} - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 + chardet@2.1.1: {} - color-convert@1.9.3: + cliui@8.0.1: dependencies: - color-name: 1.1.3 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 color-convert@2.0.1: dependencies: color-name: 1.1.4 - color-name@1.1.3: {} - color-name@1.1.4: {} - colors@1.2.5: {} + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 - commander@9.5.0: - optional: true + conventional-changelog-angular@8.3.1: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-conventionalcommits@9.3.1: + dependencies: + compare-func: 2.0.0 + + conventional-commits-parser@6.4.0: + dependencies: + '@simple-libs/stream-utils': 1.2.0 + meow: 13.2.0 - concat-map@0.0.1: {} + convert-source-map@2.0.0: {} - convert-source-map@1.9.0: {} + cosmiconfig-typescript-loader@6.3.0(@types/node@25.6.0)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3): + dependencies: + '@types/node': 25.6.0 + cosmiconfig: 9.0.1(typescript@6.0.3) + jiti: 2.6.1 + typescript: 6.0.3 - copy-to-clipboard@3.3.3: + cosmiconfig@9.0.1(typescript@6.0.3): dependencies: - toggle-selection: 1.0.6 + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: + typescript: 6.0.3 crelt@1.0.6: {} - cross-spawn@7.0.3: + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - css-in-js-utils@3.1.0: - dependencies: - hyphenate-style-name: 1.0.4 + css.escape@1.5.1: {} - css-tree@1.1.3: - dependencies: - mdn-data: 2.0.14 - source-map: 0.6.1 + csstype@3.2.3: {} - csstype@3.1.2: {} + defu@6.1.7: {} - de-indent@1.0.2: {} + dequal@2.0.3: {} - debug@4.3.4: - dependencies: - ms: 2.1.2 + detect-indent@6.1.0: {} - deep-is@0.1.4: {} + detect-libc@2.1.2: {} dir-glob@3.0.1: dependencies: path-type: 4.0.0 - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} - electron-to-chromium@1.4.488: {} + dom-accessibility-api@0.6.3: {} - error-stack-parser@2.1.4: + dot-prop@5.3.0: dependencies: - stackframe: 1.3.4 - - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 + is-obj: 2.0.0 - escalade@3.1.1: {} + dts-resolver@2.1.3: {} - escape-string-regexp@1.0.5: {} + emoji-regex@8.0.0: {} - escape-string-regexp@4.0.0: {} + empathic@2.0.0: {} - eslint-plugin-react-hooks@4.6.0(eslint@8.45.0): + enquirer@2.4.1: dependencies: - eslint: 8.45.0 + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 - eslint-plugin-react-refresh@0.4.3(eslint@8.45.0): - dependencies: - eslint: 8.45.0 + entities@7.0.1: {} - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 + env-paths@2.2.1: {} - eslint-scope@7.2.2: + error-ex@1.3.4: dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 + is-arrayish: 0.2.1 - eslint-visitor-keys@3.4.2: {} + es-module-lexer@2.1.0: {} - eslint@8.45.0: - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@eslint-community/regexpp': 4.6.2 - '@eslint/eslintrc': 2.1.1 - '@eslint/js': 8.44.0 - '@humanwhocodes/config-array': 0.11.10 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.2 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.20.0 - graphemer: 1.4.0 - ignore: 5.2.4 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color + es-toolkit@1.46.1: {} - espree@9.6.1: - dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.2 + escalade@3.2.0: {} - esquery@1.5.0: - dependencies: - estraverse: 5.3.0 + esprima@4.0.1: {} - esrecurse@4.3.0: + estree-walker@3.0.3: dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} + '@types/estree': 1.0.8 - estree-walker@2.0.2: {} + expect-type@1.3.0: {} - esutils@2.0.3: {} + extendable-error@0.1.7: {} fast-deep-equal@3.1.3: {} - fast-glob@3.3.1: + 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.5 + micromatch: 4.0.8 - fast-json-stable-stringify@2.1.0: {} + fast-uri@3.1.0: {} - fast-levenshtein@2.0.6: {} - - fast-shallow-equal@1.0.0: {} - - fastest-stable-stringify@2.0.2: {} - - fastq@1.15.0: + fastq@1.20.1: dependencies: - reusify: 1.0.4 + reusify: 1.1.0 - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.0.4 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - find-up@5.0.0: + find-up@4.1.0: dependencies: - locate-path: 6.0.0 + locate-path: 5.0.0 path-exists: 4.0.0 - flat-cache@3.0.4: - dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - - flatted@3.2.7: {} - fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 - fs.realpath@1.0.0: {} + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 - fsevents@2.3.2: + fsevents@2.3.3: optional: true - function-bind@1.1.1: {} + get-caller-file@2.0.5: {} - gensync@1.0.0-beta.2: {} - - glob-parent@5.1.2: + get-tsconfig@4.14.0: dependencies: - is-glob: 4.0.3 + resolve-pkg-maps: 1.0.0 - glob-parent@6.0.2: + git-raw-commits@5.0.1(conventional-commits-parser@6.4.0): dependencies: - is-glob: 4.0.3 + '@conventional-changelog/git-client': 2.7.0(conventional-commits-parser@6.4.0) + meow: 13.2.0 + transitivePeerDependencies: + - conventional-commits-filter + - conventional-commits-parser - glob@7.2.3: + glob-parent@5.1.2: dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - globals@11.12.0: {} + is-glob: 4.0.3 - globals@13.20.0: + global-directory@5.0.0: dependencies: - type-fest: 0.20.2 + ini: 6.0.0 globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 + fast-glob: 3.3.3 + ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 graceful-fs@4.2.11: {} - grapheme-splitter@1.0.4: {} + happy-dom@20.9.0: + dependencies: + '@types/node': 25.6.0 + '@types/whatwg-mimetype': 3.0.2 + '@types/ws': 8.18.1 + entities: 7.0.1 + whatwg-mimetype: 3.0.0 + ws: 8.20.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate - graphemer@1.4.0: {} + has-flag@4.0.0: {} - has-flag@3.0.0: {} + hookable@6.1.1: {} - has-flag@4.0.0: {} + html-escaper@2.0.2: {} - has@1.0.3: - dependencies: - function-bind: 1.1.1 + human-id@4.1.3: {} - he@1.2.0: {} + husky@9.1.7: {} - hyphenate-style-name@1.0.4: {} + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 - ignore@5.2.4: {} + ignore@5.3.2: {} - import-fresh@3.3.0: + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - import-lazy@4.0.0: {} + import-meta-resolve@4.2.0: {} - imurmurhash@0.1.4: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 + import-without-cache@0.3.3: {} - inherits@2.0.4: {} + indent-string@4.0.0: {} - inline-style-prefixer@7.0.1: - dependencies: - css-in-js-utils: 3.1.0 + ini@6.0.0: {} - is-core-module@2.13.0: - dependencies: - has: 1.0.3 + is-arrayish@0.2.1: {} is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-number@7.0.0: {} - is-path-inside@3.0.3: {} + is-obj@2.0.0: {} + + is-plain-obj@4.1.0: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} isexe@2.0.0: {} - jju@1.4.0: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jiti@2.6.1: {} - js-cookie@2.2.1: {} + js-tokens@10.0.0: {} js-tokens@4.0.0: {} - js-yaml@4.1.0: + js-yaml@3.14.2: dependencies: - argparse: 2.0.1 + argparse: 1.0.10 + esprima: 4.0.1 - jsesc@2.5.2: {} + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 - json-schema-traverse@0.4.1: {} + jsesc@3.1.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} + json-parse-even-better-errors@2.3.1: {} - json5@2.2.3: {} + json-schema-traverse@1.0.0: {} jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 - kolorist@1.8.0: {} + lightningcss-android-arm64@1.32.0: + optional: true - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 + lightningcss-darwin-arm64@1.32.0: + optional: true - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 + lightningcss-darwin-x64@1.32.0: + optional: true - lodash.get@4.4.2: {} + lightningcss-freebsd-x64@1.32.0: + optional: true - lodash.isequal@4.5.0: {} + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true - lodash.merge@4.6.2: {} + lightningcss-linux-arm64-gnu@1.32.0: + optional: true - lodash@4.17.21: {} + lightningcss-linux-arm64-musl@1.32.0: + optional: true - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true - lru-cache@5.1.1: + lightningcss@1.32.0: dependencies: - yallist: 3.1.1 + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 - lru-cache@6.0.0: + lines-and-columns@1.2.4: {} + + locate-path@5.0.0: dependencies: - yallist: 4.0.0 + p-locate: 4.1.0 - mdn-data@2.0.14: {} + lodash.startcase@4.4.0: {} - merge2@1.4.1: {} + lz-string@1.5.0: {} - micromatch@4.0.5: + magic-string@0.30.21: dependencies: - braces: 3.0.2 - picomatch: 2.3.1 + '@jridgewell/sourcemap-codec': 1.5.5 - minimatch@3.1.2: + magicast@0.5.2: dependencies: - brace-expansion: 1.1.11 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + source-map-js: 1.2.1 - minimatch@9.0.3: + make-dir@4.0.0: dependencies: - brace-expansion: 2.0.1 + semver: 7.7.4 - ms@2.1.2: {} + meow@13.2.0: {} - muggle-string@0.3.1: {} + merge2@1.4.1: {} - nano-css@5.6.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + micromatch@4.0.8: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - css-tree: 1.1.3 - csstype: 3.1.2 - fastest-stable-stringify: 2.0.2 - inline-style-prefixer: 7.0.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - rtl-css-js: 1.16.1 - stacktrace-js: 2.0.2 - stylis: 4.3.0 + braces: 3.0.3 + picomatch: 2.3.2 + + min-indent@1.0.1: {} - nanoid@3.3.6: {} + minimist@1.2.8: {} + + mri@1.2.0: {} + + nanoid@3.3.12: {} nanoid@5.1.5: {} - natural-compare-lite@1.4.0: {} + obug@2.1.1: {} - natural-compare@1.4.0: {} + outdent@0.5.0: {} - node-releases@2.0.13: {} + oxfmt@0.47.0: + dependencies: + tinypool: 2.1.0 + optionalDependencies: + '@oxfmt/binding-android-arm-eabi': 0.47.0 + '@oxfmt/binding-android-arm64': 0.47.0 + '@oxfmt/binding-darwin-arm64': 0.47.0 + '@oxfmt/binding-darwin-x64': 0.47.0 + '@oxfmt/binding-freebsd-x64': 0.47.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.47.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.47.0 + '@oxfmt/binding-linux-arm64-gnu': 0.47.0 + '@oxfmt/binding-linux-arm64-musl': 0.47.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.47.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.47.0 + '@oxfmt/binding-linux-riscv64-musl': 0.47.0 + '@oxfmt/binding-linux-s390x-gnu': 0.47.0 + '@oxfmt/binding-linux-x64-gnu': 0.47.0 + '@oxfmt/binding-linux-x64-musl': 0.47.0 + '@oxfmt/binding-openharmony-arm64': 0.47.0 + '@oxfmt/binding-win32-arm64-msvc': 0.47.0 + '@oxfmt/binding-win32-ia32-msvc': 0.47.0 + '@oxfmt/binding-win32-x64-msvc': 0.47.0 + + oxlint@1.62.0: + optionalDependencies: + '@oxlint/binding-android-arm-eabi': 1.62.0 + '@oxlint/binding-android-arm64': 1.62.0 + '@oxlint/binding-darwin-arm64': 1.62.0 + '@oxlint/binding-darwin-x64': 1.62.0 + '@oxlint/binding-freebsd-x64': 1.62.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.62.0 + '@oxlint/binding-linux-arm-musleabihf': 1.62.0 + '@oxlint/binding-linux-arm64-gnu': 1.62.0 + '@oxlint/binding-linux-arm64-musl': 1.62.0 + '@oxlint/binding-linux-ppc64-gnu': 1.62.0 + '@oxlint/binding-linux-riscv64-gnu': 1.62.0 + '@oxlint/binding-linux-riscv64-musl': 1.62.0 + '@oxlint/binding-linux-s390x-gnu': 1.62.0 + '@oxlint/binding-linux-x64-gnu': 1.62.0 + '@oxlint/binding-linux-x64-musl': 1.62.0 + '@oxlint/binding-openharmony-arm64': 1.62.0 + '@oxlint/binding-win32-arm64-msvc': 1.62.0 + '@oxlint/binding-win32-ia32-msvc': 1.62.0 + '@oxlint/binding-win32-x64-msvc': 1.62.0 - once@1.4.0: + p-filter@2.1.0: dependencies: - wrappy: 1.0.2 + p-map: 2.1.0 - optionator@0.9.3: + p-limit@2.3.0: dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 + p-try: 2.2.0 - p-limit@3.1.0: + p-locate@4.1.0: dependencies: - yocto-queue: 0.1.0 + p-limit: 2.3.0 + + p-map@2.1.0: {} - p-locate@5.0.0: + p-try@2.2.0: {} + + package-manager-detector@0.2.11: dependencies: - p-limit: 3.1.0 + quansync: 0.2.11 parent-module@1.0.1: dependencies: callsites: 3.1.0 - path-exists@4.0.0: {} + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 - path-is-absolute@1.0.1: {} + path-exists@4.0.0: {} path-key@3.1.1: {} - path-parse@1.0.7: {} - path-type@4.0.0: {} - picocolors@1.0.0: {} + pathe@2.0.3: {} + + picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@2.3.2: {} - postcss@8.4.27: + picomatch@4.0.4: {} + + pify@4.0.1: {} + + postcss@8.5.13: dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 - prelude-ls@1.2.1: {} + prettier@2.8.8: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 - prettier@3.0.1: {} + quansync@0.2.11: {} - punycode@2.3.0: {} + quansync@1.0.0: {} queue-microtask@1.2.3: {} - react-dom@18.2.0(react@18.2.0): + react-dom@19.2.5(react@19.2.5): dependencies: - loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 + react: 19.2.5 + scheduler: 0.27.0 - react-refresh@0.14.0: {} + react-is@17.0.2: {} - react-universal-interface@0.6.2(react@18.2.0)(tslib@2.6.1): - dependencies: - react: 18.2.0 - tslib: 2.6.1 + react@19.2.5: {} - react-use@17.6.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + read-yaml-file@1.1.0: dependencies: - '@types/js-cookie': 2.2.7 - '@xobotyi/scrollbar-width': 1.9.5 - copy-to-clipboard: 3.3.3 - fast-deep-equal: 3.1.3 - fast-shallow-equal: 1.0.0 - js-cookie: 2.2.1 - nano-css: 5.6.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-universal-interface: 0.6.2(react@18.2.0)(tslib@2.6.1) - resize-observer-polyfill: 1.5.1 - screenfull: 5.2.0 - set-harmonic-interval: 1.0.1 - throttle-debounce: 3.0.1 - ts-easing: 0.2.0 - tslib: 2.6.1 + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 - react@18.2.0: + redent@3.0.0: dependencies: - loose-envify: 1.4.0 + indent-string: 4.0.0 + strip-indent: 3.0.0 - regenerator-runtime@0.14.0: {} + require-directory@2.1.1: {} - resize-observer-polyfill@1.5.1: {} + require-from-string@2.0.2: {} resolve-from@4.0.0: {} - resolve@1.19.0: - dependencies: - is-core-module: 2.13.0 - path-parse: 1.0.7 + resolve-from@5.0.0: {} - resolve@1.22.4: - dependencies: - is-core-module: 2.13.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 + resolve-pkg-maps@1.0.0: {} - reusify@1.0.4: {} + reusify@1.1.0: {} - rimraf@3.0.2: + rolldown-plugin-dts@0.23.2(rolldown@1.0.0-rc.17)(typescript@6.0.3): dependencies: - glob: 7.2.3 - - rollup@3.27.2: + '@babel/generator': 8.0.0-rc.3 + '@babel/helper-validator-identifier': 8.0.0-rc.3 + '@babel/parser': 8.0.0-rc.3 + '@babel/types': 8.0.0-rc.3 + ast-kit: 3.0.0-beta.1 + birpc: 4.0.0 + dts-resolver: 2.1.3 + get-tsconfig: 4.14.0 + obug: 2.1.1 + picomatch: 4.0.4 + rolldown: 1.0.0-rc.17 optionalDependencies: - fsevents: 2.3.2 + typescript: 6.0.3 + transitivePeerDependencies: + - oxc-resolver - rtl-css-js@1.16.1: + rolldown@1.0.0-rc.17: dependencies: - '@babel/runtime': 7.22.10 + '@oxc-project/types': 0.127.0 + '@rolldown/pluginutils': 1.0.0-rc.17 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-x64': 1.0.0-rc.17 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - scheduler@0.23.0: - dependencies: - loose-envify: 1.4.0 - - screenfull@5.2.0: {} - - semver@6.3.1: {} + safer-buffer@2.1.2: {} - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 + scheduler@0.27.0: {} - set-harmonic-interval@1.0.1: {} + semver@7.7.4: {} shebang-command@2.0.0: dependencies: @@ -2702,72 +3231,95 @@ snapshots: shebang-regex@3.0.0: {} - slash@3.0.0: {} - - source-map-js@1.0.2: {} + siginfo@2.0.0: {} - source-map@0.5.6: {} + signal-exit@4.1.0: {} - source-map@0.6.1: {} + slash@3.0.0: {} - sprintf-js@1.0.3: {} + source-map-js@1.2.1: {} - stack-generator@2.0.10: + spawndamnit@3.0.1: dependencies: - stackframe: 1.3.4 + cross-spawn: 7.0.6 + signal-exit: 4.1.0 - stackframe@1.3.4: {} + sprintf-js@1.0.3: {} - stacktrace-gps@3.1.2: - dependencies: - source-map: 0.5.6 - stackframe: 1.3.4 + stackback@0.0.2: {} - stacktrace-js@2.0.2: - dependencies: - error-stack-parser: 2.1.4 - stack-generator: 2.0.10 - stacktrace-gps: 3.1.2 + 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 strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-json-comments@3.1.1: {} + strip-bom@3.0.0: {} - stylis@4.3.0: {} - - supports-color@5.5.0: + strip-indent@3.0.0: dependencies: - has-flag: 3.0.0 + min-indent: 1.0.1 supports-color@7.2.0: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - - text-table@0.2.0: {} + term-size@2.2.1: {} - throttle-debounce@3.0.1: {} + tinybench@2.9.0: {} - to-fast-properties@2.0.0: {} + tinyexec@1.1.2: {} - 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 - toggle-selection@1.0.6: {} + tinypool@2.1.0: {} - ts-api-utils@1.0.1(typescript@5.8.2): + tinyrainbow@3.1.0: {} + + to-regex-range@5.0.1: dependencies: - typescript: 5.8.2 + is-number: 7.0.0 - ts-easing@0.2.0: {} + tree-kill@1.2.2: {} + + tsdown@0.21.10(typescript@6.0.3): + dependencies: + ansis: 4.2.0 + cac: 7.0.0 + defu: 6.1.7 + empathic: 2.0.0 + hookable: 6.1.1 + import-without-cache: 0.3.3 + obug: 2.1.1 + picomatch: 4.0.4 + rolldown: 1.0.0-rc.17 + rolldown-plugin-dts: 0.23.2(rolldown@1.0.0-rc.17)(typescript@6.0.3) + semver: 7.7.4 + tinyexec: 1.1.2 + tinyglobby: 0.2.16 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + unrun: 0.2.37 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - synckit + - vue-tsc - tslib@2.6.1: {} + tslib@2.8.1: + optional: true turbo-darwin-64@2.5.6: optional: true @@ -2796,87 +3348,91 @@ snapshots: turbo-windows-64: 2.5.6 turbo-windows-arm64: 2.5.6 - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-fest@0.20.2: {} + typescript@6.0.3: {} - type-fest@4.37.0: {} - - typescript@5.0.4: {} + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 - typescript@5.8.2: {} + undici-types@7.19.2: {} universalify@0.1.2: {} - update-browserslist-db@1.0.11(browserslist@4.21.10): + unrun@0.2.37: dependencies: - browserslist: 4.21.10 - escalade: 3.1.1 - picocolors: 1.0.0 + rolldown: 1.0.0-rc.17 - uri-js@4.4.1: + vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1): dependencies: - punycode: 2.3.0 - - validator@13.11.0: {} - - vite-plugin-dts@3.5.1(@types/node@20.4.8)(rollup@3.27.2)(typescript@5.8.2)(vite@4.4.5(@types/node@20.4.8)): - dependencies: - '@microsoft/api-extractor': 7.36.4(@types/node@20.4.8) - '@rollup/pluginutils': 5.0.2(rollup@3.27.2) - '@vue/language-core': 1.8.8(typescript@5.8.2) - debug: 4.3.4 - kolorist: 1.8.0 - typescript: 5.8.2 - vue-tsc: 1.8.8(typescript@5.8.2) + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.13 + rolldown: 1.0.0-rc.17 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 25.6.0 + fsevents: 2.3.3 + jiti: 2.6.1 + + vitest@4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)): + dependencies: + '@vitest/expect': 4.1.5 + '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + '@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.2 + tinyglobby: 0.2.16 + tinyrainbow: 3.1.0 + vite: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + why-is-node-running: 2.3.0 optionalDependencies: - vite: 4.4.5(@types/node@20.4.8) + '@types/node': 25.6.0 + '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) + happy-dom: 20.9.0 transitivePeerDependencies: - - '@types/node' - - rollup - - supports-color + - msw - vite@4.4.5(@types/node@20.4.8): - dependencies: - esbuild: 0.18.20 - postcss: 8.4.27 - rollup: 3.27.2 - optionalDependencies: - '@types/node': 20.4.8 - fsevents: 2.3.2 + whatwg-mimetype@3.0.0: {} - vue-template-compiler@2.7.14: + which@2.0.2: dependencies: - de-indent: 1.0.2 - he: 1.2.0 + isexe: 2.0.0 - vue-tsc@1.8.8(typescript@5.8.2): + why-is-node-running@2.3.0: dependencies: - '@vue/language-core': 1.8.8(typescript@5.8.2) - '@vue/typescript': 1.8.8(typescript@5.8.2) - semver: 7.5.4 - typescript: 5.8.2 + siginfo: 2.0.0 + stackback: 0.0.2 - which@2.0.2: + wrap-ansi@7.0.0: dependencies: - isexe: 2.0.0 - - wrappy@1.0.2: {} + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 - yallist@3.1.1: {} + ws@8.20.0: {} - yallist@4.0.0: {} + y18n@5.0.8: {} - yocto-queue@0.1.0: {} + yargs-parser@21.1.1: {} - z-schema@5.0.5: + yargs@17.7.2: dependencies: - lodash.get: 4.4.2 - lodash.isequal: 4.5.0 - validator: 13.11.0 - optionalDependencies: - commander: 9.5.0 - - zod@3.24.2: {} + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e2f9633..58d9ca3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ +# --- Supply chain security --- ignoreScripts: true minimumReleaseAge: 10080 blockExoticSubdeps: true @@ -6,4 +7,22 @@ onlyBuiltDependencies: [] packages: - 'packages/*' - - 'playground/*' + - 'examples/*' + +catalog: + # Build + typescript: "6.0.3" + tsdown: "0.21.10" + # Test + vitest: "4.1.5" + "@vitest/coverage-v8": "4.1.5" + happy-dom: "20.9.0" + "@testing-library/jest-dom": "6.9.1" + "@testing-library/react": "16.3.2" + # Types + "@types/react": "19.2.14" + "@types/react-dom": "19.2.3" + "@standard-schema/spec": "1.1.0" + # React (dev only) + react: "19.2.5" + react-dom: "19.2.5" diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..b69fc31 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "isolatedModules": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "jsx": "react-jsx", + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "verbatimModuleSyntax": true + } +} diff --git a/turbo.json b/turbo.json index 039a011..356e6e0 100644 --- a/turbo.json +++ b/turbo.json @@ -2,15 +2,29 @@ "$schema": "https://turbo.build/schema.json", "tasks": { "build": { - "dependsOn": [ - "^build" - ], - "outputs": [ - "dist/**", - "build/**" - ] + "dependsOn": ["^build"], + "outputs": ["dist/**"] }, "dev": { + "cache": false, + "persistent": true + }, + "typecheck": { + "dependsOn": ["^build"] + }, + "test": { + "dependsOn": ["^build"] + }, + "test:coverage": { + "dependsOn": ["^build"] + }, + "//#lint": {}, + "//#lint:fix": { + "cache": false + }, + "//#format": {}, + "//#format:check": {}, + "//#format:fix": { "cache": false } } From 0324c9c60f5adec66289a91a5ecd83c217096dd0 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 19:05:09 +0530 Subject: [PATCH 04/16] feat: add Astro demo app with GitHub Pages deployment Interactive example showing izod's iframe communication with Standard Schema validation (zod). Parent and child pages exchange typed messages through a handshake-based protocol. - Astro static site in examples/astro-demo/ - GitHub Pages deploy workflow (.github/workflows/deploy.yml) - Add astro + zod to pnpm catalog --- .github/workflows/deploy.yml | 50 + examples/astro-demo/astro.config.mjs | 6 + examples/astro-demo/package.json | 16 + examples/astro-demo/src/pages/child.astro | 120 + examples/astro-demo/src/pages/index.astro | 133 + examples/astro-demo/tsconfig.json | 3 + pnpm-lock.yaml | 2921 ++++++++++++++++++++- pnpm-workspace.yaml | 3 + 8 files changed, 3194 insertions(+), 58 deletions(-) create mode 100644 .github/workflows/deploy.yml create mode 100644 examples/astro-demo/astro.config.mjs create mode 100644 examples/astro-demo/package.json create mode 100644 examples/astro-demo/src/pages/child.astro create mode 100644 examples/astro-demo/src/pages/index.astro create mode 100644 examples/astro-demo/tsconfig.json diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..e131e82 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,50 @@ +name: Deploy Demo to GitHub Pages + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: pnpm/action-setup@5d445ecbfcb90fdf1556a629d018c79e97ff973b # v6.0.6 + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 24.15.0 + cache: pnpm + + - run: pnpm install --frozen-lockfile + - run: pnpm run build + + - name: Build Astro demo + working-directory: examples/astro-demo + run: pnpm run build + + - uses: actions/upload-pages-artifact@v4 + with: + path: examples/astro-demo/dist + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 diff --git a/examples/astro-demo/astro.config.mjs b/examples/astro-demo/astro.config.mjs new file mode 100644 index 0000000..2542a30 --- /dev/null +++ b/examples/astro-demo/astro.config.mjs @@ -0,0 +1,6 @@ +import { defineConfig } from "astro/config"; + +export default defineConfig({ + site: "https://drenther.github.io", + base: "/izod", +}); diff --git a/examples/astro-demo/package.json b/examples/astro-demo/package.json new file mode 100644 index 0000000..fae9732 --- /dev/null +++ b/examples/astro-demo/package.json @@ -0,0 +1,16 @@ +{ + "name": "@izod/astro-demo", + "private": true, + "type": "module", + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview" + }, + "dependencies": { + "@izod/core": "workspace:*", + "@standard-schema/spec": "catalog:", + "astro": "catalog:", + "zod": "catalog:" + } +} diff --git a/examples/astro-demo/src/pages/child.astro b/examples/astro-demo/src/pages/child.astro new file mode 100644 index 0000000..4965bec --- /dev/null +++ b/examples/astro-demo/src/pages/child.astro @@ -0,0 +1,120 @@ +--- +--- + + + + + + izod — Child Page + + + +

Child iframe

+

Running inside parent's iframe via izod

+ + Waiting for parent... + +
+ + +
+ +
+ + + + diff --git a/examples/astro-demo/src/pages/index.astro b/examples/astro-demo/src/pages/index.astro new file mode 100644 index 0000000..156b298 --- /dev/null +++ b/examples/astro-demo/src/pages/index.astro @@ -0,0 +1,133 @@ +--- +const base = import.meta.env.BASE_URL; +--- + + + + + + izod — Parent Page + + + +

izod — Parent Page

+

Type-safe iframe communication with Standard Schema validation

+ + Connecting... + +
+ +
+ + +
+ +

Event Log

+
+ + + + diff --git a/examples/astro-demo/tsconfig.json b/examples/astro-demo/tsconfig.json new file mode 100644 index 0000000..bcbf8b5 --- /dev/null +++ b/examples/astro-demo/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "astro/tsconfigs/strict" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6f7087..ff73b37 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,6 +24,9 @@ catalogs: '@vitest/coverage-v8': specifier: 4.1.5 version: 4.1.5 + astro: + specifier: 6.2.1 + version: 6.2.1 happy-dom: specifier: 20.9.0 version: 20.9.0 @@ -42,6 +45,9 @@ catalogs: vitest: specifier: 4.1.5 version: 4.1.5 + zod: + specifier: 4.3.6 + version: 4.3.6 importers: @@ -69,6 +75,21 @@ importers: specifier: 2.5.6 version: 2.5.6 + examples/astro-demo: + dependencies: + '@izod/core': + specifier: workspace:* + version: link:../../packages/core + '@standard-schema/spec': + specifier: 'catalog:' + version: 1.1.0 + astro: + specifier: 'catalog:' + version: 6.2.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3) + zod: + specifier: 'catalog:' + version: 4.3.6 + packages/core: dependencies: crelt: @@ -95,7 +116,7 @@ importers: version: 6.0.3 vitest: specifier: 'catalog:' - version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)) packages/react: devDependencies: @@ -137,13 +158,30 @@ importers: version: 6.0.3 vitest: specifier: 'catalog:' - version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)) packages: '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + '@astrojs/compiler@4.0.0': + resolution: {integrity: sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==} + + '@astrojs/internal-helpers@0.9.0': + resolution: {integrity: sha512-GdYkzR26re8izmyYlBqf4z2s7zNngmWLFuxw0UKiPNqHraZGS6GKWIwSHgS22RDlu2ePFJ8bzmpBcUszut/SDg==} + + '@astrojs/markdown-remark@7.1.1': + resolution: {integrity: sha512-C6e9BnLGlbdv6bV8MYGeHpHxsUHrCrB4OuRLqi5LI7oiBVcBcqfUN06zpwFQdHgV48QCCrMmLpyqBr7VqC+swA==} + + '@astrojs/prism@4.0.1': + resolution: {integrity: sha512-nksZQVjlferuWzhPsBpQ1JE5XuKAf1id1/9Hj4a9KG4+ofrlzxUUwX4YGQF/SuDiuiGKEnzopGOt38F3AnVWsQ==} + engines: {node: '>=22.12.0'} + + '@astrojs/telemetry@3.3.1': + resolution: {integrity: sha512-7fcIxXS9J4ls5tr8b3ww9rbAIz2+HrhNJYZdkAhhB4za/I5IZ/60g+Bs8q7zwG0tOIZfNB4JWhVJ1Qkl/OrNCw==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -194,6 +232,10 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} + '@capsizecss/unpack@4.0.0': + resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==} + engines: {node: '>=18'} + '@changesets/apply-release-plan@7.1.1': resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==} @@ -249,6 +291,14 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + '@clack/core@1.3.0': + resolution: {integrity: sha512-xJPHpAmEQUBrXSLx0gF+q5K/IyihXpsHZcha+jB+tyahsKRK3Dxo4D0coZDewHo12NhiuzC3dTtMPbm53GEAAA==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.3.0': + resolution: {integrity: sha512-GgcWwRCs/xPtaqlMy8qRhPnZf9vlWcWZNHAitnVQ3yk7JmSralSiq5q07yaffYE8SogtDm7zFeKccx1QNVARpw==} + engines: {node: '>= 20.12.0'} + '@commitlint/cli@20.5.3': resolution: {integrity: sha512-OJdL0EXWD5y9LPa0nr/geOwzaS8BsdaybKkcloB0JgsguGxNv2R+hC2FTPqrAcprg35zF33KOQerY0x8W1aesA==} engines: {node: '>=v18'} @@ -339,6 +389,315 @@ packages: '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@inquirer/external-editor@1.0.3': resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} @@ -385,6 +744,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@oslojs/encoding@1.1.0': + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + '@oxc-project/types@0.127.0': resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} @@ -733,58 +1095,251 @@ packages: '@rolldown/pluginutils@1.0.0-rc.17': resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} - '@simple-libs/child-process-utils@1.0.2': - resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==} - engines: {node: '>=18'} - - '@simple-libs/stream-utils@1.2.0': - resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} - engines: {node: '>=18'} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@testing-library/dom@10.4.1': - resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} - engines: {node: '>=18'} - - '@testing-library/jest-dom@6.9.1': - resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} - engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - - '@testing-library/react@16.3.2': - resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} - engines: {node: '>=18'} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} peerDependencies: - '@testing-library/dom': ^10.0.0 - '@types/react': ^18.0.0 || ^19.0.0 - '@types/react-dom': ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + rollup: optional: true - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@rollup/rollup-android-arm-eabi@4.60.2': + resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} + cpu: [arm] + os: [android] - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@rollup/rollup-android-arm64@4.60.2': + resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} + cpu: [arm64] + os: [android] - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@rollup/rollup-darwin-arm64@4.60.2': + resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} + cpu: [arm64] + os: [darwin] - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@rollup/rollup-darwin-x64@4.60.2': + resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} + cpu: [x64] + os: [darwin] - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@rollup/rollup-freebsd-arm64@4.60.2': + resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} + cpu: [arm64] + os: [freebsd] - '@types/jsesc@2.5.1': + '@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.60.2': + resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@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.60.2': + resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@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-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-musl@4.60.2': + resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@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.60.2': + resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@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.60.2': + resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.2': + resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@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.60.2': + resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} + cpu: [ia32] + os: [win32] + + '@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.60.2': + resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} + cpu: [x64] + os: [win32] + + '@shikijs/core@4.0.2': + resolution: {integrity: sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==} + engines: {node: '>=20'} + + '@shikijs/engine-javascript@4.0.2': + resolution: {integrity: sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==} + engines: {node: '>=20'} + + '@shikijs/engine-oniguruma@4.0.2': + resolution: {integrity: sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==} + engines: {node: '>=20'} + + '@shikijs/langs@4.0.2': + resolution: {integrity: sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==} + engines: {node: '>=20'} + + '@shikijs/primitive@4.0.2': + resolution: {integrity: sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==} + engines: {node: '>=20'} + + '@shikijs/themes@4.0.2': + resolution: {integrity: sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==} + engines: {node: '>=20'} + + '@shikijs/types@4.0.2': + resolution: {integrity: sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==} + engines: {node: '>=20'} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@simple-libs/child-process-utils@1.0.2': + resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==} + engines: {node: '>=18'} + + '@simple-libs/stream-utils@1.2.0': + resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} + engines: {node: '>=18'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/jsesc@2.5.1': resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} @@ -799,12 +1354,19 @@ packages: '@types/react@19.2.14': resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/whatwg-mimetype@3.0.2': resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher + '@vitest/coverage-v8@4.1.5': resolution: {integrity: sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==} peerDependencies: @@ -866,6 +1428,10 @@ packages: resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} engines: {node: '>=14'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -882,6 +1448,9 @@ packages: array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} @@ -897,6 +1466,18 @@ packages: ast-v8-to-istanbul@1.0.0: resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==} + astro@6.2.1: + resolution: {integrity: sha512-3g1sYNly+QAkuO5ErNEQBYvsxorNDSCUNIeStBs+kcXGchvKQl1Q9EuDNOvSg010XLlHJFLVFZs9LV18Jjp4Hg==} + engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -904,6 +1485,9 @@ packages: birpc@4.0.0: resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -916,17 +1500,41 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -934,6 +1542,17 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + common-ancestor-path@2.0.0: + resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==} + engines: {node: '>= 18'} + compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} @@ -953,6 +1572,13 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + cosmiconfig-typescript-loader@6.3.0: resolution: {integrity: sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==} engines: {node: '>=v18'} @@ -977,12 +1603,46 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} @@ -990,6 +1650,9 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -998,20 +1661,50 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + devalue@5.8.0: + resolution: {integrity: sha512-2zA9pFEsnp7vWBZbXF5JAgAq0fsUIt/1XPbRiAmRV3lp/2C3upzH+sADiyy66aFCihoLEsrQHxNM5w1gIDfsBg==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + dts-resolver@2.1.3: resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} engines: {node: '>=20.19.0'} @@ -1032,6 +1725,14 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + entities@7.0.1: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} @@ -1049,22 +1750,40 @@ packages: es-toolkit@1.46.1: resolution: {integrity: sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==} + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -1075,9 +1794,18 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-wrap-ansi@0.2.0: + resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} + fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -1098,6 +1826,17 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + + fontace@0.4.1: + resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} + + fontkitten@1.0.3: + resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} + engines: {node: '>=20'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -1123,6 +1862,9 @@ packages: engines: {node: '>=18'} hasBin: true + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1138,6 +1880,9 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + happy-dom@20.9.0: resolution: {integrity: sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==} engines: {node: '>=20.0.0'} @@ -1146,12 +1891,51 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + hookable@6.1.1: resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + human-id@4.1.3: resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true @@ -1188,9 +1972,22 @@ packages: resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} engines: {node: ^20.17.0 || >=22.9.0} + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-docker@4.0.0: + resolution: {integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==} + engines: {node: '>=20'} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1203,6 +2000,11 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1223,6 +2025,10 @@ packages: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1354,6 +2160,13 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + lru-cache@11.3.5: + resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} + engines: {node: 20 || >=22} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -1368,6 +2181,54 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + meow@13.2.0: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} @@ -1376,11 +2237,95 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} - min-indent@1.0.1: + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -1391,6 +2336,13 @@ packages: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -1401,9 +2353,41 @@ packages: engines: {node: ^18 || >=20} hasBin: true + neotraverse@0.6.18: + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} + engines: {node: '>= 10'} + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} @@ -1430,6 +2414,10 @@ packages: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} + p-limit@7.3.0: + resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} + engines: {node: '>=20'} + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -1438,6 +2426,14 @@ packages: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} + p-queue@9.2.0: + resolution: {integrity: sha512-dWgLE8AH0HjQ9fe74pUkKkvzzYT18Inp4zra3lKHnnwqGvcfcUBrvF2EAVX+envufDNBOzpPq/IBUONDbI7+3g==} + engines: {node: '>=20'} + + p-timeout@7.0.1: + resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} + engines: {node: '>=20'} + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -1445,6 +2441,9 @@ packages: package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1453,6 +2452,12 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1468,6 +2473,9 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + piccolore@0.1.3: + resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1496,6 +2504,13 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -1505,6 +2520,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + react-dom@19.2.5: resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} peerDependencies: @@ -1521,10 +2539,51 @@ packages: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + rehype@13.0.2: + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -1544,6 +2603,18 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -1572,12 +2643,21 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + 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==} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -1586,6 +2666,10 @@ packages: engines: {node: '>=10'} hasBin: true + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1594,6 +2678,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@4.0.2: + resolution: {integrity: sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==} + engines: {node: '>=20'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -1601,14 +2689,24 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + smol-toml@1.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} + engines: {node: '>= 18'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} @@ -1625,6 +2723,9 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -1641,13 +2742,25 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + svgo@4.0.1: + resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} + engines: {node: '>=16'} + hasBin: true + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyclip@0.1.12: + resolution: {integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==} + engines: {node: ^16.14.0 || >= 17.3.0} + tinyexec@1.1.2: resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} @@ -1672,6 +2785,22 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + tsdown@0.21.10: resolution: {integrity: sha512-3wk73yBhZe/wX7REqSdivNQ84TDs1mJ+IlnzrrEREP70xlJ/AEIzqaI04l/TzMKVIdkTdC3CPaADn2Lk/0SkdA==} engines: {node: '>=20.19.0'} @@ -1742,12 +2871,54 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + ultrahtml@1.6.0: + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} + unconfig-core@7.5.0: resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@7.19.2: resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unifont@0.7.4: + resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -1762,6 +2933,117 @@ packages: synckit: optional: true + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vite@8.0.10: resolution: {integrity: sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1805,6 +3087,14 @@ packages: yaml: optional: true + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true + vitest@4.1.5: resolution: {integrity: sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -1846,10 +3136,17 @@ packages: jsdom: optional: true + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + whatwg-mimetype@3.0.0: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} + which-pm-runs@1.1.0: + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} + engines: {node: '>=4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1876,6 +3173,9 @@ packages: utf-8-validate: optional: true + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -1884,14 +3184,73 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@adobe/css-tools@4.4.4': {} + '@astrojs/compiler@4.0.0': {} + + '@astrojs/internal-helpers@0.9.0': + dependencies: + picomatch: 4.0.4 + + '@astrojs/markdown-remark@7.1.1': + dependencies: + '@astrojs/internal-helpers': 0.9.0 + '@astrojs/prism': 4.0.1 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + js-yaml: 4.1.1 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 3.0.2 + retext-smartypants: 6.2.0 + shiki: 4.0.2 + smol-toml: 1.6.1 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.1.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/prism@4.0.1': + dependencies: + prismjs: 1.30.0 + + '@astrojs/telemetry@3.3.1': + dependencies: + ci-info: 4.4.0 + dlv: 1.1.3 + dset: 3.1.4 + is-docker: 4.0.0 + is-wsl: 3.1.1 + which-pm-runs: 1.1.0 + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -1937,6 +3296,10 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} + '@capsizecss/unpack@4.0.0': + dependencies: + fontkitten: 1.0.3 + '@changesets/apply-release-plan@7.1.1': dependencies: '@changesets/config': 3.1.4 @@ -2080,6 +3443,18 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 + '@clack/core@1.3.0': + dependencies: + fast-wrap-ansi: 0.2.0 + sisteransi: 1.0.5 + + '@clack/prompts@1.3.0': + dependencies: + '@clack/core': 1.3.0 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.0 + sisteransi: 1.0.5 + '@commitlint/cli@20.5.3(@types/node@25.6.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3)': dependencies: '@commitlint/format': 20.5.0 @@ -2214,6 +3589,181 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.27.7': + optional: true + + '@esbuild/android-arm64@0.27.7': + optional: true + + '@esbuild/android-arm@0.27.7': + optional: true + + '@esbuild/android-x64@0.27.7': + optional: true + + '@esbuild/darwin-arm64@0.27.7': + optional: true + + '@esbuild/darwin-x64@0.27.7': + optional: true + + '@esbuild/freebsd-arm64@0.27.7': + optional: true + + '@esbuild/freebsd-x64@0.27.7': + optional: true + + '@esbuild/linux-arm64@0.27.7': + optional: true + + '@esbuild/linux-arm@0.27.7': + optional: true + + '@esbuild/linux-ia32@0.27.7': + optional: true + + '@esbuild/linux-loong64@0.27.7': + optional: true + + '@esbuild/linux-mips64el@0.27.7': + optional: true + + '@esbuild/linux-ppc64@0.27.7': + optional: true + + '@esbuild/linux-riscv64@0.27.7': + optional: true + + '@esbuild/linux-s390x@0.27.7': + optional: true + + '@esbuild/linux-x64@0.27.7': + optional: true + + '@esbuild/netbsd-arm64@0.27.7': + optional: true + + '@esbuild/netbsd-x64@0.27.7': + optional: true + + '@esbuild/openbsd-arm64@0.27.7': + optional: true + + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': + optional: true + + '@esbuild/sunos-x64@0.27.7': + optional: true + + '@esbuild/win32-arm64@0.27.7': + optional: true + + '@esbuild/win32-ia32@0.27.7': + optional: true + + '@esbuild/win32-x64@0.27.7': + optional: true + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + '@inquirer/external-editor@1.0.3(@types/node@25.6.0)': dependencies: chardet: 2.1.1 @@ -2270,6 +3820,8 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@oslojs/encoding@1.1.0': {} + '@oxc-project/types@0.127.0': {} '@oxfmt/binding-android-arm-eabi@0.47.0': @@ -2441,6 +3993,129 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.17': {} + '@rollup/pluginutils@5.3.0(rollup@4.60.2)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.60.2 + + '@rollup/rollup-android-arm-eabi@4.60.2': + optional: true + + '@rollup/rollup-android-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-x64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.2': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.2': + optional: true + + '@shikijs/core@4.0.2': + dependencies: + '@shikijs/primitive': 4.0.2 + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + + '@shikijs/primitive@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/themes@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + + '@shikijs/types@4.0.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + '@simple-libs/child-process-utils@1.0.2': dependencies: '@simple-libs/stream-utils': 1.2.0 @@ -2491,12 +4166,30 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} '@types/estree@1.0.8': {} + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/jsesc@2.5.1': {} + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + '@types/node@12.20.55': {} '@types/node@25.6.0': @@ -2511,12 +4204,16 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/unist@3.0.3': {} + '@types/whatwg-mimetype@3.0.2': {} '@types/ws@8.18.1': dependencies: '@types/node': 25.6.0 + '@ungap/structured-clone@1.3.0': {} + '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': dependencies: '@bcoe/v8-coverage': 1.0.2 @@ -2529,7 +4226,7 @@ snapshots: 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)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + vitest: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)) '@vitest/expect@4.1.5': dependencies: @@ -2540,13 +4237,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.5(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1))': + '@vitest/mocker@4.1.5(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1))': dependencies: '@vitest/spy': 4.1.5 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + vite: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1) '@vitest/pretty-format@4.1.5': dependencies: @@ -2591,6 +4288,11 @@ snapshots: ansis@4.2.0: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -2605,6 +4307,8 @@ snapshots: array-ify@1.0.0: {} + array-iterate@2.0.1: {} + array-union@2.1.0: {} assertion-error@2.0.1: {} @@ -2621,12 +4325,111 @@ snapshots: estree-walker: 3.0.3 js-tokens: 10.0.0 + astro@6.2.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3): + dependencies: + '@astrojs/compiler': 4.0.0 + '@astrojs/internal-helpers': 0.9.0 + '@astrojs/markdown-remark': 7.1.1 + '@astrojs/telemetry': 3.3.1 + '@capsizecss/unpack': 4.0.0 + '@clack/prompts': 1.3.0 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.3.0(rollup@4.60.2) + aria-query: 5.3.2 + axobject-query: 4.1.0 + ci-info: 4.4.0 + clsx: 2.1.1 + common-ancestor-path: 2.0.0 + cookie: 1.1.1 + devalue: 5.8.0 + diff: 8.0.4 + dset: 3.1.4 + es-module-lexer: 2.1.0 + esbuild: 0.27.7 + flattie: 1.1.1 + fontace: 0.4.1 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.2.0 + js-yaml: 4.1.1 + magic-string: 0.30.21 + magicast: 0.5.2 + mrmime: 2.0.1 + neotraverse: 0.6.18 + obug: 2.1.1 + p-limit: 7.3.0 + p-queue: 9.2.0 + package-manager-detector: 1.6.0 + piccolore: 0.1.3 + picomatch: 4.0.4 + rehype: 13.0.2 + semver: 7.7.4 + shiki: 4.0.2 + smol-toml: 1.6.1 + svgo: 4.0.1 + tinyclip: 0.1.12 + tinyexec: 1.1.2 + tinyglobby: 0.2.16 + tsconfck: 3.1.6(typescript@6.0.3) + ultrahtml: 1.6.0 + unifont: 0.7.4 + unist-util-visit: 5.1.0 + unstorage: 1.17.5 + vfile: 6.0.3 + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) + vitefu: 1.1.3(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) + xxhash-wasm: 1.1.0 + yargs-parser: 22.0.0 + zod: 4.3.6 + optionalDependencies: + sharp: 0.34.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - yaml + + axobject-query@4.1.0: {} + + bail@2.0.2: {} + better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 birpc@4.0.0: {} + boolbase@1.0.0: {} + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -2635,22 +4438,44 @@ snapshots: callsites@3.1.0: {} + ccount@2.0.1: {} + chai@6.2.2: {} + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + chardet@2.1.1: {} + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + ci-info@4.4.0: {} + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clsx@2.1.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + + common-ancestor-path@2.0.0: {} + compare-func@2.0.0: dependencies: array-ify: 1.0.0 @@ -2671,6 +4496,10 @@ snapshots: convert-source-map@2.0.0: {} + cookie-es@1.2.3: {} + + cookie@1.1.1: {} + cosmiconfig-typescript-loader@6.3.0(@types/node@25.6.0)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3): dependencies: '@types/node': 25.6.0 @@ -2695,30 +4524,98 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + css.escape@1.5.1: {} + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + csstype@3.2.3: {} + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + defu@6.1.7: {} dequal@2.0.3: {} + destr@2.0.5: {} + detect-indent@6.1.0: {} detect-libc@2.1.2: {} + devalue@5.8.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@8.0.4: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 + dlv@1.1.3: {} + dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 + dset@3.1.4: {} + dts-resolver@2.1.3: {} emoji-regex@8.0.0: {} @@ -2730,6 +4627,10 @@ snapshots: ansi-colors: 4.1.3 strip-ansi: 6.0.1 + entities@4.5.0: {} + + entities@6.0.1: {} + entities@7.0.1: {} env-paths@2.2.1: {} @@ -2742,16 +4643,53 @@ snapshots: es-toolkit@1.46.1: {} + 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 + escalade@3.2.0: {} + escape-string-regexp@5.0.0: {} + esprima@4.0.1: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 + eventemitter3@5.0.4: {} + expect-type@1.3.0: {} + extend@3.0.2: {} + extendable-error@0.1.7: {} fast-deep-equal@3.1.3: {} @@ -2764,8 +4702,18 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + fast-uri@3.1.0: {} + fast-wrap-ansi@0.2.0: + dependencies: + fast-string-width: 3.0.2 + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -2776,12 +4724,22 @@ snapshots: fill-range@7.1.1: dependencies: - to-regex-range: 5.0.1 + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + flattie@1.1.1: {} + + fontace@0.4.1: + dependencies: + fontkitten: 1.0.3 - find-up@4.1.0: + fontkitten@1.0.3: dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 + tiny-inflate: 1.0.3 fs-extra@7.0.1: dependencies: @@ -2812,6 +4770,8 @@ snapshots: - conventional-commits-filter - conventional-commits-parser + github-slugger@2.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -2831,6 +4791,18 @@ snapshots: graceful-fs@4.2.11: {} + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + happy-dom@20.9.0: dependencies: '@types/node': 25.6.0 @@ -2845,10 +4817,103 @@ snapshots: has-flag@4.0.0: {} + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.3.0 + vfile: 6.0.3 + vfile-message: 4.0.3 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + hookable@6.1.1: {} html-escaper@2.0.2: {} + html-escaper@3.0.3: {} + + html-void-elements@3.0.0: {} + + http-cache-semantics@4.2.0: {} + human-id@4.1.3: {} husky@9.1.7: {} @@ -2872,8 +4937,14 @@ snapshots: ini@6.0.0: {} + iron-webcrypto@1.2.1: {} + is-arrayish@0.2.1: {} + is-docker@3.0.0: {} + + is-docker@4.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -2882,6 +4953,10 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-number@7.0.0: {} is-obj@2.0.0: {} @@ -2894,6 +4969,10 @@ snapshots: is-windows@1.0.2: {} + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + isexe@2.0.0: {} istanbul-lib-coverage@3.2.2: {} @@ -2991,6 +5070,10 @@ snapshots: lodash.startcase@4.4.0: {} + longest-streak@3.1.0: {} + + lru-cache@11.3.5: {} + lz-string@1.5.0: {} magic-string@0.30.21: @@ -3007,10 +5090,327 @@ snapshots: dependencies: semver: 7.7.4 + markdown-table@3.0.4: {} + + mdast-util-definitions@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.28: {} + + mdn-data@2.27.1: {} + meow@13.2.0: {} merge2@1.4.1: {} + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -3022,12 +5422,48 @@ snapshots: mri@1.2.0: {} + mrmime@2.0.1: {} + + ms@2.1.3: {} + nanoid@3.3.12: {} nanoid@5.1.5: {} + neotraverse@0.6.18: {} + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + + node-fetch-native@1.6.7: {} + + node-mock-http@1.0.4: {} + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + obug@2.1.1: {} + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + ohash@2.0.11: {} + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + outdent@0.5.0: {} oxfmt@0.47.0: @@ -3084,18 +5520,31 @@ snapshots: dependencies: p-try: 2.2.0 + p-limit@7.3.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@4.1.0: dependencies: p-limit: 2.3.0 p-map@2.1.0: {} + p-queue@9.2.0: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 7.0.1 + + p-timeout@7.0.1: {} + p-try@2.2.0: {} package-manager-detector@0.2.11: dependencies: quansync: 0.2.11 + package-manager-detector@1.6.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -3107,6 +5556,19 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -3115,6 +5577,8 @@ snapshots: pathe@2.0.3: {} + piccolore@0.1.3: {} + picocolors@1.1.1: {} picomatch@2.3.2: {} @@ -3137,12 +5601,18 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + prismjs@1.30.0: {} + + property-information@7.1.0: {} + quansync@0.2.11: {} quansync@1.0.0: {} queue-microtask@1.2.3: {} + radix3@1.1.2: {} + react-dom@19.2.5(react@19.2.5): dependencies: react: 19.2.5 @@ -3159,11 +5629,89 @@ snapshots: pify: 4.0.1 strip-bom: 3.0.0 + readdirp@5.0.0: {} + redent@3.0.0: dependencies: indent-string: 4.0.0 strip-indent: 3.0.0 + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-stringify@10.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + unified: 11.0.5 + + rehype@13.0.2: + dependencies: + '@types/hast': 3.0.4 + rehype-parse: 9.0.1 + rehype-stringify: 10.0.1 + unified: 11.0.5 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -3174,6 +5722,31 @@ snapshots: resolve-pkg-maps@1.0.0: {} + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.1.0 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + reusify@1.1.0: {} rolldown-plugin-dts@0.23.2(rolldown@1.0.0-rc.17)(typescript@6.0.3): @@ -3215,30 +5788,112 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + 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 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 safer-buffer@2.1.2: {} + sax@1.6.0: {} + scheduler@0.27.0: {} semver@7.7.4: {} + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + shiki@4.0.2: + dependencies: + '@shikijs/core': 4.0.2 + '@shikijs/engine-javascript': 4.0.2 + '@shikijs/engine-oniguruma': 4.0.2 + '@shikijs/langs': 4.0.2 + '@shikijs/themes': 4.0.2 + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + siginfo@2.0.0: {} signal-exit@4.1.0: {} + sisteransi@1.0.5: {} + slash@3.0.0: {} + smol-toml@1.6.1: {} + source-map-js@1.2.1: {} + space-separated-tokens@2.0.2: {} + spawndamnit@3.0.1: dependencies: cross-spawn: 7.0.6 @@ -3256,6 +5911,11 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -3270,10 +5930,24 @@ snapshots: dependencies: has-flag: 4.0.0 + svgo@4.0.1: + dependencies: + commander: 11.1.0 + css-select: 5.2.2 + css-tree: 3.2.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.0 + term-size@2.2.1: {} + tiny-inflate@1.0.3: {} + tinybench@2.9.0: {} + tinyclip@0.1.12: {} + tinyexec@1.1.2: {} tinyglobby@0.2.16: @@ -3291,6 +5965,14 @@ snapshots: tree-kill@1.2.2: {} + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + tsconfck@3.1.6(typescript@6.0.3): + optionalDependencies: + typescript: 6.0.3 + tsdown@0.21.10(typescript@6.0.3): dependencies: ansis: 4.2.0 @@ -3350,20 +6032,124 @@ snapshots: typescript@6.0.3: {} + ufo@1.6.4: {} + + ultrahtml@1.6.0: {} + unconfig-core@7.5.0: dependencies: '@quansync/fs': 1.0.0 quansync: 1.0.0 + uncrypto@0.1.3: {} + undici-types@7.19.2: {} + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unifont@0.7.4: + dependencies: + css-tree: 3.2.1 + ofetch: 1.5.1 + ohash: 2.0.11 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-children@3.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + universalify@0.1.2: {} unrun@0.2.37: dependencies: rolldown: 1.0.0-rc.17 - vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1): + unstorage@1.17.5: + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.3.5 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0): + dependencies: + esbuild: 0.27.7 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.13 + rollup: 4.60.2 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 25.6.0 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.32.0 + + vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -3372,13 +6158,18 @@ snapshots: tinyglobby: 0.2.16 optionalDependencies: '@types/node': 25.6.0 + esbuild: 0.27.7 fsevents: 2.3.3 jiti: 2.6.1 - vitest@4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)): + vitefu@1.1.3(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)): + optionalDependencies: + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) + + vitest@4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)): dependencies: '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)) '@vitest/pretty-format': 4.1.5 '@vitest/runner': 4.1.5 '@vitest/snapshot': 4.1.5 @@ -3395,7 +6186,7 @@ snapshots: tinyexec: 1.1.2 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + vite: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.6.0 @@ -3404,8 +6195,12 @@ snapshots: transitivePeerDependencies: - msw + web-namespaces@2.0.1: {} + whatwg-mimetype@3.0.0: {} + which-pm-runs@1.1.0: {} + which@2.0.2: dependencies: isexe: 2.0.0 @@ -3423,10 +6218,14 @@ snapshots: ws@8.20.0: {} + xxhash-wasm@1.1.0: {} + y18n@5.0.8: {} yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -3436,3 +6235,9 @@ snapshots: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 + + yocto-queue@1.2.2: {} + + zod@4.3.6: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 58d9ca3..c859c81 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -26,3 +26,6 @@ catalog: # React (dev only) react: "19.2.5" react-dom: "19.2.5" + # Examples + astro: "6.2.1" + zod: "4.3.6" From 109562494c69361d14d4a7b42ab0300e1307e45d Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 19:09:58 +0530 Subject: [PATCH 05/16] chore: add .gitignore for astro-demo example --- examples/astro-demo/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 examples/astro-demo/.gitignore diff --git a/examples/astro-demo/.gitignore b/examples/astro-demo/.gitignore new file mode 100644 index 0000000..b8430ed --- /dev/null +++ b/examples/astro-demo/.gitignore @@ -0,0 +1,3 @@ +node_modules +dist +.astro From ef8ab756e23fc125a583943b1c823b02b62194e9 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 19:27:16 +0530 Subject: [PATCH 06/16] fix(core): suppress happy-dom DOMException warnings in tests Disable child frame navigation in happy-dom settings to prevent fetch attempts to iframe URLs during test teardown. --- packages/core/tests/index.test.ts | 9 +++++++++ packages/core/vitest.config.ts | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/packages/core/tests/index.test.ts b/packages/core/tests/index.test.ts index 81f64ee..49d099d 100644 --- a/packages/core/tests/index.test.ts +++ b/packages/core/tests/index.test.ts @@ -48,6 +48,9 @@ describe("createChild", () => { beforeEach(() => { container = document.createElement("div"); document.body.appendChild(container); + return () => { + container.remove(); + }; }); it("returns executeHandshake and on functions", () => { @@ -118,6 +121,9 @@ describe("Standard Schema validation", () => { beforeEach(() => { container = document.createElement("div"); document.body.appendChild(container); + return () => { + container.remove(); + }; }); it("throws on invalid event name in emit", () => { @@ -275,6 +281,9 @@ describe("handshake", () => { beforeEach(() => { container = document.createElement("div"); document.body.appendChild(container); + return () => { + container.remove(); + }; }); it("resolves on valid handshake reply", async () => { diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index d373090..537c27f 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -3,6 +3,16 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { environment: "happy-dom", + environmentOptions: { + happyDOM: { + settings: { + navigation: { + disableChildFrameNavigation: true, + disableChildPageNavigation: true, + }, + }, + }, + }, setupFiles: ["./tests/setup.ts"], coverage: { provider: "v8", From a9072218045e6531a3b87418e075eb9183820352 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 19:56:45 +0530 Subject: [PATCH 07/16] feat(examples): add React demo page and restructure Astro examples Add @izod/react example using child.useCreate and parent.useConnect hooks alongside the existing @izod/core example. Restructure pages into /core and /react paths with a landing page at root. - Add @astrojs/react integration with semver@7.7.4 override - Add ReactParent and ReactChild components with client:only directive - Move core example pages to /core subdirectory - Add landing page with links to both examples --- examples/astro-demo/astro.config.mjs | 2 + examples/astro-demo/package.json | 8 + .../astro-demo/src/components/ReactChild.tsx | 111 ++++++ .../astro-demo/src/components/ReactParent.tsx | 123 ++++++ .../src/pages/{ => core}/child.astro | 4 +- .../astro-demo/src/pages/core/index.astro | 136 +++++++ examples/astro-demo/src/pages/index.astro | 136 ++----- .../astro-demo/src/pages/react/child.astro | 38 ++ .../astro-demo/src/pages/react/index.astro | 42 +++ pnpm-lock.yaml | 356 ++++++++++++++++++ pnpm-workspace.yaml | 8 +- 11 files changed, 846 insertions(+), 118 deletions(-) create mode 100644 examples/astro-demo/src/components/ReactChild.tsx create mode 100644 examples/astro-demo/src/components/ReactParent.tsx rename examples/astro-demo/src/pages/{ => core}/child.astro (96%) create mode 100644 examples/astro-demo/src/pages/core/index.astro create mode 100644 examples/astro-demo/src/pages/react/child.astro create mode 100644 examples/astro-demo/src/pages/react/index.astro diff --git a/examples/astro-demo/astro.config.mjs b/examples/astro-demo/astro.config.mjs index 2542a30..3c0fc55 100644 --- a/examples/astro-demo/astro.config.mjs +++ b/examples/astro-demo/astro.config.mjs @@ -1,6 +1,8 @@ import { defineConfig } from "astro/config"; +import react from "@astrojs/react"; export default defineConfig({ site: "https://drenther.github.io", base: "/izod", + integrations: [react()], }); diff --git a/examples/astro-demo/package.json b/examples/astro-demo/package.json index fae9732..8a06527 100644 --- a/examples/astro-demo/package.json +++ b/examples/astro-demo/package.json @@ -8,9 +8,17 @@ "preview": "astro preview" }, "dependencies": { + "@astrojs/react": "catalog:", "@izod/core": "workspace:*", + "@izod/react": "workspace:*", "@standard-schema/spec": "catalog:", "astro": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", "zod": "catalog:" + }, + "devDependencies": { + "@types/react": "catalog:", + "@types/react-dom": "catalog:" } } diff --git a/examples/astro-demo/src/components/ReactChild.tsx b/examples/astro-demo/src/components/ReactChild.tsx new file mode 100644 index 0000000..29fc8aa --- /dev/null +++ b/examples/astro-demo/src/components/ReactChild.tsx @@ -0,0 +1,111 @@ +import { useRef, useState, useEffect } from "react"; +import { parent } from "@izod/react"; +import { z } from "zod"; + +const messageSchema = z.object({ + text: z.string(), + timestamp: z.number(), +}); + +type LogEntry = { + id: number; + message: string; + type: "sent" | "received" | "system" | "error"; +}; + +export default function ReactChild() { + const [logs, setLogs] = useState([]); + const [input, setInput] = useState(""); + const logIdRef = useRef(0); + + function appendLog(message: string, type: LogEntry["type"]) { + setLogs((prev) => [ + ...prev, + { id: ++logIdRef.current, message, type }, + ]); + } + + const { on, executeHandshake, api, isHandshakeComplete, isHandshakePending, handshakeError } = + parent.useConnect({ + namespace: "izod-react-demo", + inboundEvents: { + parentMessage: messageSchema, + }, + outboundEvents: { + childMessage: messageSchema, + }, + onHandshakeComplete: () => { + appendLog("Handshake complete — connected to parent", "system"); + }, + onHandshakeError: (error) => { + appendLog(`Connection failed: ${error.message}`, "error"); + }, + }); + + useEffect(() => { + const unsubscribe = on("parentMessage", (data) => { + appendLog(data.text, "received"); + }); + return unsubscribe; + }, [on]); + + useEffect(() => { + appendLog("Waiting for handshake from parent...", "system"); + executeHandshake(); + }, [executeHandshake]); + + function sendMessage() { + const text = input.trim(); + if (!text || !api) return; + api.emit("childMessage", { text, timestamp: Date.now() }); + appendLog(text, "sent"); + setInput(""); + } + + const statusClass = handshakeError + ? "status error" + : isHandshakeComplete + ? "status connected" + : "status pending"; + + const statusText = handshakeError + ? "Error" + : isHandshakeComplete + ? "Connected" + : isHandshakePending + ? "Connecting..." + : "Waiting for parent..."; + + return ( + <> + {statusText} + +
+ setInput(event.target.value)} + onKeyDown={(event) => { + if (event.key === "Enter") sendMessage(); + }} + /> + +
+ +
+ {logs.map((entry) => { + const prefix = { sent: "↑ SENT", received: "↓ RECV", system: "● SYS", error: "✕ ERR" }[entry.type]; + return ( +
+ [{new Date().toLocaleTimeString()}] {prefix}: {entry.message} +
+ ); + })} +
+ + ); +} diff --git a/examples/astro-demo/src/components/ReactParent.tsx b/examples/astro-demo/src/components/ReactParent.tsx new file mode 100644 index 0000000..d43fa92 --- /dev/null +++ b/examples/astro-demo/src/components/ReactParent.tsx @@ -0,0 +1,123 @@ +import { useRef, useState, useEffect } from "react"; +import { child } from "@izod/react"; +import { z } from "zod"; + +const messageSchema = z.object({ + text: z.string(), + timestamp: z.number(), +}); + +type LogEntry = { + id: number; + message: string; + type: "sent" | "received" | "system" | "error"; +}; + +export default function ReactParent({ base }: { base: string }) { + const [container] = useState(() => document.createElement("div")); + const [logs, setLogs] = useState([]); + const [input, setInput] = useState(""); + const logIdRef = useRef(0); + + function appendLog(message: string, type: LogEntry["type"]) { + setLogs((prev) => [ + ...prev, + { id: ++logIdRef.current, message, type }, + ]); + } + + const { on, executeHandshake, api, isHandshakeComplete, isHandshakePending, handshakeError } = + child.useCreate({ + container, + url: `${base}react/child`, + namespace: "izod-react-demo", + iframeAttributes: { + style: "width:100%;height:300px;border:1px solid #e5e7eb;border-radius:8px", + }, + inboundEvents: { + childMessage: messageSchema, + }, + outboundEvents: { + parentMessage: messageSchema, + }, + onHandshakeComplete: () => { + appendLog("Handshake complete — connection established", "system"); + }, + onHandshakeError: (error) => { + appendLog(`Handshake failed: ${error.message}`, "error"); + }, + }); + + useEffect(() => { + const unsubscribe = on("childMessage", (data) => { + appendLog(data.text, "received"); + }); + return unsubscribe; + }, [on]); + + useEffect(() => { + appendLog("Creating child iframe...", "system"); + executeHandshake(); + appendLog("Initiating handshake...", "system"); + }, [executeHandshake]); + + function sendMessage() { + const text = input.trim(); + if (!text || !api) return; + api.emit("parentMessage", { text, timestamp: Date.now() }); + appendLog(text, "sent"); + setInput(""); + } + + const statusClass = handshakeError + ? "status error" + : isHandshakeComplete + ? "status connected" + : "status pending"; + + const statusText = handshakeError + ? "Error" + : isHandshakeComplete + ? "Connected" + : isHandshakePending + ? "Connecting..." + : "Idle"; + + return ( + <> + {statusText} + +
{ + if (node && !node.contains(container)) node.appendChild(container); + }} /> + +
+ setInput(event.target.value)} + onKeyDown={(event) => { + if (event.key === "Enter") sendMessage(); + }} + /> + +
+ +

Event Log

+
+ {logs.map((entry) => { + const prefix = { sent: "↑ SENT", received: "↓ RECV", system: "● SYS", error: "✕ ERR" }[entry.type]; + return ( +
+ [{new Date().toLocaleTimeString()}] {prefix}: {entry.message} +
+ ); + })} +
+ + ); +} diff --git a/examples/astro-demo/src/pages/child.astro b/examples/astro-demo/src/pages/core/child.astro similarity index 96% rename from examples/astro-demo/src/pages/child.astro rename to examples/astro-demo/src/pages/core/child.astro index 4965bec..f0afc7b 100644 --- a/examples/astro-demo/src/pages/child.astro +++ b/examples/astro-demo/src/pages/core/child.astro @@ -7,8 +7,8 @@ izod — Child Page + + + ← Back to examples +

izod — Core Parent Page

+

Using @izod/core directly — createChild + connectToParent with zod validation

+ + Connecting... + +
+ +
+ + +
+ +

Event Log

+
+ + + + diff --git a/examples/astro-demo/src/pages/index.astro b/examples/astro-demo/src/pages/index.astro index 156b298..9db4f7a 100644 --- a/examples/astro-demo/src/pages/index.astro +++ b/examples/astro-demo/src/pages/index.astro @@ -6,128 +6,36 @@ const base = import.meta.env.BASE_URL; - izod — Parent Page + izod — Demo -

izod — Parent Page

+

izod

Type-safe iframe communication with Standard Schema validation

- Connecting... +
+ +

Core Example @izod/core

+

Vanilla TypeScript — direct use of createChild and connectToParent APIs with zod validation.

+
-
- - - -

Event Log

-
- - diff --git a/examples/astro-demo/src/pages/react/child.astro b/examples/astro-demo/src/pages/react/child.astro new file mode 100644 index 0000000..8c7cbcc --- /dev/null +++ b/examples/astro-demo/src/pages/react/child.astro @@ -0,0 +1,38 @@ +--- +import ReactChild from "../../components/ReactChild"; +--- + + + + + + izod — React Child Page + + + +

React Child iframe

+

Running inside parent's iframe via @izod/react hooks

+ + + + diff --git a/examples/astro-demo/src/pages/react/index.astro b/examples/astro-demo/src/pages/react/index.astro new file mode 100644 index 0000000..b5d7b7a --- /dev/null +++ b/examples/astro-demo/src/pages/react/index.astro @@ -0,0 +1,42 @@ +--- +import ReactParent from "../../components/ReactParent"; +const base = import.meta.env.BASE_URL; +--- + + + + + + izod — React Parent Page + + + + ← Back to examples +

izod — React Parent Page

+

Using @izod/react hooks with child.useCreate

+ + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ff73b37..bf6f4de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,9 @@ settings: catalogs: default: + '@astrojs/react': + specifier: 5.0.4 + version: 5.0.4 '@standard-schema/spec': specifier: 1.1.0 version: 1.1.0 @@ -49,6 +52,9 @@ catalogs: specifier: 4.3.6 version: 4.3.6 +overrides: + semver: 7.7.4 + importers: .: @@ -77,18 +83,37 @@ importers: examples/astro-demo: dependencies: + '@astrojs/react': + specifier: 'catalog:' + version: 5.0.4(@types/node@25.6.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(jiti@2.6.1)(lightningcss@1.32.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@izod/core': specifier: workspace:* version: link:../../packages/core + '@izod/react': + specifier: workspace:* + version: link:../../packages/react '@standard-schema/spec': specifier: 'catalog:' version: 1.1.0 astro: specifier: 'catalog:' version: 6.2.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3) + react: + specifier: 'catalog:' + version: 19.2.5 + react-dom: + specifier: 'catalog:' + version: 19.2.5(react@19.2.5) zod: specifier: 'catalog:' version: 4.3.6 + devDependencies: + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.14) packages/core: dependencies: @@ -178,6 +203,15 @@ packages: resolution: {integrity: sha512-nksZQVjlferuWzhPsBpQ1JE5XuKAf1id1/9Hj4a9KG4+ofrlzxUUwX4YGQF/SuDiuiGKEnzopGOt38F3AnVWsQ==} engines: {node: '>=22.12.0'} + '@astrojs/react@5.0.4': + resolution: {integrity: sha512-yDNE4VnKOzCjH9dCBi7pT4F6kpI3M9TkS+uxnCB0sGIS6t5vKonOY+Hs/UUnSajJGT5jeBRfpI9IQp+r/n1fBA==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@types/react': ^17.0.50 || ^18.0.21 || ^19.0.0 + '@types/react-dom': ^17.0.17 || ^18.0.6 || ^19.0.0 + react: ^17.0.2 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.2 || ^18.0.0 || ^19.0.0 + '@astrojs/telemetry@3.3.1': resolution: {integrity: sha512-7fcIxXS9J4ls5tr8b3ww9rbAIz2+HrhNJYZdkAhhB4za/I5IZ/60g+Bs8q7zwG0tOIZfNB4JWhVJ1Qkl/OrNCw==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} @@ -186,10 +220,44 @@ packages: resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.29.3': + resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + '@babel/generator@8.0.0-rc.3': resolution: {integrity: sha512-em37/13/nR320G4jab/nIIHZgc2Wz2y/D39lxnTyxB4/D/omPQncl/lSdlnJY1OhQcRGugTSIF2l/69o31C9dA==} engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -206,6 +274,14 @@ packages: resolution: {integrity: sha512-8AWCJ2VJJyDFlGBep5GpaaQ9AAaE/FjAcrqI7jyssYhtL7WGV0DOKpJsQqM037xDbpRLHXsY8TwU7zDma7coOw==} engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.29.3': resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} engines: {node: '>=6.0.0'} @@ -216,10 +292,30 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.29.2': resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -710,6 +806,9 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -1095,6 +1194,9 @@ packages: '@rolldown/pluginutils@1.0.0-rc.17': resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} @@ -1313,6 +1415,18 @@ packages: '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -1367,6 +1481,12 @@ packages: resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} deprecated: Potential CWE-502 - Update to 1.3.1 or higher + '@vitejs/plugin-react@5.2.0': + resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + '@vitest/coverage-v8@4.1.5': resolution: {integrity: sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==} peerDependencies: @@ -1478,6 +1598,11 @@ packages: bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + baseline-browser-mapping@2.10.25: + resolution: {integrity: sha512-QO/VHsXCQdnzADMfmkeOPvHdIAkoB7i0/rGjINPJEetLx75hNttVWGQ/jycHUDP9zZ9rupbm60WRxcwViB0MiA==} + engines: {node: '>=6.0.0'} + hasBin: true + better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -1492,6 +1617,11 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + cac@7.0.0: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} @@ -1500,6 +1630,9 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + caniuse-lite@1.0.30001791: + resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1714,6 +1847,9 @@ packages: oxc-resolver: optional: true + electron-to-chromium@1.5.349: + resolution: {integrity: sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1850,6 +1986,10 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2073,6 +2213,11 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -2167,6 +2312,9 @@ packages: resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} engines: {node: 20 || >=22} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -2366,6 +2514,9 @@ packages: node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + node-releases@2.0.38: + resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -2531,6 +2682,10 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react@19.2.5: resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} engines: {node: '>=0.10.0'} @@ -2995,6 +3150,12 @@ packages: uploadthing: optional: true + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -3180,6 +3341,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -3242,6 +3406,31 @@ snapshots: dependencies: prismjs: 1.30.0 + '@astrojs/react@5.0.4(@types/node@25.6.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(jiti@2.6.1)(lightningcss@1.32.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@astrojs/internal-helpers': 0.9.0 + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': 5.2.0(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) + devalue: 5.8.0 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + ultrahtml: 1.6.0 + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + '@astrojs/telemetry@3.3.1': dependencies: ci-info: 4.4.0 @@ -3257,6 +3446,36 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/compat-data@7.29.3': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + '@babel/generator@8.0.0-rc.3': dependencies: '@babel/parser': 8.0.0-rc.3 @@ -3266,6 +3485,34 @@ snapshots: '@types/jsesc': 2.5.1 jsesc: 3.1.0 + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.3 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 7.7.4 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.28.6': {} + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-string-parser@8.0.0-rc.4': {} @@ -3274,6 +3521,13 @@ snapshots: '@babel/helper-validator-identifier@8.0.0-rc.3': {} + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@babel/parser@7.29.3': dependencies: '@babel/types': 7.29.0 @@ -3282,8 +3536,36 @@ snapshots: dependencies: '@babel/types': 8.0.0-rc.3 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/runtime@7.29.2': {} + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -3776,6 +4058,11 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} @@ -3993,6 +4280,8 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.17': {} + '@rolldown/pluginutils@1.0.0-rc.3': {} + '@rollup/pluginutils@5.3.0(rollup@4.60.2)': dependencies: '@types/estree': 1.0.8 @@ -4161,6 +4450,27 @@ snapshots: '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 @@ -4214,6 +4524,18 @@ snapshots: '@ungap/structured-clone@1.3.0': {} + '@vitejs/plugin-react@5.2.0(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) + transitivePeerDependencies: + - supports-color + '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': dependencies: '@bcoe/v8-coverage': 1.0.2 @@ -4422,6 +4744,8 @@ snapshots: bail@2.0.2: {} + baseline-browser-mapping@2.10.25: {} + better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 @@ -4434,10 +4758,20 @@ snapshots: dependencies: fill-range: 7.1.1 + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.25 + caniuse-lite: 1.0.30001791 + electron-to-chromium: 1.5.349 + node-releases: 2.0.38 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + cac@7.0.0: {} callsites@3.1.0: {} + caniuse-lite@1.0.30001791: {} + ccount@2.0.1: {} chai@6.2.2: {} @@ -4618,6 +4952,8 @@ snapshots: dts-resolver@2.1.3: {} + electron-to-chromium@1.5.349: {} + emoji-regex@8.0.0: {} empathic@2.0.0: {} @@ -4756,6 +5092,8 @@ snapshots: fsevents@2.3.3: optional: true + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} get-tsconfig@4.14.0: @@ -5009,6 +5347,8 @@ snapshots: json-schema-traverse@1.0.0: {} + json5@2.2.3: {} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -5074,6 +5414,10 @@ snapshots: lru-cache@11.3.5: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + lz-string@1.5.0: {} magic-string@0.30.21: @@ -5440,6 +5784,8 @@ snapshots: node-mock-http@1.0.4: {} + node-releases@2.0.38: {} + normalize-path@3.0.0: {} nth-check@2.1.1: @@ -5620,6 +5966,8 @@ snapshots: react-is@17.0.2: {} + react-refresh@0.18.0: {} + react@19.2.5: {} read-yaml-file@1.1.0: @@ -6120,6 +6468,12 @@ snapshots: ofetch: 1.5.1 ufo: 1.6.4 + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -6222,6 +6576,8 @@ snapshots: y18n@5.0.8: {} + yallist@3.1.1: {} + yargs-parser@21.1.1: {} yargs-parser@22.0.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c859c81..f8a1d62 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,8 +6,11 @@ trustPolicy: no-downgrade onlyBuiltDependencies: [] packages: - - 'packages/*' - - 'examples/*' + - "packages/*" + - "examples/*" + +overrides: + semver: "7.7.4" catalog: # Build @@ -28,4 +31,5 @@ catalog: react-dom: "19.2.5" # Examples astro: "6.2.1" + "@astrojs/react": "5.0.4" zod: "4.3.6" From 9600f3ba97fb2022e6e860cf943e9acd45398db3 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 23:17:01 +0530 Subject: [PATCH 08/16] ci: add coverage report comments on pull requests Parse vitest coverage-summary.json from each package and post a markdown table as a PR comment, upserting via HTML comment marker to avoid duplicates. Uses issues:write permission (not pull-requests). --- .github/workflows/ci.yml | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4832d84..96e2f98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,7 @@ on: permissions: contents: read + issues: write concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -34,3 +35,44 @@ jobs: - run: pnpm run test - run: pnpm run test:coverage - run: pnpm run build + + - name: Post coverage comment + if: github.event_name == 'pull_request' + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + COMMENT_MARKER="" + BODY="$COMMENT_MARKER + ## Coverage Report + + | Package | Statements | Branches | Functions | Lines | + |---------|-----------|----------|-----------|-------|" + + for pkg in packages/core packages/react; do + SUMMARY="$pkg/coverage/coverage-summary.json" + if [ ! -f "$SUMMARY" ]; then + continue + fi + + NAME=$(jq -r '.total | "\(.statements.pct)% | \(.branches.pct)% | \(.functions.pct)% | \(.lines.pct)%"' "$SUMMARY") + PKG_NAME=$(jq -r '.name' "$pkg/package.json") + BODY="$BODY + | \`$PKG_NAME\` | $NAME |" + done + + BODY="$BODY + + *Updated by CI — $(date -u '+%Y-%m-%d %H:%M UTC')*" + + EXISTING=$(gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ + --jq ".[] | select(.body | startswith(\"$COMMENT_MARKER\")) | .id" \ + | head -1) + + if [ -n "$EXISTING" ]; then + gh api "repos/${{ github.repository }}/issues/comments/${EXISTING}" \ + -X PATCH -f body="$BODY" + else + gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ + -X POST -f body="$BODY" + fi From cd24d072069b0ba91589795c5b1095c8ed132519 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 23:22:16 +0530 Subject: [PATCH 09/16] docs: add per-package READMEs and update root README for v2 - Add coverage/ to .gitignore - Rewrite root README for Standard Schema and updated API - Add @izod/core README with full createChild/connectToParent docs - Add @izod/react README with child.useCreate/parent.useConnect docs - Apply oxfmt formatting across touched files --- .gitignore | 3 + README.md | 255 ++++++------------ .../astro-demo/src/components/ReactChild.tsx | 9 +- .../astro-demo/src/components/ReactParent.tsx | 17 +- package.json | 18 +- packages/core/README.md | 102 +++++++ packages/core/package.json | 36 +-- packages/core/src/index.ts | 118 ++------ packages/core/tests/index.test.ts | 21 +- packages/react/README.md | 137 ++++++++++ packages/react/package.json | 44 +-- packages/react/src/index.ts | 58 ++-- packages/react/tests/react.test.ts | 12 +- 13 files changed, 446 insertions(+), 384 deletions(-) create mode 100644 packages/core/README.md create mode 100644 packages/react/README.md diff --git a/.gitignore b/.gitignore index 66539d2..2b809cf 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ dist dist-ssr *.local +# Coverage +coverage + # Turbo .turbo diff --git a/README.md b/README.md index b456fd4..172d335 100644 --- a/README.md +++ b/README.md @@ -1,216 +1,135 @@ # izod -> NOTE: This is very early stage, documentation is not complete and breaking API changes likely ahead. Please use at your own risk. Lock your version in case you use. (Even though I will adhere to semver for updates) - ![Bundle Size](https://img.shields.io/bundlephobia/minzip/@izod/core) ![npm version](https://badgen.net/npm/v/@izod/core) ![types](https://badgen.net/npm/types/@izod/core) -`izod` leverages [zod](https://github.com/colinhacks/zod) to provide a type safe Promise oriented API to manage iframe communication. +Type-safe iframe communication using the [Standard Schema](https://github.com/standard-schema/standard-schema) interface for runtime validation. -## Installation +Works with any Standard Schema compliant validator — [zod](https://github.com/colinhacks/zod), [valibot](https://github.com/fabian-hiller/valibot), [arktype](https://github.com/arktypeio/arktype), and more. -### core (only) +## Packages + +| Package | Description | +|---------|-------------| +| [`@izod/core`](./packages/core) | Iframe communication engine — no framework dependency | +| [`@izod/react`](./packages/react) | React hooks wrapper around `@izod/core` | + +## Installation ```sh -npm i zod @izod/core +# Core only +pnpm add @izod/core + +# With React hooks +pnpm add @izod/core @izod/react ``` -### react +You also need a Standard Schema compliant validator as a peer: ```sh -npm i zod @izod/core @izod/react +pnpm add zod # or valibot, arktype, etc. ``` -## Usage +## Quick Start -### @izod/core +### Define shared event schemas ```ts -// common.ts - -import { z } from 'zod'; -import type { EventMap } from '@izod/core'; - -export const parentOriginEvents = { - askQuestion: z.object({ - question: z.string(), - }), - shout: z.object({ - message: z.string(), - }), +// events.ts +import { z } from "zod"; +import type { EventMap } from "@izod/core"; + +export const parentEvents = { + askQuestion: z.object({ question: z.string() }), + shout: z.object({ message: z.string() }), } as const satisfies EventMap; -export const childOriginEvents = { - answerQuestion: z.object({ - answer: z.string(), - }), - whisper: z.object({ - message: z.string(), - }), +export const childEvents = { + answerQuestion: z.object({ answer: z.string() }), + whisper: z.object({ message: z.string() }), } as const satisfies EventMap; ``` -```ts -// parent.html +### Parent page (creates the iframe) -import { createChild } from '@izod/core'; +```ts +import { createChild } from "@izod/core"; +import { parentEvents, childEvents } from "./events"; -// create the child instance (not mounted until handshake is executed) const child = createChild({ - container: document.body, // required - url: 'http://127.0.0.1:3010', // required - inboundEvents: childOriginEvents, // optional - outboundEvents: parentOriginEvents, // optional - handshakeOptions: { - // optional - maxHandshakeRequests: 10, // default 5 - handshakeRetryInterval: 100, // default 1000 - }, + container: document.getElementById("app"), + url: "https://child.example.com", + inboundEvents: childEvents, + outboundEvents: parentEvents, }); -// perfect time to setup event listeners so that they are ready once the handshake is over -// type safe event listeners for events coming from the child -child.on('whisper', (data) => { +child.on("whisper", (data) => { console.log(`Child whispered: ${data.message}`); }); -const childApi = await child.executeHandshake(); - -// type safe event emitters -childApi.emit('shout', { message: 'Hello' }); +const api = await child.executeHandshake(); +api.emit("shout", { message: "Hello from parent" }); ``` -```ts -// child.html +### Child page (inside the iframe) -import { connectToParent } from '@izod/core'; +```ts +import { connectToParent } from "@izod/core"; +import { parentEvents, childEvents } from "./events"; -// sets the boilerplate const parent = connectToParent({ - inboundEvents: parentOriginEvents, // optional - outboundEvents: childOriginEvents, // optional + inboundEvents: parentEvents, + outboundEvents: childEvents, }); -// type safe event listeners for events coming from the parent -parent.on('shout', (data) => { +parent.on("shout", (data) => { console.log(`Parent shouted: ${data.message}`); }); -const parentApi = await parent.executeHandshake(); - -// type safe event emitters -parentApi.emit('whisper', { message: 'Hi' }); +const api = await parent.executeHandshake(); +api.emit("whisper", { message: "Hi from child" }); ``` -### @izod/react - -```tsx -// parent.tsx - -import { child } from '@izod/react'; - -function Parent() { - // accepts all the parameters that `createChild` from @izod/core does - // `api` is the same that is returned from `connectToParent.executeHandshake` from @izod/core - // `on` can be used to attach event listeners - const { on, api, executeHandshake } = child.useCreate({ - container: document.body, // required - url: 'http://127.0.0.1:3010', // required - inboundEvents: parentOriginEvents, // optional - outboundEvents: childOriginEvents, // optional - handshakeOptions: { - // optional - maxHandshakeRequests: 10, // default 5 - handshakeRetryInterval: 100, // default 1000 - }, - onHandshakeComplete(api) { - // callback called when handshake is successful - }, - onHandshakeError(error) { - // callback called when handshake fails - }, - // remove the iframe on component unmount - destroyOnUnmount: false, // default false - optional - }); - - // `child.useEventListener` takes care of this boilerplate for you but is not fully type safe as of now - // to add event listeners - // prefer this over `onHandshakeComplete` for attaching event listeners - useEffect(() => { - if (api) { - // function is returned from `.on` that can be called to unsubscribe - const off = on('askQuestion', (data) => { - console.log('Question: ', data.question); - }); - - // return that from the useEffect for cleanup - return off; - } - }, [api]); - - const ranOnce = useRef(false); - useEffect(() => { - if (ranOnce.current) { - return; - } - - executeHandshake(); - ranOnce.current = true; - }, []); - - const shout = () => { - api.emit('shout', { message: 'Hello' }); - }; -} +See individual package READMEs for full API documentation: + +- [`@izod/core` README](./packages/core/README.md) +- [`@izod/react` README](./packages/react/README.md) + +## Examples + +The [`examples/`](./examples) directory contains a working Astro demo app with both core and React examples. + +```sh +pnpm install +cd examples/astro-demo +pnpm dev ``` -```tsx -// child.tsx - -import { parent } from '@izod/react'; - -function Child() { - // `api` is the same that is returned from `connectToParent.executeHandshake` from @izod/core - const { on, api, executeHandshake } = parent.useConnect({ - inboundEvents: parentOriginEvents, - outboundEvents: childOriginEvents, - onHandshakeComplete(api) { - // callback called when handshake is successful - }, - onHandshakeError(error) { - // callback called when handshake fails - }, - }); - - // `parent.useEventListener` takes care of this boilerplate for you but is not fully type safe as of now - // to add event listeners - useEffect(() => { - // function is returned from `.on` that can be called to unsubscribe - if (api) { - const off = api.on('shout', (data) => { - console.log(`Parent shouted: ${data.message}`); - }); - - // return that from the useEffect for cleanup - return off; - } - }, [api]); - - const ranOnce = useRef(false); - useEffect(() => { - if (ranOnce.current) { - return; - } - - executeHandshake(); - ranOnce.current = true; - }, []); - - const whisper = () => { - api.emit('whisper', { message: 'Hi' }); - }; -} +## Standard Schema Compatibility + +Any validator implementing the [Standard Schema spec](https://github.com/standard-schema/standard-schema) works out of the box. Schemas must validate **synchronously** — async validators will throw a `TypeError`. + +| Validator | Supported | +|-----------|-----------| +| zod (v3.24+, v4) | Yes | +| valibot | Yes | +| arktype | Yes | + +## Development + +```sh +pnpm install +pnpm run build # build all packages +pnpm run test # run tests +pnpm run test:coverage # run tests with coverage +pnpm run typecheck # type-check +pnpm run lint # oxlint +pnpm run format:check # check formatting ``` -## Prior Art (packages I ~~copied~~ adapted code from) +## Prior Art - [Postmate](https://github.com/dollarshaveclub/postmate) + +## License + +MIT diff --git a/examples/astro-demo/src/components/ReactChild.tsx b/examples/astro-demo/src/components/ReactChild.tsx index 29fc8aa..ac4929b 100644 --- a/examples/astro-demo/src/components/ReactChild.tsx +++ b/examples/astro-demo/src/components/ReactChild.tsx @@ -19,10 +19,7 @@ export default function ReactChild() { const logIdRef = useRef(0); function appendLog(message: string, type: LogEntry["type"]) { - setLogs((prev) => [ - ...prev, - { id: ++logIdRef.current, message, type }, - ]); + setLogs((prev) => [...prev, { id: ++logIdRef.current, message, type }]); } const { on, executeHandshake, api, isHandshakeComplete, isHandshakePending, handshakeError } = @@ -98,7 +95,9 @@ export default function ReactChild() {
{logs.map((entry) => { - const prefix = { sent: "↑ SENT", received: "↓ RECV", system: "● SYS", error: "✕ ERR" }[entry.type]; + const prefix = { sent: "↑ SENT", received: "↓ RECV", system: "● SYS", error: "✕ ERR" }[ + entry.type + ]; return (
[{new Date().toLocaleTimeString()}] {prefix}: {entry.message} diff --git a/examples/astro-demo/src/components/ReactParent.tsx b/examples/astro-demo/src/components/ReactParent.tsx index d43fa92..2560c3a 100644 --- a/examples/astro-demo/src/components/ReactParent.tsx +++ b/examples/astro-demo/src/components/ReactParent.tsx @@ -20,10 +20,7 @@ export default function ReactParent({ base }: { base: string }) { const logIdRef = useRef(0); function appendLog(message: string, type: LogEntry["type"]) { - setLogs((prev) => [ - ...prev, - { id: ++logIdRef.current, message, type }, - ]); + setLogs((prev) => [...prev, { id: ++logIdRef.current, message, type }]); } const { on, executeHandshake, api, isHandshakeComplete, isHandshakePending, handshakeError } = @@ -87,9 +84,11 @@ export default function ReactParent({ base }: { base: string }) { <> {statusText} -
{ - if (node && !node.contains(container)) node.appendChild(container); - }} /> +
{ + if (node && !node.contains(container)) node.appendChild(container); + }} + />
Event Log
{logs.map((entry) => { - const prefix = { sent: "↑ SENT", received: "↓ RECV", system: "● SYS", error: "✕ ERR" }[entry.type]; + const prefix = { sent: "↑ SENT", received: "↓ RECV", system: "● SYS", error: "✕ ERR" }[ + entry.type + ]; return (
[{new Date().toLocaleTimeString()}] {prefix}: {entry.message} diff --git a/package.json b/package.json index 86d8a89..886ec4b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,15 @@ { "name": "izod-monorepo", "private": true, + "homepage": "https://github.com/drenther/izod", + "license": "MIT", + "author": { + "name": "Soumyajit Pathak" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/drenther/izod.git" + }, "type": "module", "scripts": { "build": "turbo run build", @@ -26,15 +35,6 @@ "oxlint": "1.62.0", "turbo": "2.5.6" }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/drenther/izod.git" - }, - "homepage": "https://github.com/drenther/izod", - "author": { - "name": "Soumyajit Pathak" - }, - "license": "MIT", "engines": { "node": ">=24.15.0" }, diff --git a/packages/core/README.md b/packages/core/README.md new file mode 100644 index 0000000..78225cd --- /dev/null +++ b/packages/core/README.md @@ -0,0 +1,102 @@ +# @izod/core + +Type-safe iframe communication engine using the [Standard Schema](https://github.com/standard-schema/standard-schema) interface for runtime validation. No framework dependency. + +## Installation + +```sh +pnpm add @izod/core +``` + +You also need a Standard Schema compliant validator: + +```sh +pnpm add zod # or valibot, arktype, etc. +``` + +## API + +### `createChild(params)` + +Called from the **parent** page to create and manage a child iframe. + +```ts +import { createChild } from "@izod/core"; + +const child = createChild({ + container: document.getElementById("app"), // DOM element to append iframe to + url: "https://child.example.com", // child page URL + namespace: "my-app", // optional — isolate message channels + inboundEvents: childEvents, // schemas for events FROM the child + outboundEvents: parentEvents, // schemas for events TO the child + iframeAttributes: { // optional — passed to the iframe element + style: "width:100%;height:400px;border:none", + }, + handshakeOptions: { // optional + maxHandshakeRequests: 10, // default: 5 + handshakeRetryInterval: 100, // default: 1000 (ms) + }, + enableLogging: false, // optional — log internal messages +}); +``` + +**Returns:** + +- `on(eventName, handler)` — register a listener for inbound events. Returns an unsubscribe function. +- `executeHandshake()` — returns a `Promise` that resolves with the API object once the child is ready. + +**Handshake result API:** + +- `emit(eventName, data)` — send a validated event to the child. +- `destroy()` — remove the iframe and clean up listeners. + +### `connectToParent(params)` + +Called from the **child** page to connect back to the parent. + +```ts +import { connectToParent } from "@izod/core"; + +const parent = connectToParent({ + namespace: "my-app", // must match the parent's namespace + inboundEvents: parentEvents, // schemas for events FROM the parent + outboundEvents: childEvents, // schemas for events TO the parent + enableLogging: false, // optional +}); +``` + +**Returns:** same shape as `createChild` — `on()`, `executeHandshake()`. + +**Handshake result API:** + +- `emit(eventName, data)` — send a validated event to the parent. + +### `EventMap` + +Type alias for event schema maps: + +```ts +import type { EventMap } from "@izod/core"; + +const events = { + ping: z.object({ timestamp: z.number() }), + message: z.object({ text: z.string() }), +} as const satisfies EventMap; +``` + +Each value must be a Standard Schema compliant validator. Schemas must validate synchronously. + +## Error Handling + +Event validation errors include a `cause` property: + +| Cause | Meaning | +|-------|---------| +| `event_name_invalid` | Event name not in the schema map | +| `event_data_invalid` | Data failed schema validation | +| `handshake_request_invalid` | Malformed handshake message | +| `handshake_request_timeout` | Handshake timed out | + +## License + +MIT diff --git a/packages/core/package.json b/packages/core/package.json index 20d444d..4031da8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,11 +1,26 @@ { "name": "@izod/core", "version": "2.0.0", - "type": "module", - "sideEffects": false, + "keywords": [ + "iframe", + "postmessage", + "standard-schema", + "typescript" + ], + "homepage": "https://github.com/drenther/izod", + "license": "MIT", + "author": { + "name": "Soumyajit Pathak" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/drenther/izod.git" + }, "files": [ "dist" ], + "type": "module", + "sideEffects": false, "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", @@ -37,20 +52,5 @@ "tsdown": "catalog:", "typescript": "catalog:", "vitest": "catalog:" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/drenther/izod.git" - }, - "homepage": "https://github.com/drenther/izod", - "author": { - "name": "Soumyajit Pathak" - }, - "keywords": [ - "iframe", - "typescript", - "standard-schema", - "postmessage" - ], - "license": "MIT" + } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 28286c0..c6fc13c 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -32,8 +32,7 @@ function resolveOrigin(url?: string) { const anchor = document.createElement("a"); anchor.href = url; - const protocol = - anchor.protocol.length > 4 ? anchor.protocol : window.location.protocol; + const protocol = anchor.protocol.length > 4 ? anchor.protocol : window.location.protocol; const host = anchor.host.length ? anchor.port === "80" || anchor.port === "443" ? anchor.hostname @@ -49,9 +48,7 @@ export function generateUniqueId(namespace?: string) { function validateSync( schema: T, data: unknown, -): - | { success: true; data: StandardSchemaV1.InferOutput } - | { success: false; error: string } { +): { success: true; data: StandardSchemaV1.InferOutput } | { success: false; error: string } { const result = schema["~standard"].validate(data); if (result instanceof Promise) { throw new TypeError("Schema validation must be synchronous"); @@ -71,35 +68,25 @@ interface BaseMessageData { function isBaseMessageData(data: unknown): data is BaseMessageData { if (typeof data !== "object" || data === null) return false; const record = data as Record; - return ( - record["contentType"] === eventContentType && typeof record["id"] === "string" - ); + return record["contentType"] === eventContentType && typeof record["id"] === "string"; } export interface HandshakeRequestMessageData extends BaseMessageData { - messageType: typeof messageTypes["handshake-request"]; + messageType: (typeof messageTypes)["handshake-request"]; } -function isHandshakeRequest( - data: unknown, -): data is HandshakeRequestMessageData { +function isHandshakeRequest(data: unknown): data is HandshakeRequestMessageData { if (!isBaseMessageData(data)) return false; - return ( - "messageType" in data && - data.messageType === messageTypes["handshake-request"] - ); + return "messageType" in data && data.messageType === messageTypes["handshake-request"]; } export interface HandshakeReplyMessageData extends BaseMessageData { - messageType: typeof messageTypes["handshake-reply"]; + messageType: (typeof messageTypes)["handshake-reply"]; } function isHandshakeReply(data: unknown): data is HandshakeReplyMessageData { if (!isBaseMessageData(data)) return false; - return ( - "messageType" in data && - data.messageType === messageTypes["handshake-reply"] - ); + return "messageType" in data && data.messageType === messageTypes["handshake-reply"]; } interface EventPayload { @@ -114,35 +101,25 @@ function isEventPayload(data: unknown): data is EventPayload { } export interface ParentOriginatedMessageDataEventPayload extends BaseMessageData { - messageType: typeof messageTypes["parent-originated-event"]; + messageType: (typeof messageTypes)["parent-originated-event"]; event: EventPayload; } -function isParentOriginatedEvent( - data: unknown, -): data is ParentOriginatedMessageDataEventPayload { +function isParentOriginatedEvent(data: unknown): data is ParentOriginatedMessageDataEventPayload { if (!isBaseMessageData(data)) return false; if (!("messageType" in data) || !("event" in data)) return false; - return ( - data.messageType === messageTypes["parent-originated-event"] && - isEventPayload(data.event) - ); + return data.messageType === messageTypes["parent-originated-event"] && isEventPayload(data.event); } export interface ChildOriginatedMessageDataEventPayload extends BaseMessageData { - messageType: typeof messageTypes["child-originated-event"]; + messageType: (typeof messageTypes)["child-originated-event"]; event: EventPayload; } -function isChildOriginatedEvent( - data: unknown, -): data is ChildOriginatedMessageDataEventPayload { +function isChildOriginatedEvent(data: unknown): data is ChildOriginatedMessageDataEventPayload { if (!isBaseMessageData(data)) return false; if (!("messageType" in data) || !("event" in data)) return false; - return ( - data.messageType === messageTypes["child-originated-event"] && - isEventPayload(data.event) - ); + return data.messageType === messageTypes["child-originated-event"] && isEventPayload(data.event); } function isWhitelistedMessage(message: MessageEvent, allowedOrigin: string) { @@ -223,9 +200,7 @@ export function createChild< function on( eventName: E, - handler: ( - data: StandardSchemaV1.InferOutput, - ) => void | Promise, + handler: (data: StandardSchemaV1.InferOutput) => void | Promise, ) { const listenerId = Symbol(); listeners.set(listenerId, { @@ -241,10 +216,7 @@ export function createChild< }; } - function emit( - eventName: E, - data: StandardSchemaV1.InferInput, - ) { + function emit(eventName: E, data: StandardSchemaV1.InferInput) { const eventSchema = outboundEvents[eventName]; if (!eventSchema) { throw new Error( @@ -354,9 +326,7 @@ export function createChild< let handshakeAttempt = 0; let handshakeRetryIntervalTimer: ReturnType; - function handleHandshakeReply( - event: MessageEvent, - ) { + function handleHandshakeReply(event: MessageEvent) { log("Handshake Reply Event received:", event); if (!isWhitelistedMessage(event, childOrigin)) { @@ -380,10 +350,7 @@ export function createChild< } if (!isHandshakeReply(event.data)) { - log( - "Handshake Reply Event ignored due to invalid message data:", - event, - ); + log("Handshake Reply Event ignored due to invalid message data:", event); return; } @@ -391,11 +358,7 @@ export function createChild< log("Handshake Reply Event accepted:", event); clearInterval(handshakeRetryIntervalTimer); - parentWindow.removeEventListener( - "message", - handleHandshakeReply, - false, - ); + parentWindow.removeEventListener("message", handleHandshakeReply, false); const api = { destroy, @@ -464,10 +427,7 @@ export function createChild< }; } -export interface ConnectToParentParams< - IE extends EventMap, - OE extends EventMap, -> { +export interface ConnectToParentParams { namespace?: string; inboundEvents?: IE; outboundEvents?: OE; @@ -497,9 +457,7 @@ export function connectToParent( function on( eventName: E, - handler: ( - data: StandardSchemaV1.InferOutput, - ) => void | Promise, + handler: (data: StandardSchemaV1.InferOutput) => void | Promise, ) { const listenerId = Symbol(); listeners.set(listenerId, { @@ -516,10 +474,7 @@ export function connectToParent( } function createEmitter(parentOrigin: string) { - function emit( - eventName: E, - data: StandardSchemaV1.InferInput, - ) { + function emit(eventName: E, data: StandardSchemaV1.InferInput) { const eventSchema = outboundEvents[eventName]; if (!eventSchema) { throw new Error( @@ -575,19 +530,11 @@ export function connectToParent( on: typeof on; emit: ReturnType; }>((resolve, reject) => { - function handleHandshakeRequest( - event: MessageEvent, - ) { + function handleHandshakeRequest(event: MessageEvent) { log("Handshake Request Event Listener received:", event); - if ( - event.source instanceof MessagePort || - isEventSourceServiceWorker(event) - ) { - log( - "Handshake Request Event Listener ignored due to invalid source type:", - event.source, - ); + if (event.source instanceof MessagePort || isEventSourceServiceWorker(event)) { + log("Handshake Request Event Listener ignored due to invalid source type:", event.source); return; } @@ -637,10 +584,7 @@ export function connectToParent( } if (!isParentOriginatedEvent(parentEvent.data)) { - log( - "Parent Originated Event ignored due to invalid message data:", - parentEvent, - ); + log("Parent Originated Event ignored due to invalid message data:", parentEvent); return; } @@ -653,15 +597,9 @@ export function connectToParent( Array.from(listeners.values()) .filter(({ eventName }) => eventName === name) .forEach(({ handler, eventName }) => { - const dataParseResult = validateSync( - inboundEvents[eventName]!, - data, - ); + const dataParseResult = validateSync(inboundEvents[eventName]!, data); if (dataParseResult.success) { - log( - "Parent Originated Event Listener Handler invoked:", - eventName, - ); + log("Parent Originated Event Listener Handler invoked:", eventName); handler(dataParseResult.data); } diff --git a/packages/core/tests/index.test.ts b/packages/core/tests/index.test.ts index 49d099d..7369a0e 100644 --- a/packages/core/tests/index.test.ts +++ b/packages/core/tests/index.test.ts @@ -9,9 +9,7 @@ import { } from "../src/index.js"; function createMockSchema( - validateFn: ( - value: unknown, - ) => StandardSchemaV1.Result, + validateFn: (value: unknown) => StandardSchemaV1.Result, ): StandardSchemaV1 { return { "~standard": { @@ -26,9 +24,7 @@ function createPassthroughSchema(): StandardSchemaV1 { return createMockSchema((value) => ({ value: value as T })); } -function createFailingSchema( - issues: StandardSchemaV1.Issue[], -): StandardSchemaV1 { +function createFailingSchema(issues: StandardSchemaV1.Issue[]): StandardSchemaV1 { return createMockSchema(() => ({ issues })); } @@ -153,18 +149,13 @@ describe("Standard Schema validation", () => { return handshakePromise.then((api) => { expect(() => - (api.emit as (name: string, data: unknown) => void)( - "invalidEvent", - "data", - ), + (api.emit as (name: string, data: unknown) => void)("invalidEvent", "data"), ).toThrow("not defined in the outboundEvents map"); }); }); it("throws on invalid data for emit", () => { - const issues: StandardSchemaV1.Issue[] = [ - { message: "invalid data" }, - ]; + const issues: StandardSchemaV1.Issue[] = [{ message: "invalid data" }]; const outboundEvents = { testEvent: createFailingSchema(issues), }; @@ -227,9 +218,7 @@ describe("Standard Schema validation", () => { return handshakePromise.then((api) => { expect(() => api.emit("testEvent", "data")).toThrow(TypeError); - expect(() => api.emit("testEvent", "data")).toThrow( - "Schema validation must be synchronous", - ); + expect(() => api.emit("testEvent", "data")).toThrow("Schema validation must be synchronous"); }); }); diff --git a/packages/react/README.md b/packages/react/README.md new file mode 100644 index 0000000..8d162b0 --- /dev/null +++ b/packages/react/README.md @@ -0,0 +1,137 @@ +# @izod/react + +React hooks for type-safe iframe communication. Wraps [`@izod/core`](../core) with React lifecycle management. + +## Installation + +```sh +pnpm add @izod/core @izod/react +``` + +`react` (>=16.8) and `@izod/core` are peer dependencies. + +## API + +### `child.useCreate(params)` + +Hook for the **parent** component to create and manage a child iframe. + +```tsx +import { child } from "@izod/react"; + +function Parent() { + const [container] = useState(() => document.createElement("div")); + + const { + on, + executeHandshake, + api, + isHandshakeComplete, + isHandshakePending, + handshakeError, + } = child.useCreate({ + container, // DOM element for the iframe + url: "https://child.example.com", + namespace: "my-app", // optional + inboundEvents: childEvents, // schemas for events FROM the child + outboundEvents: parentEvents, // schemas for events TO the child + iframeAttributes: { // optional + style: "width:100%;height:400px;border:none", + }, + handshakeOptions: { // optional + maxHandshakeRequests: 10, + handshakeRetryInterval: 100, + }, + onHandshakeComplete: (api) => { + console.log("Connected!"); + }, + onHandshakeError: (error) => { + console.error("Handshake failed:", error); + }, + destroyOnUnmount: true, // default: true — remove iframe on unmount + }); + + useEffect(() => { + const off = on("childMessage", (data) => { + console.log(data); + }); + return off; + }, [on]); + + useEffect(() => { + executeHandshake(); + }, [executeHandshake]); + + return ( + <> +
{ + if (node && !node.contains(container)) node.appendChild(container); + }} /> + {isHandshakeComplete && ( + + )} + + ); +} +``` + +**Returns:** + +| Property | Type | Description | +|----------|------|-------------| +| `on` | `(event, handler) => unsubscribe` | Register inbound event listener | +| `executeHandshake` | `() => void` | Start the handshake | +| `api` | `object \| undefined` | Handshake result with `emit()` and `destroy()` | +| `isHandshakeComplete` | `boolean` | Whether handshake succeeded | +| `isHandshakePending` | `boolean` | Whether handshake is in progress | +| `handshakeError` | `Error \| undefined` | Handshake error, if any | + +### `parent.useConnect(params)` + +Hook for the **child** component (inside the iframe) to connect back to the parent. + +```tsx +import { parent } from "@izod/react"; + +function Child() { + const { + on, + executeHandshake, + api, + isHandshakeComplete, + isHandshakePending, + handshakeError, + } = parent.useConnect({ + namespace: "my-app", + inboundEvents: parentEvents, + outboundEvents: childEvents, + onHandshakeComplete: (api) => { + console.log("Connected to parent!"); + }, + onHandshakeError: (error) => { + console.error("Failed:", error); + }, + }); + + useEffect(() => { + executeHandshake(); + }, [executeHandshake]); + + useEffect(() => { + const off = on("parentMessage", (data) => { + console.log(data); + }); + return off; + }, [on]); + + return
{isHandshakeComplete ? "Connected" : "Connecting..."}
; +} +``` + +**Returns:** same shape as `child.useCreate`. + +## License + +MIT diff --git a/packages/react/package.json b/packages/react/package.json index ad4e390..f6171fd 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,11 +1,27 @@ { "name": "@izod/react", "version": "2.0.0", - "type": "module", - "sideEffects": false, + "keywords": [ + "hooks", + "iframe", + "react", + "standard-schema", + "typescript" + ], + "homepage": "https://github.com/drenther/izod", + "license": "MIT", + "author": { + "name": "Soumyajit Pathak" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/drenther/izod.git" + }, "files": [ "dist" ], + "type": "module", + "sideEffects": false, "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", @@ -26,10 +42,6 @@ "test:coverage": "vitest run --coverage", "typecheck": "tsc --noEmit" }, - "peerDependencies": { - "@izod/core": "workspace:*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - }, "devDependencies": { "@izod/core": "workspace:*", "@standard-schema/spec": "catalog:", @@ -45,20 +57,8 @@ "typescript": "catalog:", "vitest": "catalog:" }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/drenther/izod.git" - }, - "homepage": "https://github.com/drenther/izod", - "author": { - "name": "Soumyajit Pathak" - }, - "keywords": [ - "react", - "iframe", - "typescript", - "standard-schema", - "hooks" - ], - "license": "MIT" + "peerDependencies": { + "@izod/core": "workspace:*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } } diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index b35727a..465ba01 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -23,8 +23,7 @@ function useAsyncCallback(asyncFn: () => Promise) { const execute = useCallback(() => { setState({ loading: true, value: undefined, error: undefined }); asyncFn().then( - (value) => - setState({ loading: false, value, error: undefined }), + (value) => setState({ loading: false, value, error: undefined }), (error: unknown) => setState({ loading: false, @@ -41,18 +40,14 @@ type CreateChildHandshakeResult< IE extends EventMap, OE extends EventMap, T extends HTMLElement | Element, -> = Awaited< - ReturnType>["executeHandshake"]> ->; +> = Awaited>["executeHandshake"]>>; interface UseChildIframeParams< IE extends EventMap, OE extends EventMap, T extends HTMLElement | Element, > extends CreateChildParams { - onHandshakeComplete?: ( - api: CreateChildHandshakeResult, - ) => void; + onHandshakeComplete?: (api: CreateChildHandshakeResult) => void; onHandshakeError?: (error: Error) => void; destroyOnUnmount?: boolean; } @@ -68,17 +63,11 @@ function useCreateChildIframe< ...props }: UseChildIframeParams) { const childRef = useRef(createChild(props)); - const executeHandshakeFn = useCallback( - () => childRef.current.executeHandshake(), - [], - ); - const [handshakeState, executeHandshake] = - useAsyncCallback(executeHandshakeFn); - - const onHandshakeCompleteCallbackRef = - useRef(onHandshakeComplete); - const onHandshakeErrorCallbackRef = - useRef(onHandshakeError); + const executeHandshakeFn = useCallback(() => childRef.current.executeHandshake(), []); + const [handshakeState, executeHandshake] = useAsyncCallback(executeHandshakeFn); + + const onHandshakeCompleteCallbackRef = useRef(onHandshakeComplete); + const onHandshakeErrorCallbackRef = useRef(onHandshakeError); const destroyOnUnmountRef = useRef(destroyOnUnmount ?? true); const apiRef = useRef(undefined); @@ -130,18 +119,15 @@ export const child = { useCreate: useCreateChildIframe, } as const; -type ConnectToParentHandshakeResult< - IE extends EventMap, - OE extends EventMap, -> = Awaited< +type ConnectToParentHandshakeResult = Awaited< ReturnType>["executeHandshake"]> >; -interface UseParentParams - extends ConnectToParentParams { - onHandshakeComplete?: ( - api: ConnectToParentHandshakeResult, - ) => void; +interface UseParentParams extends ConnectToParentParams< + IE, + OE +> { + onHandshakeComplete?: (api: ConnectToParentHandshakeResult) => void; onHandshakeError?: (error: Error) => void; } @@ -153,17 +139,11 @@ function useConnectToParent( }: UseParentParams = {} as UseParentParams, ) { const parentRef = useRef(connectToParent(props)); - const executeHandshakeFn = useCallback( - () => parentRef.current.executeHandshake(), - [], - ); - const [handshakeState, executeHandshake] = - useAsyncCallback(executeHandshakeFn); - - const onHandshakeCompleteCallbackRef = - useRef(onHandshakeComplete); - const onHandshakeErrorCallbackRef = - useRef(onHandshakeError); + const executeHandshakeFn = useCallback(() => parentRef.current.executeHandshake(), []); + const [handshakeState, executeHandshake] = useAsyncCallback(executeHandshakeFn); + + const onHandshakeCompleteCallbackRef = useRef(onHandshakeComplete); + const onHandshakeErrorCallbackRef = useRef(onHandshakeError); const apiRef = useRef(undefined); diff --git a/packages/react/tests/react.test.ts b/packages/react/tests/react.test.ts index edb0a6a..b5282d6 100644 --- a/packages/react/tests/react.test.ts +++ b/packages/react/tests/react.test.ts @@ -27,9 +27,7 @@ describe("child.useCreate", () => { }); it("returns expected API shape", () => { - const { result } = renderHook(() => - child.useCreate({ container }), - ); + const { result } = renderHook(() => child.useCreate({ container })); expect(result.current).toHaveProperty("on"); expect(result.current).toHaveProperty("executeHandshake"); @@ -49,9 +47,7 @@ describe("child.useCreate", () => { testEvent: createPassthroughSchema(), }; - const { result } = renderHook(() => - child.useCreate({ container, inboundEvents }), - ); + const { result } = renderHook(() => child.useCreate({ container, inboundEvents })); const handler = vi.fn(); const unsubscribe = result.current.on("testEvent", handler); @@ -116,9 +112,7 @@ describe("parent.useConnect", () => { testEvent: createPassthroughSchema(), }; - const { result } = renderHook(() => - parent.useConnect({ inboundEvents }), - ); + const { result } = renderHook(() => parent.useConnect({ inboundEvents })); const handler = vi.fn(); const unsubscribe = result.current.on("testEvent", handler); From 24bd37b2c0970b2f74fb85326237964af587337a Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 23:28:33 +0530 Subject: [PATCH 10/16] style: add oxfmt config with singleQuote and reformat codebase - Add .oxfmtrc.json with singleQuote: true to match old .prettierrc - Add coverage/ to .gitignore - Add per-package README badges for bundle size, npm version, types - Reformat all source files with corrected quote style --- .github/workflows/release.yml | 2 +- .oxfmtrc.json | 4 + README.md | 42 ++-- commitlint.config.js | 2 +- examples/astro-demo/astro.config.mjs | 8 +- .../astro-demo/src/components/ReactChild.tsx | 48 ++-- .../astro-demo/src/components/ReactParent.tsx | 56 ++--- packages/core/README.md | 52 +++-- packages/core/src/index.ts | 154 ++++++------- packages/core/tests/index.test.ts | 210 +++++++++--------- packages/core/tsdown.config.ts | 14 +- packages/core/vitest.config.ts | 12 +- packages/react/README.md | 126 +++++------ packages/react/src/index.ts | 8 +- packages/react/tests/react.test.ts | 80 +++---- packages/react/tests/setup.ts | 2 +- packages/react/tsdown.config.ts | 14 +- packages/react/vitest.config.ts | 12 +- pnpm-workspace.yaml | 36 +-- 19 files changed, 441 insertions(+), 441 deletions(-) create mode 100644 .oxfmtrc.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b4d4f1..b9f5f87 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 24.15.0 - registry-url: "https://registry.npmjs.org" + registry-url: 'https://registry.npmjs.org' - run: pnpm install --frozen-lockfile diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000..3a4f99e --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,4 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "singleQuote": true +} diff --git a/README.md b/README.md index 172d335..9ee38f4 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ Works with any Standard Schema compliant validator — [zod](https://github.com/ ## Packages -| Package | Description | -|---------|-------------| -| [`@izod/core`](./packages/core) | Iframe communication engine — no framework dependency | -| [`@izod/react`](./packages/react) | React hooks wrapper around `@izod/core` | +| Package | Description | +| --------------------------------- | ----------------------------------------------------- | +| [`@izod/core`](./packages/core) | Iframe communication engine — no framework dependency | +| [`@izod/react`](./packages/react) | React hooks wrapper around `@izod/core` | ## Installation @@ -35,8 +35,8 @@ pnpm add zod # or valibot, arktype, etc. ```ts // events.ts -import { z } from "zod"; -import type { EventMap } from "@izod/core"; +import { z } from 'zod'; +import type { EventMap } from '@izod/core'; export const parentEvents = { askQuestion: z.object({ question: z.string() }), @@ -52,41 +52,41 @@ export const childEvents = { ### Parent page (creates the iframe) ```ts -import { createChild } from "@izod/core"; -import { parentEvents, childEvents } from "./events"; +import { createChild } from '@izod/core'; +import { parentEvents, childEvents } from './events'; const child = createChild({ - container: document.getElementById("app"), - url: "https://child.example.com", + container: document.getElementById('app'), + url: 'https://child.example.com', inboundEvents: childEvents, outboundEvents: parentEvents, }); -child.on("whisper", (data) => { +child.on('whisper', (data) => { console.log(`Child whispered: ${data.message}`); }); const api = await child.executeHandshake(); -api.emit("shout", { message: "Hello from parent" }); +api.emit('shout', { message: 'Hello from parent' }); ``` ### Child page (inside the iframe) ```ts -import { connectToParent } from "@izod/core"; -import { parentEvents, childEvents } from "./events"; +import { connectToParent } from '@izod/core'; +import { parentEvents, childEvents } from './events'; const parent = connectToParent({ inboundEvents: parentEvents, outboundEvents: childEvents, }); -parent.on("shout", (data) => { +parent.on('shout', (data) => { console.log(`Parent shouted: ${data.message}`); }); const api = await parent.executeHandshake(); -api.emit("whisper", { message: "Hi from child" }); +api.emit('whisper', { message: 'Hi from child' }); ``` See individual package READMEs for full API documentation: @@ -108,11 +108,11 @@ pnpm dev Any validator implementing the [Standard Schema spec](https://github.com/standard-schema/standard-schema) works out of the box. Schemas must validate **synchronously** — async validators will throw a `TypeError`. -| Validator | Supported | -|-----------|-----------| -| zod (v3.24+, v4) | Yes | -| valibot | Yes | -| arktype | Yes | +| Validator | Supported | +| ---------------- | --------- | +| zod (v3.24+, v4) | Yes | +| valibot | Yes | +| arktype | Yes | ## Development diff --git a/commitlint.config.js b/commitlint.config.js index fa584fb..3f5e287 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1 +1 @@ -export default { extends: ["@commitlint/config-conventional"] }; +export default { extends: ['@commitlint/config-conventional'] }; diff --git a/examples/astro-demo/astro.config.mjs b/examples/astro-demo/astro.config.mjs index 3c0fc55..be57b51 100644 --- a/examples/astro-demo/astro.config.mjs +++ b/examples/astro-demo/astro.config.mjs @@ -1,8 +1,8 @@ -import { defineConfig } from "astro/config"; -import react from "@astrojs/react"; +import { defineConfig } from 'astro/config'; +import react from '@astrojs/react'; export default defineConfig({ - site: "https://drenther.github.io", - base: "/izod", + site: 'https://drenther.github.io', + base: '/izod', integrations: [react()], }); diff --git a/examples/astro-demo/src/components/ReactChild.tsx b/examples/astro-demo/src/components/ReactChild.tsx index ac4929b..68439c4 100644 --- a/examples/astro-demo/src/components/ReactChild.tsx +++ b/examples/astro-demo/src/components/ReactChild.tsx @@ -1,6 +1,6 @@ -import { useRef, useState, useEffect } from "react"; -import { parent } from "@izod/react"; -import { z } from "zod"; +import { useRef, useState, useEffect } from 'react'; +import { parent } from '@izod/react'; +import { z } from 'zod'; const messageSchema = z.object({ text: z.string(), @@ -10,21 +10,21 @@ const messageSchema = z.object({ type LogEntry = { id: number; message: string; - type: "sent" | "received" | "system" | "error"; + type: 'sent' | 'received' | 'system' | 'error'; }; export default function ReactChild() { const [logs, setLogs] = useState([]); - const [input, setInput] = useState(""); + const [input, setInput] = useState(''); const logIdRef = useRef(0); - function appendLog(message: string, type: LogEntry["type"]) { + function appendLog(message: string, type: LogEntry['type']) { setLogs((prev) => [...prev, { id: ++logIdRef.current, message, type }]); } const { on, executeHandshake, api, isHandshakeComplete, isHandshakePending, handshakeError } = parent.useConnect({ - namespace: "izod-react-demo", + namespace: 'izod-react-demo', inboundEvents: { parentMessage: messageSchema, }, @@ -32,46 +32,46 @@ export default function ReactChild() { childMessage: messageSchema, }, onHandshakeComplete: () => { - appendLog("Handshake complete — connected to parent", "system"); + appendLog('Handshake complete — connected to parent', 'system'); }, onHandshakeError: (error) => { - appendLog(`Connection failed: ${error.message}`, "error"); + appendLog(`Connection failed: ${error.message}`, 'error'); }, }); useEffect(() => { - const unsubscribe = on("parentMessage", (data) => { - appendLog(data.text, "received"); + const unsubscribe = on('parentMessage', (data) => { + appendLog(data.text, 'received'); }); return unsubscribe; }, [on]); useEffect(() => { - appendLog("Waiting for handshake from parent...", "system"); + appendLog('Waiting for handshake from parent...', 'system'); executeHandshake(); }, [executeHandshake]); function sendMessage() { const text = input.trim(); if (!text || !api) return; - api.emit("childMessage", { text, timestamp: Date.now() }); - appendLog(text, "sent"); - setInput(""); + api.emit('childMessage', { text, timestamp: Date.now() }); + appendLog(text, 'sent'); + setInput(''); } const statusClass = handshakeError - ? "status error" + ? 'status error' : isHandshakeComplete - ? "status connected" - : "status pending"; + ? 'status connected' + : 'status pending'; const statusText = handshakeError - ? "Error" + ? 'Error' : isHandshakeComplete - ? "Connected" + ? 'Connected' : isHandshakePending - ? "Connecting..." - : "Waiting for parent..."; + ? 'Connecting...' + : 'Waiting for parent...'; return ( <> @@ -85,7 +85,7 @@ export default function ReactChild() { value={input} onChange={(event) => setInput(event.target.value)} onKeyDown={(event) => { - if (event.key === "Enter") sendMessage(); + if (event.key === 'Enter') sendMessage(); }} />
-

Event Log

+

Event Log

{logs.map((entry) => { - const prefix = { sent: "↑ SENT", received: "↓ RECV", system: "● SYS", error: "✕ ERR" }[ + const prefix = { sent: '↑ SENT', received: '↓ RECV', system: '● SYS', error: '✕ ERR' }[ entry.type ]; return ( diff --git a/packages/core/README.md b/packages/core/README.md index 78225cd..dcddbd0 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -1,5 +1,7 @@ # @izod/core +![Bundle Size](https://img.shields.io/bundlephobia/minzip/@izod/core) ![npm version](https://badgen.net/npm/v/@izod/core) ![types](https://badgen.net/npm/types/@izod/core) + Type-safe iframe communication engine using the [Standard Schema](https://github.com/standard-schema/standard-schema) interface for runtime validation. No framework dependency. ## Installation @@ -21,22 +23,24 @@ pnpm add zod # or valibot, arktype, etc. Called from the **parent** page to create and manage a child iframe. ```ts -import { createChild } from "@izod/core"; +import { createChild } from '@izod/core'; const child = createChild({ - container: document.getElementById("app"), // DOM element to append iframe to - url: "https://child.example.com", // child page URL - namespace: "my-app", // optional — isolate message channels - inboundEvents: childEvents, // schemas for events FROM the child - outboundEvents: parentEvents, // schemas for events TO the child - iframeAttributes: { // optional — passed to the iframe element - style: "width:100%;height:400px;border:none", + container: document.getElementById('app'), // DOM element to append iframe to + url: 'https://child.example.com', // child page URL + namespace: 'my-app', // optional — isolate message channels + inboundEvents: childEvents, // schemas for events FROM the child + outboundEvents: parentEvents, // schemas for events TO the child + iframeAttributes: { + // optional — passed to the iframe element + style: 'width:100%;height:400px;border:none', }, - handshakeOptions: { // optional - maxHandshakeRequests: 10, // default: 5 - handshakeRetryInterval: 100, // default: 1000 (ms) + handshakeOptions: { + // optional + maxHandshakeRequests: 10, // default: 5 + handshakeRetryInterval: 100, // default: 1000 (ms) }, - enableLogging: false, // optional — log internal messages + enableLogging: false, // optional — log internal messages }); ``` @@ -55,13 +59,13 @@ const child = createChild({ Called from the **child** page to connect back to the parent. ```ts -import { connectToParent } from "@izod/core"; +import { connectToParent } from '@izod/core'; const parent = connectToParent({ - namespace: "my-app", // must match the parent's namespace - inboundEvents: parentEvents, // schemas for events FROM the parent - outboundEvents: childEvents, // schemas for events TO the parent - enableLogging: false, // optional + namespace: 'my-app', // must match the parent's namespace + inboundEvents: parentEvents, // schemas for events FROM the parent + outboundEvents: childEvents, // schemas for events TO the parent + enableLogging: false, // optional }); ``` @@ -76,7 +80,7 @@ const parent = connectToParent({ Type alias for event schema maps: ```ts -import type { EventMap } from "@izod/core"; +import type { EventMap } from '@izod/core'; const events = { ping: z.object({ timestamp: z.number() }), @@ -90,12 +94,12 @@ Each value must be a Standard Schema compliant validator. Schemas must validate Event validation errors include a `cause` property: -| Cause | Meaning | -|-------|---------| -| `event_name_invalid` | Event name not in the schema map | -| `event_data_invalid` | Data failed schema validation | -| `handshake_request_invalid` | Malformed handshake message | -| `handshake_request_timeout` | Handshake timed out | +| Cause | Meaning | +| --------------------------- | -------------------------------- | +| `event_name_invalid` | Event name not in the schema map | +| `event_data_invalid` | Data failed schema validation | +| `handshake_request_invalid` | Malformed handshake message | +| `handshake_request_timeout` | Handshake timed out | ## License diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c6fc13c..21a7f93 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,40 +1,40 @@ -import type { StandardSchemaV1 } from "@standard-schema/spec"; -import crelt from "crelt"; -import { nanoid } from "nanoid"; +import type { StandardSchemaV1 } from '@standard-schema/spec'; +import crelt from 'crelt'; +import { nanoid } from 'nanoid'; -export type { StandardSchemaV1 } from "@standard-schema/spec"; +export type { StandardSchemaV1 } from '@standard-schema/spec'; -export const eventContentType = "application/x-izod+json" as const; +export const eventContentType = 'application/x-izod+json' as const; const createLogger = (enabled: boolean = false): typeof console.info => enabled ? console.info.bind(console) : () => {}; export const messageTypes = { - "handshake-request": "handshake-request", - "handshake-reply": "handshake-reply", - "child-originated-event": "child-originated-event", - "parent-originated-event": "parent-originated-event", + 'handshake-request': 'handshake-request', + 'handshake-reply': 'handshake-reply', + 'child-originated-event': 'child-originated-event', + 'parent-originated-event': 'parent-originated-event', } as const; export const errorCauses = { - handshake_request_invalid: "handshake_request_invalid", - handshake_request_timeout: "handshake_request_timeout", - event_name_invalid: "event_name_invalid", - event_data_invalid: "event_data_invalid", + handshake_request_invalid: 'handshake_request_invalid', + handshake_request_timeout: 'handshake_request_timeout', + event_name_invalid: 'event_name_invalid', + event_data_invalid: 'event_data_invalid', } as const; -const wildcardOrigin = "*"; +const wildcardOrigin = '*'; function resolveOrigin(url?: string) { if (!url) { return wildcardOrigin; } - const anchor = document.createElement("a"); + const anchor = document.createElement('a'); anchor.href = url; const protocol = anchor.protocol.length > 4 ? anchor.protocol : window.location.protocol; const host = anchor.host.length - ? anchor.port === "80" || anchor.port === "443" + ? anchor.port === '80' || anchor.port === '443' ? anchor.hostname : anchor.host : window.location.host; @@ -42,16 +42,16 @@ function resolveOrigin(url?: string) { } export function generateUniqueId(namespace?: string) { - return `${namespace ?? "anon"}__${nanoid()}`; + return `${namespace ?? 'anon'}__${nanoid()}`; } function validateSync( schema: T, data: unknown, ): { success: true; data: StandardSchemaV1.InferOutput } | { success: false; error: string } { - const result = schema["~standard"].validate(data); + const result = schema['~standard'].validate(data); if (result instanceof Promise) { - throw new TypeError("Schema validation must be synchronous"); + throw new TypeError('Schema validation must be synchronous'); } if (result.issues) { return { success: false, error: JSON.stringify(result.issues, null, 2) }; @@ -66,27 +66,27 @@ interface BaseMessageData { } function isBaseMessageData(data: unknown): data is BaseMessageData { - if (typeof data !== "object" || data === null) return false; + if (typeof data !== 'object' || data === null) return false; const record = data as Record; - return record["contentType"] === eventContentType && typeof record["id"] === "string"; + return record['contentType'] === eventContentType && typeof record['id'] === 'string'; } export interface HandshakeRequestMessageData extends BaseMessageData { - messageType: (typeof messageTypes)["handshake-request"]; + messageType: (typeof messageTypes)['handshake-request']; } function isHandshakeRequest(data: unknown): data is HandshakeRequestMessageData { if (!isBaseMessageData(data)) return false; - return "messageType" in data && data.messageType === messageTypes["handshake-request"]; + return 'messageType' in data && data.messageType === messageTypes['handshake-request']; } export interface HandshakeReplyMessageData extends BaseMessageData { - messageType: (typeof messageTypes)["handshake-reply"]; + messageType: (typeof messageTypes)['handshake-reply']; } function isHandshakeReply(data: unknown): data is HandshakeReplyMessageData { if (!isBaseMessageData(data)) return false; - return "messageType" in data && data.messageType === messageTypes["handshake-reply"]; + return 'messageType' in data && data.messageType === messageTypes['handshake-reply']; } interface EventPayload { @@ -95,31 +95,31 @@ interface EventPayload { } function isEventPayload(data: unknown): data is EventPayload { - if (typeof data !== "object" || data === null) return false; + if (typeof data !== 'object' || data === null) return false; const record = data as Record; - return typeof record["name"] === "string" && "data" in record; + return typeof record['name'] === 'string' && 'data' in record; } export interface ParentOriginatedMessageDataEventPayload extends BaseMessageData { - messageType: (typeof messageTypes)["parent-originated-event"]; + messageType: (typeof messageTypes)['parent-originated-event']; event: EventPayload; } function isParentOriginatedEvent(data: unknown): data is ParentOriginatedMessageDataEventPayload { if (!isBaseMessageData(data)) return false; - if (!("messageType" in data) || !("event" in data)) return false; - return data.messageType === messageTypes["parent-originated-event"] && isEventPayload(data.event); + if (!('messageType' in data) || !('event' in data)) return false; + return data.messageType === messageTypes['parent-originated-event'] && isEventPayload(data.event); } export interface ChildOriginatedMessageDataEventPayload extends BaseMessageData { - messageType: (typeof messageTypes)["child-originated-event"]; + messageType: (typeof messageTypes)['child-originated-event']; event: EventPayload; } function isChildOriginatedEvent(data: unknown): data is ChildOriginatedMessageDataEventPayload { if (!isBaseMessageData(data)) return false; - if (!("messageType" in data) || !("event" in data)) return false; - return data.messageType === messageTypes["child-originated-event"] && isEventPayload(data.event); + if (!('messageType' in data) || !('event' in data)) return false; + return data.messageType === messageTypes['child-originated-event'] && isEventPayload(data.event); } function isWhitelistedMessage(message: MessageEvent, allowedOrigin: string) { @@ -127,7 +127,7 @@ function isWhitelistedMessage(message: MessageEvent, allowedOrigin: string) { return true; } - if (typeof allowedOrigin === "string" && message.origin !== allowedOrigin) { + if (typeof allowedOrigin === 'string' && message.origin !== allowedOrigin) { return false; } @@ -173,7 +173,7 @@ export function createChild< enableLogging, }: CreateChildParams) { const parentWindow = window; - const iframe = crelt("iframe", iframeAttributes as object) as HTMLIFrameElement; + const iframe = crelt('iframe', iframeAttributes as object) as HTMLIFrameElement; if (url) { iframe.src = url; } @@ -183,9 +183,9 @@ export function createChild< const log = createLogger(enableLogging); function destroy() { - log("Destroying child iframe"); + log('Destroying child iframe'); - parentWindow.removeEventListener("message", handleEventsFromChild, false); + parentWindow.removeEventListener('message', handleEventsFromChild, false); return iframe.remove(); } @@ -207,10 +207,10 @@ export function createChild< eventName, handler, }); - log("Parent Frame Inbound Event Listener added:", eventName); + log('Parent Frame Inbound Event Listener added:', eventName); return () => { - log("Parent Frame Inbound Event Listener removed:", eventName); + log('Parent Frame Inbound Event Listener removed:', eventName); listeners.delete(listenerId); }; @@ -242,7 +242,7 @@ export function createChild< data: dataParseResult.data, }; - log("Parent Originated Event sent:", { + log('Parent Originated Event sent:', { namespace, event, }); @@ -250,7 +250,7 @@ export function createChild< iframe.contentWindow?.postMessage( { contentType: eventContentType, - messageType: messageTypes["parent-originated-event"], + messageType: messageTypes['parent-originated-event'], namespace, id: generateUniqueId(namespace), event: { @@ -265,7 +265,7 @@ export function createChild< function handleEventsFromChild(event: MessageEvent) { if (!isWhitelistedMessage(event, childOrigin)) { log( - "Child Originated Event ignored due to non-whitelisted origin:", + 'Child Originated Event ignored due to non-whitelisted origin:', childOrigin, event.origin, ); @@ -275,7 +275,7 @@ export function createChild< if (namespace && event.data.namespace !== namespace) { log( - "Child Originated Event ignored due to namespace mismatch:", + 'Child Originated Event ignored due to namespace mismatch:', namespace, event.data.namespace, ); @@ -284,12 +284,12 @@ export function createChild< } if (!isChildOriginatedEvent(event.data)) { - log("Child Originated Event ignored due to invalid message data:", event); + log('Child Originated Event ignored due to invalid message data:', event); return; } - log("Child Originated Event accepted:", event); + log('Child Originated Event accepted:', event); const { event: eventData } = event.data; const { name, data } = eventData; @@ -299,7 +299,7 @@ export function createChild< .forEach(({ handler, eventName }) => { const dataParseResult = validateSync(inboundEvents[eventName]!, data); if (dataParseResult.success) { - log("Child Originated Event Listener Handler invoked:", { + log('Child Originated Event Listener Handler invoked:', { eventName, data: dataParseResult.data, }); @@ -327,11 +327,11 @@ export function createChild< let handshakeRetryIntervalTimer: ReturnType; function handleHandshakeReply(event: MessageEvent) { - log("Handshake Reply Event received:", event); + log('Handshake Reply Event received:', event); if (!isWhitelistedMessage(event, childOrigin)) { log( - "Handshake Reply Event ignored due to non-whitelisted origin:", + 'Handshake Reply Event ignored due to non-whitelisted origin:', childOrigin, event.origin, ); @@ -341,7 +341,7 @@ export function createChild< if (namespace && event.data.namespace !== namespace) { log( - "Handshake Reply Event ignored due to namespace mismatch:", + 'Handshake Reply Event ignored due to namespace mismatch:', namespace, event.data.namespace, ); @@ -350,15 +350,15 @@ export function createChild< } if (!isHandshakeReply(event.data)) { - log("Handshake Reply Event ignored due to invalid message data:", event); + log('Handshake Reply Event ignored due to invalid message data:', event); return; } - log("Handshake Reply Event accepted:", event); + log('Handshake Reply Event accepted:', event); clearInterval(handshakeRetryIntervalTimer); - parentWindow.removeEventListener("message", handleHandshakeReply, false); + parentWindow.removeEventListener('message', handleHandshakeReply, false); const api = { destroy, @@ -371,7 +371,7 @@ export function createChild< return resolve(api); } - parentWindow.addEventListener("message", handleHandshakeReply, false); + parentWindow.addEventListener('message', handleHandshakeReply, false); function sendHandshakeRequest() { handshakeAttempt++; @@ -379,14 +379,14 @@ export function createChild< iframe.contentWindow?.postMessage( { contentType: eventContentType, - messageType: messageTypes["handshake-request"], + messageType: messageTypes['handshake-request'], namespace, id: generateUniqueId(namespace), } satisfies HandshakeRequestMessageData, childOrigin, ); - log("Handshake Request Sent: Attempt ", handshakeAttempt); + log('Handshake Request Sent: Attempt ', handshakeAttempt); if (handshakeAttempt === finalHandshakeOptions.maxHandshakeRequests) { clearInterval(handshakeRetryIntervalTimer); @@ -402,7 +402,7 @@ export function createChild< } function handleIframeLoad(loadEvent: Event) { - log("Iframe Load Event Listener received:", loadEvent); + log('Iframe Load Event Listener received:', loadEvent); sendHandshakeRequest(); handshakeRetryIntervalTimer = setInterval( @@ -411,7 +411,7 @@ export function createChild< ); } - iframe.addEventListener("load", handleIframeLoad, false); + iframe.addEventListener('load', handleIframeLoad, false); container.appendChild(iframe); @@ -419,7 +419,7 @@ export function createChild< }); } - parentWindow.addEventListener("message", handleEventsFromChild, false); + parentWindow.addEventListener('message', handleEventsFromChild, false); return { executeHandshake, @@ -464,10 +464,10 @@ export function connectToParent( eventName, handler, }); - log("Child Frame Inbound Event Listener added:", eventName); + log('Child Frame Inbound Event Listener added:', eventName); return () => { - log("Child Frame Inbound Event Listener removed:", eventName); + log('Child Frame Inbound Event Listener removed:', eventName); listeners.delete(listenerId); }; @@ -500,7 +500,7 @@ export function connectToParent( data: dataParseResult.data, }; - log("Child Originated Event Sent:", { + log('Child Originated Event Sent:', { namespace, event, }); @@ -508,7 +508,7 @@ export function connectToParent( parentRef.postMessage( { contentType: eventContentType, - messageType: messageTypes["child-originated-event"], + messageType: messageTypes['child-originated-event'], namespace, event, id: generateUniqueId(namespace), @@ -531,17 +531,17 @@ export function connectToParent( emit: ReturnType; }>((resolve, reject) => { function handleHandshakeRequest(event: MessageEvent) { - log("Handshake Request Event Listener received:", event); + log('Handshake Request Event Listener received:', event); if (event.source instanceof MessagePort || isEventSourceServiceWorker(event)) { - log("Handshake Request Event Listener ignored due to invalid source type:", event.source); + log('Handshake Request Event Listener ignored due to invalid source type:', event.source); return; } if (namespace && event.data.namespace !== namespace) { log( - "Handshake Request Event Listener ignored due to namespace mismatch:", + 'Handshake Request Event Listener ignored due to namespace mismatch:', namespace, event.data.namespace, ); @@ -551,21 +551,21 @@ export function connectToParent( if (!isHandshakeRequest(event.data)) { reject( - new Error("Invalid handshake request message data", { + new Error('Invalid handshake request message data', { cause: errorCauses.handshake_request_invalid, }), ); return; } - child.removeEventListener("message", handleHandshakeRequest, false); + child.removeEventListener('message', handleHandshakeRequest, false); const parentOrigin = event.origin; function handleEventsFromParent(parentEvent: MessageEvent) { if (!isWhitelistedMessage(parentEvent, parentOrigin)) { log( - "Parent Originated Event ignored due to non-whitelisted origin:", + 'Parent Originated Event ignored due to non-whitelisted origin:', parentOrigin, parentEvent.origin, ); @@ -575,7 +575,7 @@ export function connectToParent( if (namespace && parentEvent.data.namespace !== namespace) { log( - "Parent Originated Event ignored due to namespace mismatch:", + 'Parent Originated Event ignored due to namespace mismatch:', namespace, parentEvent.data.namespace, ); @@ -584,12 +584,12 @@ export function connectToParent( } if (!isParentOriginatedEvent(parentEvent.data)) { - log("Parent Originated Event ignored due to invalid message data:", parentEvent); + log('Parent Originated Event ignored due to invalid message data:', parentEvent); return; } - log("Parent Originated Event accepted:", parentEvent); + log('Parent Originated Event accepted:', parentEvent); const { event: eventData } = parentEvent.data; const { name, data } = eventData; @@ -599,20 +599,20 @@ export function connectToParent( .forEach(({ handler, eventName }) => { const dataParseResult = validateSync(inboundEvents[eventName]!, data); if (dataParseResult.success) { - log("Parent Originated Event Listener Handler invoked:", eventName); + log('Parent Originated Event Listener Handler invoked:', eventName); handler(dataParseResult.data); } }); } - child.addEventListener("message", handleEventsFromParent, false); + child.addEventListener('message', handleEventsFromParent, false); - log("Handshake Reply sent:", parentOrigin); + log('Handshake Reply sent:', parentOrigin); parentRef.postMessage( { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], + messageType: messageTypes['handshake-reply'], namespace, id: generateUniqueId(namespace), } satisfies HandshakeReplyMessageData, @@ -629,9 +629,9 @@ export function connectToParent( return resolve(api); } - child.addEventListener("message", handleHandshakeRequest, false); + child.addEventListener('message', handleHandshakeRequest, false); - log("Handshake Request Listener added"); + log('Handshake Request Listener added'); }); } diff --git a/packages/core/tests/index.test.ts b/packages/core/tests/index.test.ts index 7369a0e..39aa5e3 100644 --- a/packages/core/tests/index.test.ts +++ b/packages/core/tests/index.test.ts @@ -1,20 +1,20 @@ -import { describe, it, expect, vi, beforeEach } from "vitest"; -import type { StandardSchemaV1 } from "@standard-schema/spec"; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import type { StandardSchemaV1 } from '@standard-schema/spec'; import { createChild, connectToParent, errorCauses, eventContentType, messageTypes, -} from "../src/index.js"; +} from '../src/index.js'; function createMockSchema( validateFn: (value: unknown) => StandardSchemaV1.Result, ): StandardSchemaV1 { return { - "~standard": { + '~standard': { version: 1, - vendor: "test", + vendor: 'test', validate: validateFn, }, }; @@ -30,99 +30,99 @@ function createFailingSchema(issues: StandardSchemaV1.Issue[]): StandardSchemaV1 function createAsyncSchema(): StandardSchemaV1 { return { - "~standard": { + '~standard': { version: 1, - vendor: "test", - validate: () => Promise.resolve({ value: "async" }), + vendor: 'test', + validate: () => Promise.resolve({ value: 'async' }), }, } as unknown as StandardSchemaV1; } -describe("createChild", () => { +describe('createChild', () => { let container: HTMLElement; beforeEach(() => { - container = document.createElement("div"); + container = document.createElement('div'); document.body.appendChild(container); return () => { container.remove(); }; }); - it("returns executeHandshake and on functions", () => { + it('returns executeHandshake and on functions', () => { const result = createChild({ container }); - expect(result).toHaveProperty("executeHandshake"); - expect(result).toHaveProperty("on"); - expect(typeof result.executeHandshake).toBe("function"); - expect(typeof result.on).toBe("function"); + expect(result).toHaveProperty('executeHandshake'); + expect(result).toHaveProperty('on'); + expect(typeof result.executeHandshake).toBe('function'); + expect(typeof result.on).toBe('function'); }); - it("creates an iframe in the container", () => { - createChild({ container, url: "https://example.com" }); - expect(container.querySelector("iframe")).toBeNull(); + it('creates an iframe in the container', () => { + createChild({ container, url: 'https://example.com' }); + expect(container.querySelector('iframe')).toBeNull(); - createChild({ container, url: "https://example.com" }).executeHandshake(); - const iframe = container.querySelector("iframe"); + createChild({ container, url: 'https://example.com' }).executeHandshake(); + const iframe = container.querySelector('iframe'); expect(iframe).not.toBeNull(); - expect(iframe?.src).toBe("https://example.com/"); + expect(iframe?.src).toBe('https://example.com/'); }); - it("registers an event listener on subscribe", () => { + it('registers an event listener on subscribe', () => { const handler = vi.fn(); const inboundEvents = { testEvent: createPassthroughSchema(), }; const { on } = createChild({ container, inboundEvents }); - const unsubscribe = on("testEvent", handler); - expect(typeof unsubscribe).toBe("function"); + const unsubscribe = on('testEvent', handler); + expect(typeof unsubscribe).toBe('function'); }); - it("unsubscribe removes the listener", () => { + it('unsubscribe removes the listener', () => { const handler = vi.fn(); const inboundEvents = { testEvent: createPassthroughSchema(), }; const { on } = createChild({ container, inboundEvents }); - const unsubscribe = on("testEvent", handler); + const unsubscribe = on('testEvent', handler); unsubscribe(); }); }); -describe("connectToParent", () => { - it("returns executeHandshake and on functions", () => { +describe('connectToParent', () => { + it('returns executeHandshake and on functions', () => { const result = connectToParent(); - expect(result).toHaveProperty("executeHandshake"); - expect(result).toHaveProperty("on"); - expect(typeof result.executeHandshake).toBe("function"); - expect(typeof result.on).toBe("function"); + expect(result).toHaveProperty('executeHandshake'); + expect(result).toHaveProperty('on'); + expect(typeof result.executeHandshake).toBe('function'); + expect(typeof result.on).toBe('function'); }); - it("registers an event listener on subscribe", () => { + it('registers an event listener on subscribe', () => { const handler = vi.fn(); const inboundEvents = { testEvent: createPassthroughSchema(), }; const { on } = connectToParent({ inboundEvents }); - const unsubscribe = on("testEvent", handler); - expect(typeof unsubscribe).toBe("function"); + const unsubscribe = on('testEvent', handler); + expect(typeof unsubscribe).toBe('function'); }); }); -describe("Standard Schema validation", () => { +describe('Standard Schema validation', () => { let container: HTMLElement; beforeEach(() => { - container = document.createElement("div"); + container = document.createElement('div'); document.body.appendChild(container); return () => { container.remove(); }; }); - it("throws on invalid event name in emit", () => { + it('throws on invalid event name in emit', () => { const outboundEvents = { validEvent: createPassthroughSchema(), }; @@ -131,31 +131,31 @@ describe("Standard Schema validation", () => { const handshakePromise = executeHandshake(); - const iframe = container.querySelector("iframe")!; + const iframe = container.querySelector('iframe')!; const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, "contentWindow", { + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: postMessageSpy }, }); window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - id: "test-id", + messageType: messageTypes['handshake-reply'], + id: 'test-id', }, }), ); return handshakePromise.then((api) => { expect(() => - (api.emit as (name: string, data: unknown) => void)("invalidEvent", "data"), - ).toThrow("not defined in the outboundEvents map"); + (api.emit as (name: string, data: unknown) => void)('invalidEvent', 'data'), + ).toThrow('not defined in the outboundEvents map'); }); }); - it("throws on invalid data for emit", () => { - const issues: StandardSchemaV1.Issue[] = [{ message: "invalid data" }]; + it('throws on invalid data for emit', () => { + const issues: StandardSchemaV1.Issue[] = [{ message: 'invalid data' }]; const outboundEvents = { testEvent: createFailingSchema(issues), }; @@ -164,26 +164,26 @@ describe("Standard Schema validation", () => { const handshakePromise = executeHandshake(); - const iframe = container.querySelector("iframe")!; + const iframe = container.querySelector('iframe')!; const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, "contentWindow", { + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: postMessageSpy }, }); window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - id: "test-id", + messageType: messageTypes['handshake-reply'], + id: 'test-id', }, }), ); return handshakePromise.then((api) => { try { - api.emit("testEvent", "bad-data"); - expect.unreachable("should have thrown"); + api.emit('testEvent', 'bad-data'); + expect.unreachable('should have thrown'); } catch (error) { expect(error).toBeInstanceOf(Error); expect((error as Error).cause).toBe(errorCauses.event_data_invalid); @@ -191,7 +191,7 @@ describe("Standard Schema validation", () => { }); }); - it("throws TypeError for async schemas", () => { + it('throws TypeError for async schemas', () => { const outboundEvents = { testEvent: createAsyncSchema(), }; @@ -200,29 +200,29 @@ describe("Standard Schema validation", () => { const handshakePromise = executeHandshake(); - const iframe = container.querySelector("iframe")!; + const iframe = container.querySelector('iframe')!; const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, "contentWindow", { + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: postMessageSpy }, }); window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - id: "test-id", + messageType: messageTypes['handshake-reply'], + id: 'test-id', }, }), ); return handshakePromise.then((api) => { - expect(() => api.emit("testEvent", "data")).toThrow(TypeError); - expect(() => api.emit("testEvent", "data")).toThrow("Schema validation must be synchronous"); + expect(() => api.emit('testEvent', 'data')).toThrow(TypeError); + expect(() => api.emit('testEvent', 'data')).toThrow('Schema validation must be synchronous'); }); }); - it("emits valid data successfully", () => { + it('emits valid data successfully', () => { const outboundEvents = { testEvent: createPassthroughSchema(), }; @@ -231,31 +231,31 @@ describe("Standard Schema validation", () => { const handshakePromise = executeHandshake(); - const iframe = container.querySelector("iframe")!; + const iframe = container.querySelector('iframe')!; const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, "contentWindow", { + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: postMessageSpy }, }); window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - id: "test-id", + messageType: messageTypes['handshake-reply'], + id: 'test-id', }, }), ); return handshakePromise.then((api) => { - api.emit("testEvent", "hello"); + api.emit('testEvent', 'hello'); expect(postMessageSpy).toHaveBeenCalledWith( expect.objectContaining({ contentType: eventContentType, - messageType: messageTypes["parent-originated-event"], + messageType: messageTypes['parent-originated-event'], event: expect.objectContaining({ - name: "testEvent", - data: "hello", + name: 'testEvent', + data: 'hello', }), }), expect.any(String), @@ -264,50 +264,50 @@ describe("Standard Schema validation", () => { }); }); -describe("handshake", () => { +describe('handshake', () => { let container: HTMLElement; beforeEach(() => { - container = document.createElement("div"); + container = document.createElement('div'); document.body.appendChild(container); return () => { container.remove(); }; }); - it("resolves on valid handshake reply", async () => { + it('resolves on valid handshake reply', async () => { const { executeHandshake } = createChild({ container, - url: "https://example.com", + url: 'https://example.com', }); const handshakePromise = executeHandshake(); - const iframe = container.querySelector("iframe")!; - Object.defineProperty(iframe, "contentWindow", { + const iframe = container.querySelector('iframe')!; + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: vi.fn() }, }); window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - id: "reply-id", + messageType: messageTypes['handshake-reply'], + id: 'reply-id', }, - origin: "https://example.com", + origin: 'https://example.com', }), ); const api = await handshakePromise; - expect(api).toHaveProperty("destroy"); - expect(api).toHaveProperty("on"); - expect(api).toHaveProperty("emit"); - expect(api).toHaveProperty("iframe"); - expect(api).toHaveProperty("childOrigin"); + expect(api).toHaveProperty('destroy'); + expect(api).toHaveProperty('on'); + expect(api).toHaveProperty('emit'); + expect(api).toHaveProperty('iframe'); + expect(api).toHaveProperty('childOrigin'); }); - it("rejects after max handshake attempts", async () => { + it('rejects after max handshake attempts', async () => { const { executeHandshake } = createChild({ container, handshakeOptions: { @@ -318,52 +318,52 @@ describe("handshake", () => { const handshakePromise = executeHandshake(); - const iframe = container.querySelector("iframe")!; - Object.defineProperty(iframe, "contentWindow", { + const iframe = container.querySelector('iframe')!; + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: vi.fn() }, }); - iframe.dispatchEvent(new Event("load")); + iframe.dispatchEvent(new Event('load')); - await expect(handshakePromise).rejects.toThrow("Handshake failed after"); + await expect(handshakePromise).rejects.toThrow('Handshake failed after'); }); - it("filters messages by namespace", async () => { + it('filters messages by namespace', async () => { const { executeHandshake } = createChild({ container, - namespace: "test-ns", + namespace: 'test-ns', }); const handshakePromise = executeHandshake(); - const iframe = container.querySelector("iframe")!; - Object.defineProperty(iframe, "contentWindow", { + const iframe = container.querySelector('iframe')!; + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: vi.fn() }, }); window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - namespace: "wrong-ns", - id: "reply-id", + messageType: messageTypes['handshake-reply'], + namespace: 'wrong-ns', + id: 'reply-id', }, }), ); window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - namespace: "test-ns", - id: "reply-id-2", + messageType: messageTypes['handshake-reply'], + namespace: 'test-ns', + id: 'reply-id-2', }, }), ); const api = await handshakePromise; - expect(api).toHaveProperty("on"); + expect(api).toHaveProperty('on'); }); }); diff --git a/packages/core/tsdown.config.ts b/packages/core/tsdown.config.ts index 376214a..0e9b5d9 100644 --- a/packages/core/tsdown.config.ts +++ b/packages/core/tsdown.config.ts @@ -1,16 +1,16 @@ -import { defineConfig } from "tsdown"; +import { defineConfig } from 'tsdown'; export default defineConfig({ - entry: { index: "src/index.ts" }, - format: ["esm", "cjs"], + entry: { index: 'src/index.ts' }, + format: ['esm', 'cjs'], dts: true, clean: true, treeshake: true, - target: "es2022", - platform: "neutral", + target: 'es2022', + platform: 'neutral', outputOptions: (options, format) => - format === "cjs" ? { ...options, exports: "named" } : options, + format === 'cjs' ? { ...options, exports: 'named' } : options, deps: { - neverBundle: ["crelt", "nanoid", "@standard-schema/spec"], + neverBundle: ['crelt', 'nanoid', '@standard-schema/spec'], }, }); diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 537c27f..9ea4607 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -1,8 +1,8 @@ -import { defineConfig } from "vitest/config"; +import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - environment: "happy-dom", + environment: 'happy-dom', environmentOptions: { happyDOM: { settings: { @@ -13,11 +13,11 @@ export default defineConfig({ }, }, }, - setupFiles: ["./tests/setup.ts"], + setupFiles: ['./tests/setup.ts'], coverage: { - provider: "v8", - include: ["src/**"], - reporter: ["text", "json-summary"], + provider: 'v8', + include: ['src/**'], + reporter: ['text', 'json-summary'], }, }, }); diff --git a/packages/react/README.md b/packages/react/README.md index 8d162b0..4f43547 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -1,5 +1,7 @@ # @izod/react +![Bundle Size](https://img.shields.io/bundlephobia/minzip/@izod/react) ![npm version](https://badgen.net/npm/v/@izod/react) ![types](https://badgen.net/npm/types/@izod/react) + React hooks for type-safe iframe communication. Wraps [`@izod/core`](../core) with React lifecycle management. ## Installation @@ -17,42 +19,38 @@ pnpm add @izod/core @izod/react Hook for the **parent** component to create and manage a child iframe. ```tsx -import { child } from "@izod/react"; +import { child } from '@izod/react'; function Parent() { - const [container] = useState(() => document.createElement("div")); - - const { - on, - executeHandshake, - api, - isHandshakeComplete, - isHandshakePending, - handshakeError, - } = child.useCreate({ - container, // DOM element for the iframe - url: "https://child.example.com", - namespace: "my-app", // optional - inboundEvents: childEvents, // schemas for events FROM the child - outboundEvents: parentEvents, // schemas for events TO the child - iframeAttributes: { // optional - style: "width:100%;height:400px;border:none", - }, - handshakeOptions: { // optional - maxHandshakeRequests: 10, - handshakeRetryInterval: 100, - }, - onHandshakeComplete: (api) => { - console.log("Connected!"); - }, - onHandshakeError: (error) => { - console.error("Handshake failed:", error); - }, - destroyOnUnmount: true, // default: true — remove iframe on unmount - }); + const [container] = useState(() => document.createElement('div')); + + const { on, executeHandshake, api, isHandshakeComplete, isHandshakePending, handshakeError } = + child.useCreate({ + container, // DOM element for the iframe + url: 'https://child.example.com', + namespace: 'my-app', // optional + inboundEvents: childEvents, // schemas for events FROM the child + outboundEvents: parentEvents, // schemas for events TO the child + iframeAttributes: { + // optional + style: 'width:100%;height:400px;border:none', + }, + handshakeOptions: { + // optional + maxHandshakeRequests: 10, + handshakeRetryInterval: 100, + }, + onHandshakeComplete: (api) => { + console.log('Connected!'); + }, + onHandshakeError: (error) => { + console.error('Handshake failed:', error); + }, + destroyOnUnmount: true, // default: true — remove iframe on unmount + }); useEffect(() => { - const off = on("childMessage", (data) => { + const off = on('childMessage', (data) => { console.log(data); }); return off; @@ -64,13 +62,13 @@ function Parent() { return ( <> -
{ - if (node && !node.contains(container)) node.appendChild(container); - }} /> +
{ + if (node && !node.contains(container)) node.appendChild(container); + }} + /> {isHandshakeComplete && ( - + )} ); @@ -79,54 +77,48 @@ function Parent() { **Returns:** -| Property | Type | Description | -|----------|------|-------------| -| `on` | `(event, handler) => unsubscribe` | Register inbound event listener | -| `executeHandshake` | `() => void` | Start the handshake | -| `api` | `object \| undefined` | Handshake result with `emit()` and `destroy()` | -| `isHandshakeComplete` | `boolean` | Whether handshake succeeded | -| `isHandshakePending` | `boolean` | Whether handshake is in progress | -| `handshakeError` | `Error \| undefined` | Handshake error, if any | +| Property | Type | Description | +| --------------------- | --------------------------------- | ---------------------------------------------- | +| `on` | `(event, handler) => unsubscribe` | Register inbound event listener | +| `executeHandshake` | `() => void` | Start the handshake | +| `api` | `object \| undefined` | Handshake result with `emit()` and `destroy()` | +| `isHandshakeComplete` | `boolean` | Whether handshake succeeded | +| `isHandshakePending` | `boolean` | Whether handshake is in progress | +| `handshakeError` | `Error \| undefined` | Handshake error, if any | ### `parent.useConnect(params)` Hook for the **child** component (inside the iframe) to connect back to the parent. ```tsx -import { parent } from "@izod/react"; +import { parent } from '@izod/react'; function Child() { - const { - on, - executeHandshake, - api, - isHandshakeComplete, - isHandshakePending, - handshakeError, - } = parent.useConnect({ - namespace: "my-app", - inboundEvents: parentEvents, - outboundEvents: childEvents, - onHandshakeComplete: (api) => { - console.log("Connected to parent!"); - }, - onHandshakeError: (error) => { - console.error("Failed:", error); - }, - }); + const { on, executeHandshake, api, isHandshakeComplete, isHandshakePending, handshakeError } = + parent.useConnect({ + namespace: 'my-app', + inboundEvents: parentEvents, + outboundEvents: childEvents, + onHandshakeComplete: (api) => { + console.log('Connected to parent!'); + }, + onHandshakeError: (error) => { + console.error('Failed:', error); + }, + }); useEffect(() => { executeHandshake(); }, [executeHandshake]); useEffect(() => { - const off = on("parentMessage", (data) => { + const off = on('parentMessage', (data) => { console.log(data); }); return off; }, [on]); - return
{isHandshakeComplete ? "Connected" : "Connecting..."}
; + return
{isHandshakeComplete ? 'Connected' : 'Connecting...'}
; } ``` diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 465ba01..23e847d 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -4,8 +4,8 @@ import { type CreateChildParams, type ConnectToParentParams, connectToParent, -} from "@izod/core"; -import { useEffect, useRef, useState, useCallback } from "react"; +} from '@izod/core'; +import { useEffect, useRef, useState, useCallback } from 'react'; type AsyncState = | { loading: false; value: undefined; error: undefined } @@ -40,7 +40,7 @@ type CreateChildHandshakeResult< IE extends EventMap, OE extends EventMap, T extends HTMLElement | Element, -> = Awaited>["executeHandshake"]>>; +> = Awaited>['executeHandshake']>>; interface UseChildIframeParams< IE extends EventMap, @@ -120,7 +120,7 @@ export const child = { } as const; type ConnectToParentHandshakeResult = Awaited< - ReturnType>["executeHandshake"]> + ReturnType>['executeHandshake']> >; interface UseParentParams extends ConnectToParentParams< diff --git a/packages/react/tests/react.test.ts b/packages/react/tests/react.test.ts index b5282d6..75ed7dd 100644 --- a/packages/react/tests/react.test.ts +++ b/packages/react/tests/react.test.ts @@ -1,24 +1,24 @@ -import { describe, it, expect, vi, beforeEach } from "vitest"; -import { renderHook, act, cleanup } from "@testing-library/react"; -import type { StandardSchemaV1 } from "@standard-schema/spec"; -import { eventContentType, messageTypes } from "@izod/core"; -import { child, parent } from "../src/index.js"; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { renderHook, act, cleanup } from '@testing-library/react'; +import type { StandardSchemaV1 } from '@standard-schema/spec'; +import { eventContentType, messageTypes } from '@izod/core'; +import { child, parent } from '../src/index.js'; function createPassthroughSchema(): StandardSchemaV1 { return { - "~standard": { + '~standard': { version: 1, - vendor: "test", + vendor: 'test', validate: (value: unknown) => ({ value: value as T }), }, }; } -describe("child.useCreate", () => { +describe('child.useCreate', () => { let container: HTMLElement; beforeEach(() => { - container = document.createElement("div"); + container = document.createElement('div'); document.body.appendChild(container); return () => { cleanup(); @@ -26,23 +26,23 @@ describe("child.useCreate", () => { }; }); - it("returns expected API shape", () => { + it('returns expected API shape', () => { const { result } = renderHook(() => child.useCreate({ container })); - expect(result.current).toHaveProperty("on"); - expect(result.current).toHaveProperty("executeHandshake"); - expect(result.current).toHaveProperty("api"); - expect(result.current).toHaveProperty("isHandshakeComplete"); - expect(result.current).toHaveProperty("isHandshakePending"); - expect(result.current).toHaveProperty("handshakeError"); + expect(result.current).toHaveProperty('on'); + expect(result.current).toHaveProperty('executeHandshake'); + expect(result.current).toHaveProperty('api'); + expect(result.current).toHaveProperty('isHandshakeComplete'); + expect(result.current).toHaveProperty('isHandshakePending'); + expect(result.current).toHaveProperty('handshakeError'); - expect(typeof result.current.on).toBe("function"); - expect(typeof result.current.executeHandshake).toBe("function"); + expect(typeof result.current.on).toBe('function'); + expect(typeof result.current.executeHandshake).toBe('function'); expect(result.current.isHandshakeComplete).toBe(false); expect(result.current.isHandshakePending).toBe(false); }); - it("can register event listeners", () => { + it('can register event listeners', () => { const inboundEvents = { testEvent: createPassthroughSchema(), }; @@ -50,12 +50,12 @@ describe("child.useCreate", () => { const { result } = renderHook(() => child.useCreate({ container, inboundEvents })); const handler = vi.fn(); - const unsubscribe = result.current.on("testEvent", handler); - expect(typeof unsubscribe).toBe("function"); + const unsubscribe = result.current.on('testEvent', handler); + expect(typeof unsubscribe).toBe('function'); unsubscribe(); }); - it("calls onHandshakeComplete callback on success", async () => { + it('calls onHandshakeComplete callback on success', async () => { const onHandshakeComplete = vi.fn(); const { result } = renderHook(() => @@ -69,18 +69,18 @@ describe("child.useCreate", () => { result.current.executeHandshake(); }); - const iframe = container.querySelector("iframe")!; - Object.defineProperty(iframe, "contentWindow", { + const iframe = container.querySelector('iframe')!; + Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: vi.fn() }, }); await act(async () => { window.dispatchEvent( - new MessageEvent("message", { + new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes["handshake-reply"], - id: "test-id", + messageType: messageTypes['handshake-reply'], + id: 'test-id', }, }), ); @@ -90,24 +90,24 @@ describe("child.useCreate", () => { }); }); -describe("parent.useConnect", () => { - it("returns expected API shape", () => { +describe('parent.useConnect', () => { + it('returns expected API shape', () => { const { result } = renderHook(() => parent.useConnect()); - expect(result.current).toHaveProperty("on"); - expect(result.current).toHaveProperty("executeHandshake"); - expect(result.current).toHaveProperty("api"); - expect(result.current).toHaveProperty("isHandshakeComplete"); - expect(result.current).toHaveProperty("isHandshakePending"); - expect(result.current).toHaveProperty("handshakeError"); + expect(result.current).toHaveProperty('on'); + expect(result.current).toHaveProperty('executeHandshake'); + expect(result.current).toHaveProperty('api'); + expect(result.current).toHaveProperty('isHandshakeComplete'); + expect(result.current).toHaveProperty('isHandshakePending'); + expect(result.current).toHaveProperty('handshakeError'); - expect(typeof result.current.on).toBe("function"); - expect(typeof result.current.executeHandshake).toBe("function"); + expect(typeof result.current.on).toBe('function'); + expect(typeof result.current.executeHandshake).toBe('function'); expect(result.current.isHandshakeComplete).toBe(false); expect(result.current.isHandshakePending).toBe(false); }); - it("can register event listeners", () => { + it('can register event listeners', () => { const inboundEvents = { testEvent: createPassthroughSchema(), }; @@ -115,8 +115,8 @@ describe("parent.useConnect", () => { const { result } = renderHook(() => parent.useConnect({ inboundEvents })); const handler = vi.fn(); - const unsubscribe = result.current.on("testEvent", handler); - expect(typeof unsubscribe).toBe("function"); + const unsubscribe = result.current.on('testEvent', handler); + expect(typeof unsubscribe).toBe('function'); unsubscribe(); }); }); diff --git a/packages/react/tests/setup.ts b/packages/react/tests/setup.ts index f149f27..bb02c60 100644 --- a/packages/react/tests/setup.ts +++ b/packages/react/tests/setup.ts @@ -1 +1 @@ -import "@testing-library/jest-dom/vitest"; +import '@testing-library/jest-dom/vitest'; diff --git a/packages/react/tsdown.config.ts b/packages/react/tsdown.config.ts index 72cf858..0b17e2f 100644 --- a/packages/react/tsdown.config.ts +++ b/packages/react/tsdown.config.ts @@ -1,16 +1,16 @@ -import { defineConfig } from "tsdown"; +import { defineConfig } from 'tsdown'; export default defineConfig({ - entry: { index: "src/index.ts" }, - format: ["esm", "cjs"], + entry: { index: 'src/index.ts' }, + format: ['esm', 'cjs'], dts: true, clean: true, treeshake: true, - target: "es2022", - platform: "neutral", + target: 'es2022', + platform: 'neutral', outputOptions: (options, format) => - format === "cjs" ? { ...options, exports: "named" } : options, + format === 'cjs' ? { ...options, exports: 'named' } : options, deps: { - neverBundle: ["react", "react-dom", "@izod/core", "@standard-schema/spec"], + neverBundle: ['react', 'react-dom', '@izod/core', '@standard-schema/spec'], }, }); diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index d373090..c7d2176 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -1,13 +1,13 @@ -import { defineConfig } from "vitest/config"; +import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - environment: "happy-dom", - setupFiles: ["./tests/setup.ts"], + environment: 'happy-dom', + setupFiles: ['./tests/setup.ts'], coverage: { - provider: "v8", - include: ["src/**"], - reporter: ["text", "json-summary"], + provider: 'v8', + include: ['src/**'], + reporter: ['text', 'json-summary'], }, }, }); diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f8a1d62..3485b1d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,30 +6,30 @@ trustPolicy: no-downgrade onlyBuiltDependencies: [] packages: - - "packages/*" - - "examples/*" + - 'packages/*' + - 'examples/*' overrides: - semver: "7.7.4" + semver: '7.7.4' catalog: # Build - typescript: "6.0.3" - tsdown: "0.21.10" + typescript: '6.0.3' + tsdown: '0.21.10' # Test - vitest: "4.1.5" - "@vitest/coverage-v8": "4.1.5" - happy-dom: "20.9.0" - "@testing-library/jest-dom": "6.9.1" - "@testing-library/react": "16.3.2" + vitest: '4.1.5' + '@vitest/coverage-v8': '4.1.5' + happy-dom: '20.9.0' + '@testing-library/jest-dom': '6.9.1' + '@testing-library/react': '16.3.2' # Types - "@types/react": "19.2.14" - "@types/react-dom": "19.2.3" - "@standard-schema/spec": "1.1.0" + '@types/react': '19.2.14' + '@types/react-dom': '19.2.3' + '@standard-schema/spec': '1.1.0' # React (dev only) - react: "19.2.5" - react-dom: "19.2.5" + react: '19.2.5' + react-dom: '19.2.5' # Examples - astro: "6.2.1" - "@astrojs/react": "5.0.4" - zod: "4.3.6" + astro: '6.2.1' + '@astrojs/react': '5.0.4' + zod: '4.3.6' From bfbfb0c9480f6e0c3aa56a0ad49253777792f6ee Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sun, 10 May 2026 23:43:53 +0530 Subject: [PATCH 11/16] fix(ci): use pull-requests:write and restrict to non-fork PRs Switch from issues:write to pull-requests:write to fix 403 on PR comments. Guard the coverage comment step with a same-repo check so fork PRs cannot use the write token. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96e2f98..6822955 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: permissions: contents: read - issues: write + pull-requests: write concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -37,7 +37,7 @@ jobs: - run: pnpm run build - name: Post coverage comment - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} From 71821de9146d58eaee4a2228ec9d4058dc57139e Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Mon, 11 May 2026 00:21:41 +0530 Subject: [PATCH 12/16] test: improve coverage for core and react packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Core (55% → 93% statements): add connectToParent handshake, child-side emit, inbound event dispatch, origin filtering, namespace filtering, destroy cleanup, and validation edge cases. React (73% → 95% statements): add handshake pending state, onHandshakeError callback, parent.useConnect handshake and error flows. --- packages/core/tests/index.test.ts | 664 ++++++++++++++++++++++++++--- packages/react/tests/react.test.ts | 162 ++++++- 2 files changed, 748 insertions(+), 78 deletions(-) diff --git a/packages/core/tests/index.test.ts b/packages/core/tests/index.test.ts index 39aa5e3..7607358 100644 --- a/packages/core/tests/index.test.ts +++ b/packages/core/tests/index.test.ts @@ -38,6 +38,25 @@ function createAsyncSchema(): StandardSchemaV1 { } as unknown as StandardSchemaV1; } +function completeParentHandshake(container: HTMLElement, origin?: string) { + const iframe = container.querySelector('iframe')!; + Object.defineProperty(iframe, 'contentWindow', { + value: { postMessage: vi.fn() }, + configurable: true, + }); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-reply'], + id: 'test-id', + }, + origin: origin ?? '', + }), + ); +} + describe('createChild', () => { let container: HTMLElement; @@ -109,77 +128,328 @@ describe('connectToParent', () => { const unsubscribe = on('testEvent', handler); expect(typeof unsubscribe).toBe('function'); }); -}); -describe('Standard Schema validation', () => { - let container: HTMLElement; + it('resolves handshake on valid request', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); - beforeEach(() => { - container = document.createElement('div'); - document.body.appendChild(container); - return () => { - container.remove(); + const { executeHandshake } = connectToParent({ namespace: 'child-test' }); + const handshakePromise = executeHandshake(); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + namespace: 'child-test', + id: 'req-1', + }, + origin: 'https://parent.example.com', + source: window, + }), + ); + + const api = await handshakePromise; + expect(api).toHaveProperty('on'); + expect(api).toHaveProperty('emit'); + expect(api).toHaveProperty('parentOrigin'); + expect(api.parentOrigin).toBe('https://parent.example.com'); + + expect(parentPostMessage).toHaveBeenCalledWith( + expect.objectContaining({ + contentType: eventContentType, + messageType: messageTypes['handshake-reply'], + namespace: 'child-test', + }), + 'https://parent.example.com', + ); + + parentPostMessage.mockRestore(); + }); + + it('ignores handshake request with wrong namespace', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); + + const { executeHandshake } = connectToParent({ namespace: 'correct-ns' }); + const handshakePromise = executeHandshake(); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + namespace: 'wrong-ns', + id: 'req-wrong', + }, + origin: 'https://parent.example.com', + source: window, + }), + ); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + namespace: 'correct-ns', + id: 'req-correct', + }, + origin: 'https://parent.example.com', + source: window, + }), + ); + + const api = await handshakePromise; + expect(api).toHaveProperty('emit'); + + parentPostMessage.mockRestore(); + }); + + it('rejects on invalid handshake request data', async () => { + const { executeHandshake } = connectToParent(); + const handshakePromise = executeHandshake(); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: 'garbage', + id: 'req-bad', + }, + source: window, + }), + ); + + await expect(handshakePromise).rejects.toThrow('Invalid handshake request message data'); + }); + + it('emits events to parent after handshake', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); + + const outboundEvents = { + childMsg: createPassthroughSchema<{ text: string }>(), }; + + const { executeHandshake } = connectToParent({ outboundEvents }); + const handshakePromise = executeHandshake(); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + id: 'req-1', + }, + origin: 'https://parent.example.com', + source: window, + }), + ); + + const api = await handshakePromise; + api.emit('childMsg', { text: 'hello parent' }); + + expect(parentPostMessage).toHaveBeenCalledWith( + expect.objectContaining({ + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + event: expect.objectContaining({ + name: 'childMsg', + data: { text: 'hello parent' }, + }), + }), + 'https://parent.example.com', + ); + + parentPostMessage.mockRestore(); }); - it('throws on invalid event name in emit', () => { + it('throws on invalid event name in child emit', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); + const outboundEvents = { validEvent: createPassthroughSchema(), }; - const { executeHandshake } = createChild({ container, outboundEvents }); + const { executeHandshake } = connectToParent({ outboundEvents }); + const handshakePromise = executeHandshake(); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + id: 'req-1', + }, + source: window, + }), + ); + + const api = await handshakePromise; + expect(() => (api.emit as (name: string, data: unknown) => void)('noSuchEvent', {})).toThrow( + 'not defined in the outboundEvents map', + ); + + parentPostMessage.mockRestore(); + }); + + it('throws on invalid data in child emit', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); + + const outboundEvents = { + testEvent: createFailingSchema([{ message: 'bad data' }]), + }; + const { executeHandshake } = connectToParent({ outboundEvents }); const handshakePromise = executeHandshake(); - const iframe = container.querySelector('iframe')!; - const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, 'contentWindow', { - value: { postMessage: postMessageSpy }, - }); + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + id: 'req-1', + }, + source: window, + }), + ); + + const api = await handshakePromise; + try { + api.emit('testEvent', 'bad'); + expect.unreachable('should have thrown'); + } catch (error) { + expect(error).toBeInstanceOf(Error); + expect((error as Error).cause).toBe(errorCauses.event_data_invalid); + } + + parentPostMessage.mockRestore(); + }); + + it('receives inbound events from parent after handshake', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); + + const handler = vi.fn(); + const inboundEvents = { + parentMsg: createPassthroughSchema<{ text: string }>(), + }; + + const { executeHandshake, on } = connectToParent({ inboundEvents }); + on('parentMsg', handler); + + const handshakePromise = executeHandshake(); window.dispatchEvent( new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes['handshake-reply'], - id: 'test-id', + messageType: messageTypes['handshake-request'], + id: 'req-1', }, + origin: 'https://parent.example.com', + source: window, }), ); - return handshakePromise.then((api) => { - expect(() => - (api.emit as (name: string, data: unknown) => void)('invalidEvent', 'data'), - ).toThrow('not defined in the outboundEvents map'); - }); + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['parent-originated-event'], + id: 'evt-1', + event: { name: 'parentMsg', data: { text: 'hi child' } }, + }, + origin: 'https://parent.example.com', + }), + ); + + expect(handler).toHaveBeenCalledWith({ text: 'hi child' }); + + parentPostMessage.mockRestore(); }); - it('throws on invalid data for emit', () => { - const issues: StandardSchemaV1.Issue[] = [{ message: 'invalid data' }]; - const outboundEvents = { - testEvent: createFailingSchema(issues), + it('drops parent events from wrong origin', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); + + const handler = vi.fn(); + const inboundEvents = { + parentMsg: createPassthroughSchema(), }; - const { executeHandshake } = createChild({ container, outboundEvents }); + const { executeHandshake, on } = connectToParent({ inboundEvents }); + on('parentMsg', handler); const handshakePromise = executeHandshake(); - const iframe = container.querySelector('iframe')!; - const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, 'contentWindow', { - value: { postMessage: postMessageSpy }, - }); + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + id: 'req-1', + }, + origin: 'https://parent.example.com', + source: window, + }), + ); + + await handshakePromise; window.dispatchEvent( new MessageEvent('message', { data: { contentType: eventContentType, - messageType: messageTypes['handshake-reply'], - id: 'test-id', + messageType: messageTypes['parent-originated-event'], + id: 'evt-1', + event: { name: 'parentMsg', data: 'sneaky' }, }, + origin: 'https://evil.example.com', }), ); + expect(handler).not.toHaveBeenCalled(); + + parentPostMessage.mockRestore(); + }); +}); + +describe('Standard Schema validation', () => { + let container: HTMLElement; + + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + return () => { + container.remove(); + }; + }); + + it('throws on invalid event name in emit', () => { + const outboundEvents = { + validEvent: createPassthroughSchema(), + }; + + const { executeHandshake } = createChild({ container, outboundEvents }); + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + + return handshakePromise.then((api) => { + expect(() => + (api.emit as (name: string, data: unknown) => void)('invalidEvent', 'data'), + ).toThrow('not defined in the outboundEvents map'); + }); + }); + + it('throws on invalid data for emit', () => { + const issues: StandardSchemaV1.Issue[] = [{ message: 'invalid data' }]; + const outboundEvents = { + testEvent: createFailingSchema(issues), + }; + + const { executeHandshake } = createChild({ container, outboundEvents }); + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + return handshakePromise.then((api) => { try { api.emit('testEvent', 'bad-data'); @@ -197,24 +467,8 @@ describe('Standard Schema validation', () => { }; const { executeHandshake } = createChild({ container, outboundEvents }); - const handshakePromise = executeHandshake(); - - const iframe = container.querySelector('iframe')!; - const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, 'contentWindow', { - value: { postMessage: postMessageSpy }, - }); - - window.dispatchEvent( - new MessageEvent('message', { - data: { - contentType: eventContentType, - messageType: messageTypes['handshake-reply'], - id: 'test-id', - }, - }), - ); + completeParentHandshake(container); return handshakePromise.then((api) => { expect(() => api.emit('testEvent', 'data')).toThrow(TypeError); @@ -228,27 +482,16 @@ describe('Standard Schema validation', () => { }; const { executeHandshake } = createChild({ container, outboundEvents }); - const handshakePromise = executeHandshake(); - - const iframe = container.querySelector('iframe')!; - const postMessageSpy = vi.fn(); - Object.defineProperty(iframe, 'contentWindow', { - value: { postMessage: postMessageSpy }, - }); - - window.dispatchEvent( - new MessageEvent('message', { - data: { - contentType: eventContentType, - messageType: messageTypes['handshake-reply'], - id: 'test-id', - }, - }), - ); + completeParentHandshake(container); return handshakePromise.then((api) => { api.emit('testEvent', 'hello'); + + const iframe = container.querySelector('iframe')!; + const postMessageSpy = ( + iframe as unknown as { contentWindow: { postMessage: ReturnType } } + ).contentWindow.postMessage; expect(postMessageSpy).toHaveBeenCalledWith( expect.objectContaining({ contentType: eventContentType, @@ -367,3 +610,288 @@ describe('handshake', () => { expect(api).toHaveProperty('on'); }); }); + +describe('inbound events', () => { + let container: HTMLElement; + + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + return () => { + container.remove(); + }; + }); + + it('parent receives child-originated events', async () => { + const handler = vi.fn(); + const inboundEvents = { + childMsg: createPassthroughSchema<{ text: string }>(), + }; + + const { executeHandshake, on } = createChild({ container, inboundEvents }); + on('childMsg', handler); + + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + id: 'evt-1', + event: { name: 'childMsg', data: { text: 'hello parent' } }, + }, + }), + ); + + expect(handler).toHaveBeenCalledWith({ text: 'hello parent' }); + }); + + it('dispatches to multiple listeners for the same event', async () => { + const handler1 = vi.fn(); + const handler2 = vi.fn(); + const inboundEvents = { + ping: createPassthroughSchema(), + }; + + const { executeHandshake, on } = createChild({ container, inboundEvents }); + on('ping', handler1); + on('ping', handler2); + + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + id: 'evt-1', + event: { name: 'ping', data: 'pong' }, + }, + }), + ); + + expect(handler1).toHaveBeenCalledWith('pong'); + expect(handler2).toHaveBeenCalledWith('pong'); + }); + + it('unsubscribed listener does not receive events', async () => { + const handler = vi.fn(); + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { executeHandshake, on } = createChild({ container, inboundEvents }); + const unsubscribe = on('testEvent', handler); + unsubscribe(); + + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + id: 'evt-1', + event: { name: 'testEvent', data: 'value' }, + }, + }), + ); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('silently drops events with unknown names', async () => { + const handler = vi.fn(); + const inboundEvents = { + knownEvent: createPassthroughSchema(), + }; + + const { executeHandshake, on } = createChild({ container, inboundEvents }); + on('knownEvent', handler); + + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + id: 'evt-1', + event: { name: 'unknownEvent', data: 'value' }, + }, + }), + ); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('silently drops events failing inbound validation', async () => { + const handler = vi.fn(); + const inboundEvents = { + strictEvent: createFailingSchema([{ message: 'bad' }]), + }; + + const { executeHandshake, on } = createChild({ container, inboundEvents }); + on('strictEvent', handler); + + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + id: 'evt-1', + event: { name: 'strictEvent', data: 'invalid' }, + }, + }), + ); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('drops events from non-whitelisted origin', async () => { + const handler = vi.fn(); + const inboundEvents = { + childMsg: createPassthroughSchema(), + }; + + const { executeHandshake, on } = createChild({ + container, + url: 'https://trusted.example.com', + inboundEvents, + }); + on('childMsg', handler); + + const handshakePromise = executeHandshake(); + completeParentHandshake(container, 'https://trusted.example.com'); + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + id: 'evt-1', + event: { name: 'childMsg', data: 'sneaky' }, + }, + origin: 'https://evil.example.com', + }), + ); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('ignores events with wrong namespace', async () => { + const handler = vi.fn(); + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { executeHandshake, on } = createChild({ + container, + namespace: 'app-ns', + inboundEvents, + }); + on('testEvent', handler); + + const handshakePromise = executeHandshake(); + + const iframe = container.querySelector('iframe')!; + Object.defineProperty(iframe, 'contentWindow', { + value: { postMessage: vi.fn() }, + configurable: true, + }); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-reply'], + namespace: 'app-ns', + id: 'reply-id', + }, + }), + ); + + await handshakePromise; + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + namespace: 'other-ns', + id: 'evt-1', + event: { name: 'testEvent', data: 'value' }, + }, + }), + ); + + expect(handler).not.toHaveBeenCalled(); + }); +}); + +describe('destroy', () => { + let container: HTMLElement; + + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + return () => { + container.remove(); + }; + }); + + it('removes the iframe from DOM', async () => { + const { executeHandshake } = createChild({ container }); + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + + const api = await handshakePromise; + expect(container.querySelector('iframe')).not.toBeNull(); + + api.destroy(); + expect(container.querySelector('iframe')).toBeNull(); + }); + + it('stops receiving events after destroy', async () => { + const handler = vi.fn(); + const inboundEvents = { + testEvent: createPassthroughSchema(), + }; + + const { executeHandshake, on } = createChild({ container, inboundEvents }); + on('testEvent', handler); + + const handshakePromise = executeHandshake(); + completeParentHandshake(container); + const api = await handshakePromise; + + api.destroy(); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['child-originated-event'], + id: 'evt-1', + event: { name: 'testEvent', data: 'value' }, + }, + }), + ); + + expect(handler).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/react/tests/react.test.ts b/packages/react/tests/react.test.ts index 75ed7dd..4b8bf41 100644 --- a/packages/react/tests/react.test.ts +++ b/packages/react/tests/react.test.ts @@ -14,6 +14,24 @@ function createPassthroughSchema(): StandardSchemaV1 { }; } +function completeParentHandshake(container: HTMLElement) { + const iframe = container.querySelector('iframe')!; + Object.defineProperty(iframe, 'contentWindow', { + value: { postMessage: vi.fn() }, + configurable: true, + }); + + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-reply'], + id: 'test-id', + }, + }), + ); +} + describe('child.useCreate', () => { let container: HTMLElement; @@ -69,28 +87,82 @@ describe('child.useCreate', () => { result.current.executeHandshake(); }); + await act(async () => { + completeParentHandshake(container); + }); + + expect(onHandshakeComplete).toHaveBeenCalled(); + expect(result.current.isHandshakeComplete).toBe(true); + expect(result.current.api).toBeDefined(); + }); + + it('sets isHandshakePending while handshake is in progress', async () => { + const { result } = renderHook(() => child.useCreate({ container })); + + expect(result.current.isHandshakePending).toBe(false); + + act(() => { + result.current.executeHandshake(); + }); + + expect(result.current.isHandshakePending).toBe(true); + + await act(async () => { + completeParentHandshake(container); + }); + + expect(result.current.isHandshakePending).toBe(false); + expect(result.current.isHandshakeComplete).toBe(true); + }); + + it('calls onHandshakeError on failure', async () => { + vi.useFakeTimers(); + const onHandshakeError = vi.fn(); + + const { result } = renderHook(() => + child.useCreate({ + container, + onHandshakeError, + handshakeOptions: { + maxHandshakeRequests: 1, + handshakeRetryInterval: 10, + }, + }), + ); + + act(() => { + result.current.executeHandshake(); + }); + const iframe = container.querySelector('iframe')!; Object.defineProperty(iframe, 'contentWindow', { value: { postMessage: vi.fn() }, + configurable: true, }); await act(async () => { - window.dispatchEvent( - new MessageEvent('message', { - data: { - contentType: eventContentType, - messageType: messageTypes['handshake-reply'], - id: 'test-id', - }, - }), - ); + iframe.dispatchEvent(new Event('load')); }); - expect(onHandshakeComplete).toHaveBeenCalled(); + await vi.waitFor(() => { + expect(result.current.handshakeError).toBeDefined(); + }); + + expect(onHandshakeError).toHaveBeenCalled(); + expect(result.current.handshakeError).toBeInstanceOf(Error); + expect(result.current.isHandshakeComplete).toBe(false); + + vi.useRealTimers(); }); }); describe('parent.useConnect', () => { + beforeEach(() => { + return () => { + cleanup(); + }; + }); + it('returns expected API shape', () => { const { result } = renderHook(() => parent.useConnect()); @@ -119,4 +191,74 @@ describe('parent.useConnect', () => { expect(typeof unsubscribe).toBe('function'); unsubscribe(); }); + + it('completes handshake and sets api', async () => { + const parentPostMessage = vi.spyOn(window.parent, 'postMessage').mockImplementation(() => {}); + + const onHandshakeComplete = vi.fn(); + + const { result } = renderHook(() => + parent.useConnect({ + onHandshakeComplete, + }), + ); + + act(() => { + result.current.executeHandshake(); + }); + + expect(result.current.isHandshakePending).toBe(true); + + await act(async () => { + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: messageTypes['handshake-request'], + id: 'req-1', + }, + origin: 'https://parent.example.com', + source: window, + }), + ); + }); + + expect(onHandshakeComplete).toHaveBeenCalled(); + expect(result.current.isHandshakeComplete).toBe(true); + expect(result.current.api).toBeDefined(); + expect(result.current.api).toHaveProperty('emit'); + + parentPostMessage.mockRestore(); + }); + + it('calls onHandshakeError on invalid request', async () => { + const onHandshakeError = vi.fn(); + + const { result } = renderHook(() => + parent.useConnect({ + onHandshakeError, + }), + ); + + act(() => { + result.current.executeHandshake(); + }); + + await act(async () => { + window.dispatchEvent( + new MessageEvent('message', { + data: { + contentType: eventContentType, + messageType: 'garbage', + id: 'req-bad', + }, + source: window, + }), + ); + }); + + expect(onHandshakeError).toHaveBeenCalled(); + expect(result.current.handshakeError).toBeInstanceOf(Error); + expect(result.current.isHandshakeComplete).toBe(false); + }); }); From 0d8b48b3b52b66c25d26eba0ca2f023f680bd662 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Mon, 11 May 2026 00:21:45 +0530 Subject: [PATCH 13/16] ci: pin deploy workflow actions to commit hashes Pin upload-pages-artifact and deploy-pages to their commit SHAs to match the pinning convention used in the CI workflow. --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e131e82..f0f235c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -34,7 +34,7 @@ jobs: working-directory: examples/astro-demo run: pnpm run build - - uses: actions/upload-pages-artifact@v4 + - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0 with: path: examples/astro-demo/dist @@ -47,4 +47,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v5 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 From 401cd57979f637bc9f4f8b47747fe0d96f92aa37 Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sat, 16 May 2026 13:43:07 +0530 Subject: [PATCH 14/16] refactor(react): extract and improve useAsyncCallback hook Replace the inline useAsyncCallback with a proper implementation matching react-use's useAsyncFn: race condition protection via call ID tracking, unmount guards, argument forwarding, promise return from execute, and stale-while-reloading state preservation. --- packages/react/src/index.ts | 32 +-- packages/react/src/useAsyncCallback.ts | 60 ++++ packages/react/tests/useAsyncCallback.test.ts | 265 ++++++++++++++++++ 3 files changed, 327 insertions(+), 30 deletions(-) create mode 100644 packages/react/src/useAsyncCallback.ts create mode 100644 packages/react/tests/useAsyncCallback.test.ts diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 23e847d..1ad60a9 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -5,36 +5,8 @@ import { type ConnectToParentParams, connectToParent, } from '@izod/core'; -import { useEffect, useRef, useState, useCallback } from 'react'; - -type AsyncState = - | { loading: false; value: undefined; error: undefined } - | { loading: true; value: undefined; error: undefined } - | { loading: false; value: T; error: undefined } - | { loading: false; value: undefined; error: Error }; - -function useAsyncCallback(asyncFn: () => Promise) { - const [state, setState] = useState>({ - loading: false, - value: undefined, - error: undefined, - }); - - const execute = useCallback(() => { - setState({ loading: true, value: undefined, error: undefined }); - asyncFn().then( - (value) => setState({ loading: false, value, error: undefined }), - (error: unknown) => - setState({ - loading: false, - value: undefined, - error: error instanceof Error ? error : new Error(String(error)), - }), - ); - }, [asyncFn]); - - return [state, execute] as const; -} +import { useEffect, useRef, useCallback } from 'react'; +import { useAsyncCallback } from './useAsyncCallback.js'; type CreateChildHandshakeResult< IE extends EventMap, diff --git a/packages/react/src/useAsyncCallback.ts b/packages/react/src/useAsyncCallback.ts new file mode 100644 index 0000000..4984aac --- /dev/null +++ b/packages/react/src/useAsyncCallback.ts @@ -0,0 +1,60 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; + +export type AsyncState = + | { loading: boolean } + | { loading: boolean; value: T } + | { loading: boolean; error: Error }; + +type FunctionReturningPromise = (...args: never[]) => Promise; + +export function useAsyncCallback( + asyncFn: TFn, +): [ + AsyncState>>, + (...args: Parameters) => Promise> | undefined>, +] { + type TResult = Awaited>; + + const lastCallId = useRef(0); + const mountedRef = useRef(false); + + useEffect(() => { + mountedRef.current = true; + return () => { + mountedRef.current = false; + }; + }, []); + + const [state, setState] = useState>({ + loading: false, + }); + + const execute = useCallback( + (...args: Parameters): Promise => { + const callId = ++lastCallId.current; + + if (!state.loading) { + setState((previousState) => ({ ...previousState, loading: true })); + } + + return (asyncFn as (...args: Parameters) => Promise)(...args).then( + (value) => { + if (mountedRef.current && callId === lastCallId.current) { + setState({ loading: false, value, error: undefined }); + } + return value; + }, + (error: unknown) => { + const normalizedError = error instanceof Error ? error : new Error(String(error)); + if (mountedRef.current && callId === lastCallId.current) { + setState({ loading: false, value: undefined, error: normalizedError }); + } + return; + }, + ); + }, + [asyncFn, state.loading], + ); + + return [state, execute]; +} diff --git a/packages/react/tests/useAsyncCallback.test.ts b/packages/react/tests/useAsyncCallback.test.ts new file mode 100644 index 0000000..1dacdc3 --- /dev/null +++ b/packages/react/tests/useAsyncCallback.test.ts @@ -0,0 +1,265 @@ +import { describe, it, expect, vi } from 'vitest'; +import { renderHook, act } from '@testing-library/react'; +import { useAsyncCallback } from '../src/useAsyncCallback.js'; + +function createDeferred() { + let resolve!: (value: T) => void; + let reject!: (reason: unknown) => void; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + return { promise, resolve, reject }; +} + +describe('useAsyncCallback', () => { + it('returns initial idle state', () => { + const asyncFn = vi.fn(async () => 'value'); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + const [state] = result.current; + expect(state).toEqual({ loading: false, value: undefined, error: undefined }); + }); + + it('sets loading on execute', () => { + const deferred = createDeferred(); + const asyncFn = vi.fn(() => deferred.promise); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + act(() => { + result.current[1](); + }); + + expect(result.current[0].loading).toBe(true); + }); + + it('resolves with value', async () => { + const asyncFn = vi.fn(async () => 'hello'); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + await act(async () => { + await result.current[1](); + }); + + expect(result.current[0]).toEqual({ loading: false, value: 'hello', error: undefined }); + }); + + it('rejects and sets error', async () => { + const error = new Error('boom'); + const asyncFn = vi.fn(async () => { + throw error; + }); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + await act(async () => { + await result.current[1](); + }); + + expect(result.current[0].loading).toBe(false); + expect(result.current[0].error).toBe(error); + expect(result.current[0].value).toBeUndefined(); + }); + + it('normalizes non-Error rejections to Error instances', async () => { + const asyncFn = vi.fn(async () => { + throw 'string-error'; + }); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + await act(async () => { + await result.current[1](); + }); + + expect(result.current[0].error).toBeInstanceOf(Error); + expect(result.current[0].error?.message).toBe('string-error'); + }); + + it('preserves previous value during reload', async () => { + const firstDeferred = createDeferred(); + const secondDeferred = createDeferred(); + let callCount = 0; + const asyncFn = vi.fn(() => { + callCount++; + return callCount === 1 ? firstDeferred.promise : secondDeferred.promise; + }); + + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + await act(async () => { + firstDeferred.resolve('first'); + await result.current[1](); + }); + + expect(result.current[0].value).toBe('first'); + + act(() => { + result.current[1](); + }); + + expect(result.current[0]).toEqual({ loading: true, value: 'first', error: undefined }); + }); + + it('preserves previous error during reload', async () => { + const firstDeferred = createDeferred(); + const secondDeferred = createDeferred(); + let callCount = 0; + const asyncFn = vi.fn(() => { + callCount++; + return callCount === 1 ? firstDeferred.promise : secondDeferred.promise; + }); + + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + await act(async () => { + firstDeferred.reject(new Error('failed')); + await result.current[1](); + }); + + expect(result.current[0].error?.message).toBe('failed'); + + act(() => { + result.current[1](); + }); + + expect(result.current[0].loading).toBe(true); + expect(result.current[0].error?.message).toBe('failed'); + expect(result.current[0].value).toBeUndefined(); + }); + + it('ignores stale resolve when a newer call is pending', async () => { + const deferredA = createDeferred(); + const deferredB = createDeferred(); + let callCount = 0; + const asyncFn = vi.fn(() => { + callCount++; + return callCount === 1 ? deferredA.promise : deferredB.promise; + }); + + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + act(() => { + result.current[1](); + }); + + act(() => { + result.current[1](); + }); + + await act(async () => { + deferredB.resolve('B'); + }); + + expect(result.current[0].value).toBe('B'); + + await act(async () => { + deferredA.resolve('A'); + }); + + expect(result.current[0].value).toBe('B'); + }); + + it('ignores stale reject when a newer call is pending', async () => { + const deferredA = createDeferred(); + const deferredB = createDeferred(); + let callCount = 0; + const asyncFn = vi.fn(() => { + callCount++; + return callCount === 1 ? deferredA.promise : deferredB.promise; + }); + + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + act(() => { + result.current[1](); + }); + + act(() => { + result.current[1](); + }); + + await act(async () => { + deferredB.resolve('B'); + }); + + await act(async () => { + deferredA.reject(new Error('stale error')); + }); + + expect(result.current[0].value).toBe('B'); + expect(result.current[0].error).toBeUndefined(); + }); + + it('does not update state after unmount', async () => { + const deferred = createDeferred(); + const asyncFn = vi.fn(() => deferred.promise); + const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}); + + const { result, unmount } = renderHook(() => useAsyncCallback(asyncFn)); + + act(() => { + result.current[1](); + }); + + unmount(); + + await act(async () => { + deferred.resolve('too late'); + }); + + expect(consoleError).not.toHaveBeenCalled(); + consoleError.mockRestore(); + }); + + it('forwards arguments to async function', async () => { + const asyncFn = vi.fn(async (name: string, count: number) => `${name}-${count}`); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + await act(async () => { + await result.current[1]('hello', 3); + }); + + expect(asyncFn).toHaveBeenCalledWith('hello', 3); + expect(result.current[0].value).toBe('hello-3'); + }); + + it('returns promise from execute that resolves to the value', async () => { + const asyncFn = vi.fn(async () => 42); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + let returnedValue: number | undefined; + await act(async () => { + returnedValue = await result.current[1](); + }); + + expect(returnedValue).toBe(42); + }); + + it('returned promise resolves to undefined on error instead of rejecting', async () => { + const asyncFn = vi.fn(async () => { + throw new Error('fail'); + }); + const { result } = renderHook(() => useAsyncCallback(asyncFn)); + + let returnedValue: unknown = 'sentinel'; + await act(async () => { + returnedValue = await result.current[1](); + }); + + expect(returnedValue).toBeUndefined(); + }); + + it('creates new callback when asyncFn reference changes', () => { + const asyncFnA = vi.fn(async () => 'a'); + const asyncFnB = vi.fn(async () => 'b'); + + const { result, rerender } = renderHook(({ fn }) => useAsyncCallback(fn), { + initialProps: { fn: asyncFnA }, + }); + + const firstCallback = result.current[1]; + + rerender({ fn: asyncFnB }); + + expect(result.current[1]).not.toBe(firstCallback); + }); +}); From a393201438daec6e6cbffe7a1ff5514038ec36fa Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sat, 16 May 2026 16:51:08 +0530 Subject: [PATCH 15/16] fix(react): stabilize useAsyncCallback and deduplicate demo styles Replace state.loading with a ref in useAsyncCallback's dependency array so the execute callback stays referentially stable, preventing the React demo parent from re-initiating the handshake in a loop. Extract shared demo styles into ParentLayout and ChildLayout Astro components so core and React examples share identical styling without duplication. Center-align the base index page. --- .../astro-demo/src/layouts/ChildLayout.astro | 43 ++++ .../astro-demo/src/layouts/ParentLayout.astro | 48 ++++ .../astro-demo/src/pages/core/child.astro | 176 ++++++-------- .../astro-demo/src/pages/core/index.astro | 225 ++++++++---------- examples/astro-demo/src/pages/index.astro | 6 +- .../astro-demo/src/pages/react/child.astro | 38 +-- .../astro-demo/src/pages/react/index.astro | 42 +--- packages/react/src/useAsyncCallback.ts | 10 +- 8 files changed, 277 insertions(+), 311 deletions(-) create mode 100644 examples/astro-demo/src/layouts/ChildLayout.astro create mode 100644 examples/astro-demo/src/layouts/ParentLayout.astro diff --git a/examples/astro-demo/src/layouts/ChildLayout.astro b/examples/astro-demo/src/layouts/ChildLayout.astro new file mode 100644 index 0000000..3d0de90 --- /dev/null +++ b/examples/astro-demo/src/layouts/ChildLayout.astro @@ -0,0 +1,43 @@ +--- +interface Props { + title: string; + subtitle: string; +} + +const { title, subtitle } = Astro.props; +--- + + + + + + izod — {title} + + + +

{title}

+

{subtitle}

+ + + + diff --git a/examples/astro-demo/src/layouts/ParentLayout.astro b/examples/astro-demo/src/layouts/ParentLayout.astro new file mode 100644 index 0000000..a6b0b37 --- /dev/null +++ b/examples/astro-demo/src/layouts/ParentLayout.astro @@ -0,0 +1,48 @@ +--- +interface Props { + title: string; + subtitle: string; +} + +const { title, subtitle } = Astro.props; +const base = import.meta.env.BASE_URL; +--- + + + + + + izod — {title} + + + + ← Back to examples +

izod — {title}

+

{subtitle}

+ + + + diff --git a/examples/astro-demo/src/pages/core/child.astro b/examples/astro-demo/src/pages/core/child.astro index f0afc7b..3a6c39c 100644 --- a/examples/astro-demo/src/pages/core/child.astro +++ b/examples/astro-demo/src/pages/core/child.astro @@ -1,120 +1,90 @@ --- +import ChildLayout from "../../layouts/ChildLayout.astro"; --- - - - - - izod — Child Page - - - -

Child iframe

-

Running inside parent's iframe via izod

+ + Waiting for parent... - Waiting for parent... +
+ + +
-
- - -
+
-
+ - - + }) + .catch((error: unknown) => { + statusEl.textContent = "Error"; + statusEl.className = "status error"; + appendLog( + `Connection failed: ${error instanceof Error ? error.message : String(error)}`, + "error", + ); + }); + +
diff --git a/examples/astro-demo/src/pages/core/index.astro b/examples/astro-demo/src/pages/core/index.astro index d7a62da..6aaf410 100644 --- a/examples/astro-demo/src/pages/core/index.astro +++ b/examples/astro-demo/src/pages/core/index.astro @@ -1,136 +1,99 @@ --- -const base = import.meta.env.BASE_URL; +import ParentLayout from "../../layouts/ParentLayout.astro"; --- - - - - - izod — Parent Page - - - - ← Back to examples -

izod — Core Parent Page

-

Using @izod/core directly — createChild + connectToParent with zod validation

- - Connecting... - -
- -
- - -
- -

Event Log

-
- - - - + }) + .catch((error: unknown) => { + statusEl.textContent = "Error"; + statusEl.className = "status error"; + appendLog( + `Handshake failed: ${error instanceof Error ? error.message : String(error)}`, + "error", + ); + }); + + diff --git a/examples/astro-demo/src/pages/index.astro b/examples/astro-demo/src/pages/index.astro index 9db4f7a..c35f4c9 100644 --- a/examples/astro-demo/src/pages/index.astro +++ b/examples/astro-demo/src/pages/index.astro @@ -7,12 +7,12 @@ const base = import.meta.env.BASE_URL; izod — Demo - - - -

React Child iframe

-

Running inside parent's iframe via @izod/react hooks

- - - - + + + diff --git a/examples/astro-demo/src/pages/react/index.astro b/examples/astro-demo/src/pages/react/index.astro index b5d7b7a..8ef2afc 100644 --- a/examples/astro-demo/src/pages/react/index.astro +++ b/examples/astro-demo/src/pages/react/index.astro @@ -1,42 +1,10 @@ --- +import ParentLayout from "../../layouts/ParentLayout.astro"; import ReactParent from "../../components/ReactParent"; + const base = import.meta.env.BASE_URL; --- - - - - - izod — React Parent Page - - - - ← Back to examples -

izod — React Parent Page

-

Using @izod/react hooks with child.useCreate

- - - - + + + diff --git a/packages/react/src/useAsyncCallback.ts b/packages/react/src/useAsyncCallback.ts index 4984aac..22d310f 100644 --- a/packages/react/src/useAsyncCallback.ts +++ b/packages/react/src/useAsyncCallback.ts @@ -17,6 +17,7 @@ export function useAsyncCallback( const lastCallId = useRef(0); const mountedRef = useRef(false); + const loadingRef = useRef(false); useEffect(() => { mountedRef.current = true; @@ -33,27 +34,30 @@ export function useAsyncCallback( (...args: Parameters): Promise => { const callId = ++lastCallId.current; - if (!state.loading) { + if (!loadingRef.current) { + loadingRef.current = true; setState((previousState) => ({ ...previousState, loading: true })); } return (asyncFn as (...args: Parameters) => Promise)(...args).then( (value) => { + loadingRef.current = false; if (mountedRef.current && callId === lastCallId.current) { setState({ loading: false, value, error: undefined }); } return value; }, (error: unknown) => { + loadingRef.current = false; const normalizedError = error instanceof Error ? error : new Error(String(error)); if (mountedRef.current && callId === lastCallId.current) { setState({ loading: false, value: undefined, error: normalizedError }); } - return; + return undefined; }, ); }, - [asyncFn, state.loading], + [asyncFn], ); return [state, execute]; From 21230ad33a4821d9216938f85e87d8701dc6cd6e Mon Sep 17 00:00:00 2001 From: drenther <12991390+drenther@users.noreply.github.com> Date: Sat, 16 May 2026 17:01:11 +0530 Subject: [PATCH 16/16] fix: proper AsyncState union type and publish @standard-schema/spec Model AsyncState as a 4-variant discriminated union (matching react-use) so value/error are accessible on all variants while preserving narrowing. Move @standard-schema/spec from devDependencies to dependencies in @izod/core since it's re-exported in public type declarations. --- packages/core/package.json | 2 +- packages/react/src/useAsyncCallback.ts | 7 ++++--- pnpm-lock.yaml | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 4031da8..2a2afd4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -42,11 +42,11 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@standard-schema/spec": "catalog:", "crelt": "1.0.6", "nanoid": "5.1.5" }, "devDependencies": { - "@standard-schema/spec": "catalog:", "@vitest/coverage-v8": "catalog:", "happy-dom": "catalog:", "tsdown": "catalog:", diff --git a/packages/react/src/useAsyncCallback.ts b/packages/react/src/useAsyncCallback.ts index 22d310f..6baa7d1 100644 --- a/packages/react/src/useAsyncCallback.ts +++ b/packages/react/src/useAsyncCallback.ts @@ -1,9 +1,10 @@ import { useCallback, useEffect, useRef, useState } from 'react'; export type AsyncState = - | { loading: boolean } - | { loading: boolean; value: T } - | { loading: boolean; error: Error }; + | { loading: boolean; error?: undefined; value?: undefined } + | { loading: true; error?: Error; value?: T } + | { loading: false; error: Error; value?: undefined } + | { loading: false; error?: undefined; value: T }; type FunctionReturningPromise = (...args: never[]) => Promise; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bf6f4de..202887f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,6 +117,9 @@ importers: packages/core: dependencies: + '@standard-schema/spec': + specifier: 'catalog:' + version: 1.1.0 crelt: specifier: 1.0.6 version: 1.0.6 @@ -124,9 +127,6 @@ importers: specifier: 5.1.5 version: 5.1.5 devDependencies: - '@standard-schema/spec': - specifier: 'catalog:' - version: 1.1.0 '@vitest/coverage-v8': specifier: 'catalog:' version: 4.1.5(vitest@4.1.5)