diff --git a/AGENTS.md b/AGENTS.md index 80d49b3..7d6a430 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -148,7 +148,7 @@ clarity, strictness, and reproducibility goals used elsewhere in this guide. - **ESM-first with a documented CLI exception**: Source modules and the published library surface are expected to be ESM. This repository retains a - CommonJS build artifact for the Node CLI because `bin/start.cjs` requires + CommonJS build artefact for the Node CLI because `bin/start.cjs` requires `../dist/index.cjs` so it can run under Node without transpilation. Treat that CommonJS output as a narrow operational exception, not as the default module model. diff --git a/Makefile b/Makefile index 7d53254..840c6b1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all check-fmt typecheck lint test build clean generate markdownlint \ +.PHONY: all check-fmt typecheck docs-check lint test build clean generate markdownlint \ nixie spelling spelling-helper-test MDLINT ?= markdownlint-cli2 @@ -8,7 +8,7 @@ TYPOS_VERSION ?= 1.48.0 TYPOS = $(UV) tool run typos@$(TYPOS_VERSION) XARGS_R := $(shell if xargs --help 2>&1 | grep -q '\\-r'; then printf -- '-r'; fi) -all: check-fmt typecheck lint test spelling +all: check-fmt typecheck docs-check lint test spelling check-fmt: bun node_modules/@biomejs/biome/bin/biome check --linter-enabled=false --assist-enabled=false . @@ -16,6 +16,12 @@ check-fmt: typecheck: bun run check:types +# Zero-tolerance documentation gate: TypeDoc's notDocumented validation over +# the package entry point (typedoc.json). Runs after typecheck so the +# generated GraphQL types already exist. Emits no documentation artefacts. +docs-check: + bun run docs:check + lint: bun run lint diff --git a/bun.lock b/bun.lock index 91dbc77..c050689 100644 --- a/bun.lock +++ b/bun.lock @@ -28,6 +28,7 @@ "fast-check": "^4.8.0", "publint": "^0.3.21", "tsdown": "^0.22.3", + "typedoc": "^0.28.20", "typescript": "^6.0.3", }, }, @@ -129,6 +130,8 @@ "@fastify/busboy": ["@fastify/busboy@3.2.0", "", {}, "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA=="], + "@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=="], + "@graphql-codegen/add": ["@graphql-codegen/add@7.0.1", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^7.0.1", "tslib": "^2.8.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-kWw6RMu9ysBw1wcgcgf9mOnswc5M3ekOApDTiaJC/UZNTEYins01srZHYTP7z3P/WlGGC844BRtjwh3U2kNd/A=="], "@graphql-codegen/cli": ["@graphql-codegen/cli@7.1.3", "", { "dependencies": { "@babel/generator": "^7.18.13", "@babel/template": "^7.18.10", "@babel/types": "^7.18.13", "@graphql-codegen/client-preset": "^6.0.1", "@graphql-codegen/core": "^6.1.0", "@graphql-codegen/plugin-helpers": "^7.0.1", "@graphql-tools/apollo-engine-loader": "^8.0.28", "@graphql-tools/code-file-loader": "^8.1.28", "@graphql-tools/git-loader": "^8.0.32", "@graphql-tools/github-loader": "^9.0.6", "@graphql-tools/graphql-file-loader": "^8.1.11", "@graphql-tools/json-file-loader": "^8.0.26", "@graphql-tools/load": "^8.1.8", "@graphql-tools/merge": "^9.0.6", "@graphql-tools/url-loader": "^9.0.6", "@graphql-tools/utils": "^11.0.0", "@inquirer/prompts": "^8.3.2", "@whatwg-node/fetch": "^0.10.0", "chalk": "^5.6.0", "cosmiconfig": "^9.0.0", "debounce": "^3.0.0", "detect-indent": "^7.0.0", "graphql-config": "^5.1.6", "is-glob": "^4.0.1", "jiti": "^2.3.0", "json-to-pretty-yaml": "^1.2.2", "listr2": "^10.2.1", "log-symbols": "^7.0.0", "micromatch": "^4.0.5", "shell-quote": "^1.7.3", "string-env-interpolation": "^1.0.1", "ts-log": "^3.0.0", "tslib": "^2.4.0", "yaml": "^2.3.1", "yargs": "^18.0.0" }, "peerDependencies": { "@parcel/watcher": "^2.1.0", "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "optionalPeers": ["@parcel/watcher"], "bin": { "gql-gen": "esm/bin.js", "graphql-codegen": "esm/bin.js", "graphql-codegen-cjs": "cjs/bin.js", "graphql-codegen-esm": "esm/bin.js", "graphql-code-generator": "esm/bin.js" } }, "sha512-mMYwpvpqJjjHoA/c6HBjdlbT8JqFC6W85RB80tpHACapufBnLlyNtYHYeOYAoUuU1n3cGQi1if1pKHnjLgS/eQ=="], @@ -319,6 +322,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=="], + "@simulacrum/foundation-simulator": ["@simulacrum/foundation-simulator@0.8.0", "", { "dependencies": { "ajv-formats": "^3.0.1", "cors": "^2.8.6", "defu": "^6.1.7", "express": "^5.2.1", "fdir": "^6.5.0", "http-proxy-middleware": "^3.0.5", "openapi-backend": "^5.17.0", "starfx": "^0.16.1" } }, "sha512-zTaJR0eC02uep1sII6jQfLtfTgwhWecQL1hPA672o6l7OW9jnCJDDkPYhVD/xNRNStUoIooccwMJaciPRMeEJw=="], "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], @@ -333,6 +346,8 @@ "@types/express-serve-static-core": ["@types/express-serve-static-core@5.1.1", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A=="], + "@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="], + "@types/http-errors": ["@types/http-errors@2.0.5", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="], "@types/jsesc": ["@types/jsesc@2.5.1", "", {}, "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw=="], @@ -349,6 +364,8 @@ "@types/serve-static": ["@types/serve-static@2.2.0", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*" } }, "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ=="], + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], "@whatwg-node/disposablestack": ["@whatwg-node/disposablestack@0.0.6", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.6.3" } }, "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw=="], @@ -489,6 +506,8 @@ "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], @@ -657,6 +676,8 @@ "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=="], + "listr2": ["listr2@10.2.2", "", { "dependencies": { "cli-truncate": "^5.2.0", "eventemitter3": "^5.0.4", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^10.0.0" } }, "sha512-JtNtbZj8q5BnDMR7trpwvwk3RIrANtIVzEUm8w7amp6xelLgyuq+4WZoTH913XaQAoH/cNdYhaNzBPA2U3xbDw=="], "lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="], @@ -673,10 +694,16 @@ "lru-cache": ["lru-cache@11.3.5", "", {}, "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw=="], + "lunr": ["lunr@2.3.9", "", {}, "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="], + "map-cache": ["map-cache@0.2.2", "", {}, "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="], + "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=="], + "mdurl": ["mdurl@2.0.0", "", {}, "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="], + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], @@ -761,6 +788,8 @@ "publint": ["publint@0.3.21", "", { "dependencies": { "@publint/pack": "^0.1.4", "package-manager-detector": "^1.6.0", "picocolors": "^1.1.1", "sade": "^1.8.1" }, "bin": { "publint": "src/cli.js" } }, "sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ=="], + "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], + "pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], "qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="], @@ -867,8 +896,12 @@ "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + "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=="], + "unc-path-regex": ["unc-path-regex@0.1.2", "", {}, "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="], "unconfig-core": ["unconfig-core@7.5.0", "", { "dependencies": { "@quansync/fs": "^1.0.0", "quansync": "^1.0.0" } }, "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w=="], @@ -1045,6 +1078,8 @@ "tsdown/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + "typedoc/yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + "wrap-ansi/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], "@babel/core/@babel/traverse/@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="], diff --git a/docs/developers-guide.md b/docs/developers-guide.md index 2b5ea8c..6193186 100644 --- a/docs/developers-guide.md +++ b/docs/developers-guide.md @@ -87,6 +87,13 @@ BRANCH=$(git branch --show-current | tr '/ ' '__') make all 2>&1 | tee /tmp/all-digitalpuddle-${BRANCH}.out ``` +`make all` includes `docs-check` (`bun run docs:check`): TypeDoc's +`notDocumented` validation over the package entry point (`typedoc.json`), +requiring a JSDoc block on every declaration in the public surface, treating +warnings as errors, and emitting no documentation artefacts. Zod schema +constants are tagged `@internal` so their field definitions stay out of the +documented surface. + Run documentation gates when Markdown changes: ```bash diff --git a/package.json b/package.json index 4d1fd5f..3346668 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "bench": "bun test --bench", "build": "tsdown", "check:types": "bun run generate && bunx tsc --noEmit", + "docs:check": "typedoc --options typedoc.json", "fmt": "bunx @biomejs/biome format --write .", "generate": "graphql-codegen", "lint": "bunx @biomejs/biome lint .", @@ -96,6 +97,7 @@ "fast-check": "^4.8.0", "publint": "^0.3.21", "tsdown": "^0.22.3", + "typedoc": "^0.28.20", "typescript": "^6.0.3" }, "overrides": { @@ -113,7 +115,7 @@ "ws": "8.21.0" }, "inlinedDependencies": { - "starfx": "0.15.0" + "starfx": "0.16.1" }, "main": "./dist/index.cjs" } diff --git a/src/index.ts b/src/index.ts index 71f526c..aad04b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,12 @@ /** - * @file Public compatibility facade for the DigitalPuddle package entry. + * Public compatibility facade for the DigitalPuddle package entry. * * This module preserves the package-facing import surface while internal * assembly moves into target DigitalPuddle modules. It re-exports the * simulation factory and retained GitHub fixture schemas so existing consumers * and build configuration can keep importing from the package root. + * + * @module */ export {simulation} from './simulation.ts'; export type {GitHubSimulatorArgs, InitialState} from './simulation.ts'; diff --git a/src/simulation.ts b/src/simulation.ts index ced03e1..17c03ac 100644 --- a/src/simulation.ts +++ b/src/simulation.ts @@ -23,19 +23,28 @@ import { } from './store/index.ts'; import type {SchemaFile} from './utils.ts'; +/** Seed data accepted for the GitHub fixtures a simulation server starts with. */ export type InitialState = GitHubInitialStore; type FoundationRouter = Parameters< NonNullable[0]['extendRouter']> >[0]; +/** Options accepted by {@link simulation} to seed and extend a GitHub simulation server. */ export type GitHubSimulatorArgs = { + /** Seed data for the GitHub fixture store. */ initialState?: GitHubInitialStore; + /** Base URL the simulated GitHub API is served from. */ apiUrl?: string; + /** OpenAPI document, or path to one, describing the simulated GitHub API. */ apiSchema?: SchemaFile | string; + /** Store, REST, and router extensions layered onto the base simulation. */ extend?: { + /** Additional store state and reducers merged into the GitHub fixture store. */ extendStore?: GitHubExtendStoreInput; + /** Builds extra REST handlers from the extended simulation store. */ openapiHandlers?: (simulationStore: ExtendedSimulationStore) => SimulationHandlers; + /** Registers additional routes on the extended simulation store's router. */ extendRouter?: (router: FoundationRouter, simulationStore: ExtendedSimulationStore) => void; }; }; diff --git a/src/store/entities.ts b/src/store/entities.ts index 7b30690..0ffcff3 100644 --- a/src/store/entities.ts +++ b/src/store/entities.ts @@ -39,6 +39,12 @@ const getNextInstallationId = (usedInstallationIds: Set, nextInstallatio }; }; +/** + * Validates and normalizes a seeded GitHub user fixture, deriving a display + * name and email address when they are omitted. + * + * @internal + */ export const githubUserSchema = z .object({ id: z diff --git a/src/store/entities/blob.ts b/src/store/entities/blob.ts index 2bb9a82..22cd1c9 100644 --- a/src/store/entities/blob.ts +++ b/src/store/entities/blob.ts @@ -2,6 +2,12 @@ import {faker} from '@faker-js/faker'; import {z} from 'zod'; +/** + * Validates a seeded git blob fixture, requiring a path or a sha so the + * fixture can be keyed within the store. + * + * @internal + */ export const githubBlobSchema = z .object({ content: z.string().optional().default(faker.lorem.paragraphs), diff --git a/src/store/entities/branch.ts b/src/store/entities/branch.ts index e87b48e..c1bcd61 100644 --- a/src/store/entities/branch.ts +++ b/src/store/entities/branch.ts @@ -4,6 +4,12 @@ import {z} from 'zod'; const GITHUB_API_HOST = 'https://api.github.com'; +/** + * Validates and normalizes a seeded GitHub branch fixture, deriving a commit + * SHA and protection URL when they are omitted. + * + * @internal + */ export const githubBranchSchema = z .object({ owner: z.string(), diff --git a/src/store/entities/organization.ts b/src/store/entities/organization.ts index d96a054..472ec76 100644 --- a/src/store/entities/organization.ts +++ b/src/store/entities/organization.ts @@ -25,6 +25,12 @@ const deriveOrganizationBaseUrl = (url?: string) => { } }; +/** + * Validates and normalizes a seeded GitHub organization fixture, filling in + * the profile URLs that GitHub derives from the login. + * + * @internal + */ export const githubOrganizationSchema = z .object({ id: z.number().default(() => faker.number.int({min: 4000, max: 9_999_999})), diff --git a/src/store/entities/repository.ts b/src/store/entities/repository.ts index ec719ca..a8663c5 100644 --- a/src/store/entities/repository.ts +++ b/src/store/entities/repository.ts @@ -16,6 +16,12 @@ export const resetNextRepositoryId = (newValue = 3000) => { nextGeneratedRepositoryId = newValue; }; +/** + * Validates and normalizes a seeded GitHub repository fixture, deriving the + * full name and the GitHub-style API URLs for the repository. + * + * @internal + */ export const githubRepositorySchema = z .object({ id: z.number().optional(), diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..61053d1 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://typedoc.org/schema.json", + + "entryPoints": ["src/index.ts"], + "entryPointStrategy": "resolve", + + "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 +} diff --git a/typos.toml b/typos.toml index 55d2f9d..e77b5c2 100644 --- a/typos.toml +++ b/typos.toml @@ -32,10 +32,12 @@ locale = "en-gb" extend-ignore-re = [ "(?s)```.*?```", "\\bba[0-9a-f]{5,39}\\b", + "\\brust-analyzer\\b", "`[^`\\n]+`", ] [default.extend-words] +"ASO" = "ASO" "Flavored" = "Flavored" "absolutisable" = "absolutizable" "absolutisation" = "absolutization" @@ -145,8 +147,6 @@ extend-ignore-re = [ "apologizers" = "apologizers" "apologizes" = "apologizes" "apologizing" = "apologizing" -"artifact" = "artifact" -"artifacts" = "artifacts" "atomisable" = "atomizable" "atomisation" = "atomization" "atomisations" = "atomizations" @@ -833,6 +833,7 @@ extend-ignore-re = [ "globalizers" = "globalizers" "globalizes" = "globalizes" "globalizing" = "globalizing" +"handwritten" = "handwritten" "harmonisable" = "harmonizable" "harmonisation" = "harmonization" "harmonisations" = "harmonizations" @@ -1013,6 +1014,24 @@ extend-ignore-re = [ "internationalizers" = "internationalizers" "internationalizes" = "internationalizes" "internationalizing" = "internationalizing" +"italicisable" = "italicizable" +"italicisation" = "italicization" +"italicisations" = "italicizations" +"italicise" = "italicize" +"italicised" = "italicized" +"italiciser" = "italicizer" +"italicisers" = "italicizers" +"italicises" = "italicizes" +"italicising" = "italicizing" +"italicizable" = "italicizable" +"italicization" = "italicization" +"italicizations" = "italicizations" +"italicize" = "italicize" +"italicized" = "italicized" +"italicizer" = "italicizer" +"italicizers" = "italicizers" +"italicizes" = "italicizes" +"italicizing" = "italicizing" "itemisable" = "itemizable" "itemisation" = "itemization" "itemisations" = "itemizations" @@ -1682,6 +1701,24 @@ extend-ignore-re = [ "pluralizers" = "pluralizers" "pluralizes" = "pluralizes" "pluralizing" = "pluralizing" +"polymerisable" = "polymerizable" +"polymerisation" = "polymerization" +"polymerisations" = "polymerizations" +"polymerise" = "polymerize" +"polymerised" = "polymerized" +"polymeriser" = "polymerizer" +"polymerisers" = "polymerizers" +"polymerises" = "polymerizes" +"polymerising" = "polymerizing" +"polymerizable" = "polymerizable" +"polymerization" = "polymerization" +"polymerizations" = "polymerizations" +"polymerize" = "polymerize" +"polymerized" = "polymerized" +"polymerizer" = "polymerizer" +"polymerizers" = "polymerizers" +"polymerizes" = "polymerizes" +"polymerizing" = "polymerizing" "popularisable" = "popularizable" "popularisation" = "popularization" "popularisations" = "popularizations" @@ -2438,6 +2475,24 @@ extend-ignore-re = [ "uncategorizers" = "uncategorizers" "uncategorizes" = "uncategorizes" "uncategorizing" = "uncategorizing" +"underutilisable" = "underutilizable" +"underutilisation" = "underutilization" +"underutilisations" = "underutilizations" +"underutilise" = "underutilize" +"underutilised" = "underutilized" +"underutiliser" = "underutilizer" +"underutilisers" = "underutilizers" +"underutilises" = "underutilizes" +"underutilising" = "underutilizing" +"underutilizable" = "underutilizable" +"underutilization" = "underutilization" +"underutilizations" = "underutilizations" +"underutilize" = "underutilize" +"underutilized" = "underutilized" +"underutilizer" = "underutilizer" +"underutilizers" = "underutilizers" +"underutilizes" = "underutilizes" +"underutilizing" = "underutilizing" "uninitialisable" = "uninitializable" "uninitialisation" = "uninitialization" "uninitialisations" = "uninitializations"