diff --git a/.changeset/gentle-hoops-repeat.md b/.changeset/gentle-hoops-repeat.md
new file mode 100644
index 0000000..a300477
--- /dev/null
+++ b/.changeset/gentle-hoops-repeat.md
@@ -0,0 +1,7 @@
+---
+"@btravstack/entity": patch
+---
+
+Point the package README at the new documentation site,
+, instead of the Markdown files in the
+repository. No code change.
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
new file mode 100644
index 0000000..6620fee
--- /dev/null
+++ b/.github/actions/setup/action.yml
@@ -0,0 +1,30 @@
+name: "Setup Node.js and pnpm"
+description: "Setup Node.js and pnpm, install dependencies"
+
+# CI and Release call btravstack/config's reusable workflows, which do their own
+# setup. This composite exists for Deploy Documentation, which runs its own
+# steps in this repo and needs the same toolchain.
+
+runs:
+ using: "composite"
+ steps:
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: .node-version
+ cache: pnpm
+
+ - name: Setup Turbo Cache
+ uses: actions/cache@v4
+ with:
+ path: .turbo
+ key: ${{ runner.os }}-turbo-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-turbo-
+
+ - name: Install dependencies
+ shell: bash
+ run: pnpm install --frozen-lockfile
diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
new file mode 100644
index 0000000..f5bf59c
--- /dev/null
+++ b/.github/workflows/deploy-docs.yml
@@ -0,0 +1,62 @@
+name: Deploy Documentation
+
+# Publish the VitePress site once CI is green on main. Chaining off CI rather
+# than pushing directly means the site is never built from a commit that does
+# not compile, and the `github-pages` environment's branch policy sees `main`
+# (a `workflow_run` event runs against the default branch).
+on:
+ workflow_run:
+ workflows: ["CI"]
+ types:
+ - completed
+ branches:
+ - main
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ # A Pages deploy replaces the whole site, so only one may be in flight.
+ group: pages
+ cancel-in-progress: false
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+jobs:
+ build:
+ # A `workflow_run` fires on ANY CI conclusion (failure, cancelled); deploy
+ # only after a successful one. `workflow_dispatch` is unconditional.
+ if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v7
+
+ - name: Setup
+ uses: ./.github/actions/setup
+
+ # The docs build runs TypeDoc (straight from packages/entity/src into
+ # docs/api/entity) and then VitePress — see docs/package.json.
+ - name: Build documentation
+ run: pnpm --filter ./docs exec turbo build
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v5
+ with:
+ path: docs/.vitepress/dist
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ needs: build
+ runs-on: ubuntu-latest
+ name: Deploy
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v5
diff --git a/.gitignore b/.gitignore
index aca1408..b166f8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,13 @@ coverage/
# Turbo
.turbo/
+# VitePress
+docs/.vitepress/cache/
+docs/.vitepress/dist/
+# The package's API reference, generated by TypeDoc at build time
+# (the hand-written docs/api/index.md overview is kept)
+docs/api/entity/
+
# Logs
*.log
diff --git a/CLAUDE.md b/CLAUDE.md
index 66bf30a..fe24c06 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -10,18 +10,43 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
fallible operation returns an `unthrown` `Result` instead of
throwing.
-pnpm + turbo monorepo with a single package, `packages/entity`. Root scripts
-delegate to turbo; package scripts are where the real commands live.
+pnpm + turbo monorepo with two workspaces: the package, `packages/entity`, and
+the documentation site, `docs`. Root scripts delegate to turbo; workspace
+scripts are where the real commands live.
## Commands
-Scripts are in `package.json`; the root ones delegate to turbo. Two things
+Scripts are in `package.json`; the root ones delegate to turbo. Three things
that are not derivable from there:
- **The gate CI runs, in order**: `format --check`, `lint`, `typecheck`,
`test`, `knip`, `build`. `typecheck` is three passes — the main `tsc`, the
`.test-d.ts` pass, and the consumer declaration-emit pass.
- **A single test file runs from inside `packages/entity`**, not the root.
+- **The docs site runs from inside `docs`**: `pnpm --filter ./docs dev`.
+ `pnpm build` at the root builds it too, since it is a workspace.
+
+## The documentation site
+
+`docs/` is a VitePress site deployed to
+by `.github/workflows/deploy-docs.yml` once CI is green on `main`. It is
+organised by the four [Diátaxis](https://diataxis.fr/) modes — `tutorial/`,
+`how-to/`, `reference/`, `explanation/` — with one shared sidebar across all
+four so any page reaches any other. `docs/.vitepress/theme/custom.css` sets a
+single `--accent` token; the shared `@btravstack/theme` derives every other
+shade from it.
+
+Its build is `typedoc && vitepress build`. TypeDoc reads
+`packages/entity/src/index.ts` straight through and writes `docs/api/entity/`,
+which is git-ignored and regenerated every build — `docs/api/index.md` is the
+one hand-written page under `api/`.
+
+TypeDoc runs from **`docs/`** rather than from `packages/entity/` (where the
+other btravstack repos put it), with its own TypeScript from the named
+`typedoc` catalog. That is forced, not stylistic: the default catalog's
+`typescript: 7.0.2` is the native port and ships no JS compiler API, so TypeDoc
+cannot run against it. Measured — the reason is inline in
+`pnpm-workspace.yaml`.
## Architecture
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 421059d..3bf7376 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -29,11 +29,35 @@ pnpm lint # oxlint
pnpm typecheck # tsc (incl. type-level tests)
pnpm test # vitest
pnpm knip # dead code / unused deps
-pnpm build # tsdown dual CJS/ESM + d.ts
+pnpm build # tsdown dual CJS/ESM + d.ts, and the docs site
```
Run `pnpm format` (no `--check`) to auto-fix formatting.
+### The documentation site
+
+`docs/` is a workspace of its own — a [VitePress](https://vitepress.dev) site
+organised by the four [Diátaxis](https://diataxis.fr/) modes (Tutorial, How-to,
+Reference, Explanation), deployed to
+ by `.github/workflows/deploy-docs.yml`
+once CI is green on `main`.
+
+```sh
+pnpm --filter ./docs dev # local preview with hot reload
+pnpm --filter ./docs build # what CI and the deploy build
+```
+
+The build is `typedoc && vitepress build`. TypeDoc reads
+`packages/entity/src/index.ts` and writes `docs/api/entity/` (git-ignored,
+regenerated every build); `docs/api/index.md` is the one hand-written page
+there.
+
+TypeDoc runs from **`docs/`**, not from `packages/entity/` as it does in the
+other btravstack repos, and with its own TypeScript. That is forced, not
+stylistic: the catalog's `typescript: 7.0.2` is the native port, which ships no
+JS compiler API for TypeDoc to drive. The named `typedoc` catalog in
+`pnpm-workspace.yaml` pins 6.0.3 for that one job, with the reason inline.
+
### Type-level tests
Behaviour that only shows up at the type level — the construction seal, the
@@ -69,8 +93,8 @@ types, while the plain `tsc` pass is `noEmit` from the shared base.
## Design rules (binding)
-`docs/reference.md` documents the public behaviour and `docs/explanation.md`
-the rationale behind it; many of those rules were measured against a specific
+`docs/reference/` documents the public behaviour and `docs/explanation/` the
+rationale behind it; many of those rules were measured against a specific
compiler/library version, not assumed. Where a
source comment records a measurement (a TS diagnostic code, a specific
library's output), treat it as a regression guard, not decoration — verify
diff --git a/README.md b/README.md
index 662b698..ac65e2e 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
-[**Reference**](./docs/reference.md) · [**Explanation**](./docs/explanation.md) · [**How-to guides**](./docs/how-to)
+[**Documentation**](https://btravstack.github.io/entity/) · [**Getting started**](https://btravstack.github.io/entity/tutorial/getting-started) · [**Reference**](https://btravstack.github.io/entity/reference/declaration) · [**Why entity?**](https://btravstack.github.io/entity/explanation/why-entity)
@@ -67,7 +67,8 @@ pnpm add @btravstack/entity zod unthrown @unthrown/standard-schema
```
`zod`, `unthrown` and `@unthrown/standard-schema` are **peer dependencies** —
-install all four. ([Why](./docs/explanation.md#peer-dependencies).)
+install all four.
+([Why](https://btravstack.github.io/entity/explanation/peer-dependencies).)
## A worked example
@@ -146,13 +147,14 @@ existing one.
## Documentation
-- **[Reference](./docs/reference.md)** — every member, option and type, with signatures.
-- **[Explanation](./docs/explanation.md)** — why it is built this way: sealed construction, deep immutability, no I/O, why entities are not subclassable.
-- **How-to guides**
- - [Expose an HTTP contract](./docs/how-to/http-contract.md)
- - [Persist and rehydrate](./docs/how-to/persist-and-rehydrate.md)
- - [Model an aggregate](./docs/how-to/model-an-aggregate.md)
- - [Test domain logic](./docs/how-to/test-domain-logic.md)
+**[btravstack.github.io/entity](https://btravstack.github.io/entity/)** — built
+with VitePress from [`docs/`](./docs), and organised by the four
+[Diátaxis](https://diataxis.fr/) modes:
+
+- **[Tutorial](https://btravstack.github.io/entity/tutorial/getting-started)** — from nothing to a working entity, one step at a time.
+- **How-to guides** — [expose an HTTP contract](https://btravstack.github.io/entity/how-to/http-contract) · [persist and rehydrate](https://btravstack.github.io/entity/how-to/persist-and-rehydrate) · [model an aggregate](https://btravstack.github.io/entity/how-to/model-an-aggregate) · [test domain logic](https://btravstack.github.io/entity/how-to/test-domain-logic)
+- **[Reference](https://btravstack.github.io/entity/reference/declaration)** — every member, option and type, with signatures. Plus the [generated API reference](https://btravstack.github.io/entity/api/).
+- **[Explanation](https://btravstack.github.io/entity/explanation/why-entity)** — why it is built this way: sealed construction, deep immutability, no I/O, why entities are not subclassable.
## Development
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
new file mode 100644
index 0000000..39467cd
--- /dev/null
+++ b/docs/.vitepress/config.ts
@@ -0,0 +1,282 @@
+import { defineConfig } from "vitepress";
+
+const SITE_DESCRIPTION =
+ "A domain-entity builder on zod v4: branded fields, immutable data, sealed construction, and Result instead of throws.";
+
+const BASE = "/entity/";
+const SITE_URL = `https://btravstack.github.io${BASE}`;
+
+// The guide is structured by the four Diátaxis modes (https://diataxis.fr/): a
+// learning-oriented Tutorial, task-oriented How-to guides, information-oriented
+// Reference, and understanding-oriented Explanation. One shared sidebar carries
+// all four so any page can reach any other.
+const GUIDE_SIDEBAR = [
+ {
+ text: "Tutorial",
+ items: [{ text: "Getting started", link: "/tutorial/getting-started" }],
+ },
+ {
+ text: "How-to guides",
+ items: [
+ { text: "Expose an HTTP contract", link: "/how-to/http-contract" },
+ { text: "Persist and rehydrate", link: "/how-to/persist-and-rehydrate" },
+ { text: "Model an aggregate", link: "/how-to/model-an-aggregate" },
+ { text: "Test domain logic", link: "/how-to/test-domain-logic" },
+ ],
+ },
+ {
+ text: "Reference",
+ items: [
+ { text: "Declaring an entity", link: "/reference/declaration" },
+ { text: "Schema members", link: "/reference/schemas" },
+ { text: "Entry points", link: "/reference/entry-points" },
+ { text: "Errors", link: "/reference/errors" },
+ { text: "Helper types", link: "/reference/types" },
+ { text: "API reference", link: "/api/" },
+ ],
+ },
+ {
+ text: "Explanation",
+ items: [
+ { text: "Why entity?", link: "/explanation/why-entity" },
+ { text: "No I/O, by design", link: "/explanation/no-io" },
+ { text: "Sealed construction", link: "/explanation/sealed-construction" },
+ { text: "Immutability", link: "/explanation/immutability" },
+ { text: "Why computed re-derives", link: "/explanation/computed-fields" },
+ { text: "Tags and identity", link: "/explanation/tags-and-identity" },
+ { text: "Errors are values", link: "/explanation/errors-are-values" },
+ { text: "Peer dependencies", link: "/explanation/peer-dependencies" },
+ ],
+ },
+];
+
+// https://vitepress.dev/reference/site-config
+export default defineConfig({
+ title: "entity",
+ description: SITE_DESCRIPTION,
+ base: BASE,
+ lang: "en-US",
+ cleanUrls: true,
+
+ // `docs/superpowers/` is local design scratch — git-ignored, and not part of
+ // the published site. Without this VitePress renders whatever happens to be
+ // sitting there into a page and a sitemap entry.
+ srcExclude: ["superpowers/**"],
+
+ // The API reference under /api/entity/ is generated by TypeDoc and copied in at
+ // build time; its cross-references use relative links TypeDoc resolves itself.
+ ignoreDeadLinks: [/^\/api\//, /^\.\/index$/, /^\.\/[a-z-]+$/, /^\.\.\//],
+
+ sitemap: {
+ hostname: SITE_URL,
+ },
+
+ // Per-page canonical URL + Open Graph / Twitter title & description, so every
+ // page shares a correct preview and avoids duplicate-content ambiguity.
+ transformPageData(pageData) {
+ if (!pageData.relativePath.endsWith(".md")) {
+ return;
+ }
+
+ const normalizedPath = pageData.relativePath.replace(/^\/+/, "");
+ // cleanUrls is true, so the public URL has no `.html` extension: strip
+ // `index.md` to the directory and any other `.md` to the bare route.
+ const canonicalUrl = `${SITE_URL}${normalizedPath}`
+ .replace(/index\.md$/, "")
+ .replace(/\.md$/, "");
+
+ pageData.frontmatter ??= {};
+ pageData.frontmatter.head ??= [];
+
+ // The /api/ pages (except the hand-written overview) are TypeDoc output copied
+ // in at build time — they have no source file in the repo, so "Edit this page"
+ // would 404. docs/api/index.md is the one committed file there.
+ if (pageData.relativePath.startsWith("api/") && pageData.relativePath !== "api/index.md") {
+ pageData.frontmatter.editLink = false;
+ }
+
+ pageData.frontmatter.head.push(["link", { rel: "canonical", href: canonicalUrl }]);
+
+ const pageTitle = pageData.title || pageData.frontmatter.title || "entity";
+ const pageDescription =
+ pageData.description || pageData.frontmatter.description || SITE_DESCRIPTION;
+
+ pageData.frontmatter.head.push(
+ ["meta", { property: "og:url", content: canonicalUrl }],
+ ["meta", { property: "og:title", content: pageTitle }],
+ ["meta", { property: "og:description", content: pageDescription }],
+ ["meta", { name: "twitter:title", content: pageTitle }],
+ ["meta", { name: "twitter:description", content: pageDescription }],
+ );
+ },
+
+ themeConfig: {
+ logo: { light: "/logo-light.svg", dark: "/logo-dark.svg" },
+
+ nav: [
+ // The guide is organised by the four Diátaxis modes; the dropdown links
+ // the entry page of each. See the sidebar for the full contents.
+ {
+ text: "Guide",
+ items: [
+ { text: "Tutorial", link: "/tutorial/getting-started" },
+ { text: "How-to guides", link: "/how-to/http-contract" },
+ { text: "Reference", link: "/reference/declaration" },
+ { text: "Explanation", link: "/explanation/why-entity" },
+ ],
+ },
+ { text: "API", link: "/api/" },
+ {
+ text: "Changelog",
+ link: "https://github.com/btravstack/entity/releases",
+ },
+ // Back to the btravstack hub (links the docs up to the landing page).
+ { text: "btravstack", link: "https://btravstack.github.io/" },
+ ],
+
+ sidebar: {
+ // One shared sidebar across all four Diátaxis sections, so a reader can
+ // move between Tutorial / How-to / Reference / Explanation from any page.
+ ...Object.fromEntries(
+ ["/tutorial/", "/how-to/", "/reference/", "/explanation/"].map((prefix) => [
+ prefix,
+ GUIDE_SIDEBAR,
+ ]),
+ ),
+ "/api/": [
+ {
+ text: "API Reference",
+ items: [
+ { text: "Overview", link: "/api/" },
+ { text: "@btravstack/entity", link: "/api/entity/" },
+ ],
+ },
+ ],
+ },
+
+ socialLinks: [
+ { icon: "github", link: "https://github.com/btravstack/entity" },
+ { icon: "npm", link: "https://www.npmjs.com/package/@btravstack/entity" },
+ ],
+
+ footer: {
+ message: "Released under the MIT License.",
+ copyright: `Copyright © ${new Date().getFullYear()} Benoit TRAVERS`,
+ },
+
+ search: {
+ provider: "local",
+ },
+
+ // The reference pages are dense with `###`-level members; surfacing them in
+ // the right-rail outline is what makes them navigable.
+ outline: { level: [2, 3] },
+
+ editLink: {
+ pattern: "https://github.com/btravstack/entity/edit/main/docs/:path",
+ text: "Edit this page on GitHub",
+ },
+ },
+
+ vite: {
+ // @btravstack/theme's entry imports `vitepress/theme` (which pulls in `.css`)
+ // and its own `style.css`. VitePress externalizes node_modules deps in the SSR
+ // build, so Node's ESM loader would hit those `.css` files and throw
+ // ERR_UNKNOWN_FILE_EXTENSION. Bundling the theme through Vite handles the CSS.
+ ssr: { noExternal: ["@btravstack/theme"] },
+ },
+
+ head: [
+ ["link", { rel: "icon", type: "image/svg+xml", href: `${BASE}logo.svg` }],
+ ["meta", { name: "author", content: "Benoit TRAVERS" }],
+ ["meta", { name: "robots", content: "index, follow" }],
+ ["meta", { name: "application-name", content: "entity" }],
+ [
+ "meta",
+ {
+ name: "keywords",
+ content:
+ "typescript, zod, entity, domain-driven design, ddd, value object, immutable, branded types, json schema, errors as values, result, unthrown",
+ },
+ ],
+ // Open Graph — og:title/description/url are added per page in transformPageData
+ ["meta", { property: "og:type", content: "website" }],
+ ["meta", { property: "og:site_name", content: "entity" }],
+ ["meta", { property: "og:locale", content: "en_US" }],
+ ["meta", { property: "og:image", content: `${SITE_URL}logo-light.svg` }],
+ ["meta", { property: "og:image:type", content: "image/svg+xml" }],
+ [
+ "meta",
+ {
+ property: "og:image:alt",
+ content: "entity — a domain-entity builder for TypeScript, on zod v4",
+ },
+ ],
+ // Twitter Card
+ ["meta", { name: "twitter:card", content: "summary" }],
+ ["meta", { name: "twitter:image", content: `${SITE_URL}logo-light.svg` }],
+ [
+ "meta",
+ {
+ name: "twitter:image:alt",
+ content: "entity — a domain-entity builder for TypeScript, on zod v4",
+ },
+ ],
+ // JSON-LD structured data for better SEO
+ [
+ "script",
+ { type: "application/ld+json" },
+ JSON.stringify({
+ "@context": "https://schema.org",
+ "@type": "SoftwareApplication",
+ name: "@btravstack/entity",
+ description: SITE_DESCRIPTION,
+ applicationCategory: "DeveloperApplication",
+ operatingSystem: "Cross-platform",
+ offers: {
+ "@type": "Offer",
+ price: "0",
+ priceCurrency: "USD",
+ },
+ url: SITE_URL,
+ author: {
+ "@type": "Person",
+ name: "Benoit TRAVERS",
+ },
+ programmingLanguage: {
+ "@type": "ComputerLanguage",
+ name: "TypeScript",
+ url: "https://www.typescriptlang.org/",
+ },
+ keywords: "TypeScript, zod, domain-driven design, entity, immutability, Result",
+ }),
+ ],
+ // WebSite JSON-LD for proper site name display in Google search
+ [
+ "script",
+ { type: "application/ld+json" },
+ JSON.stringify({
+ "@context": "https://schema.org",
+ "@type": "WebSite",
+ name: "entity",
+ url: SITE_URL,
+ }),
+ ],
+ // Organization JSON-LD for logo display in Google search
+ [
+ "script",
+ { type: "application/ld+json" },
+ JSON.stringify({
+ "@context": "https://schema.org",
+ "@type": "Organization",
+ name: "entity",
+ url: SITE_URL,
+ logo: {
+ "@type": "ImageObject",
+ url: `${SITE_URL}logo.svg`,
+ },
+ sameAs: ["https://github.com/btravstack/entity"],
+ }),
+ ],
+ ],
+});
diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css
new file mode 100644
index 0000000..6b96f33
--- /dev/null
+++ b/docs/.vitepress/theme/custom.css
@@ -0,0 +1,59 @@
+/* entity accent — the mascotte's blush pink. The shared @btravstack/theme
+ * derives every accent shade (deep/hover/soft/washes/hero glow/feature icons/AA
+ * text) from this single token, including the darkened --text-accent that keeps
+ * accent-coloured text readable on the light canvas. */
+:root {
+ --accent: #ee9cc4;
+}
+
+/* Hero name in the package accent — the BtravStack multi-accent rule: the
+ * canvas stays neutral, the product glows in its own color (AA via
+ * --text-accent, which darkens on light). */
+:root:root {
+ --vp-home-hero-name-color: var(--text-accent);
+}
+
+/* Home-hero background glyph — the project's motif behind the hero: a record
+ * card with its fields, stamped validated. Painted in --accent through a mask,
+ * so it always tracks the accent token; the SVG is base64-encoded so no CSS
+ * minifier can mangle it. */
+.VPHome {
+ position: relative;
+ isolation: isolate;
+ /* content-column width, and the gutter from the viewport edge in to it —
+ defined once so the glow and glyph stay anchored to the same column. */
+ --btv-col: 1152px;
+ --btv-gutter: max(0px, calc((100% - var(--btv-col)) / 2));
+}
+.VPHome::after {
+ content: "";
+ position: absolute;
+ top: 8px;
+ left: var(--btv-gutter);
+ right: var(--btv-gutter);
+ aspect-ratio: 500 / 300;
+ background-color: var(--accent);
+ -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MDAgMzAwIiBmaWxsPSJub25lIj48cmVjdCB4PSIxNDAiIHk9IjUyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjE0NiIgcng9IjE2IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIvPjxnIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiPjxwYXRoIGQ9Ik0xNzIsOTYgSDI2MiIvPjxwYXRoIGQ9Ik0xNzIsMTI0IEgzMDIiLz48cGF0aCBkPSJNMTcyLDE1MiBIMjMyIi8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCwxODYpIHJvdGF0ZSgtMTQpIiBzdHJva2U9IiNmZmYiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PGNpcmNsZSByPSIzMCIgc3Ryb2tlLXdpZHRoPSIyLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQwIDcgNTIgNyA1OCA3Ii8+PGNpcmNsZSByPSIyMC41IiBzdHJva2Utd2lkdGg9IjEuNSIvPjxwYXRoIGQ9Ik0tOCwwLjYgTC0yLjcsNi4yIEw4LjksLTYuNiIgc3Ryb2tlLXdpZHRoPSIyLjQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L2c+PHRleHQgeD0iMTQwIiB5PSIyNDgiIGZvbnQtZmFtaWx5PSJtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTUiIGZpbGw9IiNmZmYiPkVudGl0eSgiT3JnYW5pemF0aW9uIik8L3RleHQ+PC9zdmc+")
+ no-repeat top center / contain;
+ mask: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MDAgMzAwIiBmaWxsPSJub25lIj48cmVjdCB4PSIxNDAiIHk9IjUyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjE0NiIgcng9IjE2IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIvPjxnIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiPjxwYXRoIGQ9Ik0xNzIsOTYgSDI2MiIvPjxwYXRoIGQ9Ik0xNzIsMTI0IEgzMDIiLz48cGF0aCBkPSJNMTcyLDE1MiBIMjMyIi8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCwxODYpIHJvdGF0ZSgtMTQpIiBzdHJva2U9IiNmZmYiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PGNpcmNsZSByPSIzMCIgc3Ryb2tlLXdpZHRoPSIyLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQwIDcgNTIgNyA1OCA3Ii8+PGNpcmNsZSByPSIyMC41IiBzdHJva2Utd2lkdGg9IjEuNSIvPjxwYXRoIGQ9Ik0tOCwwLjYgTC0yLjcsNi4yIEw4LjksLTYuNiIgc3Ryb2tlLXdpZHRoPSIyLjQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L2c+PHRleHQgeD0iMTQwIiB5PSIyNDgiIGZvbnQtZmFtaWx5PSJtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTUiIGZpbGw9IiNmZmYiPkVudGl0eSgiT3JnYW5pemF0aW9uIik8L3RleHQ+PC9zdmc+")
+ no-repeat top center / contain;
+ opacity: 0.14;
+ pointer-events: none;
+ z-index: -1;
+}
+@media (max-width: 768px) {
+ .VPHome::after {
+ display: none;
+ }
+}
+
+/* The shared theme only enlarges the hero mark at >=960px; below that the
+ * mark's small intrinsic size leaves it tiny, so size it up for tablet/mobile
+ * too. */
+@media (max-width: 959px) {
+ .VPHero .image-src {
+ width: min(208px, 62vw);
+ height: min(208px, 62vw);
+ object-fit: contain;
+ }
+}
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
new file mode 100644
index 0000000..d0c50ff
--- /dev/null
+++ b/docs/.vitepress/theme/index.ts
@@ -0,0 +1,5 @@
+import Theme from "@btravstack/theme";
+
+import "./custom.css";
+
+export default Theme;
diff --git a/docs/api/index.md b/docs/api/index.md
new file mode 100644
index 0000000..509aaba
--- /dev/null
+++ b/docs/api/index.md
@@ -0,0 +1,30 @@
+# API reference
+
+Generated from the source with [TypeDoc](https://typedoc.org/) — every exported
+symbol, with its signature and TSDoc.
+
+- **[`@btravstack/entity`](/api/entity/)** — `Entity`, the merged `Entity`
+ namespace, and the three seal names (`BaseInstance`, `ConstructionKey`,
+ `Sealed`) the published declarations force out.
+
+::: tip Looking for prose?
+The generated pages document _signatures_. For what each member is **for**, with
+worked examples, read the hand-written [Reference](/reference/declaration); for
+_why_ the surface is shaped this way, read the
+[Explanation](/explanation/why-entity).
+:::
+
+## The shape of the surface
+
+`index.ts` exports exactly one name you write against:
+
+```ts
+import { Entity } from "@btravstack/entity";
+```
+
+`Entity.computed`, `Entity.invariant`, `Entity.union` and `Entity.InvalidEntity`
+hang off it as values, and every public type lives in a merged
+`declare namespace Entity`. A bare `computed` or `union` would be too generic to
+take from a consumer's import scope, so nothing else is exported — with one
+measured exception, [`BaseInstance` / `ConstructionKey` /
+`Sealed`](/reference/types#the-seal-names).
diff --git a/docs/explanation.md b/docs/explanation.md
deleted file mode 100644
index 6360503..0000000
--- a/docs/explanation.md
+++ /dev/null
@@ -1,217 +0,0 @@
-# Explanation
-
-Why the package is built the way it is. Several of these record behaviour that
-was **measured**, not assumed — the diagnostic codes are quoted so a future
-change can re-check rather than re-litigate.
-
-> Snippets below assume these imports:
->
-> ```ts
-> import { z } from "zod";
-> import { match, P } from "unthrown";
-> import { Entity } from "@btravstack/entity";
-> ```
-
-## What an entity is, and why this exists
-
-An entity is simultaneously four things: a **type** your domain code programs
-against, a **validator** for data crossing a trust boundary, a **value with
-behaviour** (methods, invariants), and something that **nests inside other
-entities**. Most tools give you two or three at once — a validation library
-gives a type and a validator; a plain class gives a type and behaviour — and
-stitching the rest together by hand is exactly the repetitive, error-prone work
-a library should absorb.
-
-[Effect's `Schema.Class`](https://www.effect.website/docs/v3/schema/classes)
-gets all four right at once and is the closest prior art. This package targets
-the same shape on top of **zod v4** and
-**[Standard Schema](https://standardschema.dev)**, with entry points named for
-the use case they serve rather than one generic `parse`.
-
-## The rule the design turns on
-
-**Contracts compose the four `ZodObject`s; domain code composes the class.**
-
-It comes from a real constraint in zod's schema-to-JSON-Schema conversion: a
-schema carrying a `.transform()` — which is what turns parsed data into a class
-instance — has no output representation. The class does exactly that, so
-`z.toJSONSchema(Organization, { io: "output" })` throws by design, while the
-four plain `ZodObject`s convert in both directions with no hand-written omit
-lists.
-
-## No I/O, by design
-
-The package reads no clock and generates no id. A factory's generators, not an
-internal `crypto.randomUUID()`/`Date.now()`, are how a domain-generated value
-reaches an entity.
-
-The _rule_ — which fields the domain owns, and that a caller may never supply
-them — lives in the declaration. The _sources_ are bound once at your
-composition root. That keeps the entity pure, and lets a test bind fixed
-generators instead of stubbing globals.
-
-Generators are functions, called once per create, so a factory built at startup
-still yields a fresh id per entity.
-
-## Sealed construction
-
-`new SomeEntity(...)` does not compile. The constructor takes a `Sealed`,
-and no outside code can produce a value assignable to it — so every instance
-comes through `make`, `update` or a factory, which means the invariants have
-run and the stored data is exactly what `output` describes.
-
-The seal is a type, not a runtime check, because a runtime guard would mean
-throwing — which this package exists to avoid.
-
-Two alternatives were measured and rejected:
-
-- **`private constructor`** → `TS2675: Cannot extend a class 'Base'`. The
- declaration form `class X extends Entity("X")(…)` stops compiling outright.
-- **`protected constructor`** → seals correctly (`TS2674`) but breaks the
- statics with `TS2684` — a protected constructor type is not assignable to a
- public one — so `make` could only return the base class.
-
-The key is an **exported but unconstructable** `ConstructionKey` rather than a
-module-private `unique symbol`. That matters for consumers: a `unique symbol`
-in computed-key position cannot be named across a module boundary even when
-exported, so any downstream library compiling with `declaration: true` failed
-with `TS4020: 'extends' clause of exported class has or is using private name`.
-A fixture in CI compiles a consumer with declaration emit against the built
-types, so that cannot regress.
-
-## Immutability
-
-Data is immutable in both halves. Each field is installed non-writable, and its
-value is **deep-frozen** — a shallow guard would leave `org.tags.push(…)` legal,
-which could push an entity into a state its own invariants had already
-rejected. The instance type is `DeepReadonly<…>`, not a shallow `Readonly<…>`,
-so mutation is a compile error first and a `TypeError` only if a consumer casts
-around the type system:
-
-```ts
-org.slug = otherSlug; // ✗ compile error — read-only property
-(org as never as Record).slug = "hacked"; // TypeError
-
-// on a `Team` declared with `tags: z.array(Tag)` and `address: Address`
-team.tags.push(tag); // ✗ compile error — tags is `readonly Tag[]`
-(team.tags as never as string[]).push("hacked"); // TypeError — the array is frozen
-team.address.city = "Paris"; // ✗ compile error — nested objects are readonly too
-```
-
-Locking the binding alone would not be enough: `writable: false` stops
-`team.tags = [...]` but not `team.tags.push(...)`, and a shallow `Readonly`
-types an array field as a mutable `Tag[]`, because `z.infer` of `z.array(Tag)`
-is `Tag[]`. Both halves matter — the second is what lets `invariants` mean
-anything after construction.
-
-What the freeze covers is deliberately narrow: arrays and plain objects are
-frozen and recursed into; `Date` is frozen as a leaf; `Map`, `Set` and typed
-arrays are left alone, because freezing those is either theatre (a frozen `Map`
-still accepts `.set`) or destructive. A field whose schema yields a live mutable
-object is outside the guarantee.
-
-A `z.custom(...)`/`z.instanceof(...)` field is skipped **by its schema**, not by
-what the value turns out to look like at runtime. That distinction is the whole
-point: `z.custom` hands back the caller's own reference, and a plain-object one
-is indistinguishable at runtime from decoded data. Deciding by runtime shape
-froze objects the caller still owned, so their next write threw. Only the
-declaration knows which values were passed through, so that is where the
-decision is made.
-
-`Object.freeze(this)` is **not** used and cannot be: a class body's field
-initialisers run after `super()` returns, so the instance itself must stay
-extensible.
-
-## Why `computed` re-derives
-
-A computed field reads the declared fields and is re-derived on `make` and
-`update` alike, rather than computed once and stored.
-
-The alternative was tried and is quietly wrong. Deriving `fullName` from
-`first` + `last` once, then renaming the person, leaves `fullName` frozen at the
-old value — and since a derived field is not patchable, unrepairable. Every
-plausible use (`totalCents`, `tier`, `wordCount`, `durationDays`) has that shape.
-
-Re-deriving also makes `make` self-healing: a row written before a derivation
-changed, or before the field existed at all, is corrected on read rather than
-trusted. That is why `make` validates against `input` and not `output` —
-validating stored computed values would reject exactly the rows it is meant to
-repair.
-
-**Why not a getter?** Because a getter carries no schema. It cannot appear in
-`output`, cannot generate JSON Schema, and is skipped by `toJSON()` — it lives
-on the prototype, not in the data. The rule:
-
-| | use |
-| -------------------------------------------------- | ---------- |
-| derived, needed in the response body / JSON Schema | `computed` |
-| derived, domain-only behaviour | a getter |
-
-## Entities are not subclassable
-
-`class Sub extends Organization {}` fails at construction with a `Defect`.
-
-A bare subclass is an alias you cannot tell apart from what it aliases: same
-tag, same schemas, indistinguishable under `equals`. `extend` exists for the
-legitimate case and produces a genuine entity with its own identity.
-
-The prohibition is runtime-only. TypeScript has no `final`, and the constructor
-accessibility modifiers that would express it break the declaration form or the
-statics (see [Sealed construction](#sealed-construction)). So the declaration
-compiles and reports on first construction.
-
-Redeclaring a data field in a subclass is caught earlier — TypeScript reports
-`TS4114` under `noImplicitOverride`, and the field is non-configurable, so
-construction fails with `TypeError: Cannot redefine property`.
-
-## `_tag` is runtime-only
-
-Every instance carries a non-enumerable `_tag`, for pattern matching with
-`unthrown`'s `P.tag(...)`:
-
-```ts
-match(member)
- .with(P.tag("User"), (u) => u.email)
- .with(P.tag("ServiceAccount"), (s) => s.label)
- .exhaustive();
-```
-
-It never reaches the wire — absent from every schema, from `toJSON()`,
-`JSON.stringify`, `Object.keys` and spread. That has a direct consequence: a
-union that must survive a JSON round trip **cannot** discriminate on `_tag`,
-because it is not there after serialisation. Declare the discriminant as an
-ordinary domain field; `Entity.union` takes that field.
-
-The two are not redundant. A brand is per-field and type-only; the tag is
-per-entity and runtime-present, which is what makes it matchable. `entityName`
-is the same string read from the class rather than an instance — the only path
-for code holding the class and no instance.
-
-## Errors are values, and defects are separate
-
-Every fallible entry point returns `Result`. Bad input is
-modelled; a bug in domain code is not.
-
-The line: a field failing its schema or a broken invariant is `InvalidEntity` —
-expected, caller-caused. A `computed` function throwing or producing data its
-own schema rejects is a **defect**: `computed` is pure, total and typed, so a
-violation is a bug rather than bad input. An async generator rejecting is a
-defect for the same reason — infrastructure failing is not bad domain input.
-
-A defect is never folded into a validation issue, even when the entity is
-nested inside another schema. An unmodelled bug stays distinguishable from bad
-caller input all the way to the edge.
-
-Issues are carried **structured**, exactly as the validator produced them, so
-keying a field-level error response is a `path` lookup rather than a string
-parse.
-
-## Peer dependencies
-
-`zod`, `unthrown` and `@unthrown/standard-schema` are peer dependencies, not
-bundled ones. The package hands back real `ZodObject`s and real `Result`s built
-from _your_ copies. If it pinned its own, a consumer would end up with two
-copies of zod in the tree, and identity checks — `result instanceof Result`,
-`schema instanceof z.ZodType`, or composing an entity into your own
-`z.object({...})` — can silently misbehave across the boundary between two
-copies of the same package.
diff --git a/docs/explanation/computed-fields.md b/docs/explanation/computed-fields.md
new file mode 100644
index 0000000..4ed8dde
--- /dev/null
+++ b/docs/explanation/computed-fields.md
@@ -0,0 +1,34 @@
+---
+title: Why computed re-derives
+description: Why a derived field is recomputed on every construction instead of stored, why make validates against input, and when to use a getter instead.
+---
+
+# Why `computed` re-derives
+
+A computed field reads the declared fields and is re-derived on `make` and
+`update` alike, rather than computed once and stored.
+
+The alternative was tried and is quietly wrong. Deriving `fullName` from
+`first` + `last` once, then renaming the person, leaves `fullName` frozen at the
+old value — and since a derived field is not patchable, unrepairable. Every
+plausible use (`totalCents`, `tier`, `wordCount`, `durationDays`) has that shape.
+
+Re-deriving also makes `make` self-healing: a row written before a derivation
+changed, or before the field existed at all, is corrected on read rather than
+trusted. That is why `make` validates against `input` and not `output` —
+validating stored computed values would reject exactly the rows it is meant to
+repair.
+
+## Why not a getter?
+
+Because a getter carries no schema. It cannot appear in `output`, cannot
+generate JSON Schema, and is skipped by `toJSON()` — it lives on the prototype,
+not in the data. The rule:
+
+| | use |
+| -------------------------------------------------- | ---------- |
+| derived, needed in the response body / JSON Schema | `computed` |
+| derived, domain-only behaviour | a getter |
+
+[Persist and rehydrate](/how-to/persist-and-rehydrate#computed-columns-heal-themselves)
+shows the self-healing read against a real table.
diff --git a/docs/explanation/errors-are-values.md b/docs/explanation/errors-are-values.md
new file mode 100644
index 0000000..9a116d2
--- /dev/null
+++ b/docs/explanation/errors-are-values.md
@@ -0,0 +1,27 @@
+---
+title: Errors are values, and defects are separate
+description: Where the line falls between bad caller input and a bug in domain code, and why the two never merge.
+---
+
+# Errors are values, and defects are separate
+
+Every fallible entry point returns `Result`. Bad input is
+modelled; a bug in domain code is not.
+
+The line: a field failing its schema or a broken invariant is `InvalidEntity` —
+expected, caller-caused. A `computed` function throwing or producing data its
+own schema rejects is a **defect**: `computed` is pure, total and typed, so a
+violation is a bug rather than bad input. An async generator rejecting is a
+defect for the same reason — infrastructure failing is not bad domain input.
+
+A defect is never folded into a validation issue, even when the entity is
+nested inside another schema. An unmodelled bug stays distinguishable from bad
+caller input all the way to the edge.
+
+Issues are carried **structured**, exactly as the validator produced them, so
+keying a field-level error response is a `path` lookup rather than a string
+parse.
+
+[Errors](/reference/errors) tabulates which failure takes which channel; the
+[unthrown docs](https://btravstack.github.io/unthrown/explanation/the-defect-channel)
+explain the defect channel itself.
diff --git a/docs/explanation/immutability.md b/docs/explanation/immutability.md
new file mode 100644
index 0000000..0331b50
--- /dev/null
+++ b/docs/explanation/immutability.md
@@ -0,0 +1,49 @@
+---
+title: Immutability
+description: Why both halves matter — non-writable bindings and a deep freeze — and exactly what the freeze does and does not cover.
+---
+
+# Immutability
+
+Data is immutable in both halves. Each field is installed non-writable, and its
+value is **deep-frozen** — a shallow guard would leave `org.tags.push(…)` legal,
+which could push an entity into a state its own invariants had already
+rejected. The instance type is `DeepReadonly<…>`, not a shallow `Readonly<…>`,
+so mutation is a compile error first and a `TypeError` only if a consumer casts
+around the type system:
+
+```ts
+org.slug = otherSlug; // ✗ compile error — read-only property
+(org as never as Record).slug = "hacked"; // TypeError
+
+// on a `Team` declared with `tags: z.array(Tag)` and `address: Address`
+team.tags.push(tag); // ✗ compile error — tags is `readonly Tag[]`
+(team.tags as never as string[]).push("hacked"); // TypeError — the array is frozen
+team.address.city = "Paris"; // ✗ compile error — nested objects are readonly too
+```
+
+Locking the binding alone would not be enough: `writable: false` stops
+`team.tags = [...]` but not `team.tags.push(...)`, and a shallow `Readonly`
+types an array field as a mutable `Tag[]`, because `z.infer` of `z.array(Tag)`
+is `Tag[]`. Both halves matter — the second is what lets `invariants` mean
+anything after construction.
+
+## What the freeze covers
+
+What the freeze covers is deliberately narrow: arrays and plain objects are
+frozen and recursed into; `Date` is frozen as a leaf; `Map`, `Set` and typed
+arrays are left alone, because freezing those is either theatre (a frozen `Map`
+still accepts `.set`) or destructive. A field whose schema yields a live mutable
+object is outside the guarantee.
+
+A `z.custom(...)`/`z.instanceof(...)` field is skipped **by its schema**, not by
+what the value turns out to look like at runtime. That distinction is the whole
+point: `z.custom` hands back the caller's own reference, and a plain-object one
+is indistinguishable at runtime from decoded data. Deciding by runtime shape
+froze objects the caller still owned, so their next write threw. Only the
+declaration knows which values were passed through, so that is where the
+decision is made.
+
+`Object.freeze(this)` is **not** used and cannot be: a class body's field
+initialisers run after `super()` returns, so the instance itself must stay
+extensible.
diff --git a/docs/explanation/no-io.md b/docs/explanation/no-io.md
new file mode 100644
index 0000000..fcc8b17
--- /dev/null
+++ b/docs/explanation/no-io.md
@@ -0,0 +1,36 @@
+---
+title: No I/O, by design
+description: Why the package reads no clock and generates no id, and why generators are functions bound at the composition root.
+---
+
+# No I/O, by design
+
+The package reads no clock and generates no id. A factory's generators, not an
+internal `crypto.randomUUID()`/`Date.now()`, are how a domain-generated value
+reaches an entity.
+
+The _rule_ — which fields the domain owns, and that a caller may never supply
+them — lives in the declaration. The _sources_ are bound once at your
+composition root. That keeps the entity pure, and lets a test bind fixed
+generators instead of stubbing globals.
+
+Generators are functions, called once per create, so a factory built at startup
+still yields a fresh id per entity.
+
+```ts
+// composition root
+const createOrganization = Organization.factory({
+ id: () => ids.next(),
+ createdAt: () => clock.now(),
+});
+
+// a test — no global stubbing, no fake timers
+const createFixed = Organization.factory({
+ id: () => FIXED_ID,
+ createdAt: () => FIXED_INSTANT,
+});
+```
+
+See [`factory` / `factoryAsync`](/reference/entry-points) for the signatures, and
+[Test domain logic](/how-to/test-domain-logic#bind-fixed-generators-instead-of-stubbing-globals)
+for the testing pattern this enables.
diff --git a/docs/explanation/peer-dependencies.md b/docs/explanation/peer-dependencies.md
new file mode 100644
index 0000000..e6e1c08
--- /dev/null
+++ b/docs/explanation/peer-dependencies.md
@@ -0,0 +1,20 @@
+---
+title: Peer dependencies
+description: Why zod, unthrown and @unthrown/standard-schema are peers rather than bundled dependencies.
+---
+
+# Peer dependencies
+
+`zod`, `unthrown` and `@unthrown/standard-schema` are peer dependencies, not
+bundled ones. The package hands back real `ZodObject`s and real `Result`s built
+from _your_ copies. If it pinned its own, a consumer would end up with two
+copies of zod in the tree, and identity checks — `result instanceof Result`,
+`schema instanceof z.ZodType`, or composing an entity into your own
+`z.object({...})` — can silently misbehave across the boundary between two
+copies of the same package.
+
+So all four are installed together:
+
+```sh
+pnpm add @btravstack/entity zod unthrown @unthrown/standard-schema
+```
diff --git a/docs/explanation/sealed-construction.md b/docs/explanation/sealed-construction.md
new file mode 100644
index 0000000..cbce82e
--- /dev/null
+++ b/docs/explanation/sealed-construction.md
@@ -0,0 +1,48 @@
+---
+title: Sealed construction
+description: Why new SomeEntity(…) does not compile, the two alternatives that were measured and rejected, and why entities are not subclassable.
+---
+
+# Sealed construction
+
+`new SomeEntity(...)` does not compile. The constructor takes a `Sealed`,
+and no outside code can produce a value assignable to it — so every instance
+comes through `make`, `update` or a factory, which means the invariants have
+run and the stored data is exactly what `output` describes.
+
+The seal is a type, not a runtime check, because a runtime guard would mean
+throwing — which this package exists to avoid.
+
+Two alternatives were measured and rejected:
+
+- **`private constructor`** → `TS2675: Cannot extend a class 'Base'`. The
+ declaration form `class X extends Entity("X")(…)` stops compiling outright.
+- **`protected constructor`** → seals correctly (`TS2674`) but breaks the
+ statics with `TS2684` — a protected constructor type is not assignable to a
+ public one — so `make` could only return the base class.
+
+The key is an **exported but unconstructable** `ConstructionKey` rather than a
+module-private `unique symbol`. That matters for consumers: a `unique symbol`
+in computed-key position cannot be named across a module boundary even when
+exported, so any downstream library compiling with `declaration: true` failed
+with `TS4020: 'extends' clause of exported class has or is using private name`.
+A fixture in CI compiles a consumer with declaration emit against the built
+types, so that cannot regress.
+
+## Entities are not subclassable
+
+`class Sub extends Organization {}` fails at construction with a `Defect`.
+
+A bare subclass is an alias you cannot tell apart from what it aliases: same
+tag, same schemas, indistinguishable under `equals`.
+[`extend`](/reference/declaration#someentity-extend-tag-fields-options) exists
+for the legitimate case and produces a genuine entity with its own identity.
+
+The prohibition is runtime-only. TypeScript has no `final`, and the constructor
+accessibility modifiers that would express it break the declaration form or the
+statics (see above). So the declaration compiles and reports on first
+construction.
+
+Redeclaring a data field in a subclass is caught earlier — TypeScript reports
+`TS4114` under `noImplicitOverride`, and the field is non-configurable, so
+construction fails with `TypeError: Cannot redefine property`.
diff --git a/docs/explanation/tags-and-identity.md b/docs/explanation/tags-and-identity.md
new file mode 100644
index 0000000..c8a340a
--- /dev/null
+++ b/docs/explanation/tags-and-identity.md
@@ -0,0 +1,31 @@
+---
+title: Tags and identity
+description: Why every instance carries a runtime _tag that never reaches the wire, and why a serialisable union must discriminate on a domain field instead.
+---
+
+# Tags and identity
+
+Every instance carries a non-enumerable `_tag`, for pattern matching with
+`unthrown`'s `P.tag(...)`:
+
+```ts
+match(member)
+ .with(P.tag("User"), (u) => u.email)
+ .with(P.tag("ServiceAccount"), (s) => s.label)
+ .exhaustive();
+```
+
+It never reaches the wire — absent from every schema, from `toJSON()`,
+`JSON.stringify`, `Object.keys` and spread. That has a direct consequence: a
+union that must survive a JSON round trip **cannot** discriminate on `_tag`,
+because it is not there after serialisation. Declare the discriminant as an
+ordinary domain field; [`Entity.union`](/reference/declaration#entity-union-discriminant-members)
+takes that field.
+
+The two are not redundant. A brand is per-field and type-only; the tag is
+per-entity and runtime-present, which is what makes it matchable. `entityName`
+is the same string read from the class rather than an instance — the only path
+for code holding the class and no instance.
+
+[Model an aggregate](/how-to/model-an-aggregate#model-a-union-of-entities)
+declares such a union against a real payload.
diff --git a/docs/explanation/why-entity.md b/docs/explanation/why-entity.md
new file mode 100644
index 0000000..c69872f
--- /dev/null
+++ b/docs/explanation/why-entity.md
@@ -0,0 +1,48 @@
+---
+title: Why entity?
+description: What an entity actually is, why the four jobs belong in one declaration, and the rule the whole design turns on.
+---
+
+# Why entity?
+
+Why the package is built the way it is. Several pages in this section record
+behaviour that was **measured**, not assumed — the diagnostic codes are quoted
+so a future change can re-check rather than re-litigate.
+
+> Snippets in this section assume these imports:
+>
+> ```ts
+> import { z } from "zod";
+> import { match, P } from "unthrown";
+> import { Entity } from "@btravstack/entity";
+> ```
+
+## What an entity is, and why this exists
+
+An entity is simultaneously four things: a **type** your domain code programs
+against, a **validator** for data crossing a trust boundary, a **value with
+behaviour** (methods, invariants), and something that **nests inside other
+entities**. Most tools give you two or three at once — a validation library
+gives a type and a validator; a plain class gives a type and behaviour — and
+stitching the rest together by hand is exactly the repetitive, error-prone work
+a library should absorb.
+
+[Effect's `Schema.Class`](https://www.effect.website/docs/v3/schema/classes)
+gets all four right at once and is the closest prior art. This package targets
+the same shape on top of **zod v4** and
+**[Standard Schema](https://standardschema.dev)**, with entry points named for
+the use case they serve rather than one generic `parse`.
+
+## The rule the design turns on
+
+**Contracts compose the four `ZodObject`s; domain code composes the class.**
+
+It comes from a real constraint in zod's schema-to-JSON-Schema conversion: a
+schema carrying a `.transform()` — which is what turns parsed data into a class
+instance — has no output representation. The class does exactly that, so
+`z.toJSONSchema(Organization, { io: "output" })` throws by design, while the
+four plain `ZodObject`s convert in both directions with no hand-written omit
+lists.
+
+[Expose an HTTP contract](/how-to/http-contract) is that rule applied end to
+end; [Schema members](/reference/schemas) is what each of the four is for.
diff --git a/docs/how-to/http-contract.md b/docs/how-to/http-contract.md
index f85e7ab..a02af69 100644
--- a/docs/how-to/http-contract.md
+++ b/docs/how-to/http-contract.md
@@ -1,3 +1,8 @@
+---
+title: Expose an HTTP contract
+description: Turn an entity into request and response schemas for a route, converted to JSON Schema in both directions, with no hand-written omit lists.
+---
+
# Expose an HTTP contract
**Problem:** you have an entity and need request and response schemas for a
diff --git a/docs/how-to/model-an-aggregate.md b/docs/how-to/model-an-aggregate.md
index f2f76b9..b0bfc8a 100644
--- a/docs/how-to/model-an-aggregate.md
+++ b/docs/how-to/model-an-aggregate.md
@@ -1,3 +1,8 @@
+---
+title: Model an aggregate
+description: Nest entities inside entities, span invariants across the boundary, and model a union of entities that survives a JSON round trip.
+---
+
# Model an aggregate
**Problem:** one entity contains others — an order with a customer and line
@@ -145,4 +150,4 @@ class PersonWithAge extends Person.extend("PersonWithAge")({ age: Age }) {}
That produces a new entity with its own tag and identity — not a variant of
`Person`, and not a subclass, which is
-[refused](../explanation.md#entities-are-not-subclassable).
+[refused](/explanation/sealed-construction#entities-are-not-subclassable).
diff --git a/docs/how-to/persist-and-rehydrate.md b/docs/how-to/persist-and-rehydrate.md
index 3a30482..e4a8852 100644
--- a/docs/how-to/persist-and-rehydrate.md
+++ b/docs/how-to/persist-and-rehydrate.md
@@ -1,3 +1,8 @@
+---
+title: Persist and rehydrate
+description: Write an entity to a database with toJSON() and read it back with make(), without the storage layer knowing about entity internals.
+---
+
# Persist and rehydrate
**Problem:** you need to write an entity to a database and read it back,
diff --git a/docs/how-to/test-domain-logic.md b/docs/how-to/test-domain-logic.md
index e74b365..ae0b55d 100644
--- a/docs/how-to/test-domain-logic.md
+++ b/docs/how-to/test-domain-logic.md
@@ -1,3 +1,8 @@
+---
+title: Test domain logic
+description: Deterministic entity tests without stubbing Date.now or crypto.randomUUID, asserting on failures without try/catch.
+---
+
# Test domain logic
**Problem:** entities involve ids and timestamps, and you want deterministic
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..cec8042
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,102 @@
+---
+layout: home
+title: entity — a domain-entity builder for TypeScript, on zod v4
+description: One declaration gives you a type, four request/response schemas, behaviour, and a class that is itself a zod schema. Nothing throws.
+
+hero:
+ name: "entity"
+ text: "Domain entities, declared once"
+ tagline: One declaration yields a type, four request/response schemas, behaviour, and a class that is itself a zod schema — with branded fields, immutable data, sealed construction, and Result instead of throws.
+ image:
+ light: /logo-light.svg
+ dark: /logo-dark.svg
+ alt: entity
+ actions:
+ - theme: brand
+ text: Get Started
+ link: /tutorial/getting-started
+ - theme: alt
+ text: Why entity?
+ link: /explanation/why-entity
+ - theme: alt
+ text: GitHub
+ link: https://github.com/btravstack/entity
+
+features:
+ - icon: { src: /icons/schemas.svg }
+ title: One declaration, four schemas
+ details: "input, output, createInput and updateInput are derived from one field map plus generated / immutable / computed. Plain ZodObjects, so they convert to JSON Schema in both directions — no hand-written omit lists."
+ - icon: { src: /icons/seal.svg }
+ title: Sealed and immutable
+ details: "new SomeEntity(…) does not compile. Every instance comes through make, update or a factory, so the invariants have run — and its data is deep-frozen, mutation a compile error first."
+ - icon: { src: /icons/nest.svg }
+ title: Entities nest in entities
+ details: "The class is itself a zod schema, so it drops into z.object({ owner: Organization }) as a field and still parses to a real instance, with its own behaviour and identity."
+ - icon: { src: /icons/result.svg }
+ title: Nothing throws
+ details: "Every fallible operation returns an unthrown Result carrying structured issues. A bug in your own domain code stays a separate defect, never folded into caller error."
+---
+
+## At a glance
+
+```ts
+import { z } from "zod";
+import { Entity } from "@btravstack/entity";
+
+const OrgId = z.uuid().brand("OrgId");
+const Slug = z.string().min(1).brand("Slug");
+const DisplayName = z.string().min(1).brand("DisplayName");
+const Instant = z.iso.datetime().brand("Instant");
+const Upper = z.string().min(1).brand("Upper");
+
+class Organization extends Entity("Organization")(
+ { id: OrgId, slug: Slug, name: DisplayName, createdAt: Instant },
+ {
+ generated: ["id", "createdAt"],
+ immutable: ["id", "createdAt", "slug"],
+ computed: {
+ shout: Entity.computed(
+ Upper,
+ (d) => d.name.toUpperCase() as z.infer,
+ ),
+ },
+ invariants: [
+ Entity.invariant(
+ (d) => d.name.length <= 80,
+ "name must be at most 80 characters",
+ ),
+ ],
+ },
+) {
+ get greeting(): string {
+ return `Welcome, ${this.name}`;
+ }
+}
+
+// The package reads no clock and generates no id: bind the sources once,
+// where your ports already live.
+const createOrganization = Organization.factory({
+ id: () => ids.next(),
+ createdAt: () => clock.now(),
+});
+
+const org = createOrganization({ slug, name }).getOrThrow();
+await db.insert(org.toJSON()); // exactly the stored shape — never `_tag`
+const loaded = Organization.make(row).getOrThrow(); // rows, imports, event folds
+const renamed = loaded.update({ name: next }).getOrThrow(); // a NEW entity
+```
+
+Failures are values, not exceptions:
+
+```ts
+import { P } from "unthrown";
+
+Organization.make({ ...row, name: "" }).match({
+ ok: (o) => o,
+ errCases: (m) => m.with(P.tag("InvalidEntity"), (e) => e.issues), // [{ path: ["name"], … }]
+ defect: (cause) => report(cause), // a bug in domain code, kept separate
+});
+```
+
+The design rule the whole package turns on: **contracts compose the four plain
+`ZodObject`s; domain code composes the class itself.** [Why](/explanation/why-entity).
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 0000000..20bca3c
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@btravstack/entity-docs",
+ "private": true,
+ "description": "Documentation website for @btravstack/entity",
+ "license": "MIT",
+ "author": "Benoit TRAVERS ",
+ "type": "module",
+ "scripts": {
+ "build": "typedoc && vitepress build .",
+ "dev": "typedoc && vitepress dev .",
+ "preview": "vitepress preview ."
+ },
+ "devDependencies": {
+ "@btravstack/theme": "catalog:",
+ "@btravstack/typedoc": "catalog:",
+ "@types/node": "catalog:",
+ "typedoc": "catalog:",
+ "typedoc-plugin-markdown": "catalog:",
+ "typescript": "catalog:typedoc",
+ "vitepress": "catalog:"
+ }
+}
diff --git a/docs/public/icons/nest.svg b/docs/public/icons/nest.svg
new file mode 100644
index 0000000..3cf4dad
--- /dev/null
+++ b/docs/public/icons/nest.svg
@@ -0,0 +1 @@
+
diff --git a/docs/public/icons/result.svg b/docs/public/icons/result.svg
new file mode 100644
index 0000000..2542241
--- /dev/null
+++ b/docs/public/icons/result.svg
@@ -0,0 +1 @@
+
diff --git a/docs/public/icons/schemas.svg b/docs/public/icons/schemas.svg
new file mode 100644
index 0000000..ec1db89
--- /dev/null
+++ b/docs/public/icons/schemas.svg
@@ -0,0 +1 @@
+
diff --git a/docs/public/icons/seal.svg b/docs/public/icons/seal.svg
new file mode 100644
index 0000000..6e062ef
--- /dev/null
+++ b/docs/public/icons/seal.svg
@@ -0,0 +1 @@
+
diff --git a/docs/public/logo.svg b/docs/public/logo.svg
new file mode 100644
index 0000000..4aa0e63
--- /dev/null
+++ b/docs/public/logo.svg
@@ -0,0 +1,18 @@
+
diff --git a/docs/reference.md b/docs/reference.md
deleted file mode 100644
index 273dddd..0000000
--- a/docs/reference.md
+++ /dev/null
@@ -1,274 +0,0 @@
-# Reference
-
-Every member of the public surface. For _why_ it is shaped this way, see
-[Explanation](./explanation.md); for task recipes, see the
-[how-to guides](./how-to/).
-
-> Snippets below assume these imports:
->
-> ```ts
-> import { z } from "zod";
-> import { match, P } from "unthrown";
-> import { Entity } from "@btravstack/entity";
-> ```
-
-## `Entity(tag)(fields, options?)`
-
-Declares an entity. Curried on the tag so it reads next to the class name.
-
-```ts
-class Organization extends Entity("Organization")(fields, options) {}
-```
-
-### `fields`
-
-A map of field name to schema. Every field must be **nominal** — a branded
-schema, a narrow literal union, a boolean, or another entity class. A bare
-`z.string()` is a compile error naming `DomainFieldMustBeBrandedOrAnEntity`.
-
-Four names are reserved, because an entity installs them on every instance:
-`_tag`, `equals`, `toJSON`, `update`. Using one is a compile error naming
-`FieldNameIsReservedByEntity`.
-
-### `options`
-
-| Option | Type | Effect |
-| ------------ | ---------------------------------- | -------------------------------------------------------------------------------- |
-| `generated` | `readonly (keyof fields)[]` | omitted from `createInput`; supplied by a factory's generators |
-| `immutable` | `readonly (keyof output)[]` | omitted from `updateInput`; `update()` drops them even if smuggled in at runtime |
-| `computed` | `{ [name]: Entity.ComputedField }` | derived fields; added to `output`, re-derived on every construction |
-| `invariants` | `readonly Entity.Invariant[]` | rules spanning two or more declared fields; any failing rule rejects |
-
-`generated` and `immutable` are keyed off the field names, so a typo is a
-compile error rather than a silently-inert entry.
-
-`Entity.ComputedField` and `Entity.Invariant` are both generic; the
-parameters are elided above because you never write them. `Entity.computed` and
-`Entity.invariant` infer them from the surrounding declaration, which is what
-makes `d` contextually typed with no annotation.
-
-## Schema members
-
-```ts
-Organization.input; // ZodObject — everything make() accepts
-Organization.output; // ZodObject — stored state and response body
-Organization.createInput; // ZodObject — input minus generated
-Organization.updateInput; // ZodObject — output minus immutable, partial
-Organization.entityName; // the tag, as a literal type
-Organization; // …is itself a zod schema, parsing to an instance
-```
-
-`output` is `input` plus the computed fields. All four `ZodObject`s generate
-JSON Schema in **both** `"input"` and `"output"` directions.
-
-The class carries zod's internal slots (`_zod`, `~standard`) but **not** its
-methods, so it composes anywhere zod takes a schema while `.parse()` — which
-throws — does not exist on it:
-
-```ts
-z.object({ owner: Organization }); // ✓
-z.array(Organization); // ✓
-z.optional(Organization); // ✓ the function form
-Organization.optional(); // ✗ does not exist
-Organization.parse(raw); // ✗ does not exist — use make()
-z.toJSONSchema(Organization, { io: "output" }); // ✗ throws — the class carries a transform
-```
-
-## Entry points
-
-### `SomeEntity.factory(generators)` → `(input) => Result`
-
-Binds the `generated` fields' sources. Generators are **functions**, called
-once per create.
-
-```ts
-const createOrg = Organization.factory({
- id: () => ids.next(),
- createdAt: () => clock.now(),
-});
-createOrg({ slug, name }); // Result
-```
-
-Pass an arrow, not a bare method reference — `{ id: ids.next }` loses `this`.
-
-### `SomeEntity.factoryAsync(generators)` → `(input) => AsyncResult`
-
-The same for promise-returning generators — an id from a database sequence,
-say. A generator that **rejects** surfaces as a `Defect`, not an
-`InvalidEntity`: infrastructure failing is not the same as bad domain input.
-
-```ts
-const createOrgAsync = Organization.factoryAsync({
- id: () => ids.nextFromSequence(),
- createdAt: () => clock.now(),
-});
-(await createOrgAsync({ slug, name })).getOrThrow();
-```
-
-### `SomeEntity.make(data)` → `Result`
-
-The only way in. Validates against `input`, re-derives the computed fields,
-checks the invariants, constructs. Extra keys are ignored, so a stored row
-carrying computed columns round-trips.
-
-### `entity.update(patch)` → `Result`
-
-Returns a **new** entity. Re-runs the invariants and re-derives the computed
-fields. `immutable` and `computed` fields are absent from the patch type and
-dropped at runtime.
-
-### `entity.toJSON()` → the stored shape
-
-Projects exactly `output`'s keys. Excludes `_tag` and any class-body fields.
-Called implicitly by `JSON.stringify`.
-
-### `entity.equals(other)` → `boolean`
-
-True when both are the same entity and their stored data is deep-equal.
-Compares the stored data **structurally**, so entities holding equal arrays
-compare equal. `Set`, `Map` and typed-array fields compare by contents, `Date`
-by timestamp, `bigint` like any other primitive, and a nested object or record
-is compared key-by-key rather than by key order. Arrays stay order-sensitive.
-Two separate `Entity(...)` calls never compare equal, even with identical
-fields.
-
-## `Entity.computed(schema, from)`
-
-One derived field: its schema, and the function producing it.
-
-```ts
-computed: {
- fullName: Entity.computed(FullName, (d) => `${d.first} ${d.last}` as z.infer),
- initials: Entity.computed(Initials, (d) => `${d.first[0]}${d.last[0]}` as z.infer),
-}
-```
-
-`d` is the declared shape, contextually typed. Each return value is checked
-against **that field's** schema. A computed field cannot read another computed
-field — every derivation is a function of declared data only.
-
-Output that fails its own schema is a `Defect`, named for the field
-(`Person.computed.initials: …`).
-
-## `Entity.invariant(ensure, message)`
-
-One rule spanning the whole entity: the predicate, and what to say when it
-fails.
-
-```ts
-invariants: [
- Entity.invariant(
- (d) => d.name.length <= 80,
- "name must be at most 80 characters",
- ),
- Entity.invariant(
- (d) => d.endsAt > d.startsAt,
- (d) => `endsAt must be after ${d.startsAt}`,
- ),
-];
-```
-
-`ensure` returning **true** means valid — a rule reads as the assertion it
-makes. `d` is contextually typed and needs no annotation. `message` takes the
-data when the text depends on it.
-
-Every failing rule in the list reports, not just the first, and none of them
-carries a `path`: an invariant spans the entity, which is what separates it from
-a field complaint.
-
-`d` is the **declared** fields, not the output — a rule cannot read a computed
-field. Every computed value is a function of declared data, so any rule about
-one is expressible over its sources, and a computed value failing its own schema
-is already a Defect rather than something to re-check here.
-
-A predicate that throws is a Defect, not an `InvalidEntity`, on the same
-reasoning as `computed`.
-
-## `SomeEntity.extend(tag)(fields, options?)`
-
-A **new** entity carrying the parent's fields plus more, under its own tag —
-its own schemas, its own `equals` identity.
-
-```ts
-class PersonWithAge extends Person.extend("PersonWithAge")({ age: Age }) {
- get isAdult(): boolean {
- return this.age >= 18;
- }
-}
-```
-
-Options merge per key, child winning — **except `invariants`**, which
-concatenates parent-then-child. An extension can add rules; it cannot shed them,
-so it is never quietly laxer than what it extends. Declaring `invariants: []` on
-a child does not clear the parent's.
-
-`extend` rebuilds from the **declaration**, so class-body members do not carry
-over — re-declare them.
-
-## `Entity.union(discriminant, members)`
-
-A union of entities that is itself entity-like.
-
-```ts
-const Member = Entity.union("kind", [User, ServiceAccount]);
-
-Member.make(row); // Result
-Member.input; // discriminated union, one branch per member
-Member.output; // ditto — JSON Schema both directions
-Member.members; // the tuple, for registries and exhaustiveness
-Member.discriminant; // "kind"
-```
-
-`discriminant` names a declared domain field, not `_tag`. The union dispatches
-on it rather than trying each branch, so a failing member reports its own
-issues. The union is a schema too, so it nests as a field.
-
-## `Entity.InvalidEntity`
-
-```ts
-class InvalidEntity extends TaggedError("InvalidEntity")<{
- readonly entity: string;
- readonly issues: SchemaIssues; // readonly StandardSchemaV1.Issue[]
-}> {}
-```
-
-Reachable as both a value and a type — `e instanceof Entity.InvalidEntity` and
-`const e: Entity.InvalidEntity`. The signatures above write it unqualified, the
-way `SomeEntity` is also a stand-in; `Entity.InvalidEntity` is how you spell it.
-Matching by tag needs no import at all: `P.tag("InvalidEntity")`.
-
-Schema failures carry the failing field's `path`; an `invariants` violation has
-none — that absence distinguishes a whole-entity rule from a field complaint.
-
-| Failure | Channel |
-| ---------------------------------------- | ------------------------------------ |
-| a field fails its own schema | `InvalidEntity`, issue has a `path` |
-| a broken `invariants` rule | `InvalidEntity`, issue has no `path` |
-| `computed` output failing its own schema | **defect** |
-| a `computed` function throwing | **defect** |
-| an async generator rejecting | **defect** |
-| subclassing an entity | **defect** |
-
-## Helper types
-
-```ts
-import { Entity } from "@btravstack/entity";
-
-type OrgWire = Entity.Input; // what make() accepts
-type OrgState = Entity.Output; // what toJSON() returns
-type OrgCreate = Entity.CreateInput; // what a factory accepts
-type OrgPatch = Entity.Patch; // what update() accepts
-```
-
-Also `Entity.ComputedField` and `Entity.Union`, the shapes `Entity.computed` and
-`Entity.union` return.
-
-`BaseInstance`, `ConstructionKey` and `Sealed` are the one exception to the
-single-import rule: they are exported at the top level **as well as** under
-`Entity`, because a downstream library compiling with `declaration: true` emits
-the underlying name rather than the namespace path that aliases it, and would
-otherwise fail with `TS4020`. They are not part of the API you write against.
-
-```ts
-import type { BaseInstance, ConstructionKey, Sealed } from "@btravstack/entity";
-```
diff --git a/docs/reference/declaration.md b/docs/reference/declaration.md
new file mode 100644
index 0000000..06a6458
--- /dev/null
+++ b/docs/reference/declaration.md
@@ -0,0 +1,156 @@
+---
+title: Declaring an entity
+description: Entity(tag)(fields, options), the field rules, the four options, and the Entity.computed / Entity.invariant / extend / union declaration helpers.
+---
+
+# Declaring an entity
+
+The builder itself, the rules a field map must satisfy, the four options, and the
+helpers that go inside them. For _why_ it is shaped this way, see
+[Explanation](/explanation/why-entity); for task recipes, see the
+[how-to guides](/how-to/http-contract).
+
+> Snippets on this page assume these imports:
+>
+> ```ts
+> import { z } from "zod";
+> import { match, P } from "unthrown";
+> import { Entity } from "@btravstack/entity";
+> ```
+
+## `Entity(tag)(fields, options?)`
+
+Declares an entity. Curried on the tag so it reads next to the class name.
+
+```ts
+class Organization extends Entity("Organization")(fields, options) {}
+```
+
+### `fields`
+
+A map of field name to schema. Every field must be **nominal** — a branded
+schema, a narrow literal union, a boolean, or another entity class. A bare
+`z.string()` is a compile error naming `DomainFieldMustBeBrandedOrAnEntity`.
+
+Four names are reserved, because an entity installs them on every instance:
+`_tag`, `equals`, `toJSON`, `update`. Using one is a compile error naming
+`FieldNameIsReservedByEntity`.
+
+### `options`
+
+| Option | Type | Effect |
+| ------------ | ---------------------------------- | -------------------------------------------------------------------------------- |
+| `generated` | `readonly (keyof fields)[]` | omitted from `createInput`; supplied by a factory's generators |
+| `immutable` | `readonly (keyof output)[]` | omitted from `updateInput`; `update()` drops them even if smuggled in at runtime |
+| `computed` | `{ [name]: Entity.ComputedField }` | derived fields; added to `output`, re-derived on every construction |
+| `invariants` | `readonly Entity.Invariant[]` | rules spanning two or more declared fields; any failing rule rejects |
+
+`generated` and `immutable` are keyed off the field names, so a typo is a
+compile error rather than a silently-inert entry.
+
+`Entity.ComputedField` and `Entity.Invariant` are both generic; the
+parameters are elided above because you never write them. `Entity.computed` and
+`Entity.invariant` infer them from the surrounding declaration, which is what
+makes `d` contextually typed with no annotation.
+
+## `Entity.computed(schema, from)`
+
+One derived field: its schema, and the function producing it.
+
+```ts
+computed: {
+ fullName: Entity.computed(FullName, (d) => `${d.first} ${d.last}` as z.infer),
+ initials: Entity.computed(Initials, (d) => `${d.first[0]}${d.last[0]}` as z.infer),
+}
+```
+
+`d` is the declared shape, contextually typed. Each return value is checked
+against **that field's** schema. A computed field cannot read another computed
+field — every derivation is a function of declared data only.
+
+Output that fails its own schema is a `Defect`, named for the field
+(`Person.computed.initials: …`).
+
+Computed fields are re-derived on every construction path rather than stored —
+see [Why `computed` re-derives](/explanation/computed-fields), which also covers
+when to reach for a plain getter instead.
+
+## `Entity.invariant(ensure, message)`
+
+One rule spanning the whole entity: the predicate, and what to say when it
+fails.
+
+```ts
+invariants: [
+ Entity.invariant(
+ (d) => d.name.length <= 80,
+ "name must be at most 80 characters",
+ ),
+ Entity.invariant(
+ (d) => d.endsAt > d.startsAt,
+ (d) => `endsAt must be after ${d.startsAt}`,
+ ),
+];
+```
+
+`ensure` returning **true** means valid — a rule reads as the assertion it
+makes. `d` is contextually typed and needs no annotation. `message` takes the
+data when the text depends on it.
+
+Every failing rule in the list reports, not just the first, and none of them
+carries a `path`: an invariant spans the entity, which is what separates it from
+a field complaint.
+
+`d` is the **declared** fields, not the output — a rule cannot read a computed
+field. Every computed value is a function of declared data, so any rule about
+one is expressible over its sources, and a computed value failing its own schema
+is already a Defect rather than something to re-check here.
+
+A predicate that throws is a Defect, not an `InvalidEntity`, on the same
+reasoning as `computed`.
+
+## `SomeEntity.extend(tag)(fields, options?)`
+
+A **new** entity carrying the parent's fields plus more, under its own tag —
+its own schemas, its own `equals` identity.
+
+```ts
+class PersonWithAge extends Person.extend("PersonWithAge")({ age: Age }) {
+ get isAdult(): boolean {
+ return this.age >= 18;
+ }
+}
+```
+
+Options merge per key, child winning — **except `invariants`**, which
+concatenates parent-then-child. An extension can add rules; it cannot shed them,
+so it is never quietly laxer than what it extends. Declaring `invariants: []` on
+a child does not clear the parent's.
+
+`extend` rebuilds from the **declaration**, so class-body members do not carry
+over — re-declare them.
+
+This is the only supported way to build on an existing entity: a bare
+`class Sub extends Organization {}` is
+[rejected at construction](/explanation/sealed-construction#entities-are-not-subclassable).
+
+## `Entity.union(discriminant, members)`
+
+A union of entities that is itself entity-like.
+
+```ts
+const Member = Entity.union("kind", [User, ServiceAccount]);
+
+Member.make(row); // Result
+Member.input; // discriminated union, one branch per member
+Member.output; // ditto — JSON Schema both directions
+Member.members; // the tuple, for registries and exhaustiveness
+Member.discriminant; // "kind"
+```
+
+`discriminant` names a declared domain field, not `_tag`. The union dispatches
+on it rather than trying each branch, so a failing member reports its own
+issues. The union is a schema too, so it nests as a field.
+
+`_tag` cannot serve as the discriminant here, and that is not an oversight —
+[it never reaches the wire](/explanation/tags-and-identity).
diff --git a/docs/reference/entry-points.md b/docs/reference/entry-points.md
new file mode 100644
index 0000000..e5efcca
--- /dev/null
+++ b/docs/reference/entry-points.md
@@ -0,0 +1,73 @@
+---
+title: Entry points
+description: factory, factoryAsync, make, update, toJSON and equals — every way in and out of an entity.
+---
+
+# Entry points
+
+Every way an entity comes into existence, and the two projections out of one.
+There is no other: `new SomeEntity(…)`
+[does not compile](/explanation/sealed-construction).
+
+> Snippets on this page assume these imports:
+>
+> ```ts
+> import { z } from "zod";
+> import { Entity } from "@btravstack/entity";
+> ```
+
+## `SomeEntity.factory(generators)` → `(input) => Result`
+
+Binds the `generated` fields' sources. Generators are **functions**, called
+once per create.
+
+```ts
+const createOrg = Organization.factory({
+ id: () => ids.next(),
+ createdAt: () => clock.now(),
+});
+createOrg({ slug, name }); // Result
+```
+
+Pass an arrow, not a bare method reference — `{ id: ids.next }` loses `this`.
+
+## `SomeEntity.factoryAsync(generators)` → `(input) => AsyncResult`
+
+The same for promise-returning generators — an id from a database sequence,
+say. A generator that **rejects** surfaces as a `Defect`, not an
+`InvalidEntity`: infrastructure failing is not the same as bad domain input.
+
+```ts
+const createOrgAsync = Organization.factoryAsync({
+ id: () => ids.nextFromSequence(),
+ createdAt: () => clock.now(),
+});
+(await createOrgAsync({ slug, name })).getOrThrow();
+```
+
+## `SomeEntity.make(data)` → `Result`
+
+The only way in. Validates against `input`, re-derives the computed fields,
+checks the invariants, constructs. Extra keys are ignored, so a stored row
+carrying computed columns round-trips.
+
+## `entity.update(patch)` → `Result`
+
+Returns a **new** entity. Re-runs the invariants and re-derives the computed
+fields. `immutable` and `computed` fields are absent from the patch type and
+dropped at runtime.
+
+## `entity.toJSON()` → the stored shape
+
+Projects exactly `output`'s keys. Excludes `_tag` and any class-body fields.
+Called implicitly by `JSON.stringify`.
+
+## `entity.equals(other)` → `boolean`
+
+True when both are the same entity and their stored data is deep-equal.
+Compares the stored data **structurally**, so entities holding equal arrays
+compare equal. `Set`, `Map` and typed-array fields compare by contents, `Date`
+by timestamp, `bigint` like any other primitive, and a nested object or record
+is compared key-by-key rather than by key order. Arrays stay order-sensitive.
+Two separate `Entity(...)` calls never compare equal, even with identical
+fields.
diff --git a/docs/reference/errors.md b/docs/reference/errors.md
new file mode 100644
index 0000000..6fc1af1
--- /dev/null
+++ b/docs/reference/errors.md
@@ -0,0 +1,67 @@
+---
+title: Errors
+description: Entity.InvalidEntity, its structured issues, and the table of which failure goes down which channel.
+---
+
+# Errors
+
+Every fallible entry point returns `Result`. Bad input is
+modelled as a value; a bug in domain code goes down the separate defect channel.
+
+> Snippets on this page assume these imports:
+>
+> ```ts
+> import { match, P } from "unthrown";
+> import { Entity } from "@btravstack/entity";
+> ```
+
+## `Entity.InvalidEntity`
+
+```ts
+class InvalidEntity extends TaggedError("InvalidEntity")<{
+ readonly entity: string;
+ readonly issues: SchemaIssues; // readonly StandardSchemaV1.Issue[]
+}> {}
+```
+
+Reachable as both a value and a type — `e instanceof Entity.InvalidEntity` and
+`const e: Entity.InvalidEntity`. The signatures throughout this reference write
+it unqualified, the way `SomeEntity` is also a stand-in; `Entity.InvalidEntity`
+is how you spell it. Matching by tag needs no import at all:
+`P.tag("InvalidEntity")`.
+
+Schema failures carry the failing field's `path`; an `invariants` violation has
+none — that absence distinguishes a whole-entity rule from a field complaint.
+
+## Which channel a failure takes
+
+| Failure | Channel |
+| ---------------------------------------- | ------------------------------------ |
+| a field fails its own schema | `InvalidEntity`, issue has a `path` |
+| a broken `invariants` rule | `InvalidEntity`, issue has no `path` |
+| `computed` output failing its own schema | **defect** |
+| a `computed` function throwing | **defect** |
+| an async generator rejecting | **defect** |
+| subclassing an entity | **defect** |
+
+The line between the two columns is argued in
+[Errors are values, and defects are separate](/explanation/errors-are-values).
+
+## Handling both at the edge
+
+```ts
+Organization.make(row).match({
+ ok: (org) => respond(200, org.toJSON()),
+ errCases: (m) =>
+ m.with(P.tag("InvalidEntity"), (e) => respond(422, e.issues)),
+ defect: (cause) => {
+ report(cause);
+ return respond(500);
+ },
+});
+```
+
+Issues are carried **structured**, exactly as the validator produced them, so
+keying a field-level error response is a `path` lookup rather than a string
+parse. [Expose an HTTP contract](/how-to/http-contract#handle-failures-at-the-edge)
+works this through end to end.
diff --git a/docs/reference/schemas.md b/docs/reference/schemas.md
new file mode 100644
index 0000000..a6c9e88
--- /dev/null
+++ b/docs/reference/schemas.md
@@ -0,0 +1,46 @@
+---
+title: Schema members
+description: input, output, createInput, updateInput, entityName — and the class itself as a zod schema.
+---
+
+# Schema members
+
+Every entity carries four plain `ZodObject`s as statics, plus the class itself.
+
+> Snippets on this page assume these imports:
+>
+> ```ts
+> import { z } from "zod";
+> import { Entity } from "@btravstack/entity";
+> ```
+
+```ts
+Organization.input; // ZodObject — everything make() accepts
+Organization.output; // ZodObject — stored state and response body
+Organization.createInput; // ZodObject — input minus generated
+Organization.updateInput; // ZodObject — output minus immutable, partial
+Organization.entityName; // the tag, as a literal type
+Organization; // …is itself a zod schema, parsing to an instance
+```
+
+`output` is `input` plus the computed fields. All four `ZodObject`s generate
+JSON Schema in **both** `"input"` and `"output"` directions.
+
+The class carries zod's internal slots (`_zod`, `~standard`) but **not** its
+methods, so it composes anywhere zod takes a schema while `.parse()` — which
+throws — does not exist on it:
+
+```ts
+z.object({ owner: Organization }); // ✓
+z.array(Organization); // ✓
+z.optional(Organization); // ✓ the function form
+Organization.optional(); // ✗ does not exist
+Organization.parse(raw); // ✗ does not exist — use make()
+z.toJSONSchema(Organization, { io: "output" }); // ✗ throws — the class carries a transform
+```
+
+That last line is the design rule made concrete: **contracts compose the four
+plain `ZodObject`s; domain code composes the class itself.** See
+[Why entity?](/explanation/why-entity#the-rule-the-design-turns-on) for the
+constraint it comes from, and
+[Expose an HTTP contract](/how-to/http-contract) for the recipe.
diff --git a/docs/reference/types.md b/docs/reference/types.md
new file mode 100644
index 0000000..2bff596
--- /dev/null
+++ b/docs/reference/types.md
@@ -0,0 +1,38 @@
+---
+title: Helper types
+description: Entity.Input, Entity.Output, Entity.CreateInput, Entity.Patch — and the three seal names exported at the top level.
+---
+
+# Helper types
+
+Every public type hangs off the merged `Entity` namespace, so one import covers
+the whole surface.
+
+```ts
+import { Entity } from "@btravstack/entity";
+
+type OrgWire = Entity.Input; // what make() accepts
+type OrgState = Entity.Output; // what toJSON() returns
+type OrgCreate = Entity.CreateInput; // what a factory accepts
+type OrgPatch = Entity.Patch; // what update() accepts
+```
+
+Also `Entity.ComputedField` and `Entity.Union`, the shapes `Entity.computed` and
+`Entity.union` return.
+
+## The seal names
+
+`BaseInstance`, `ConstructionKey` and `Sealed` are the one exception to the
+single-import rule: they are exported at the top level **as well as** under
+`Entity`, because a downstream library compiling with `declaration: true` emits
+the underlying name rather than the namespace path that aliases it, and would
+otherwise fail with `TS4020`. They are not part of the API you write against.
+
+```ts
+import type { BaseInstance, ConstructionKey, Sealed } from "@btravstack/entity";
+```
+
+That is measured, not assumed: a fixture in CI compiles a consumer with
+declaration emit against the built types, so it cannot regress. See
+[Sealed construction](/explanation/sealed-construction) for what the seal buys
+and what the two rejected alternatives cost.
diff --git a/docs/tutorial/getting-started.md b/docs/tutorial/getting-started.md
new file mode 100644
index 0000000..34e9efe
--- /dev/null
+++ b/docs/tutorial/getting-started.md
@@ -0,0 +1,293 @@
+---
+title: Getting started
+description: Build a working entity from nothing — declare it, create one, watch a bad value fail as a value, update it, and send it over the wire.
+---
+
+# Getting started
+
+By the end of this page you will have declared an entity, created one through a
+factory, seen a bad value come back as a `Result` instead of an exception,
+updated it into a new instance, and projected it to the shape you would store or
+respond with.
+
+The snippets build on one another, so follow along in a `.ts` file. Each step
+shows only what changed; the two lines marked `// ✗` are meant not to compile,
+and that is the point of them.
+
+## Install
+
+```sh
+pnpm add @btravstack/entity zod unthrown @unthrown/standard-schema
+```
+
+All four, because `zod`, `unthrown` and `@unthrown/standard-schema` are **peer**
+dependencies — the package hands you back _your_ copies of them rather than its
+own. ([Why](/explanation/peer-dependencies).)
+
+## 1. Brand your fields
+
+Every field of an entity must be **nominal** — a schema that carries a brand, a
+narrow literal union, a boolean, or another entity. A bare `z.string()` is a
+compile error.
+
+```ts
+import { z } from "zod";
+
+const OrgId = z.uuid().brand("OrgId");
+const Slug = z.string().min(1).brand("Slug");
+const DisplayName = z.string().min(1).brand("DisplayName");
+const Instant = z.iso.datetime().brand("Instant");
+```
+
+The reason is the one every domain modeller already knows: with plain strings,
+`findOrg(slug, name)` type-checks with the arguments swapped. Branded, it does
+not.
+
+## 2. Declare the entity
+
+```ts
+import { Entity } from "@btravstack/entity";
+
+class Organization extends Entity("Organization")({
+ id: OrgId,
+ slug: Slug,
+ name: DisplayName,
+ createdAt: Instant,
+}) {}
+```
+
+That single declaration already gives you four validators and a class that is
+itself a zod schema:
+
+```ts
+Organization.input; // ZodObject — everything make() accepts
+Organization.output; // ZodObject — the stored shape / response body
+Organization.createInput; // ZodObject — the create request
+Organization.updateInput; // ZodObject — the update request, partial
+```
+
+Right now `createInput` equals `input` and `updateInput` is just `output` made
+partial. The next step is what makes them differ.
+
+## 3. Say which fields the domain owns
+
+`id` and `createdAt` are not the caller's to supply, and never change once set.
+Declare that:
+
+```ts
+class Organization extends Entity("Organization")(
+ { id: OrgId, slug: Slug, name: DisplayName, createdAt: Instant },
+ {
+ generated: ["id", "createdAt"],
+ immutable: ["id", "createdAt", "slug"],
+ },
+) {}
+```
+
+- `generated` drops those fields from `createInput` — a create request cannot
+ carry them.
+- `immutable` drops them from `updateInput` — and `update()` discards them at
+ runtime even if something smuggles them past the type.
+
+Both are keyed off the field names, so a typo is a compile error rather than a
+silently-inert entry.
+
+## 4. Create one
+
+The package reads no clock and generates no id. Instead you bind the **sources**
+once — at your composition root, next to the ports you already have:
+
+```ts
+const createOrganization = Organization.factory({
+ id: () => crypto.randomUUID() as z.infer,
+ createdAt: () => new Date().toISOString() as z.infer,
+});
+```
+
+Now a create use case supplies only the caller's fields:
+
+```ts
+const created = createOrganization({
+ slug: "acme" as z.infer,
+ name: "Acme" as z.infer,
+});
+
+const org = created.getOrThrow();
+org.name; // "Acme"
+org.id; // a fresh uuid
+```
+
+Generators are **functions**, called once per create — so a factory built at
+startup still yields a fresh id per entity. And a test can bind fixed generators
+instead of stubbing globals. ([Why no I/O](/explanation/no-io).)
+
+::: tip `getOrThrow()` is for a tutorial
+It is the shortest way to get at a value while you are exploring. Real code
+handles the `Result` — [step 6](#_6-handle-failure-as-a-value) does.
+:::
+
+## 5. Try to break it
+
+The entity is immutable in both halves — the binding is non-writable and the
+value is deep-frozen:
+
+```ts
+org.name = "Other" as z.infer; // ✗ compile error — read-only property
+```
+
+And you cannot sidestep the entry points:
+
+```ts
+new Organization(org.toJSON()); // ✗ does not compile — the constructor is sealed
+```
+
+The constructor takes a value no outside code can produce. That is what
+guarantees every instance in your program went through validation and the
+invariants. ([Sealed construction](/explanation/sealed-construction).)
+
+## 6. Handle failure as a value
+
+Nothing throws. `make` is the general entry point — a database row, a folded
+event stream, an untrusted import all come in the same way — and it returns a
+`Result`:
+
+```ts
+import { P } from "unthrown";
+
+const outcome = Organization.make({
+ id: "not-a-uuid",
+ slug: "acme",
+ name: "Acme",
+ createdAt: "2026-01-01T00:00:00.000Z",
+}).match({
+ ok: (o) => `created ${o.slug}`,
+ errCases: (m) => m.with(P.tag("InvalidEntity"), (e) => e.issues),
+ defect: (cause) => {
+ console.error(cause);
+ return "bug";
+ },
+});
+```
+
+`outcome` is the issue list: `[{ path: ["id"], message: "Invalid UUID" }]`.
+Structured, exactly as the validator produced it — keying a field-level error
+response is a `path` lookup, not a string parse.
+
+The third branch is not decoration. `defect` is a separate channel for a bug in
+your own domain code, and it is never folded into `errCases`. ([Errors are
+values, and defects are separate](/explanation/errors-are-values).)
+
+## 7. Add a rule that spans fields
+
+A single field's schema cannot express "these two fields must agree".
+`invariants` can:
+
+```ts
+class Organization extends Entity("Organization")(
+ { id: OrgId, slug: Slug, name: DisplayName, createdAt: Instant },
+ {
+ generated: ["id", "createdAt"],
+ immutable: ["id", "createdAt", "slug"],
+ invariants: [
+ Entity.invariant(
+ (d) => d.name.length <= 80,
+ "name must be at most 80 characters",
+ ),
+ ],
+ },
+) {}
+```
+
+`ensure` returning **true** means valid, so a rule reads as the assertion it
+makes. `d` is contextually typed — no annotation needed. Every failing rule
+reports, not just the first, and an invariant's issue carries no `path`: it is a
+complaint about the entity, not about one field.
+
+Invariants re-run on every construction path, including `update`.
+
+## 8. Derive a field, and add behaviour
+
+Two different things live in a class, and they go in two different places:
+
+```ts
+const Upper = z.string().min(1).brand("Upper");
+
+class Organization extends Entity("Organization")(
+ { id: OrgId, slug: Slug, name: DisplayName, createdAt: Instant },
+ {
+ generated: ["id", "createdAt"],
+ immutable: ["id", "createdAt", "slug"],
+ computed: {
+ shout: Entity.computed(
+ Upper,
+ (d) => d.name.toUpperCase() as z.infer,
+ ),
+ },
+ },
+) {
+ get greeting(): string {
+ return `Welcome, ${this.name}`;
+ }
+}
+
+org.shout; // "ACME" — data: in `output`, in toJSON(), in the JSON Schema
+org.greeting; // "Welcome, Acme" — behaviour: on the prototype, never serialised
+```
+
+A `computed` field is **data**. A getter is **behaviour**. If it belongs in the
+response body, it is `computed`. ([Why `computed`
+re-derives](/explanation/computed-fields).)
+
+## 9. Update
+
+`update` returns a **new** entity — the original is untouched:
+
+```ts
+const renamed = org
+ .update({ name: "Acme Corp" as z.infer })
+ .getOrThrow();
+
+renamed.name; // "Acme Corp"
+renamed.shout; // "ACME CORP" — re-derived, never stale
+org.name; // "Acme" — the original is unchanged
+renamed.equals(org); // false
+```
+
+`org.update({ slug })` does not compile: `slug` is `immutable`.
+
+## 10. Send it over the wire
+
+`toJSON()` projects exactly `output`'s keys — never `_tag`, never `greeting`,
+never anything your class body added:
+
+```ts
+console.log(renamed.toJSON());
+// { id, slug, name, createdAt, shout } — that object is what you store or respond with
+```
+
+And the four schema members are plain `ZodObject`s, so a contract layer converts
+them to JSON Schema in **both** directions:
+
+```ts
+z.toJSONSchema(Organization.createInput, { io: "input" }); // ✓
+z.toJSONSchema(Organization.output, { io: "output" }); // ✓
+z.toJSONSchema(Organization, { io: "output" }); // ✗ throws — by design
+```
+
+That last line is the rule the whole package turns on: **contracts compose the
+four plain `ZodObject`s; domain code composes the class itself.** The class
+carries a `.transform()` (that is what produces an instance), and a transform has
+no output representation.
+
+## Where to go next
+
+- [Expose an HTTP contract](/how-to/http-contract) — the contract layer, worked
+ end to end.
+- [Persist and rehydrate](/how-to/persist-and-rehydrate) — repositories, and why
+ computed columns heal themselves.
+- [Model an aggregate](/how-to/model-an-aggregate) — entities nested in entities,
+ and `Entity.union`.
+- [Test domain logic](/how-to/test-domain-logic) — deterministic tests with no
+ global stubbing.
+- [Reference](/reference/declaration) — every member, option and type.
+- [Why entity?](/explanation/why-entity) — the design, and what was measured.
diff --git a/docs/typedoc.json b/docs/typedoc.json
new file mode 100644
index 0000000..0954900
--- /dev/null
+++ b/docs/typedoc.json
@@ -0,0 +1,29 @@
+{
+ "extends": "@btravstack/typedoc/base.json",
+ "entryPoints": ["../packages/entity/src/index.ts"],
+ "tsconfig": "../packages/entity/tsconfig.json",
+ "out": "api/entity",
+ "categoryOrder": ["Facade", "Declaration", "Entry points", "Types", "Errors", "*"],
+ "intentionallyNotExported": [
+ "BaseInstanceSrc",
+ "ComputedField",
+ "ComputedFieldSrc",
+ "ComputedOf",
+ "ConstructionKeySrc",
+ "DomainFieldMustBeBrandedOrAnEntity",
+ "EntityStatic",
+ "EntityUnion",
+ "EntityUnionSrc",
+ "Fields",
+ "InputOf",
+ "InvalidEntity",
+ "Invariant",
+ "InvariantSrc",
+ "IsNominalField",
+ "OnlyNominal",
+ "OutputOf",
+ "PatchOf",
+ "SealedSrc",
+ "UnionMember"
+ ]
+}
diff --git a/knip.json b/knip.json
index 4ccdf17..12eac17 100644
--- a/knip.json
+++ b/knip.json
@@ -5,7 +5,15 @@
"workspaces": {
"packages/*": {
"project": ["src/**/*.ts"]
+ },
+ "docs": {
+ "project": [".vitepress/**/*.ts"]
}
},
- "ignoreDependencies": ["@btravstack/oxlint", "@btravstack/lefthook"]
+ "ignoreDependencies": [
+ "@btravstack/oxlint",
+ "@btravstack/lefthook",
+ "@btravstack/typedoc",
+ "typedoc-plugin-markdown"
+ ]
}
diff --git a/packages/entity/README.md b/packages/entity/README.md
index a7567cb..aab4c25 100644
--- a/packages/entity/README.md
+++ b/packages/entity/README.md
@@ -67,11 +67,12 @@ Also `Entity.union(...)` for a union that is itself entity-like, and
## Documentation
-Full docs live in the repository:
+**[btravstack.github.io/entity](https://btravstack.github.io/entity/)**
-- [Reference](https://github.com/btravstack/entity/blob/main/docs/reference.md) — every member, option and type
-- [Explanation](https://github.com/btravstack/entity/blob/main/docs/explanation.md) — why it is built this way
-- How-to: [HTTP contract](https://github.com/btravstack/entity/blob/main/docs/how-to/http-contract.md) · [persist and rehydrate](https://github.com/btravstack/entity/blob/main/docs/how-to/persist-and-rehydrate.md) · [model an aggregate](https://github.com/btravstack/entity/blob/main/docs/how-to/model-an-aggregate.md) · [test domain logic](https://github.com/btravstack/entity/blob/main/docs/how-to/test-domain-logic.md)
+- [Getting started](https://btravstack.github.io/entity/tutorial/getting-started) — from nothing to a working entity
+- [Reference](https://btravstack.github.io/entity/reference/declaration) — every member, option and type
+- [Explanation](https://btravstack.github.io/entity/explanation/why-entity) — why it is built this way
+- How-to: [HTTP contract](https://btravstack.github.io/entity/how-to/http-contract) · [persist and rehydrate](https://btravstack.github.io/entity/how-to/persist-and-rehydrate) · [model an aggregate](https://btravstack.github.io/entity/how-to/model-an-aggregate) · [test domain logic](https://btravstack.github.io/entity/how-to/test-domain-logic)
## License
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 724e941..b9c0812 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,9 +15,15 @@ catalogs:
'@btravstack/oxlint':
specifier: 0.2.1
version: 0.2.1
+ '@btravstack/theme':
+ specifier: 1.7.0
+ version: 1.7.0
'@btravstack/tsconfig':
specifier: 0.2.0
version: 0.2.0
+ '@btravstack/typedoc':
+ specifier: 0.1.0
+ version: 0.1.0
'@changesets/cli':
specifier: 2.31.1
version: 2.31.1
@@ -60,18 +66,34 @@ catalogs:
turbo:
specifier: 2.10.8
version: 2.10.8
+ typedoc:
+ specifier: 0.28.20
+ version: 0.28.20
+ typedoc-plugin-markdown:
+ specifier: 4.12.0
+ version: 4.12.0
typescript:
specifier: 7.0.2
version: 7.0.2
unthrown:
specifier: 5.1.0
version: 5.1.0
+ vitepress:
+ specifier: 1.6.4
+ version: 1.6.4
vitest:
specifier: 4.1.10
version: 4.1.10
zod:
specifier: 4.4.3
version: 4.4.3
+ typedoc:
+ typescript:
+ specifier: 6.0.3
+ version: 6.0.3
+
+overrides:
+ vite@<6.4.3: 6.4.3
importers:
@@ -111,6 +133,30 @@ importers:
specifier: 'catalog:'
version: 2.10.8
+ docs:
+ devDependencies:
+ '@btravstack/theme':
+ specifier: 'catalog:'
+ version: 1.7.0(vitepress@1.6.4(@algolia/client-search@5.56.0)(@types/node@26.1.2)(jiti@2.7.0)(postcss@8.5.25)(typescript@6.0.3)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))
+ '@btravstack/typedoc':
+ specifier: 'catalog:'
+ version: 0.1.0(typedoc-plugin-markdown@4.12.0(typedoc@0.28.20(typescript@6.0.3)))(typedoc@0.28.20(typescript@6.0.3))
+ '@types/node':
+ specifier: 'catalog:'
+ version: 26.1.2
+ typedoc:
+ specifier: 'catalog:'
+ version: 0.28.20(typescript@6.0.3)
+ typedoc-plugin-markdown:
+ specifier: 'catalog:'
+ version: 4.12.0(typedoc@0.28.20(typescript@6.0.3))
+ typescript:
+ specifier: catalog:typedoc
+ version: 6.0.3
+ vitepress:
+ specifier: 'catalog:'
+ version: 1.6.4(@algolia/client-search@5.56.0)(@types/node@26.1.2)(jiti@2.7.0)(postcss@8.5.25)(typescript@6.0.3)(yaml@2.9.0)
+
packages/entity:
devDependencies:
'@btravstack/tsconfig':
@@ -149,6 +195,82 @@ importers:
packages:
+ '@algolia/abtesting@1.22.0':
+ resolution: {integrity: sha512-BFR6zNowNKcY7Ou7TaJc9QWexES4YKPbmf/OTFofpdsdhz4x6q0lbxp3duO0EHnyrN7rE4ba/TSXuY+BDGu4+g==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/autocomplete-core@1.17.7':
+ resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==}
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.17.7':
+ resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==}
+ peerDependencies:
+ search-insights: '>= 1 < 3'
+
+ '@algolia/autocomplete-preset-algolia@1.17.7':
+ resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+
+ '@algolia/autocomplete-shared@1.17.7':
+ resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+
+ '@algolia/client-abtesting@5.56.0':
+ resolution: {integrity: sha512-7r4Z3NC7yU1oAQVWJNA2HX7tX481F3pJvCGyLIXiTdBcthz4Q/o21jwcMYDFkuI92UWTNBQQmHYgwHo1zS5dzg==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-analytics@5.56.0':
+ resolution: {integrity: sha512-avmjXQSq+jadFO8Xl2em05/uQdQnEmHsJyOAdVbZkmVgpMfxL12aJwVVfGNwYr9nulcpuJN1X0lTaQ5wxuNGcA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-common@5.56.0':
+ resolution: {integrity: sha512-v2TPStUhY//ripPjIVclZ8AWc7DEGooXULZGFlFu37zNatgHjw34oZZ+OSbbc/YHO+xZwPl62I1k8xH1m4S2eg==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-insights@5.56.0':
+ resolution: {integrity: sha512-P0ehROpM4Sem3Sqo5x2cKPgj67D3G3jy0rh1Amwkcvsfr6tkvIcdCmerieanqTF7NxUMPNFLkpIFeMO8Rpa50w==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-personalization@5.56.0':
+ resolution: {integrity: sha512-SXK3Vn3WVxyzbm31oePZBJkp1wpOyuWdd4B/Pv7n0aXDxmeSWhC1R1FC1517mMrFAIaPH4Rt0x6RUe7ZNjz8FA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-query-suggestions@5.56.0':
+ resolution: {integrity: sha512-5+ZdX8garFnmycnZgKhtXHePEaLj5zqDxI/0lkhhluzCcvTn0/PvvTirTg8hHYetQHvn7GDyeAiqTAieMvMW4A==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-search@5.56.0':
+ resolution: {integrity: sha512-+mKUdYvqOi0BcvpAEyCEw49vSBptufIcfibtHz2bdr1pI789M46Yt0uQEk/sxtK3teh71OQvVFHaTDzShUWewQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/ingestion@1.56.0':
+ resolution: {integrity: sha512-9g/zj+AZx5moFcdFIrYQoVrueXivjUcc3MQHtCYT8WhIuk1lUh1AyEhvJCS0XBZld09cLvd1AZ3BvDBpVpX2UA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/monitoring@1.56.0':
+ resolution: {integrity: sha512-Qf3Sr6f9A9uxCZUf3MXS0d2b877uYzEB5yxqpVGXAhcJnBCQjrRRon0KvefpGkxy+BshrIJs96OUoMtGqXTFDA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/recommend@5.56.0':
+ resolution: {integrity: sha512-GXWG1rWc5wu8hY4N33Y3b6ernY6sAdAvmKWN/zHAiACOx40WnpG0TVX5YazCAr/9gOYGInSiM2A0y2jy2xbiDA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-browser-xhr@5.56.0':
+ resolution: {integrity: sha512-7t24cBxaInS3mZb7ddEaZT/tp6q+/aR4YttsQVyP1/i+LmwPR34atO35KjaLFCcRVrlP7sYOAqkCfg6lIRB+ew==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-fetch@5.56.0':
+ resolution: {integrity: sha512-R7ePHgVYmDFjZpvrsVAfbDz/d4RxKAYZ5/vgLfIsCVRZRryjWl/3INOxpOICzitehQ5FjNtNjcLQTrmHPTcHBQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-node-http@5.56.0':
+ resolution: {integrity: sha512-PIOUXlSnrqM0S+WOgDRb4RzotydJH7ZoT6tOyL7tAO7qJOfvX5wsEW8Pe+PMKMwvuI4/gIyK9cg2H7lJXqnc4Q==}
+ engines: {node: '>= 14.0.0'}
+
'@babel/code-frame@7.29.7':
resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
engines: {node: '>=6.9.0'}
@@ -196,10 +318,26 @@ packages:
peerDependencies:
oxlint: '>=1'
+ '@btravstack/theme@1.7.0':
+ resolution: {integrity: sha512-EcBvQruZdsiL/zuNsu7Y1r2FeMDv0J5LZJx7ikO6cFvNRzKCc63A7582gVmfJNQlGJIg0cUCjQXB4Tm1YHtyug==}
+ peerDependencies:
+ vitepress: ^1.6.0
+ vue: ^3.3.0
+ peerDependenciesMeta:
+ vue:
+ optional: true
+
'@btravstack/tsconfig@0.2.0':
resolution: {integrity: sha512-0VZt4DNJlY+XgAeCS4HybgsG0kdWDGjRwBiDdQZ6pYPUo1ayjM4AIH1oPatL5+YQvICTqrSaXTHSa8DnP+GXbg==}
engines: {node: '>=20'}
+ '@btravstack/typedoc@0.1.0':
+ resolution: {integrity: sha512-cAhj15iqJwPQ+Z+I/Kc1Bafu9HqfS2D/uaU7czPecaCgZpH5F8LUfNRmTZppkvnTMpDX0La+UrdIUyNHHLqtIg==}
+ engines: {node: '>=20'}
+ peerDependencies:
+ typedoc: '>=0.28'
+ typedoc-plugin-markdown: '>=4'
+
'@changesets/apply-release-plan@7.1.1':
resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==}
@@ -340,6 +478,29 @@ packages:
resolution: {integrity: sha512-TzlTVpKPjaqW6qOYjQcYUDuGsLCNsvFHVBXkYGTAnf5V37jCWrE5haKNXzz0WZUtVHjrpV76L1buANjwXMfT8w==}
engines: {node: '>=22'}
+ '@docsearch/css@3.8.2':
+ resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==}
+
+ '@docsearch/js@3.8.2':
+ resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==}
+
+ '@docsearch/react@3.8.2':
+ resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==}
+ peerDependencies:
+ '@types/react': '>= 16.8.0 < 19.0.0'
+ react: '>= 16.8.0 < 19.0.0'
+ react-dom: '>= 16.8.0 < 19.0.0'
+ search-insights: '>= 1 < 3'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ search-insights:
+ optional: true
+
'@emnapi/core@1.11.2':
resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==}
@@ -349,6 +510,171 @@ packages:
'@emnapi/wasi-threads@1.2.2':
resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
+ '@esbuild/aix-ppc64@0.25.12':
+ resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.25.12':
+ resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.25.12':
+ resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.25.12':
+ resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.25.12':
+ resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.25.12':
+ resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.25.12':
+ resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.25.12':
+ resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.25.12':
+ resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.25.12':
+ resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.25.12':
+ resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.25.12':
+ resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.25.12':
+ resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.25.12':
+ resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.25.12':
+ resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.25.12':
+ resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.25.12':
+ resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.25.12':
+ resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.25.12':
+ resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.25.12':
+ resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.25.12':
+ resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.25.12':
+ resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.25.12':
+ resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.25.12':
+ resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@gerrit0/mini-shiki@3.23.0':
+ resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==}
+
+ '@iconify-json/simple-icons@1.2.93':
+ resolution: {integrity: sha512-/XhANjfGYOuqvSR3TmUnkQkINvQ4GVjVuukvymRbxtVFBvIq/yiXJqCDycKcQPT401OYT9H2vIY6ihAlz1QIAw==}
+
+ '@iconify/types@2.0.0':
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+
'@inquirer/external-editor@1.0.3':
resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==}
engines: {node: '>=18'}
@@ -374,6 +700,13 @@ packages:
'@manypkg/get-packages@1.1.3':
resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==}
+ '@napi-rs/lzma-linux-x64-gnu@1.5.1':
+ resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==}
+ engines: {node: ^22.20 || ^24.12 || >=25}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
'@napi-rs/wasm-runtime@1.2.2':
resolution: {integrity: sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==}
engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
@@ -1006,91 +1339,286 @@ packages:
'@rolldown/pluginutils@1.0.1':
resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
- '@simple-libs/child-process-utils@2.0.0':
- resolution: {integrity: sha512-dvNoRKLijXnD0XoJAz94pbNuB5GQgDr55UhpSPhffDkTT0Cmcqh9jSCOtwfT2d4H6MI9E7c4SgtMuJXZ6F3c6A==}
- engines: {node: '>=22'}
-
- '@simple-libs/stream-utils@2.0.0':
- resolution: {integrity: sha512-fCTuZK4QBa+39Oz9l4OGfJfz+GpwCp3AqO7Zch3to99xHPgstVsRFpeQ8LNd2o1Gv8raL2mCFwiaHh7bFSp5DQ==}
- engines: {node: '>=22'}
-
- '@standard-schema/spec@1.1.0':
- resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
-
- '@standardserver/aws-lambda@0.7.1':
- resolution: {integrity: sha512-fuwAx2M2O5Bnjk2JdFrtEQALmBwVtnn4jKApzFVmlIivWA7EGMj5kOzCNaJizxCQXlhPmC+doDHqf/H7FKMaNA==}
-
- '@standardserver/core@0.7.1':
- resolution: {integrity: sha512-ZMoFDR92p9HnaI6vXK1iNFKXyLK8/6r3D4EJUM+SqeyReUH3OEJO4CZKU8BfXyzAV1A6Nsa7y2dGqDOYqH5LlQ==}
-
- '@standardserver/fastify@0.7.1':
- resolution: {integrity: sha512-Oa+ttR0CyNkFjNczs2dO/WFFeZ4sAszVBKIOhKb1FFcDtD9VdqDgMBhbQ4sFR885fwpYckoYjFU6xXWWTueBlw==}
- peerDependencies:
- fastify: '>=5.6.1'
- peerDependenciesMeta:
- fastify:
- optional: true
-
- '@standardserver/fetch@0.7.1':
- resolution: {integrity: sha512-BeiAWESedv0woYpoBHCnq2Y3xLZZ3voFahdzpFd+HqLyenXIL4XX3z7/WgWNQnf+WsSQrK6HzBkDWCicCXVoKQ==}
-
- '@standardserver/node@0.7.1':
- resolution: {integrity: sha512-Ikc07cGBTJ8tJgPd1OanNKVNpijcbixB1iKk0GdL/b1vkYbriGgNW3oHvbApM7+XqeCeNHj5XawHk6q90mwEEA==}
+ '@rollup/rollup-android-arm-eabi@4.62.4':
+ resolution: {integrity: sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==}
+ cpu: [arm]
+ os: [android]
- '@standardserver/peer@0.7.1':
- resolution: {integrity: sha512-ggqPbwz4X4GIziQgoyCTDHFw9nM9YuEvlSpO21pfoXLYF80ijtpN/iq4P0zKpb4kcXnBoSVDRUSnBJSZi0SJDg==}
+ '@rollup/rollup-android-arm64@4.62.4':
+ resolution: {integrity: sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==}
+ cpu: [arm64]
+ os: [android]
- '@standardserver/shared@0.7.1':
- resolution: {integrity: sha512-tBDheI3Me1gQEKPU+XhcCZ6/njmkKgJhA5rhi1/m6GauGhHq87UuVslDNc8qB+T/xsxVch/qETFhssEWO9c6BA==}
+ '@rollup/rollup-darwin-arm64@4.62.4':
+ resolution: {integrity: sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==}
+ cpu: [arm64]
+ os: [darwin]
- '@turbo/darwin-64@2.10.8':
- resolution: {integrity: sha512-po+7rfJfUnFXjWlcoN2RwhErgzCdRtBc1T26vYPcywHlggmCQiQe1uWaE4j+BibI2uY9/2pDoFzMN0rmSaPFOw==}
+ '@rollup/rollup-darwin-x64@4.62.4':
+ resolution: {integrity: sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==}
cpu: [x64]
os: [darwin]
- '@turbo/darwin-arm64@2.10.8':
- resolution: {integrity: sha512-+zB2btDJ00lnPRuqOvpVvgl4x34k/djZQGZTTCfjn7JgNCl8QFY5Njo5+dqkY1g/+9gbbsnAvWm9CmJg9ebcXA==}
+ '@rollup/rollup-freebsd-arm64@4.62.4':
+ resolution: {integrity: sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==}
cpu: [arm64]
- os: [darwin]
+ os: [freebsd]
- '@turbo/linux-64@2.10.8':
- resolution: {integrity: sha512-K1dxqiVisyN7cViVsfQLs6xscQbYuI8aO2nbUhFURDACgEDfZRdP/b4CCxeosBJpcMfhYyiibWqJorCnvz9kKg==}
+ '@rollup/rollup-freebsd-x64@4.62.4':
+ resolution: {integrity: sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==}
cpu: [x64]
- os: [android, linux]
+ os: [freebsd]
- '@turbo/linux-arm64@2.10.8':
- resolution: {integrity: sha512-Gi77ibVnrE1fEmvr+/wBD/yvRqhwp/RQuCp2+//lv1U1wNFFyVg0V7Wj8FG9FXPFAw5QHReo8rxc9+wBSDZjzA==}
- cpu: [arm64]
- os: [android, linux]
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.4':
+ resolution: {integrity: sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
- '@turbo/windows-64@2.10.8':
- resolution: {integrity: sha512-znnLO1haJPYTHoKMKwlAvlkjRiYbbhBzME6wIGaMd+fwir23U6jVd1ecaTWWi1fbnRVqxMfgDBKseQ/hLKb83g==}
- cpu: [x64]
- os: [win32]
+ '@rollup/rollup-linux-arm-musleabihf@4.62.4':
+ resolution: {integrity: sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
- '@turbo/windows-arm64@2.10.8':
- resolution: {integrity: sha512-VN30vh3b3Czh2WzYHNTfF1FE0YMZ5aHsLO8dBMGHJewA6792wX6iJR8ZxlzFW6WdOu0gEAKIvlYhfyT81Wkm4Q==}
+ '@rollup/rollup-linux-arm64-gnu@4.62.4':
+ resolution: {integrity: sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==}
cpu: [arm64]
- os: [win32]
-
- '@tybys/wasm-util@0.10.3':
- resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
+ os: [linux]
+ libc: [glibc]
- '@types/chai@5.2.3':
- resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+ '@rollup/rollup-linux-arm64-musl@4.62.4':
+ resolution: {integrity: sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
- '@types/deep-eql@4.0.2':
- resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+ '@rollup/rollup-linux-loong64-gnu@4.62.4':
+ resolution: {integrity: sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
- '@types/estree@1.0.9':
- resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+ '@rollup/rollup-linux-loong64-musl@4.62.4':
+ resolution: {integrity: sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
- '@types/node@12.20.55':
- resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
+ '@rollup/rollup-linux-ppc64-gnu@4.62.4':
+ resolution: {integrity: sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
- '@types/node@26.1.2':
+ '@rollup/rollup-linux-ppc64-musl@4.62.4':
+ resolution: {integrity: sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.62.4':
+ resolution: {integrity: sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-riscv64-musl@4.62.4':
+ resolution: {integrity: sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-s390x-gnu@4.62.4':
+ resolution: {integrity: sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-gnu@4.62.4':
+ resolution: {integrity: sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-musl@4.62.4':
+ resolution: {integrity: sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-openbsd-x64@4.62.4':
+ resolution: {integrity: sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.62.4':
+ resolution: {integrity: sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.62.4':
+ resolution: {integrity: sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.62.4':
+ resolution: {integrity: sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.62.4':
+ resolution: {integrity: sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.62.4':
+ resolution: {integrity: sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==}
+ cpu: [x64]
+ os: [win32]
+
+ '@shikijs/core@2.5.0':
+ resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==}
+
+ '@shikijs/engine-javascript@2.5.0':
+ resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==}
+
+ '@shikijs/engine-oniguruma@2.5.0':
+ resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==}
+
+ '@shikijs/engine-oniguruma@3.23.0':
+ resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==}
+
+ '@shikijs/langs@2.5.0':
+ resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==}
+
+ '@shikijs/langs@3.23.0':
+ resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==}
+
+ '@shikijs/themes@2.5.0':
+ resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==}
+
+ '@shikijs/themes@3.23.0':
+ resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==}
+
+ '@shikijs/transformers@2.5.0':
+ resolution: {integrity: sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==}
+
+ '@shikijs/types@2.5.0':
+ resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==}
+
+ '@shikijs/types@3.23.0':
+ resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==}
+
+ '@shikijs/vscode-textmate@10.0.2':
+ resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
+
+ '@simple-libs/child-process-utils@2.0.0':
+ resolution: {integrity: sha512-dvNoRKLijXnD0XoJAz94pbNuB5GQgDr55UhpSPhffDkTT0Cmcqh9jSCOtwfT2d4H6MI9E7c4SgtMuJXZ6F3c6A==}
+ engines: {node: '>=22'}
+
+ '@simple-libs/stream-utils@2.0.0':
+ resolution: {integrity: sha512-fCTuZK4QBa+39Oz9l4OGfJfz+GpwCp3AqO7Zch3to99xHPgstVsRFpeQ8LNd2o1Gv8raL2mCFwiaHh7bFSp5DQ==}
+ engines: {node: '>=22'}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@standardserver/aws-lambda@0.7.1':
+ resolution: {integrity: sha512-fuwAx2M2O5Bnjk2JdFrtEQALmBwVtnn4jKApzFVmlIivWA7EGMj5kOzCNaJizxCQXlhPmC+doDHqf/H7FKMaNA==}
+
+ '@standardserver/core@0.7.1':
+ resolution: {integrity: sha512-ZMoFDR92p9HnaI6vXK1iNFKXyLK8/6r3D4EJUM+SqeyReUH3OEJO4CZKU8BfXyzAV1A6Nsa7y2dGqDOYqH5LlQ==}
+
+ '@standardserver/fastify@0.7.1':
+ resolution: {integrity: sha512-Oa+ttR0CyNkFjNczs2dO/WFFeZ4sAszVBKIOhKb1FFcDtD9VdqDgMBhbQ4sFR885fwpYckoYjFU6xXWWTueBlw==}
+ peerDependencies:
+ fastify: '>=5.6.1'
+ peerDependenciesMeta:
+ fastify:
+ optional: true
+
+ '@standardserver/fetch@0.7.1':
+ resolution: {integrity: sha512-BeiAWESedv0woYpoBHCnq2Y3xLZZ3voFahdzpFd+HqLyenXIL4XX3z7/WgWNQnf+WsSQrK6HzBkDWCicCXVoKQ==}
+
+ '@standardserver/node@0.7.1':
+ resolution: {integrity: sha512-Ikc07cGBTJ8tJgPd1OanNKVNpijcbixB1iKk0GdL/b1vkYbriGgNW3oHvbApM7+XqeCeNHj5XawHk6q90mwEEA==}
+
+ '@standardserver/peer@0.7.1':
+ resolution: {integrity: sha512-ggqPbwz4X4GIziQgoyCTDHFw9nM9YuEvlSpO21pfoXLYF80ijtpN/iq4P0zKpb4kcXnBoSVDRUSnBJSZi0SJDg==}
+
+ '@standardserver/shared@0.7.1':
+ resolution: {integrity: sha512-tBDheI3Me1gQEKPU+XhcCZ6/njmkKgJhA5rhi1/m6GauGhHq87UuVslDNc8qB+T/xsxVch/qETFhssEWO9c6BA==}
+
+ '@turbo/darwin-64@2.10.8':
+ resolution: {integrity: sha512-po+7rfJfUnFXjWlcoN2RwhErgzCdRtBc1T26vYPcywHlggmCQiQe1uWaE4j+BibI2uY9/2pDoFzMN0rmSaPFOw==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@turbo/darwin-arm64@2.10.8':
+ resolution: {integrity: sha512-+zB2btDJ00lnPRuqOvpVvgl4x34k/djZQGZTTCfjn7JgNCl8QFY5Njo5+dqkY1g/+9gbbsnAvWm9CmJg9ebcXA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@turbo/linux-64@2.10.8':
+ resolution: {integrity: sha512-K1dxqiVisyN7cViVsfQLs6xscQbYuI8aO2nbUhFURDACgEDfZRdP/b4CCxeosBJpcMfhYyiibWqJorCnvz9kKg==}
+ cpu: [x64]
+ os: [android, linux]
+
+ '@turbo/linux-arm64@2.10.8':
+ resolution: {integrity: sha512-Gi77ibVnrE1fEmvr+/wBD/yvRqhwp/RQuCp2+//lv1U1wNFFyVg0V7Wj8FG9FXPFAw5QHReo8rxc9+wBSDZjzA==}
+ cpu: [arm64]
+ os: [android, linux]
+
+ '@turbo/windows-64@2.10.8':
+ resolution: {integrity: sha512-znnLO1haJPYTHoKMKwlAvlkjRiYbbhBzME6wIGaMd+fwir23U6jVd1ecaTWWi1fbnRVqxMfgDBKseQ/hLKb83g==}
+ cpu: [x64]
+ os: [win32]
+
+ '@turbo/windows-arm64@2.10.8':
+ resolution: {integrity: sha512-VN30vh3b3Czh2WzYHNTfF1FE0YMZ5aHsLO8dBMGHJewA6792wX6iJR8ZxlzFW6WdOu0gEAKIvlYhfyT81Wkm4Q==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tybys/wasm-util@0.10.3':
+ resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
+
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/hast@3.0.5':
+ resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==}
+
+ '@types/linkify-it@5.0.0':
+ resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
+
+ '@types/markdown-it@14.1.2':
+ resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdurl@2.0.0':
+ resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
+
+ '@types/node@12.20.55':
+ resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
+
+ '@types/node@26.1.2':
resolution: {integrity: sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==}
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/web-bluetooth@0.0.21':
+ resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
+
'@typescript/typescript-aix-ppc64@7.0.2':
resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==}
engines: {node: '>=16.20.0'}
@@ -1211,6 +1739,9 @@ packages:
cpu: [x64]
os: [win32]
+ '@ungap/structured-clone@1.3.3':
+ resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==}
+
'@unthrown/oxlint@5.1.0':
resolution: {integrity: sha512-xTbO9Qoz5W0J7Ur+vFiKAw8buxd6gCaOt16dYkVuNHIyiROl/fL5S9hCQkxduLYReiVATMOis4cgh0KnQy4HIQ==}
engines: {node: '>=20'}
@@ -1228,6 +1759,13 @@ packages:
unthrown: ^5.1.0
vitest: ^4
+ '@vitejs/plugin-vue@5.2.4':
+ resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: 6.4.3
+ vue: ^3.2.25
+
'@vitest/coverage-v8@4.1.10':
resolution: {integrity: sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==}
peerDependencies:
@@ -1244,7 +1782,7 @@ packages:
resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==}
peerDependencies:
msw: ^2.4.9
- vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ vite: 6.4.3
peerDependenciesMeta:
msw:
optional: true
@@ -1266,6 +1804,92 @@ packages:
'@vitest/utils@4.1.10':
resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==}
+ '@vue/compiler-core@3.5.41':
+ resolution: {integrity: sha512-q0Xtv/F9w2YO/7htQhtiL+Ev2WCJbe5N2hc+XfgyKkEKqWpSxknmT8QOuGdEKNdjPq0c3F7rNpFkTo3Kfrm7pg==}
+
+ '@vue/compiler-dom@3.5.41':
+ resolution: {integrity: sha512-oKacVfNglLvGjnS6BXOlGL7EyG2h8X03pqXCjzotRZUaXGjbrTJUnVAQjrCqUnS+lyu31nwQjZY/d817GmCnfw==}
+
+ '@vue/compiler-sfc@3.5.41':
+ resolution: {integrity: sha512-XJhip7R2wy6vX3knCxdZN4KracFaZUef58s1KYewqluedHIJaPIVfXoYT7MF1F8nCvv6k8bWWxDC8opMkg1VTQ==}
+
+ '@vue/compiler-ssr@3.5.41':
+ resolution: {integrity: sha512-U3v5OejKEGqOI0Wy0+Sz7hGuIFZHA4LSXzrNM3IMIeDyJEBBfTpX26n3SDgToRpP2bLc9FfI2j/kSgcJ8Emq5A==}
+
+ '@vue/devtools-api@7.7.10':
+ resolution: {integrity: sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==}
+
+ '@vue/devtools-kit@7.7.10':
+ resolution: {integrity: sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==}
+
+ '@vue/devtools-shared@7.7.10':
+ resolution: {integrity: sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==}
+
+ '@vue/reactivity@3.5.41':
+ resolution: {integrity: sha512-rznsqKM0np0x18EjzF8x88MpEhdNsffbvFbckLL5+oUKz1BxAImEmO7J1ArRYSyo6aQaVoBDp7jEkT91OOxydA==}
+
+ '@vue/runtime-core@3.5.41':
+ resolution: {integrity: sha512-Vcry58hiAKwGen9Z1jUZE0feFsNArPCMOImYI8el48A9Idf6DuQYD0U05zZIF2Iad1hGhPSvcbBbAOhNr55fhg==}
+
+ '@vue/runtime-dom@3.5.41':
+ resolution: {integrity: sha512-3vVBahVBS9+U6cmXBLyb8nE6/yYo4J/CGI9eVFs3KiMc0YHuudwKyShTD65jtJy/L9PUUxNAFu4cj4LiJ0UFbw==}
+
+ '@vue/server-renderer@3.5.41':
+ resolution: {integrity: sha512-n6hx/pNFfbD6SuyeuMVkvqox8bwf/ET9JlA/kAz/imw8sw++wkqKe2mHX5KutjPpbKE4Z56yTHszoOjGMI9igQ==}
+
+ '@vue/shared@3.5.41':
+ resolution: {integrity: sha512-IOnwSCma8j+9xJT6b8H0dEYidC80NsYmNMlZxRsukYcSoGaDBohog5hDxzeUXdFeGWFA++vWvxqOmrr96VlqMA==}
+
+ '@vueuse/core@12.8.2':
+ resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==}
+
+ '@vueuse/integrations@12.8.2':
+ resolution: {integrity: sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==}
+ peerDependencies:
+ async-validator: ^4
+ axios: ^1
+ change-case: ^5
+ drauu: ^0.4
+ focus-trap: ^7
+ fuse.js: ^7
+ idb-keyval: ^6
+ jwt-decode: ^4
+ nprogress: ^0.2
+ qrcode: ^1.5
+ sortablejs: ^1
+ universal-cookie: ^7
+ peerDependenciesMeta:
+ async-validator:
+ optional: true
+ axios:
+ optional: true
+ change-case:
+ optional: true
+ drauu:
+ optional: true
+ focus-trap:
+ optional: true
+ fuse.js:
+ optional: true
+ idb-keyval:
+ optional: true
+ jwt-decode:
+ optional: true
+ nprogress:
+ optional: true
+ qrcode:
+ optional: true
+ sortablejs:
+ optional: true
+ universal-cookie:
+ optional: true
+
+ '@vueuse/metadata@12.8.2':
+ resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==}
+
+ '@vueuse/shared@12.8.2':
+ resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==}
+
'@yuku-codegen/binding-android-arm64@0.8.3':
resolution: {integrity: sha512-/EKnnqwvN7xYoVDhQEIEJTdPDwGW1wkFz/2Eku3ES/IJd4lcQh/OaIDFBmoJKvpe12enrb1TIoYh1fxasGXolA==}
cpu: [arm64]
@@ -1404,6 +2028,10 @@ packages:
ajv@8.20.0:
resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+ algoliasearch@5.56.0:
+ resolution: {integrity: sha512-PrqppUmhT4ENdas2pH9caE7efUcxy6EcSFhWzosiVuQBzu2tQ5yLTI6jwomT/1cuBnivzGfxiJCqDNN9FRRh+Q==}
+ engines: {node: '>= 14.0.0'}
+
ansi-colors@4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
@@ -1445,10 +2073,21 @@ packages:
ast-v8-to-istanbul@1.0.5:
resolution: {integrity: sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==}
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
better-path-resolve@1.0.0:
resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
engines: {node: '>=4'}
+ birpc@2.9.0:
+ resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==}
+
+ brace-expansion@5.0.9:
+ resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==}
+ engines: {node: 20 || >=22}
+
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
@@ -1461,10 +2100,19 @@ 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==}
+
chardet@2.2.0:
resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==}
@@ -1472,6 +2120,9 @@ packages:
resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==}
engines: {node: '>=20'}
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
conventional-changelog-angular@9.2.1:
resolution: {integrity: sha512-oWSL6ZhnXbYraOFTK3PgRAQJ8fADDAEv5K6AdeyQPLvjFmhG8+ejL0jZZp/R7vTmGJaBvZEE+sE7dB4bCv7sAw==}
engines: {node: '>=22'}
@@ -1492,6 +2143,10 @@ packages:
resolution: {integrity: sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==}
engines: {node: '>=22'}
+ copy-anything@4.0.5:
+ resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
+ engines: {node: '>=18'}
+
cosmiconfig-typescript-loader@6.3.0:
resolution: {integrity: sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==}
engines: {node: '>=v18'}
@@ -1513,16 +2168,22 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
defu@6.1.7:
resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
detect-indent@6.1.0:
resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
engines: {node: '>=8'}
- detect-libc@2.1.2:
- resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
- engines: {node: '>=8'}
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
@@ -1537,6 +2198,9 @@ packages:
oxc-resolver:
optional: true
+ emoji-regex-xs@1.0.0:
+ resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==}
+
emoji-regex@10.6.0:
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
@@ -1548,6 +2212,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@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
@@ -1561,6 +2233,11 @@ packages:
es-toolkit@1.50.0:
resolution: {integrity: sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==}
+ esbuild@0.25.12:
+ resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
@@ -1570,6 +2247,9 @@ packages:
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==}
@@ -1613,6 +2293,9 @@ packages:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
+ focus-trap@7.8.0:
+ resolution: {integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==}
+
formatly@0.3.0:
resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==}
engines: {node: '>=18.3.0'}
@@ -1665,12 +2348,24 @@ packages:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hookable@5.5.3:
+ resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+
hookable@6.1.1:
resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==}
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
human-id@4.2.0:
resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==}
hasBin: true
@@ -1718,6 +2413,10 @@ packages:
resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==}
engines: {node: '>=4'}
+ is-what@5.5.0:
+ resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==}
+ engines: {node: '>=18'}
+
is-windows@1.0.2:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
@@ -1830,83 +2529,12 @@ packages:
resolution: {integrity: sha512-K7mM4WoqMwqfXYK11EHy+lSH1uW8XHni3Yn/bSqyerPkUPygGdf3xn18JoV5HyA06xuQL3ofGAOjG01QX9oJ4w==}
hasBin: true
- lightningcss-android-arm64@1.33.0:
- resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [android]
-
- lightningcss-darwin-arm64@1.33.0:
- resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [darwin]
-
- lightningcss-darwin-x64@1.33.0:
- resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [darwin]
-
- lightningcss-freebsd-x64@1.33.0:
- resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [freebsd]
-
- lightningcss-linux-arm-gnueabihf@1.33.0:
- resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm]
- os: [linux]
-
- lightningcss-linux-arm64-gnu@1.33.0:
- resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- lightningcss-linux-arm64-musl@1.33.0:
- resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- lightningcss-linux-x64-gnu@1.33.0:
- resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- lightningcss-linux-x64-musl@1.33.0:
- resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- lightningcss-win32-arm64-msvc@1.33.0:
- resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [win32]
-
- lightningcss-win32-x64-msvc@1.33.0:
- resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [win32]
-
- lightningcss@1.33.0:
- resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
- engines: {node: '>= 12.0.0'}
-
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+ linkify-it@5.0.2:
+ resolution: {integrity: sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==}
+
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
@@ -1914,6 +2542,9 @@ packages:
lodash.startcase@4.4.0:
resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
+ lunr@2.3.9:
+ resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==}
+
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@@ -1924,14 +2555,52 @@ packages:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
+ mark.js@8.11.1:
+ resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
+
+ markdown-it@14.3.0:
+ resolution: {integrity: sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==}
+ hasBin: true
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdurl@2.1.0:
+ resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==}
+
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
+ minimatch@10.2.6:
+ resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==}
+ engines: {node: 18 || 20 || >=22}
+
+ minisearch@7.2.0:
+ resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==}
+
+ mitt@3.0.1:
+ resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
+
mri@1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
@@ -1945,6 +2614,9 @@ packages:
resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==}
engines: {node: '>=12.20.0'}
+ oniguruma-to-es@3.1.1:
+ resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==}
+
outdent@0.5.0:
resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==}
@@ -2027,6 +2699,9 @@ packages:
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+ perfect-debounce@1.0.0:
+ resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -2046,11 +2721,26 @@ packages:
resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==}
engines: {node: ^10 || ^12 || >=14}
+ preact@10.29.8:
+ resolution: {integrity: sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==}
+ peerDependencies:
+ preact-render-to-string: '>=5'
+ peerDependenciesMeta:
+ preact-render-to-string:
+ optional: true
+
prettier@2.8.8:
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
engines: {node: '>=10.13.0'}
hasBin: true
+ property-information@7.2.0:
+ resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
+
+ punycode.js@2.3.1:
+ resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
+ engines: {node: '>=6'}
+
quansync@0.2.11:
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
@@ -2068,6 +2758,15 @@ packages:
resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
engines: {node: '>=6'}
+ 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==}
+
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
@@ -2087,6 +2786,9 @@ packages:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
rolldown-plugin-dts@0.27.14:
resolution: {integrity: sha512-ZvuDDwoIpRK9RPxDXratCpklFO9QZZWndf/sd0VBFb4LEj0jj07UcHK9OCh7V4XiFz2Z89ziyBC2K6tJiDjrbw==}
engines: {node: ^22.18.0 || >=24.11.0}
@@ -2111,6 +2813,11 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
+ rollup@4.62.4:
+ resolution: {integrity: sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
@@ -2130,6 +2837,9 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
+ shiki@2.5.0:
+ resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==}
+
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
@@ -2149,9 +2859,16 @@ packages:
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==}
+ speakingurl@14.0.1:
+ resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
+ engines: {node: '>=0.10.0'}
+
sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
@@ -2169,6 +2886,9 @@ packages:
resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==}
engines: {node: '>=20'}
+ 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'}
@@ -2185,10 +2905,17 @@ packages:
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
engines: {node: '>=14.16'}
+ superjson@2.2.6:
+ resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==}
+ engines: {node: '>=16'}
+
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
+ tabbable@6.5.0:
+ resolution: {integrity: sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==}
+
tagged-tag@1.0.0:
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
engines: {node: '>=20'}
@@ -2224,6 +2951,9 @@ packages:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
tsdown@0.22.14:
resolution: {integrity: sha512-ule7Y+fsAN2iZbLDoo7C4KYljFJNJJ+fLshyn+9gozeTspVersWHxwdGB+Dm2hzA38s6muFnUTl0jK3vJm9ifQ==}
engines: {node: ^22.18.0 || >=24.11.0}
@@ -2269,11 +2999,32 @@ packages:
resolution: {integrity: sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==}
engines: {node: '>=20'}
+ typedoc-plugin-markdown@4.12.0:
+ resolution: {integrity: sha512-eJDEMAfxCmede22c/Jw7d0FA13ggAQv+KkwQYKYCdqI02cin6Rc9QRwbG/7XvvHWinuFejySnZVUWDtvGk3Vbg==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ typedoc: 0.28.x
+
+ typedoc@0.28.20:
+ resolution: {integrity: sha512-uSKqkh8Cr48vllnEy+jdaAgOeR6Y+QCBW7usgUsKj7gJEfR7stw9U/fE49LBnj2tPRKPY0c0EBJSWe9Appmplg==}
+ engines: {node: '>= 18', pnpm: '>= 10'}
+ hasBin: true
+ peerDependencies:
+ typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x
+
+ typescript@6.0.3:
+ resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
typescript@7.0.2:
resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==}
engines: {node: '>=16.20.0'}
hasBin: true
+ uc.micro@2.1.0:
+ resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
+
unbash@4.0.6:
resolution: {integrity: sha512-YGBMSVG/WrA2vgaZbXVvxrGgoMcWZecyyS4foGt8clbtY7s1nIKNmt7Z9LR74XE6FkYTSqDmKk2lIOhOjIvmrw==}
engines: {node: '>=14'}
@@ -2284,6 +3035,21 @@ packages:
undici-types@8.3.0:
resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==}
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ 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'}
@@ -2296,34 +3062,37 @@ packages:
resolution: {integrity: sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==}
engines: {node: '>=18.12.0'}
- vite@8.2.0:
- resolution: {integrity: sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite@6.4.3:
+ resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
- '@types/node': ^20.19.0 || >=22.12.0
- '@vitejs/devtools': ^0.4.0
- esbuild: ^0.27.0 || ^0.28.0
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.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
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
peerDependenciesMeta:
'@types/node':
optional: true
- '@vitejs/devtools':
- optional: true
- esbuild:
- optional: true
jiti:
optional: true
less:
optional: true
+ lightningcss:
+ optional: true
sass:
optional: true
sass-embedded:
@@ -2339,6 +3108,18 @@ packages:
yaml:
optional: true
+ vitepress@1.6.4:
+ resolution: {integrity: sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==}
+ hasBin: true
+ peerDependencies:
+ markdown-it-mathjax3: ^4
+ postcss: ^8
+ peerDependenciesMeta:
+ markdown-it-mathjax3:
+ optional: true
+ postcss:
+ optional: true
+
vitest@4.1.10:
resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==}
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
@@ -2379,6 +3160,14 @@ packages:
jsdom:
optional: true
+ vue@3.5.41:
+ resolution: {integrity: sha512-2laE0p+aK+/AOPG/XL/WepOs/GlK755LJ1XECi9kDUrz1FKNw8rb2Xzlw9JS1rqEV55nb0ttsKxVlTCcd+R5cg==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
walk-up-path@4.0.0:
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
engines: {node: 20 || >=22}
@@ -2426,8 +3215,122 @@ packages:
zod@4.4.3:
resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
snapshots:
+ '@algolia/abtesting@1.22.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)':
+ dependencies:
+ '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+ - search-insights
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+
+ '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)
+ '@algolia/client-search': 5.56.0
+ algoliasearch: 5.56.0
+
+ '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)':
+ dependencies:
+ '@algolia/client-search': 5.56.0
+ algoliasearch: 5.56.0
+
+ '@algolia/client-abtesting@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/client-analytics@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/client-common@5.56.0': {}
+
+ '@algolia/client-insights@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/client-personalization@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/client-query-suggestions@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/client-search@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/ingestion@1.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/monitoring@1.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/recommend@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
+ '@algolia/requester-browser-xhr@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+
+ '@algolia/requester-fetch@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+
+ '@algolia/requester-node-http@5.56.0':
+ dependencies:
+ '@algolia/client-common': 5.56.0
+
'@babel/code-frame@7.29.7':
dependencies:
'@babel/helper-validator-identifier': 7.29.7
@@ -2464,8 +3367,19 @@ snapshots:
dependencies:
oxlint: 1.77.0
+ '@btravstack/theme@1.7.0(vitepress@1.6.4(@algolia/client-search@5.56.0)(@types/node@26.1.2)(jiti@2.7.0)(postcss@8.5.25)(typescript@6.0.3)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))':
+ dependencies:
+ vitepress: 1.6.4(@algolia/client-search@5.56.0)(@types/node@26.1.2)(jiti@2.7.0)(postcss@8.5.25)(typescript@6.0.3)(yaml@2.9.0)
+ optionalDependencies:
+ vue: 3.5.41(typescript@6.0.3)
+
'@btravstack/tsconfig@0.2.0': {}
+ '@btravstack/typedoc@0.1.0(typedoc-plugin-markdown@4.12.0(typedoc@0.28.20(typescript@6.0.3)))(typedoc@0.28.20(typescript@6.0.3))':
+ dependencies:
+ typedoc: 0.28.20(typescript@6.0.3)
+ typedoc-plugin-markdown: 4.12.0(typedoc@0.28.20(typescript@6.0.3))
+
'@changesets/apply-release-plan@7.1.1':
dependencies:
'@changesets/config': 3.1.4
@@ -2728,6 +3642,29 @@ snapshots:
'@conventional-changelog/template@1.2.1': {}
+ '@docsearch/css@3.8.2': {}
+
+ '@docsearch/js@3.8.2(@algolia/client-search@5.56.0)':
+ dependencies:
+ '@docsearch/react': 3.8.2(@algolia/client-search@5.56.0)
+ preact: 10.29.8
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/react'
+ - preact-render-to-string
+ - react
+ - react-dom
+ - search-insights
+
+ '@docsearch/react@3.8.2(@algolia/client-search@5.56.0)':
+ dependencies:
+ '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)
+ '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)
+ '@docsearch/css': 3.8.2
+ algoliasearch: 5.56.0
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+
'@emnapi/core@1.11.2':
dependencies:
'@emnapi/wasi-threads': 1.2.2
@@ -2744,6 +3681,98 @@ snapshots:
tslib: 2.8.1
optional: true
+ '@esbuild/aix-ppc64@0.25.12':
+ optional: true
+
+ '@esbuild/android-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/android-arm@0.25.12':
+ optional: true
+
+ '@esbuild/android-x64@0.25.12':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/darwin-x64@0.25.12':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-arm@0.25.12':
+ optional: true
+
+ '@esbuild/linux-ia32@0.25.12':
+ optional: true
+
+ '@esbuild/linux-loong64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.25.12':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-s390x@0.25.12':
+ optional: true
+
+ '@esbuild/linux-x64@0.25.12':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/sunos-x64@0.25.12':
+ optional: true
+
+ '@esbuild/win32-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/win32-ia32@0.25.12':
+ optional: true
+
+ '@esbuild/win32-x64@0.25.12':
+ optional: true
+
+ '@gerrit0/mini-shiki@3.23.0':
+ dependencies:
+ '@shikijs/engine-oniguruma': 3.23.0
+ '@shikijs/langs': 3.23.0
+ '@shikijs/themes': 3.23.0
+ '@shikijs/types': 3.23.0
+ '@shikijs/vscode-textmate': 10.0.2
+
+ '@iconify-json/simple-icons@1.2.93':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify/types@2.0.0': {}
+
'@inquirer/external-editor@1.0.3(@types/node@26.1.2)':
dependencies:
chardet: 2.2.0
@@ -2776,6 +3805,9 @@ snapshots:
globby: 11.1.0
read-yaml-file: 1.1.0
+ '@napi-rs/lzma-linux-x64-gnu@1.5.1':
+ optional: true
+
'@napi-rs/wasm-runtime@1.2.2(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)':
dependencies:
'@emnapi/core': 1.11.2
@@ -3045,109 +4077,242 @@ snapshots:
'@oxlint/binding-android-arm-eabi@1.77.0':
optional: true
- '@oxlint/binding-android-arm64@1.77.0':
+ '@oxlint/binding-android-arm64@1.77.0':
+ optional: true
+
+ '@oxlint/binding-darwin-arm64@1.77.0':
+ optional: true
+
+ '@oxlint/binding-darwin-x64@1.77.0':
+ optional: true
+
+ '@oxlint/binding-freebsd-x64@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm-gnueabihf@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm-musleabihf@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm64-gnu@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm64-musl@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-ppc64-gnu@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-riscv64-gnu@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-riscv64-musl@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-s390x-gnu@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-x64-gnu@1.77.0':
+ optional: true
+
+ '@oxlint/binding-linux-x64-musl@1.77.0':
+ optional: true
+
+ '@oxlint/binding-openharmony-arm64@1.77.0':
+ optional: true
+
+ '@oxlint/binding-win32-arm64-msvc@1.77.0':
+ optional: true
+
+ '@oxlint/binding-win32-ia32-msvc@1.77.0':
+ optional: true
+
+ '@oxlint/binding-win32-x64-msvc@1.77.0':
+ optional: true
+
+ '@oxlint/plugins@1.77.0': {}
+
+ '@quansync/fs@1.0.0':
+ dependencies:
+ quansync: 1.0.0
+
+ '@rolldown/binding-android-arm64@1.2.3':
+ optional: true
+
+ '@rolldown/binding-darwin-arm64@1.2.3':
+ optional: true
+
+ '@rolldown/binding-darwin-x64@1.2.3':
+ optional: true
+
+ '@rolldown/binding-freebsd-x64@1.2.3':
+ optional: true
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.2.3':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-gnu@1.2.3':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-musl@1.2.3':
+ optional: true
+
+ '@rolldown/binding-linux-ppc64-gnu@1.2.3':
+ optional: true
+
+ '@rolldown/binding-linux-s390x-gnu@1.2.3':
+ optional: true
+
+ '@rolldown/binding-linux-x64-gnu@1.2.3':
+ optional: true
+
+ '@rolldown/binding-linux-x64-musl@1.2.3':
+ optional: true
+
+ '@rolldown/binding-openharmony-arm64@1.2.3':
+ optional: true
+
+ '@rolldown/binding-win32-arm64-msvc@1.2.3':
+ optional: true
+
+ '@rolldown/binding-win32-x64-msvc@1.2.3':
+ optional: true
+
+ '@rolldown/pluginutils@1.0.1': {}
+
+ '@rollup/rollup-android-arm-eabi@4.62.4':
optional: true
- '@oxlint/binding-darwin-arm64@1.77.0':
+ '@rollup/rollup-android-arm64@4.62.4':
optional: true
- '@oxlint/binding-darwin-x64@1.77.0':
+ '@rollup/rollup-darwin-arm64@4.62.4':
optional: true
- '@oxlint/binding-freebsd-x64@1.77.0':
+ '@rollup/rollup-darwin-x64@4.62.4':
optional: true
- '@oxlint/binding-linux-arm-gnueabihf@1.77.0':
+ '@rollup/rollup-freebsd-arm64@4.62.4':
optional: true
- '@oxlint/binding-linux-arm-musleabihf@1.77.0':
+ '@rollup/rollup-freebsd-x64@4.62.4':
optional: true
- '@oxlint/binding-linux-arm64-gnu@1.77.0':
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.4':
optional: true
- '@oxlint/binding-linux-arm64-musl@1.77.0':
+ '@rollup/rollup-linux-arm-musleabihf@4.62.4':
optional: true
- '@oxlint/binding-linux-ppc64-gnu@1.77.0':
+ '@rollup/rollup-linux-arm64-gnu@4.62.4':
optional: true
- '@oxlint/binding-linux-riscv64-gnu@1.77.0':
+ '@rollup/rollup-linux-arm64-musl@4.62.4':
optional: true
- '@oxlint/binding-linux-riscv64-musl@1.77.0':
+ '@rollup/rollup-linux-loong64-gnu@4.62.4':
optional: true
- '@oxlint/binding-linux-s390x-gnu@1.77.0':
+ '@rollup/rollup-linux-loong64-musl@4.62.4':
optional: true
- '@oxlint/binding-linux-x64-gnu@1.77.0':
+ '@rollup/rollup-linux-ppc64-gnu@4.62.4':
optional: true
- '@oxlint/binding-linux-x64-musl@1.77.0':
+ '@rollup/rollup-linux-ppc64-musl@4.62.4':
optional: true
- '@oxlint/binding-openharmony-arm64@1.77.0':
+ '@rollup/rollup-linux-riscv64-gnu@4.62.4':
optional: true
- '@oxlint/binding-win32-arm64-msvc@1.77.0':
+ '@rollup/rollup-linux-riscv64-musl@4.62.4':
optional: true
- '@oxlint/binding-win32-ia32-msvc@1.77.0':
+ '@rollup/rollup-linux-s390x-gnu@4.62.4':
optional: true
- '@oxlint/binding-win32-x64-msvc@1.77.0':
+ '@rollup/rollup-linux-x64-gnu@4.62.4':
optional: true
- '@oxlint/plugins@1.77.0': {}
-
- '@quansync/fs@1.0.0':
- dependencies:
- quansync: 1.0.0
-
- '@rolldown/binding-android-arm64@1.2.3':
+ '@rollup/rollup-linux-x64-musl@4.62.4':
optional: true
- '@rolldown/binding-darwin-arm64@1.2.3':
+ '@rollup/rollup-openbsd-x64@4.62.4':
optional: true
- '@rolldown/binding-darwin-x64@1.2.3':
+ '@rollup/rollup-openharmony-arm64@4.62.4':
optional: true
- '@rolldown/binding-freebsd-x64@1.2.3':
+ '@rollup/rollup-win32-arm64-msvc@4.62.4':
optional: true
- '@rolldown/binding-linux-arm-gnueabihf@1.2.3':
+ '@rollup/rollup-win32-ia32-msvc@4.62.4':
optional: true
- '@rolldown/binding-linux-arm64-gnu@1.2.3':
+ '@rollup/rollup-win32-x64-gnu@4.62.4':
optional: true
- '@rolldown/binding-linux-arm64-musl@1.2.3':
+ '@rollup/rollup-win32-x64-msvc@4.62.4':
optional: true
- '@rolldown/binding-linux-ppc64-gnu@1.2.3':
- optional: true
+ '@shikijs/core@2.5.0':
+ dependencies:
+ '@shikijs/engine-javascript': 2.5.0
+ '@shikijs/engine-oniguruma': 2.5.0
+ '@shikijs/types': 2.5.0
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+ hast-util-to-html: 9.0.5
- '@rolldown/binding-linux-s390x-gnu@1.2.3':
- optional: true
+ '@shikijs/engine-javascript@2.5.0':
+ dependencies:
+ '@shikijs/types': 2.5.0
+ '@shikijs/vscode-textmate': 10.0.2
+ oniguruma-to-es: 3.1.1
- '@rolldown/binding-linux-x64-gnu@1.2.3':
- optional: true
+ '@shikijs/engine-oniguruma@2.5.0':
+ dependencies:
+ '@shikijs/types': 2.5.0
+ '@shikijs/vscode-textmate': 10.0.2
- '@rolldown/binding-linux-x64-musl@1.2.3':
- optional: true
+ '@shikijs/engine-oniguruma@3.23.0':
+ dependencies:
+ '@shikijs/types': 3.23.0
+ '@shikijs/vscode-textmate': 10.0.2
- '@rolldown/binding-openharmony-arm64@1.2.3':
- optional: true
+ '@shikijs/langs@2.5.0':
+ dependencies:
+ '@shikijs/types': 2.5.0
- '@rolldown/binding-win32-arm64-msvc@1.2.3':
- optional: true
+ '@shikijs/langs@3.23.0':
+ dependencies:
+ '@shikijs/types': 3.23.0
- '@rolldown/binding-win32-x64-msvc@1.2.3':
- optional: true
+ '@shikijs/themes@2.5.0':
+ dependencies:
+ '@shikijs/types': 2.5.0
- '@rolldown/pluginutils@1.0.1': {}
+ '@shikijs/themes@3.23.0':
+ dependencies:
+ '@shikijs/types': 3.23.0
+
+ '@shikijs/transformers@2.5.0':
+ dependencies:
+ '@shikijs/core': 2.5.0
+ '@shikijs/types': 2.5.0
+
+ '@shikijs/types@2.5.0':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+
+ '@shikijs/types@3.23.0':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+
+ '@shikijs/vscode-textmate@10.0.2': {}
'@simple-libs/child-process-utils@2.0.0':
dependencies:
@@ -3223,12 +4388,33 @@ snapshots:
'@types/estree@1.0.9': {}
+ '@types/hast@3.0.5':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/linkify-it@5.0.0': {}
+
+ '@types/markdown-it@14.1.2':
+ dependencies:
+ '@types/linkify-it': 5.0.0
+ '@types/mdurl': 2.0.0
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdurl@2.0.0': {}
+
'@types/node@12.20.55': {}
'@types/node@26.1.2':
dependencies:
undici-types: 8.3.0
+ '@types/unist@3.0.3': {}
+
+ '@types/web-bluetooth@0.0.21': {}
+
'@typescript/typescript-aix-ppc64@7.0.2':
optional: true
@@ -3289,6 +4475,8 @@ snapshots:
'@typescript/typescript-win32-x64@7.0.2':
optional: true
+ '@ungap/structured-clone@1.3.3': {}
+
'@unthrown/oxlint@5.1.0(oxlint@1.77.0)':
dependencies:
'@oxlint/plugins': 1.77.0
@@ -3304,6 +4492,11 @@ snapshots:
unthrown: 5.1.0
vitest: 4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(jiti@2.7.0)(yaml@2.9.0)
+ '@vitejs/plugin-vue@5.2.4(vite@6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))':
+ dependencies:
+ vite: 6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0)
+ vue: 3.5.41(typescript@6.0.3)
+
'@vitest/coverage-v8@4.1.10(vitest@4.1.10)':
dependencies:
'@bcoe/v8-coverage': 1.0.2
@@ -3327,13 +4520,13 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.1.1
- '@vitest/mocker@4.1.10(vite@8.2.0(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0))':
+ '@vitest/mocker@4.1.10(vite@6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0))':
dependencies:
'@vitest/spy': 4.1.10
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
- vite: 8.2.0(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0)
+ vite: 6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0)
'@vitest/pretty-format@4.1.10':
dependencies:
@@ -3359,6 +4552,105 @@ snapshots:
convert-source-map: 2.0.0
tinyrainbow: 3.1.1
+ '@vue/compiler-core@3.5.41':
+ dependencies:
+ '@babel/parser': 7.29.8
+ '@vue/shared': 3.5.41
+ entities: 7.0.1
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.41':
+ dependencies:
+ '@vue/compiler-core': 3.5.41
+ '@vue/shared': 3.5.41
+
+ '@vue/compiler-sfc@3.5.41':
+ dependencies:
+ '@babel/parser': 7.29.8
+ '@vue/compiler-core': 3.5.41
+ '@vue/compiler-dom': 3.5.41
+ '@vue/compiler-ssr': 3.5.41
+ '@vue/shared': 3.5.41
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.25
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.41':
+ dependencies:
+ '@vue/compiler-dom': 3.5.41
+ '@vue/shared': 3.5.41
+
+ '@vue/devtools-api@7.7.10':
+ dependencies:
+ '@vue/devtools-kit': 7.7.10
+
+ '@vue/devtools-kit@7.7.10':
+ dependencies:
+ '@vue/devtools-shared': 7.7.10
+ birpc: 2.9.0
+ hookable: 5.5.3
+ mitt: 3.0.1
+ perfect-debounce: 1.0.0
+ speakingurl: 14.0.1
+ superjson: 2.2.6
+
+ '@vue/devtools-shared@7.7.10':
+ dependencies:
+ rfdc: 1.4.1
+
+ '@vue/reactivity@3.5.41':
+ dependencies:
+ '@vue/shared': 3.5.41
+
+ '@vue/runtime-core@3.5.41':
+ dependencies:
+ '@vue/reactivity': 3.5.41
+ '@vue/shared': 3.5.41
+
+ '@vue/runtime-dom@3.5.41':
+ dependencies:
+ '@vue/reactivity': 3.5.41
+ '@vue/runtime-core': 3.5.41
+ '@vue/shared': 3.5.41
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.41':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.41
+ '@vue/runtime-dom': 3.5.41
+ '@vue/shared': 3.5.41
+
+ '@vue/shared@3.5.41': {}
+
+ '@vueuse/core@12.8.2(typescript@6.0.3)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.21
+ '@vueuse/metadata': 12.8.2
+ '@vueuse/shared': 12.8.2(typescript@6.0.3)
+ vue: 3.5.41(typescript@6.0.3)
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/integrations@12.8.2(focus-trap@7.8.0)(typescript@6.0.3)':
+ dependencies:
+ '@vueuse/core': 12.8.2(typescript@6.0.3)
+ '@vueuse/shared': 12.8.2(typescript@6.0.3)
+ vue: 3.5.41(typescript@6.0.3)
+ optionalDependencies:
+ focus-trap: 7.8.0
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/metadata@12.8.2': {}
+
+ '@vueuse/shared@12.8.2(typescript@6.0.3)':
+ dependencies:
+ vue: 3.5.41(typescript@6.0.3)
+ transitivePeerDependencies:
+ - typescript
+
'@yuku-codegen/binding-android-arm64@0.8.3':
optional: true
@@ -3440,6 +4732,23 @@ snapshots:
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
+ algoliasearch@5.56.0:
+ dependencies:
+ '@algolia/abtesting': 1.22.0
+ '@algolia/client-abtesting': 5.56.0
+ '@algolia/client-analytics': 5.56.0
+ '@algolia/client-common': 5.56.0
+ '@algolia/client-insights': 5.56.0
+ '@algolia/client-personalization': 5.56.0
+ '@algolia/client-query-suggestions': 5.56.0
+ '@algolia/client-search': 5.56.0
+ '@algolia/ingestion': 1.56.0
+ '@algolia/monitoring': 1.56.0
+ '@algolia/recommend': 5.56.0
+ '@algolia/requester-browser-xhr': 5.56.0
+ '@algolia/requester-fetch': 5.56.0
+ '@algolia/requester-node-http': 5.56.0
+
ansi-colors@4.1.3: {}
ansi-regex@5.0.1: {}
@@ -3468,10 +4777,18 @@ snapshots:
estree-walker: 3.0.3
js-tokens: 10.0.0
+ balanced-match@4.0.4: {}
+
better-path-resolve@1.0.0:
dependencies:
is-windows: 1.0.2
+ birpc@2.9.0: {}
+
+ brace-expansion@5.0.9:
+ dependencies:
+ balanced-match: 4.0.4
+
braces@3.0.3:
dependencies:
fill-range: 7.1.1
@@ -3480,8 +4797,14 @@ 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: {}
+
chardet@2.2.0: {}
cliui@9.0.1:
@@ -3490,6 +4813,8 @@ snapshots:
strip-ansi: 7.2.0
wrap-ansi: 9.0.2
+ comma-separated-tokens@2.0.3: {}
+
conventional-changelog-angular@9.2.1:
dependencies:
'@conventional-changelog/template': 1.2.1
@@ -3507,6 +4832,10 @@ snapshots:
cookie@2.0.1: {}
+ copy-anything@4.0.5:
+ dependencies:
+ is-what: 5.5.0
+
cosmiconfig-typescript-loader@6.3.0(@types/node@26.1.2)(cosmiconfig@9.0.2(typescript@7.0.2))(typescript@7.0.2):
dependencies:
'@types/node': 26.1.2
@@ -3529,11 +4858,17 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
+ csstype@3.2.3: {}
+
defu@6.1.7: {}
+ dequal@2.0.3: {}
+
detect-indent@6.1.0: {}
- detect-libc@2.1.2: {}
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
dir-glob@3.0.1:
dependencies:
@@ -3543,6 +4878,8 @@ snapshots:
optionalDependencies:
oxc-resolver: 11.24.2
+ emoji-regex-xs@1.0.0: {}
+
emoji-regex@10.6.0: {}
empathic@2.0.1: {}
@@ -3552,6 +4889,10 @@ snapshots:
ansi-colors: 4.1.3
strip-ansi: 6.0.1
+ entities@4.5.0: {}
+
+ entities@7.0.1: {}
+
env-paths@2.2.1: {}
error-ex@1.3.4:
@@ -3562,10 +4903,41 @@ snapshots:
es-toolkit@1.50.0: {}
+ esbuild@0.25.12:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.12
+ '@esbuild/android-arm': 0.25.12
+ '@esbuild/android-arm64': 0.25.12
+ '@esbuild/android-x64': 0.25.12
+ '@esbuild/darwin-arm64': 0.25.12
+ '@esbuild/darwin-x64': 0.25.12
+ '@esbuild/freebsd-arm64': 0.25.12
+ '@esbuild/freebsd-x64': 0.25.12
+ '@esbuild/linux-arm': 0.25.12
+ '@esbuild/linux-arm64': 0.25.12
+ '@esbuild/linux-ia32': 0.25.12
+ '@esbuild/linux-loong64': 0.25.12
+ '@esbuild/linux-mips64el': 0.25.12
+ '@esbuild/linux-ppc64': 0.25.12
+ '@esbuild/linux-riscv64': 0.25.12
+ '@esbuild/linux-s390x': 0.25.12
+ '@esbuild/linux-x64': 0.25.12
+ '@esbuild/netbsd-arm64': 0.25.12
+ '@esbuild/netbsd-x64': 0.25.12
+ '@esbuild/openbsd-arm64': 0.25.12
+ '@esbuild/openbsd-x64': 0.25.12
+ '@esbuild/openharmony-arm64': 0.25.12
+ '@esbuild/sunos-x64': 0.25.12
+ '@esbuild/win32-arm64': 0.25.12
+ '@esbuild/win32-ia32': 0.25.12
+ '@esbuild/win32-x64': 0.25.12
+
escalade@3.2.0: {}
esprima@4.0.1: {}
+ estree-walker@2.0.2: {}
+
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.9
@@ -3607,6 +4979,10 @@ snapshots:
locate-path: 5.0.0
path-exists: 4.0.0
+ focus-trap@7.8.0:
+ dependencies:
+ tabbable: 6.5.0
+
formatly@0.3.0:
dependencies:
fd-package-json: 2.0.0
@@ -3659,10 +5035,32 @@ snapshots:
has-flag@4.0.0: {}
+ hast-util-to-html@9.0.5:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@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.2.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hookable@5.5.3: {}
+
hookable@6.1.1: {}
html-escaper@2.0.2: {}
+ html-void-elements@3.0.0: {}
+
human-id@4.2.0: {}
iconv-lite@0.7.3:
@@ -3696,6 +5094,8 @@ snapshots:
dependencies:
better-path-resolve: 1.0.0
+ is-what@5.5.0: {}
+
is-windows@1.0.2: {}
isexe@2.0.0: {}
@@ -3799,56 +5199,11 @@ snapshots:
lefthook-windows-arm64: 2.1.10
lefthook-windows-x64: 2.1.10
- lightningcss-android-arm64@1.33.0:
- optional: true
-
- lightningcss-darwin-arm64@1.33.0:
- optional: true
-
- lightningcss-darwin-x64@1.33.0:
- optional: true
-
- lightningcss-freebsd-x64@1.33.0:
- optional: true
-
- lightningcss-linux-arm-gnueabihf@1.33.0:
- optional: true
-
- lightningcss-linux-arm64-gnu@1.33.0:
- optional: true
-
- lightningcss-linux-arm64-musl@1.33.0:
- optional: true
-
- lightningcss-linux-x64-gnu@1.33.0:
- optional: true
-
- lightningcss-linux-x64-musl@1.33.0:
- optional: true
-
- lightningcss-win32-arm64-msvc@1.33.0:
- optional: true
-
- lightningcss-win32-x64-msvc@1.33.0:
- optional: true
+ lines-and-columns@1.2.4: {}
- lightningcss@1.33.0:
+ linkify-it@5.0.2:
dependencies:
- detect-libc: 2.1.2
- optionalDependencies:
- lightningcss-android-arm64: 1.33.0
- lightningcss-darwin-arm64: 1.33.0
- lightningcss-darwin-x64: 1.33.0
- lightningcss-freebsd-x64: 1.33.0
- lightningcss-linux-arm-gnueabihf: 1.33.0
- lightningcss-linux-arm64-gnu: 1.33.0
- lightningcss-linux-arm64-musl: 1.33.0
- lightningcss-linux-x64-gnu: 1.33.0
- lightningcss-linux-x64-musl: 1.33.0
- lightningcss-win32-arm64-msvc: 1.33.0
- lightningcss-win32-x64-msvc: 1.33.0
-
- lines-and-columns@1.2.4: {}
+ uc.micro: 2.1.0
locate-path@5.0.0:
dependencies:
@@ -3856,6 +5211,8 @@ snapshots:
lodash.startcase@4.4.0: {}
+ lunr@2.3.9: {}
+
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -3870,19 +5227,75 @@ snapshots:
dependencies:
semver: 7.8.5
+ mark.js@8.11.1: {}
+
+ markdown-it@14.3.0:
+ dependencies:
+ argparse: 2.0.1
+ entities: 4.5.0
+ linkify-it: 5.0.2
+ mdurl: 2.1.0
+ punycode.js: 2.3.1
+ uc.micro: 2.1.0
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.3
+ 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
+
+ mdurl@2.1.0: {}
+
merge2@1.4.1: {}
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-encode@2.0.1: {}
+
+ 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-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
micromatch@4.0.8:
dependencies:
braces: 3.0.3
picomatch: 2.3.2
+ minimatch@10.2.6:
+ dependencies:
+ brace-expansion: 5.0.9
+
+ minisearch@7.2.0: {}
+
+ mitt@3.0.1: {}
+
mri@1.2.0: {}
nanoid@3.3.17: {}
obug@2.1.4: {}
+ oniguruma-to-es@3.1.1:
+ dependencies:
+ emoji-regex-xs: 1.0.0
+ regex: 6.1.0
+ regex-recursion: 6.0.2
+
outdent@0.5.0: {}
oxc-parser@0.142.0:
@@ -4017,6 +5430,8 @@ snapshots:
pathe@2.0.3: {}
+ perfect-debounce@1.0.0: {}
+
picocolors@1.1.1: {}
picomatch@2.3.2: {}
@@ -4031,8 +5446,14 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
+ preact@10.29.8: {}
+
prettier@2.8.8: {}
+ property-information@7.2.0: {}
+
+ punycode.js@2.3.1: {}
+
quansync@0.2.11: {}
quansync@1.0.0: {}
@@ -4048,6 +5469,16 @@ snapshots:
pify: 4.0.1
strip-bom: 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
+
require-from-string@2.0.2: {}
resolve-from@4.0.0: {}
@@ -4058,6 +5489,8 @@ snapshots:
reusify@1.1.0: {}
+ rfdc@1.4.1: {}
+
rolldown-plugin-dts@0.27.14(oxc-resolver@11.24.2)(rolldown@1.2.3)(typescript@7.0.2):
dependencies:
dts-resolver: 3.0.0(oxc-resolver@11.24.2)
@@ -4092,6 +5525,38 @@ snapshots:
'@rolldown/binding-win32-arm64-msvc': 1.2.3
'@rolldown/binding-win32-x64-msvc': 1.2.3
+ rollup@4.62.4:
+ dependencies:
+ '@types/estree': 1.0.9
+ optionalDependencies:
+ '@napi-rs/lzma-linux-x64-gnu': 1.5.1
+ '@rollup/rollup-android-arm-eabi': 4.62.4
+ '@rollup/rollup-android-arm64': 4.62.4
+ '@rollup/rollup-darwin-arm64': 4.62.4
+ '@rollup/rollup-darwin-x64': 4.62.4
+ '@rollup/rollup-freebsd-arm64': 4.62.4
+ '@rollup/rollup-freebsd-x64': 4.62.4
+ '@rollup/rollup-linux-arm-gnueabihf': 4.62.4
+ '@rollup/rollup-linux-arm-musleabihf': 4.62.4
+ '@rollup/rollup-linux-arm64-gnu': 4.62.4
+ '@rollup/rollup-linux-arm64-musl': 4.62.4
+ '@rollup/rollup-linux-loong64-gnu': 4.62.4
+ '@rollup/rollup-linux-loong64-musl': 4.62.4
+ '@rollup/rollup-linux-ppc64-gnu': 4.62.4
+ '@rollup/rollup-linux-ppc64-musl': 4.62.4
+ '@rollup/rollup-linux-riscv64-gnu': 4.62.4
+ '@rollup/rollup-linux-riscv64-musl': 4.62.4
+ '@rollup/rollup-linux-s390x-gnu': 4.62.4
+ '@rollup/rollup-linux-x64-gnu': 4.62.4
+ '@rollup/rollup-linux-x64-musl': 4.62.4
+ '@rollup/rollup-openbsd-x64': 4.62.4
+ '@rollup/rollup-openharmony-arm64': 4.62.4
+ '@rollup/rollup-win32-arm64-msvc': 4.62.4
+ '@rollup/rollup-win32-ia32-msvc': 4.62.4
+ '@rollup/rollup-win32-x64-gnu': 4.62.4
+ '@rollup/rollup-win32-x64-msvc': 4.62.4
+ fsevents: 2.3.3
+
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
@@ -4106,6 +5571,17 @@ snapshots:
shebang-regex@3.0.0: {}
+ shiki@2.5.0:
+ dependencies:
+ '@shikijs/core': 2.5.0
+ '@shikijs/engine-javascript': 2.5.0
+ '@shikijs/engine-oniguruma': 2.5.0
+ '@shikijs/langs': 2.5.0
+ '@shikijs/themes': 2.5.0
+ '@shikijs/types': 2.5.0
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+
siginfo@2.0.0: {}
signal-exit@4.1.0: {}
@@ -4116,11 +5592,15 @@ snapshots:
source-map-js@1.2.1: {}
+ space-separated-tokens@2.0.2: {}
+
spawndamnit@3.0.1:
dependencies:
cross-spawn: 7.0.6
signal-exit: 4.1.0
+ speakingurl@14.0.1: {}
+
sprintf-js@1.0.3: {}
stackback@0.0.2: {}
@@ -4138,6 +5618,11 @@ snapshots:
get-east-asian-width: 1.6.0
strip-ansi: 7.2.0
+ 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
@@ -4150,10 +5635,16 @@ snapshots:
strip-json-comments@5.0.3: {}
+ superjson@2.2.6:
+ dependencies:
+ copy-anything: 4.0.5
+
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
+ tabbable@6.5.0: {}
+
tagged-tag@1.0.0: {}
term-size@2.2.1: {}
@@ -4177,6 +5668,8 @@ snapshots:
tree-kill@1.2.2: {}
+ trim-lines@3.0.1: {}
+
tsdown@0.22.14(oxc-resolver@11.24.2)(typescript@7.0.2):
dependencies:
ansis: 4.3.1
@@ -4218,6 +5711,21 @@ snapshots:
dependencies:
tagged-tag: 1.0.0
+ typedoc-plugin-markdown@4.12.0(typedoc@0.28.20(typescript@6.0.3)):
+ dependencies:
+ typedoc: 0.28.20(typescript@6.0.3)
+
+ typedoc@0.28.20(typescript@6.0.3):
+ dependencies:
+ '@gerrit0/mini-shiki': 3.23.0
+ lunr: 2.3.9
+ markdown-it: 14.3.0
+ minimatch: 10.2.6
+ typescript: 6.0.3
+ yaml: 2.9.0
+
+ typescript@6.0.3: {}
+
typescript@7.0.2:
optionalDependencies:
'@typescript/typescript-aix-ppc64': 7.0.2
@@ -4241,6 +5749,8 @@ snapshots:
'@typescript/typescript-win32-arm64': 7.0.2
'@typescript/typescript-win32-x64': 7.0.2
+ uc.micro@2.1.0: {}
+
unbash@4.0.6: {}
unconfig-core@7.5.0:
@@ -4250,18 +5760,52 @@ snapshots:
undici-types@8.3.0: {}
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.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: {}
unthrown@5.1.0: {}
verkit@0.3.2: {}
- vite@8.2.0(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0):
+ 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@6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0):
dependencies:
- lightningcss: 1.33.0
+ esbuild: 0.25.12
+ fdir: 6.5.0(picomatch@4.0.5)
picomatch: 4.0.5
postcss: 8.5.25
- rolldown: 1.2.3
+ rollup: 4.62.4
tinyglobby: 0.2.17
optionalDependencies:
'@types/node': 26.1.2
@@ -4269,10 +5813,63 @@ snapshots:
jiti: 2.7.0
yaml: 2.9.0
+ vitepress@1.6.4(@algolia/client-search@5.56.0)(@types/node@26.1.2)(jiti@2.7.0)(postcss@8.5.25)(typescript@6.0.3)(yaml@2.9.0):
+ dependencies:
+ '@docsearch/css': 3.8.2
+ '@docsearch/js': 3.8.2(@algolia/client-search@5.56.0)
+ '@iconify-json/simple-icons': 1.2.93
+ '@shikijs/core': 2.5.0
+ '@shikijs/transformers': 2.5.0
+ '@shikijs/types': 2.5.0
+ '@types/markdown-it': 14.1.2
+ '@vitejs/plugin-vue': 5.2.4(vite@6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))
+ '@vue/devtools-api': 7.7.10
+ '@vue/shared': 3.5.41
+ '@vueuse/core': 12.8.2(typescript@6.0.3)
+ '@vueuse/integrations': 12.8.2(focus-trap@7.8.0)(typescript@6.0.3)
+ focus-trap: 7.8.0
+ mark.js: 8.11.1
+ minisearch: 7.2.0
+ shiki: 2.5.0
+ vite: 6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0)
+ vue: 3.5.41(typescript@6.0.3)
+ optionalDependencies:
+ postcss: 8.5.25
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/node'
+ - '@types/react'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - fuse.js
+ - idb-keyval
+ - jiti
+ - jwt-decode
+ - less
+ - lightningcss
+ - nprogress
+ - preact-render-to-string
+ - qrcode
+ - react
+ - react-dom
+ - sass
+ - sass-embedded
+ - search-insights
+ - sortablejs
+ - stylus
+ - sugarss
+ - terser
+ - tsx
+ - typescript
+ - universal-cookie
+ - yaml
+
vitest@4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(jiti@2.7.0)(yaml@2.9.0):
dependencies:
'@vitest/expect': 4.1.10
- '@vitest/mocker': 4.1.10(vite@8.2.0(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0))
+ '@vitest/mocker': 4.1.10(vite@6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0))
'@vitest/pretty-format': 4.1.10
'@vitest/runner': 4.1.10
'@vitest/snapshot': 4.1.10
@@ -4289,16 +5886,15 @@ snapshots:
tinyexec: 1.3.0
tinyglobby: 0.2.17
tinyrainbow: 3.1.1
- vite: 8.2.0(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0)
+ vite: 6.4.3(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.9.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 26.1.2
'@vitest/coverage-v8': 4.1.10(vitest@4.1.10)
transitivePeerDependencies:
- - '@vitejs/devtools'
- - esbuild
- jiti
- less
+ - lightningcss
- msw
- sass
- sass-embedded
@@ -4308,6 +5904,16 @@ snapshots:
- tsx
- yaml
+ vue@3.5.41(typescript@6.0.3):
+ dependencies:
+ '@vue/compiler-dom': 3.5.41
+ '@vue/compiler-sfc': 3.5.41
+ '@vue/runtime-dom': 3.5.41
+ '@vue/server-renderer': 3.5.41
+ '@vue/shared': 3.5.41
+ optionalDependencies:
+ typescript: 6.0.3
+
walk-up-path@4.0.0: {}
which@2.0.2:
@@ -4380,3 +5986,5 @@ snapshots:
'@yuku-parser/binding-win32-x64': 0.8.3
zod@4.4.3: {}
+
+ zwitch@2.0.4: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index e21faeb..50cfe30 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -6,12 +6,15 @@ strictPeerDependencies: true
packages:
- packages/*
+ - docs
catalog:
"@btravstack/commitlint": 0.1.0
"@btravstack/lefthook": 0.1.1
"@btravstack/oxlint": 0.2.1
+ "@btravstack/theme": 1.7.0
"@btravstack/tsconfig": 0.2.0
+ "@btravstack/typedoc": 0.1.0
"@changesets/cli": 2.31.1
"@commitlint/cli": 21.2.1
# Pinned to the exact prerelease the package's design doc measured
@@ -30,6 +33,8 @@ catalog:
oxlint: 1.77.0
tsdown: 0.22.14
turbo: 2.10.8
+ typedoc: 0.28.20
+ typedoc-plugin-markdown: 4.12.0
# 7.0.2 is the exact release the package's design doc measured the
# construction-seal declaration-emit behaviour against (zero TS4020, `declare
# const CtorKey: unique symbol` carried module-local into the emitted
@@ -37,11 +42,57 @@ catalog:
typescript: 7.0.2
unthrown: 5.1.0
"@vitest/coverage-v8": 4.1.10
+ vitepress: 1.6.4
vitest: 4.1.10
zod: 4.4.3
+catalogs:
+ # TypeDoc's own toolchain, deliberately NOT the default catalog's TypeScript.
+ # `typescript: 7.0.2` above is the native port: it ships `lib/tsc.js` (a thin
+ # launcher) and no `typescript.js`, so the compiler API TypeDoc is written
+ # against does not exist there — measured, and the reason `typedoc` runs from
+ # the `docs` workspace rather than from `packages/entity` as it does in the
+ # other btravstack repos. 6.0.3 is the last release carrying the JS API, and
+ # is what `typedoc@0.28`'s peer range allows.
+ typedoc:
+ typescript: 6.0.3
+
+# Force patched versions of vulnerable transitive dependencies. Every advisory
+# below reaches us only through dev/build tooling (never the published package's
+# runtime deps, which are the three peers). Each selector is version-scoped so
+# only the affected line moves and unrelated lines are untouched.
+overrides:
+ # GHSA-fx2h-pf6j-xcff (High, `server.fs.deny` bypass on Windows alternate data
+ # streams) plus three moderates on the same line: GHSA path traversal in
+ # optimized deps, launch-editor NTLMv2 disclosure, and the esbuild dev-server
+ # advisory reached through vite's own dependency. All four are dev-server-only;
+ # the docs ship as static HTML. They reach us via docs > vitepress > vite:
+ # vitepress 1.6.x pins `vite ^5.4.14`, and the 5.x line has no patched release,
+ # so lift any pre-6.4.3 vite to 6.4.3 (the first fixed version). That also
+ # drags esbuild up to a patched 0.25.x. `vitepress build` and `vitepress dev`
+ # are both verified against it.
+ #
+ # Side effect, measured and accepted: vitest's own vite was resolving to 8.2.0,
+ # and pnpm dedupes it onto this 6.4.3 rather than keeping a second copy —
+ # vitest 4.1.10 declares `vite: "^6.0.0 || ^7.0.0 || ^8.0.0"`, so 6.4.3 is
+ # inside its supported range and the suite passes on it. Path-scoped selectors
+ # (`vitepress>vite`) were tried and produce the byte-identical tree, because
+ # the dedupe is resolution, not the selector — so the simpler form is kept.
+ # Pinning vitest's vite apart would mean an inline `vite` devDependency on the
+ # library package for a purely transitive concern; not worth it.
+ "vite@<6.4.3": "6.4.3"
+
+peerDependencyRules:
+ ignoreMissing:
+ # Optional analytics peer of VitePress's bundled Algolia DocSearch.
+ - search-insights
+
minimumReleaseAgeExclude:
- knip@6.32.0
+ # First-party shared config (@btravstack scope): adopt immediately, skip any
+ # registry-maturity delay — these are published from btravstack repos.
+ - "@btravstack/theme"
+ - "@btravstack/typedoc"
allowBuilds:
esbuild: true
diff --git a/turbo.json b/turbo.json
index d62d1c7..3a641c3 100644
--- a/turbo.json
+++ b/turbo.json
@@ -24,6 +24,10 @@
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
+ },
+ "@btravstack/entity-docs#build": {
+ "inputs": ["$TURBO_DEFAULT$", "../packages/entity/src/**"],
+ "outputs": [".vitepress/dist/**", "api/entity/**"]
}
}
}