fix(#4570): reference 页的 import 示例改由真实导出面生成,并加只减不增的棘轮兜底 - #4595
Merged
Conversation
…surface
`build-docs.ts` derived each page's "TypeScript Usage" block from the JSON
Schema file name — the value import verbatim, the `import type` line with a
`Schema` suffix stripped — on the assumption that both names exist. Nothing
verified it, and `check:docs` structurally could not: it diffs the generator's
output against the committed docs, so a name the generator invents stays "in
sync" with itself forever.
Compiling the committed `import type` lines against `packages/spec/src` gives
150 `has no exported member` errors, and every `.parse()` example called a type
rather than the schema const.
Both lines are now resolved against `api-surface.json`, the committed record of
every `name (kind)` per public entry point:
- value import: `<Name>Schema` when the entry exports it, else `<Name>` (a
merged `export const Foo = z.enum(…)` + `export type Foo` is reported as
`type` by kindOf, so presence — not kind — is the sound signal there);
- type import: `<Name>` only when the entry exports it with a type-bearing
kind, which kindOf's TypeAlias-before-Variable ordering makes decidable;
- the example parses with the resolved const.
A name that resolves to nothing is dropped from the page AND recorded in the new
`docs-import-surface.baseline.json` — a shrink-only ratchet, so #4539's scenario
(deleting a zero-consumer type alias while its schema keeps its reference page)
now turns `check:docs` red instead of silently publishing a dead import. The
baseline is regenerated only by an explicit `--update-import-baseline`, never by
a `gen:` script, for the same reason the dual-source baseline is (#4446).
225 reference pages regenerate with corrected imports. The 154 accepted gaps
are 150 schemas with no exported type alias (#4593) and 4 whose names are
mangled by a first-occurrence `replace('Schema','')` in build-schemas.ts (#4592).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5
…s-import-surface # Conflicts: # content/docs/references/api/connector.mdx # content/docs/references/api/rest-server.mdx
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
August 2, 2026 09:31
os-zhuang
enabled auto-merge
August 2, 2026 09:32
os-zhuang
pushed a commit
that referenced
this pull request
Aug 2, 2026
…rface gate (#4595) The merge brought in build-docs' new import-surface ratchet. This PR's MetadataBulkRegisterRequest type alias on ./api closes the gap the fresh baseline had accepted, so its line is deleted (shrink-only ratchet).
This was referenced Aug 2, 2026
os-zhuang
pushed a commit
that referenced
this pull request
Aug 2, 2026
Conflict was in `content/docs/references/data/datasource.mdx` — a GENERATED file, conflicting because both sides regenerated it: main's #4595 taught the generator to spell import examples from the real export surface, while this branch removed `DatasourceCapabilities` from that surface. Resolved by regenerating rather than hand-merging. The result is exactly what the two changes imply together — #4595's corrected spelling minus the removed export: import { DatasourceSchema, DriverDefinitionSchema, DriverType, ExternalDatasourceSettingsSchema } from '@objectstack/spec/data'; #4595 also added an import-surface baseline, which listed `data/DatasourceCapabilities — no type export` as a known gap. This removal closes that gap, and the baseline is shrink-only, so the stale line is deleted (--update-import-baseline) — a stale exemption would otherwise stay available to excuse the NEXT missing export. The three auto-merged baseline JSONs (authorable-surface, api-surface, json-schema.manifest) were not trusted as merged text: `gen:schema` rewrites them wholesale once its vanished-key gate passes, and the full build confirms no residue of either side's removals. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5CYr5SDwe85gH2Jr5KSgu
This was referenced Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4570
问题
packages/spec/scripts/build-docs.ts生成每页 "TypeScript Usage" 时,两行 import 都是从 JSON Schema 文件名机械拼出来的:值导入原样照抄,import type那行剥掉Schema后缀。没有任何东西验证这两个名字真的存在,而check:docs结构上也验证不了——它比对的是「生成器现在的输出」和「已提交的文档」,生成器自己编出来的名字永远和自己一致。把已提交文档里的
import type行抽出来,对着packages/spec/src编译一遍:1694 个名字里 150 个编译不过。 同时值导入那行也一直是错的:
import { Object } from '@objectstack/spec/data'——./data根本没有名为Object的导出,真正的导出是ObjectSchema;紧跟着的const result = Object.parse(data)自然也调不动。这两行正是 AI 写元数据应用时最常整段复制的行。改法(两半都做)
一、从真实导出面生成
新增
scripts/lib/docs-import-surface.ts,以api-surface.json(每个入口name (kind)的已提交记录,由check:api-surface看着)为准解析两行名字。这里有一处不对称,决定了两侧规则不同:build-api-surface.ts的kindOf先测 TypeAlias/Interface 再测 Variable,所以带类型的名字永远不会被记成const。type/interface/class/enum即证明import type { N }成立,const即证明它不成立。export const FieldType = z.enum(…)加export type FieldType = …只会被记成type。所以值侧不能看 kind,只能看存在性——而这足够了,因为build-schemas.ts的 schema 名本就是从该入口某个真实运行时导出键剥Schema后缀得来的,所以 schemaN背后的常量非NSchema即N,入口导出了哪个就是哪个。解析不到的名字不写进页面(文档不再宣传一个编不过的 import),空掉的那行整行省略。
二、棘轮兜底
只把生成改对是不够的:类型别名被删之后,名字会安静地从 import 行消失——输出仍然正确,回归却没人看见。所以每个解析不到的名字都记进新的
packages/spec/docs-import-surface.baseline.json,只减不增:check:docs变红。这正是 [#4535·B] 跨形态同名三条:ShareRecipientType(type≠const)、TransformType(const≠type)、suggestFieldType(双实现 function) #4539 的场景:删掉零消费者的类型别名、schema 保留自己的 reference 页;基线不接任何
gen:脚本,只有手跑--update-import-baseline才会重写——和 dual-source 基线同一个理由(#4446):一个能重写账本的 fix 命令,会让新债务靠条件反射而不是靠决策被接纳。证据
scripts/docs-import-surface.test.ts13 项。Gadget有 schema 无别名 → 必须不出现在import type行;删掉Widget的别名 →evaluateBaseline报 fresh(红);删掉一条已修复的基线行 → 报 stale(红)。api-surface.json删掉FieldMappingTransform (type)(即 [#4535·B] 跨形态同名三条:ShareRecipientType(type≠const)、TransformType(const≠type)、suggestFieldType(双实现 function) #4539 的动作),check:docs报✗ 1 reference page import example(s) name an export that '@objectstack/spec' no longer has: shared/FieldMappingTransform — no type export,退出码 1。import type名 → 150 个编译错误。改后:1544 个名 →tsc干净通过。in对应入口模块 → 全部命中;.parse例子的常量全部可调用。回归产物
225 个 reference 页的 import 行被更正(这正是本 PR 的意义:此前它们在宣传编不过的 import)。
content/docs/releases/一个字没动。154 条已接受缺口:150 条是「schema 有、
export type没有」(已开 #4593 请维护者定夺补哪些),4 条是build-schemas.ts的replace('Schema','')只替换首次出现、把名字前缀里的Schema剥掉造成的(已开 #4592)。验证
已合入当时的
origin/main(#4581 改了./api的 webhook 导出);生成文件的冲突一律取 main 侧后整体重跑生成器,未手工合并。🤖 Generated with Claude Code
Generated by Claude Code