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
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Aug 3, 2026
… ./api,./kernel 侧死删 (objectstack-ai#4587) (objectstack-ai#4603) * feat(spec)!: resolve the MetadataEvent/MetadataBulkRegisterRequest dual source — ./kernel copies removed, ./api keeps the bare names (objectstack-ai#4587) The three objectstack-ai#4535-C2 baseline rows were the objectstack-ai#4411 trap on the kernel metadata family: MetadataEvent(Schema) and MetadataBulkRegisterRequestSchema each had a second, different declaration in ./kernel, and which shape a consumer got depended only on the import path. Import-statement-level scan across framework, cloud and objectui: - ./kernel copies: zero importers outside their own unit test in all three repos. The kernel MetadataEvent lifecycle vocabulary (metadata.registered/.../exported) has NO producer anywhere; the kernel bulk-register per-item `namespace` field matches no enforced write path (IMetadataService.bulkRegister and MetadataManager.bulkRegister both take {type,name,data} items only). - ./api MetadataEvent is the live realtime contract: MetadataManager publishes metadata.{type}.{created|deleted} events and @objectstack/client / client-react subscribe against the type. - ./api MetadataBulkRegisterRequestSchema is the POST /api/meta/bulk/register contract whose item shape matches the runtime. Disposal (route 1, dead-side delete, v17 major window): both kernel copies removed; ./api is the sole owner of the bare names. Name continuity for the kernel-only type alias: `MetadataBulkRegisterRequest` (z.input) is now exported from ./api beside its schema, per the family convention and the objectstack-ai#4570 docs-import concern. Compile-time pin (typeof import conditional type, objectstack-ai#4581 pattern) keeps the bare names out of ./kernel; new events.test.ts covers the surviving ./api declarations. dual-source-exports.baseline.json: exactly the 3 named rows removed (31 -> 28). json-schema.manifest: kernel/MetadataEvent and kernel/MetadataBulkRegisterRequest retired deliberately; their 11 authorable-surface rows hand-deleted per the objectstack-ai#4458/objectstack-ai#4568/objectstack-ai#4581 precedent (plugin TS types, schema bodies deleted — no silent-strip path, misuse fails at the import site at compile time). Changeset: @objectstack/spec major with FROM -> TO migration lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL * chore(spec): regenerate api-surface + reference docs for objectstack-ai#4587 (check:generated --fix, 2 proved stale) api-surface.json: ./kernel loses MetadataEvent(type)/MetadataEventSchema and MetadataBulkRegisterRequest(type)/MetadataBulkRegisterRequestSchema; ./api gains the MetadataBulkRegisterRequest type alias beside its schema. Reference docs: the api/metadata-plugin.mdx page (which documented the removed kernel pair under the api section and advertised a then-nonexistent ./api type import) is no longer emitted; api/events.mdx now documents MetadataEvent, api/metadata.mdx documents MetadataBulkRegisterRequest, and kernel/metadata-plugin.mdx drops the removed schemas. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL * chore(spec): regenerate reference docs after merging main's import-surface gate (objectstack-ai#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). --------- Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Aug 3, 2026
…ai#4610) (objectstack-ai#4638) * feat(spec)!: resolve the notification-vocabulary dual sources — ./ui Notification(Config) removed, ./system NotificationConfig removed, ./api keeps the bare names (objectstack-ai#4610) The four objectstack-ai#4535-C3 baseline rows were the objectstack-ai#4411 trap on the notification vocabulary: Notification(Schema) had a second declaration in ./ui diverging from ./api, and NotificationConfig(Schema) had two declarations (./system vs ./ui) that shared nothing but the name. Import-statement-level scan across framework, cloud and objectui: - ./api Notification(Schema) is the live REST inbox-row contract: embedded in ListNotificationsResponseSchema, part of NotificationProtocol, implemented by @objectstack/client, served by the runtime notifications domain, and mirrored by contracts' InboxNotification (ADR-0030: the bell reads this shape). - ./ui Notification(Schema) — a toast/banner instance shape — had zero importers outside its own unit test; objectui pins only the presentation enums (NotificationType/Position/ActionSchema), which stay. - ./system NotificationConfig(Schema) — a channel+template+recipients+ schedule+retryPolicy+tracking wrapper — had zero importers, is wired into no parent schema, predates ADR-0030's accepted delivery model (NotificationService.emit / NotifyConfigSchema / sys_* objects), and advertised unenforced capability (objectstack-ai#3197 dead-letter channels). - ./ui NotificationConfig(Schema) — a toaster global config — had zero importers. Disposal (route 1, dead-side delete, v17 major window): the ./ui pair and BOTH NotificationConfig declarations removed; ./api is the sole owner of the bare Notification(Schema) names and NotificationConfig left the export surface entirely. Compile-time pins (typeof import conditional type, objectstack-ai#4581 pattern) keep the bare names out of ./ui and ./system; the surviving ./api declaration is already covered by api/protocol.test.ts. dual-source-exports.baseline.json: exactly the 4 named rows removed (28 -> 24). json-schema.manifest: system/NotificationConfig, ui/Notification and ui/NotificationConfig retired deliberately; their 25 authorable-surface rows hand-deleted per the objectstack-ai#4458/objectstack-ai#4568/objectstack-ai#4581/objectstack-ai#4603 precedent. api-surface + reference docs regenerated via check:generated --fix (2 proved stale; the api/notification.mdx page folds into api/protocol.mdx where the declaration lives). docs-import-surface baseline (objectstack-ai#4595): untouched. Changeset: @objectstack/spec major with FROM -> TO migration lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL * docs(audits): 严格性台账跟随 objectstack-ai#4610 —— ui/notification.zod.ts 站点 3 → 1 删除 ./ui 的 Notification / NotificationConfig 两个形状后,台账里 `notification.zod.ts` 那行声明的站点数过期(gate 点名 ledger:454: declares 3 site(s), found 1)。把它从「3 ea」的合并行拆出单列为 1, 并写明为何掉了两个站点;`ui/` 章节总计 200 → 198 相应收敛。 check:strictness-ledger 恢复绿(67 文件 / 5 目录,站点数与章节总计均衡); 同 job 的其余源码审计(liveness / empty-state / variant-docs / exported-any / react-declaration-parity / skill-examples)一并复跑通过。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL --------- Co-authored-by: Claude <noreply@anthropic.com>
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