Repository navigation
refactor(metadata-protocol): getMetaTypes() declares a named return type, pinned equal to the type it returned - #29730
Conversation
…ype, pinned equal to the inferred one The method's inferred return type printed 793 lines inline in index.d.ts. It now declares Promise<MetaTypesListing>, composed from spec's MetadataTypeRegistryEntryParsed, Action and FormView, and a compile-time Equal check in the body holds the name equal to what the body builds. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JQwxbWaMuBU5CquKAT7ZmH
📓 Docs Drift CheckThis PR changes 1 package(s): 12 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 10 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 5e903068369fe128e16608870df2e187a6a3f812 && git checkout 5e903068369fe128e16608870df2e187a6a3f812
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87956dcc33b47d5c8bed301a87d6d4c8bdd87262 94b9d02b30f1873a89c1b310453b115ff0f94acc && git checkout -B drift-repro 87956dcc33b47d5c8bed301a87d6d4c8bdd87262 && git merge --no-ff 94b9d02b30f1873a89c1b310453b115ff0f94acc
node scripts/docs-audit/affected-docs.mjs --json 87956dcc33b47d5c8bed301a87d6d4c8bdd87262
|
|
domain:server#3 · os-warren · session_01JQwxbYyp6wSRcywGFK2L4A 维护者速读
席位核对ACCEPT ·
|
Requested by Warren · project thread
Fixes #29510
Clause-②: no
Metadata-protocol: none
维护者速读
getMetaTypes()现在声明具名返回类型Promise<MetaTypesListing>,由 spec 已导出的类型组合而成;方法体内一行编译期Equal断言把它钉成与方法体推断出的类型完全相等。index.d.ts内联展开 793 行,[maintainer] refactor(metadata-protocol): splitsrc/protocol.ts(33,065 lines, +10,169 in 30 days) along itsObjectStackProtocolImplementationseams, one move-only slice per PR #25467 每一刀都要人工读这一块原始 diff。现在 d.ts 只印别名,类型一旦漂移tsc直接报错。MetaTypesListing不从包导出,不新增公开名。回滚即 revert。packages/metadata-protocol/src/protocol-meta-types-listing.ts(类型定义,注意actions的两臂);protocol.ts中getMetaTypes()的签名与结尾exact一行。pnpm --filter @objectstack/metadata-protocol typecheck,预期 exit 0;把类型里schemaId: string;改成schemaId?: string;再跑,预期只在exact那一行报 TS2322。What changes
packages/metadata-protocol/src/protocol-meta-types-listing.ts(new, 68 lines):MetaTypesListingEntry,MetaTypesListingand a strictEqualtype. The entry isMetadataTypeRegistryEntryParsed(minustype,allowEnvironmentOverlay,actions) plus the fields the listing adds or overrides:type: string,schemaId,allowEnvironmentOverlay: boolean,overrideSource,schema: Record<string, unknown>,form: FormView,createSeed?: {} | null, andactions?: Action[] | NonNullable<MetadataTypeRegistryEntryParsed['actions']>. The secondactionsarm is in main's type because the row spreads the registry entry before it overridesactions; leaving it out fails the pin. A mappedFlattenturns the intersection into one object type, which the strictEqualneeds to compare equal to an inferred object literal. Nothing new is exported from the package index.packages/metadata-protocol/src/protocol.ts:getMetaTypes()declaresPromise<MetaTypesListing>. The body is unchanged up to its last line, which now buildsconst listing = { types: allTypes, entries }, holdsconst exact: Equal<typeof listing, MetaTypesListing> = true, and returnslisting. One type-only import. 11 lines, +9/-2..changeset/29510-meta-types-named-return.md:@objectstack/metadata-protocolpatch, both declaration lines.Why
The #25467 E1 seat ruling (PR #29488) kept
getMetaTypes()inferred so E1'sindex.d.tsstayed byte-identical, and moved the explicit return type to its own step, option B of the E1 report: a named composed type with a type-equality pin. Triage audit 6592554479 kept it p3,domain:server.What retires the per-cut raw-diff reading of
getMetaTypes()The
exactline.typeof listingis the type the body infers, which is the typemainemitted. If a cut or any later edit changes what the body builds, or changes the declared name,tscfails at that line intypecheckand in the tsup declaration build. The.d.tsnow printsgetMetaTypes(): Promise<MetaTypesListing>and an alias, so there is no 793-line inline block left for a cut to read, and no inferred block a stray class comment can surface inside.What this does not retire: ruling 6348891160's whole-
index.d.tsreading still applies to each cut, because other public members of the class stay inferred (getDiscovery,getMetaItems,getMetaItem,findData, … as listed in 6385903828). The module comment above theprotocol-meta-type-schema.jsimport inprotocol.ts("read its raw diff after any edit here") is still true for them, so it is left as it is.Tests
Measured on
main1c1a5d4 before the edit: the dependency closure built under the lock (pnpm --filter '@objectstack/metadata-protocol...' build, VERDICT command-exit 0).dist/index.d.tslines 3057–3849 holdgetMetaTypes(): 793 lines, sha256b0f7f61a…c85bf, startinggetMetaTypes(): Promise<{and ending}>;. No comment sits inside that block on this tree.Type equality against main's emitted type (one-time proof, not committed)
A scratch probe beside the package imported
ObjectStackProtocolImplementationfrom a copy of main'sdist/index.d.tsand from this branch's rebuiltdist/index.d.ts, and compiledEqual<Before, After>andEqual<Before['entries'][number], After['entries'][number]>withtrue:tscexit 0. Negative control, same probe plusEqual<Before['entries'][number], Omit<After['entries'][number], 'schemaId'>> = true: exit 2,TS2322: Type 'true' is not assignable to type 'false'. The probe was deleted afterwards.The
.d.tstext diff, main vs this branch: the 793-line block becomesgetMetaTypes(): Promise<MetaTypesListing>;, 39 lines of alias declarations are added (not exported), and two import lines change (FormFieldInputwas only used inside the old inline block;FormView,ActionandMetadataTypeRegistryEntryParsedare now imported). Nothing else in the file moves.Ablation: the pin fails on a member drift
Committed first (6525242), then
node scripts/ablation-replace.mjs --file …/protocol-meta-types-listing.ts --anchor "schemaId: string;" --replacement "schemaId?: string;" -- pnpm --filter @objectstack/metadata-protocol typecheck, with anEXIT INT TERMtrap restoring fromHEAD:81483bc18bca→b5392c1a893c;tsc --noEmit: one error,src/protocol.ts(3297,15): error TS2322: Type 'true' is not assignable to type 'false'(theexactline), exit 2;81483bc18bca),git diff HEADempty.Making a member optional is assignable to the declared type, so
returnalone would not catch it. Only the pin did.Gates on 94b9d02 (final head, after merging main c9636f1)
pnpm turbo run build --concurrency=2 --filter=@objectstack/metadata-protocol... --filter=@objectstack/objectql(VERDICT command-exit 0).pnpm --filter @objectstack/metadata-protocol testunder the lock: Test Files 308 passed, 4 skipped (312); Tests 22264 passed, 26 skipped (22290); VERDICT command-exit 0. (On 6525242, before the merge: 22262 passed, VERDICT 0.)pnpm --filter @objectstack/metadata-protocol typecheck: exit 0 (the pin holds on the merged tree).pnpm lint: exit 0.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 54 families (3 paths vs merge base, +87/-2), the same list before and after the merge. Each run once, exit captured before any pipe: 53 exit 0.pnpm check:dual-build-cjs-loads: exit 3, PREREQUISITE NOT MET (about 70 workspace packages unbuilt in this container). NOT MEASURED locally; CI runs it on a full build.dispatch-gates --ran: 54 derived, 53 run, 1 NOT-MEASURED (dual-build, from its recorded exit 3), 0 UNRUN.check-plugin-teardown-shape --self-testneeded its pinned fixture commit fetched (shallow clone),check:lean-entry-closureneeded objectql built; both then exit 0.Acceptance notes
.d.tstext changes and the type does not; that is the card's stated bar, measured above.MetaTypesListingandMetaTypesListingEntryare not exported from@objectstack/metadata-protocol, so no new public name.Human Minimum
packages/specholds no runtime logic. (not touched)pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (not touched)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.domain:server#3 · os-warren · session_01JQwxbWaMuBU5CquKAT7ZmH
🤖 Generated with Claude Code
https://claude.ai/code/session_01JQwxbWaMuBU5CquKAT7ZmH
Generated by Claude Code