Skip to content

spec 缺一条「跨 barrel 同名导出」检查:api-surface.json 里同名跨入口目前可见但不报警(#4411 遗留裁决 2) #4446

Description

@os-zhuang

#4411 的第二条待裁决。那条 issue 由一次同名双源引发(MetadataWatchEvent./kernel./system 各一份、形状不同、kernel 版零消费方),已在 #4411 的 PR 里连同同文件另外 10 个同类一并退役。但产生这类问题的机制没有被堵上 —— api-surface.json 里同名跨入口是可见但不报警的,下一个同名双源仍会静默落地。

为什么这类缺陷特别值得机器来抓

它是只在 import 路径上分叉的缺陷:两份声明共用一个名字,靠 from '@objectstack/spec/<entry>' 区分。

一次 code review 很难看见它 —— 两个文件各自都是合理的。

当前实测基线(#4411 PR 合入后)

packages/spec/api-surface.json 直接算:

指标 #4411 #4411
子路径同名导出(name (kind) 出现在 >1 个非 . 入口) 103 83
其中在 >1 个源文件里各自声明的(真·多源,非 re-export) 70 待重算

复算脚本:

const s = require('./packages/spec/api-surface.json');
const map = new Map();
for (const [ep, list] of Object.entries(s).filter(([, v]) => Array.isArray(v)))
  for (const n of list) (map.get(n) ?? map.set(n, []).get(n)).push(ep);
console.log([...map].filter(([, eps]) => eps.filter(e => e !== '.').length > 1).length);

.(根入口)+ 子路径的组合要排除 —— 那是有意的 re-export,同一个符号。

设计要点(裁决时值得先看的几条)

  1. 按符号 identity 判定,不能只按名字。 83 条里绝大多数是同一个声明从两个入口可达(合法),真正的缺陷是两个不同声明共用一个名字scripts/build-api-surface.ts 已经用 TS checker 解析 module symbol,拿到 declaration 位置来做同一性判断是可行的 —— 这也是这条检查唯一有价值的形态,只比名字会淹没在误报里。
  2. 需要 allowlist 基线。 剩余的真·多源不可能在一个 PR 里清完,得按 ratchet 模式落地(新增即失败,存量记账),形态参照 authorable-surface.json / check-type-check-coverage.mjs
  3. 挂载点。 跟着 check:api-surface 走(同一个 TypeScript Type Check job,读 built dist/*.d.ts);注意 AGENTS.md 记的 stale-dist 陷阱同样适用。

已知的存量条目(建档,便于起基线)

  • MetadataFormat —— system/metadata-persistence.zod.ts(7 个成员,含 yml/ts/js 别名)与 shared/metadata-types.zod.ts(4 个成员)枚举分歧,两者都在导出面上。spec 同名双源:两个 MetadataWatchEvent 形状不同、分挂两个子路径入口,其中 kernel 版零消费方(ADR-0049 enforce-or-remove) #4411 只把 kernel 的第三份删掉了,这一对仍在。
  • contracts/metadata-service.ts 自有的 MetadataExportOptions / MetadataImportOptions interface —— 与 system/metadata-persistence.zod.ts 的同名 schema 第三形状,且有消费方,不是删得掉的死副本,需要单独判定哪边是真源。
  • systemintegration(ConsumerConfigDatabaseProviderMessageQueueProviderMultipartUploadConfig)、systemcloud(EnvironmentArtifactTenantPlan)、kernelapi(*PackageRequest/Response 一族)、uishared(HttpRequestHttpMethodSchema)等成组条目 —— 需逐组判定 re-export vs 真分歧。

待裁决

这条检查是否值得做、按什么优先级做,由维护者定(#4411 里已明确记为「值不值当由维护者定」)。开这条 issue 是为了不让那次裁决连同实测基线一起丢失。


关联:#4411(触发路径 + 已退役的 11 个同名双源)、#4404#4251#4393、ADR-0049

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions