From 3623bb4fe1cc911d62be14df80b98ccc45492912 Mon Sep 17 00:00:00 2001 From: leynos Date: Sat, 18 Jul 2026 00:22:30 +0200 Subject: [PATCH 1/2] Document the remaining undocumented src declarations Prepare for a zero-tolerance TypeDoc documentation gate: add JSDoc to the nineteen declarations TypeDoc flags across the app shell, the display-mode provider, the observability logger, the application state machine unions, and the root props. Reflow the state-machine union members to multiline so each variant's discriminant can carry its own comment (shapes unchanged), and convert the two application barrel headers from `@file` (unknown to TypeDoc) to the `@module` form. --- src/app/layout/mobile-shell.tsx | 1 + src/app/observability/logger.ts | 4 +++ src/app/providers/display-mode-provider.tsx | 15 +++++++++++ src/app/routes/app-routes.tsx | 1 + src/application/index.ts | 4 ++- src/application/machines/app.machine.ts | 30 ++++++++++++++++----- src/application/machines/index.ts | 4 ++- src/main.tsx | 2 ++ 8 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/app/layout/mobile-shell.tsx b/src/app/layout/mobile-shell.tsx index c677208..79dc12a 100644 --- a/src/app/layout/mobile-shell.tsx +++ b/src/app/layout/mobile-shell.tsx @@ -4,6 +4,7 @@ import type { JSX, ReactNode } from "react"; import { useDisplayMode } from "../providers/display-mode-provider"; +/** Props accepted by {@link MobileShell}. */ export interface MobileShellProps { /** Main content rendered inside the framed device shell. */ children: ReactNode; diff --git a/src/app/observability/logger.ts b/src/app/observability/logger.ts index bf98069..64e3aa0 100644 --- a/src/app/observability/logger.ts +++ b/src/app/observability/logger.ts @@ -88,9 +88,13 @@ function log(level: LogLevel, message: string, context?: Record * the `TelemetrySink` port). */ export const appLogger = { + /** Logs a debug-level entry; use for verbose diagnostic detail. */ debug: (message: string, context?: Record) => log("debug", message, context), + /** Logs an info-level entry; use for routine operational events. */ info: (message: string, context?: Record) => log("info", message, context), + /** Logs a warn-level entry; use for recoverable, unexpected conditions. */ warn: (message: string, context?: Record) => log("warn", message, context), + /** Logs an error-level entry, optionally attaching the causing error. */ error: (message: string, context?: Record, error?: unknown) => log("error", message, context, error), }; diff --git a/src/app/providers/display-mode-provider.tsx b/src/app/providers/display-mode-provider.tsx index 90baedb..bfb4ec4 100644 --- a/src/app/providers/display-mode-provider.tsx +++ b/src/app/providers/display-mode-provider.tsx @@ -7,6 +7,10 @@ import { appLogger } from "../observability/logger"; const STORAGE_KEY = "vibecoder.displayMode"; +/** + * Layout mode for the shell: `"hosted"` frames content in a fixed mobile + * viewport, `"full-browser"` fills the available browser window. + */ export type DisplayMode = "hosted" | "full-browser"; const DESKTOP_DEFAULT_MODE: DisplayMode = "hosted"; @@ -80,10 +84,17 @@ function detectPreferredDisplayMode(): DisplayMode { return DESKTOP_DEFAULT_MODE; } +/** Props accepted by {@link DisplayModeProvider}. */ export interface DisplayModeProviderProps { + /** Subtree that gains access to the display mode context. */ children: ReactNode; } +/** + * Supplies the current {@link DisplayMode} to descendants, seeding it from + * `localStorage` or a media-query-based default, and persisting subsequent + * user choices back to `localStorage`. + */ export function DisplayModeProvider({ children }: DisplayModeProviderProps): JSX.Element { const storedMode = readStoredMode(); const [mode, setModeState] = useState(() => { @@ -176,6 +187,10 @@ export function DisplayModeProvider({ children }: DisplayModeProviderProps): JSX return {children}; } +/** + * Reads the {@link DisplayModeContextValue} from the nearest + * {@link DisplayModeProvider}. Throws if called outside one. + */ export function useDisplayMode(): DisplayModeContextValue { const context = useContext(DisplayModeContext); if (!context) { diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index 887281c..b0c8b45 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -40,6 +40,7 @@ declare module "@tanstack/react-router" { } } +/** Props accepted by {@link AppRoutes}. */ export interface AppRoutesProps { /** * Optional router instance. Tests can supply their own router to control the diff --git a/src/application/index.ts b/src/application/index.ts index c4dd019..186f2dd 100644 --- a/src/application/index.ts +++ b/src/application/index.ts @@ -1,5 +1,5 @@ /** - * @file Application layer barrel. + * Application layer barrel. * * The application layer wires domain services together into use-case * implementations, hosts XState machines for workflow orchestration, and @@ -8,6 +8,8 @@ * * See `docs/adr-002-adopt-hexagonal-architecture-for-domain-boundaries.md` * and `docs/adr-003-use-xstate-for-workflow-orchestration.md` for rationale. + * + * @module */ export type { AppMachineAction, AppMachineEvent, AppMachineStateValue } from "./machines"; diff --git a/src/application/machines/app.machine.ts b/src/application/machines/app.machine.ts index 6517048..77e7a80 100644 --- a/src/application/machines/app.machine.ts +++ b/src/application/machines/app.machine.ts @@ -24,9 +24,18 @@ import { createMachine } from "xstate"; * Events accepted by the application boot workflow machine. */ export type AppMachineEvent = - | { readonly type: "BOOT_READY" } - | { readonly type: "BOOT_FAILED" } - | { readonly type: "RETRY_BOOT" }; + | { + /** Signals that the boot sequence completed successfully. */ + readonly type: "BOOT_READY"; + } + | { + /** Signals that the boot sequence failed. */ + readonly type: "BOOT_FAILED"; + } + | { + /** Requests a retry of a failed boot sequence. */ + readonly type: "RETRY_BOOT"; + }; /** * State values exposed by the application boot workflow machine. @@ -37,9 +46,18 @@ export type AppMachineStateValue = "booting" | "failed" | "title"; * Named actions emitted by boot workflow transitions for adapters to observe. */ export type AppMachineAction = - | { readonly type: "recordBootFailed" } - | { readonly type: "recordBootRetryRequested" } - | { readonly type: "recordBootSucceeded" }; + | { + /** Emitted when a boot attempt fails. */ + readonly type: "recordBootFailed"; + } + | { + /** Emitted when a retry is requested after a boot failure. */ + readonly type: "recordBootRetryRequested"; + } + | { + /** Emitted when a boot attempt succeeds. */ + readonly type: "recordBootSucceeded"; + }; /** * XState machine that models boot success, boot failure, and retry reachability. diff --git a/src/application/machines/index.ts b/src/application/machines/index.ts index 867a9a3..cbcf1f3 100644 --- a/src/application/machines/index.ts +++ b/src/application/machines/index.ts @@ -1,9 +1,11 @@ /** - * @file Application machine exports. + * Application machine exports. * * This barrel keeps inbound adapters and tests on the accepted * `src/application/machines/` boundary without exposing future machine * internals before their roadmap slices exist. + * + * @module */ export type { AppMachineAction, AppMachineEvent, AppMachineStateValue } from "./app.machine"; diff --git a/src/main.tsx b/src/main.tsx index 62a60fc..5efadc5 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -36,7 +36,9 @@ export function LoadingBackdrop(): JSX.Element { /** Props accepted by the {@link AppRoot} bootstrap wrapper. */ export interface AppRootProps { + /** Component to render inside the Suspense boundary; defaults to {@link App}. */ readonly AppComponent?: ComponentType; + /** Suspense fallback; defaults to {@link LoadingBackdrop} when omitted. */ readonly fallback?: ReactNode; } From 9923f1e893c72cb7b2432209de1fd81a9af1b716 Mon Sep 17 00:00:00 2001 From: leynos Date: Sat, 18 Jul 2026 00:22:30 +0200 Subject: [PATCH 2/2] Add a zero-tolerance TypeDoc documentation gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `docs:check` to the `test:all` aggregate (after `check:types`) and expose it as `make docs-check`: TypeDoc's `notDocumented` validation over `src` (`entryPointStrategy: "expand"`, `emit: "none"`, validation warnings as errors), configured by `typedoc.json` with a scoped `tsconfig.typedoc.json` (`skipLibCheck`, `src` only — the repository's `check:types` passes `--skipLibCheck` on the command line, which TypeDoc cannot see). Generated declarations, `*.gen.*`, `__generated__`, tests, and fixtures are excluded. The gate requires 100% documentation of the surface, reports the qualified name of each undocumented declaration, and writes no artefacts. The semantic-lint workflow gains a `bun run docs:check` step so CI reaches the gate. Also bump the stale transitive `playwright-core` from 1.59.1 to 1.61.1 so it deduplicates against `playwright@1.61.1` — the duplicated package made `check:types` (and therefore `test:all`) fail before this branch. --- .github/workflows/semantic-lint.yml | 1 + Makefile | 7 +++- bun.lock | 56 +++++++++++++++++++++++------ package.json | 5 ++- tsconfig.typedoc.json | 7 ++++ typedoc.json | 49 +++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 tsconfig.typedoc.json create mode 100644 typedoc.json diff --git a/.github/workflows/semantic-lint.yml b/.github/workflows/semantic-lint.yml index b08b155..657173f 100644 --- a/.github/workflows/semantic-lint.yml +++ b/.github/workflows/semantic-lint.yml @@ -17,4 +17,5 @@ jobs: - name: Enforce Oxford spelling run: make spelling - run: bun install --frozen-lockfile + - run: bun run docs:check - run: bun semantic diff --git a/Makefile b/Makefile index f49d5f0..b9b99ed 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ SPELLING_HELPER_PYTEST = PYTHONPATH=scripts $(UV_ENV) $(UV) run --no-project \ --python 3.14 --with pathspec==$(PATHSPEC_VERSION) --with pytest==9.0.2 \ --with pytest-cov==7.0.0 python -m pytest -.PHONY: check-fmt typecheck lint test spelling spelling-config \ +.PHONY: check-fmt typecheck docs-check lint test spelling spelling-config \ spelling-config-write spelling-phrase-check spelling-helper-test check-fmt: @@ -24,6 +24,11 @@ check-fmt: typecheck: bun check:types +# Zero-tolerance documentation gate: TypeDoc's notDocumented validation over +# src (typedoc.json); also runs inside `bun test:all`. Emits no artefacts. +docs-check: + bun run docs:check + lint: bun lint diff --git a/bun.lock b/bun.lock index 95b9c07..a5990d5 100644 --- a/bun.lock +++ b/bun.lock @@ -25,6 +25,7 @@ "i18next-browser-languagedetector": "^8.2.0", "i18next-fluent": "^2.0.0", "i18next-fluent-backend": "^1.0.0", + "playwright-core": "^1.61.1", "react": "^19.2.7", "react-dom": "^19.2.7", "react-i18next": "^17.0.9", @@ -59,6 +60,7 @@ "style-dictionary": "^5.5.0", "stylelint": "^17.14.0", "stylelint-declaration-strict-value": "^1.10.11", + "typedoc": "^0.28.20", "typescript": "^6.0.3", "vite": "^8.1.4", "vitest": "^4.1.10", @@ -200,6 +202,8 @@ "@fluent/syntax": ["@fluent/syntax@0.19.0", "", {}, "sha512-5D2qVpZrgpjtqU4eNOcWGp1gnUCgjfM+vKGE2y03kKN6z5EBhtx0qdRFbg8QuNNj8wXNoX93KJoYb+NqoxswmQ=="], + "@gerrit0/mini-shiki": ["@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" } }, "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg=="], + "@getgrit/cli": ["@getgrit/cli@0.1.0-alpha.1743007075", "", { "dependencies": { "axios": "^1.7.5", "axios-proxy-builder": "^0.1.2", "console.table": "^0.10.0", "detect-libc": "^2.0.3", "rimraf": "^5.0.8", "tar": "^7.4.3" }, "bin": { "grit": "run-grit.js" } }, "sha512-IvAa0QPrgiEQCjtWPpNucvnLUW7l6uR5P55tBC/NlIl36vZzoffLsEcQSIHR9gJmyURbCFcvb+Oaq33Z8WlOWA=="], "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], @@ -406,6 +410,16 @@ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], + + "@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="], + + "@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], + + "@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + "@sinclair/typebox": ["@sinclair/typebox@0.27.10", "", {}, "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA=="], "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], @@ -478,12 +492,16 @@ "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="], + "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], "@types/react": ["@types/react@19.2.17", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw=="], "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + "@types/whatwg-mimetype": ["@types/whatwg-mimetype@3.0.2", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="], "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], @@ -536,7 +554,7 @@ "axios-proxy-builder": ["axios-proxy-builder@0.1.2", "", { "dependencies": { "tunnel": "^0.0.6" } }, "sha512-6uBVsBZzkB3tCC8iyx59mCjQckhB8+GQrI9Cop8eC7ybIsvs/KtnNgEBfRMSEa7GqK2VBGUzgjNYMdPIfotyPA=="], - "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], @@ -544,7 +562,7 @@ "bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="], - "brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], + "brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], @@ -878,22 +896,30 @@ "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + "linkify-it": ["linkify-it@5.0.2", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q=="], + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], "lodash.truncate": ["lodash.truncate@4.4.2", "", {}, "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw=="], "lru-cache": ["lru-cache@11.5.1", "", {}, "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A=="], + "lunr": ["lunr@2.3.9", "", {}, "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="], + "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "markdown-it": ["markdown-it@14.3.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.5.0", "linkify-it": "^5.0.2", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "mathml-tag-names": ["mathml-tag-names@4.0.0", "", {}, "sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ=="], "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], + "mdurl": ["mdurl@2.0.0", "", {}, "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="], + "memfs": ["memfs@4.57.2", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.2", "@jsonjoy.com/fs-fsa": "4.57.2", "@jsonjoy.com/fs-node": "4.57.2", "@jsonjoy.com/fs-node-builtins": "4.57.2", "@jsonjoy.com/fs-node-to-fsa": "4.57.2", "@jsonjoy.com/fs-node-utils": "4.57.2", "@jsonjoy.com/fs-print": "4.57.2", "@jsonjoy.com/fs-snapshot": "4.57.2", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" } }, "sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ=="], "meow": ["meow@14.1.0", "", {}, "sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw=="], @@ -908,7 +934,7 @@ "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="], - "minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], @@ -960,7 +986,7 @@ "playwright": ["playwright@1.61.1", "", { "dependencies": { "playwright-core": "1.61.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ=="], - "playwright-core": ["playwright-core@1.59.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg=="], + "playwright-core": ["playwright-core@1.61.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg=="], "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], @@ -982,6 +1008,8 @@ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], + "pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], "qified": ["qified@0.10.1", "", { "dependencies": { "hookified": "^2.1.1" } }, "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA=="], @@ -1122,8 +1150,12 @@ "tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="], + "typedoc": ["typedoc@0.28.20", "", { "dependencies": { "@gerrit0/mini-shiki": "^3.23.0", "lunr": "^2.3.9", "markdown-it": "^14.3.0", "minimatch": "^10.2.5", "yaml": "^2.9.0" }, "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" }, "bin": { "typedoc": "bin/typedoc" } }, "sha512-uSKqkh8Cr48vllnEy+jdaAgOeR6Y+QCBW7usgUsKj7gJEfR7stw9U/fE49LBnj2tPRKPY0c0EBJSWe9Appmplg=="], + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + "uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="], + "undici": ["undici@7.28.0", "", {}, "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA=="], "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], @@ -1184,6 +1216,8 @@ "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + "@bundled-es-modules/glob/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], @@ -1220,6 +1254,8 @@ "data-urls/whatwg-mimetype": ["whatwg-mimetype@5.0.0", "", {}, "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw=="], + "glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + "i18next-fluent/@fluent/bundle": ["@fluent/bundle@0.13.0", "", {}, "sha512-Q3XQSoeCvptsWXdu4H3pJZLp45FX8JnhQ7A9OV9w6dU+czKJnuKJkC5xLv19N0OG/NRnVFKqhcQBrx+IWAk09g=="], "jest-axe/axe-core": ["axe-core@4.10.2", "", {}, "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w=="], @@ -1230,6 +1266,8 @@ "jsdom/whatwg-mimetype": ["whatwg-mimetype@5.0.0", "", {}, "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw=="], + "markdown-it/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], "parse5/entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="], @@ -1240,8 +1278,6 @@ "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - "playwright/playwright-core": ["playwright-core@1.61.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg=="], - "qified/hookified": ["hookified@2.2.0", "", {}, "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA=="], "slice-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], @@ -1278,8 +1314,6 @@ "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "@bundled-es-modules/glob/glob/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], - "@bundled-es-modules/glob/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], @@ -1294,6 +1328,8 @@ "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], + "jest-diff/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], "jest-matcher-utils/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], @@ -1302,8 +1338,6 @@ "wrap-ansi/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - "@bundled-es-modules/glob/glob/minimatch/brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="], - - "@bundled-es-modules/glob/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], } } diff --git a/package.json b/package.json index b6acc5b..9ac0191 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "fmt": "bunx biome format --write src tests tools scripts package.json biome.jsonc bunfig.toml", "lint": "bunx biome ci src tests tools", "check:types": "tsc --noEmit --skipLibCheck", + "docs:check": "typedoc --options typedoc.json", "test": "bun test --preload ./tests/setup-happy-dom.ts --preload ./tests/setup-snapshot-guard.ts", "test:a11y": "vitest --run --config vitest.a11y.config.ts", "test:a11y:watch": "vitest --watch --config vitest.a11y.config.ts", @@ -24,7 +25,7 @@ "lint:class-duplicates": "bun run scripts/find-near-duplicate-classes.ts", "lint:hardcoded-strings": "bun run scripts/check-hardcoded-strings.ts", "lint:imports": "bun run scripts/lint-import-boundaries.ts", - "test:all": "bun lint && bun check:types && bun test && bun run test:a11y && bun run lint:ftl-vars && bun run semantic && bun test:e2e", + "test:all": "bun lint && bun check:types && bun run docs:check && bun test && bun run test:a11y && bun run lint:ftl-vars && bun run semantic && bun test:e2e", "ff": "bunx --bun @tailwindcss/cli --input src/index.css --output tmp/tailwind.css --verbose && rm -f tmp/tailwind.css && bun run test:all" }, "dependencies": { @@ -48,6 +49,7 @@ "i18next-browser-languagedetector": "^8.2.0", "i18next-fluent": "^2.0.0", "i18next-fluent-backend": "^1.0.0", + "playwright-core": "^1.61.1", "react": "^19.2.7", "react-dom": "^19.2.7", "react-i18next": "^17.0.9", @@ -82,6 +84,7 @@ "style-dictionary": "^5.5.0", "stylelint": "^17.14.0", "stylelint-declaration-strict-value": "^1.10.11", + "typedoc": "^0.28.20", "typescript": "^6.0.3", "vite": "^8.1.4", "vitest": "^4.1.10" diff --git a/tsconfig.typedoc.json b/tsconfig.typedoc.json new file mode 100644 index 0000000..95016c9 --- /dev/null +++ b/tsconfig.typedoc.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "skipLibCheck": true + }, + "include": ["src"] +} diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..7677f5c --- /dev/null +++ b/typedoc.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://typedoc.org/schema.json", + + "tsconfig": "tsconfig.typedoc.json", + "entryPoints": ["src"], + "entryPointStrategy": "expand", + + "exclude": [ + "**/*.d.ts", + "**/*.gen.*", + "**/*.generated.*", + "**/__generated__/**", + "**/tests/**", + "**/test/**", + "**/fixtures/**" + ], + + "emit": "none", + "commentStyle": "jsdoc", + + "excludeExternals": true, + "excludeInternal": true, + "excludePrivate": true, + "excludeProtected": true, + + "validation": { + "notDocumented": true, + "notExported": false, + "invalidLink": false, + "invalidPath": false, + "rewrittenLink": false, + "unusedMergeModuleWith": false + }, + + "requiredToBeDocumented": [ + "Enum", + "EnumMember", + "Variable", + "Function", + "Class", + "Interface", + "Property", + "Method", + "Accessor", + "TypeAlias" + ], + + "treatValidationWarningsAsErrors": true +}