fix(metadata-protocol): 读路径 _diagnostics 保留 union 分支的真实拒绝理由 (#5598) - #5765
Merged
Conversation
computeMetadataDiagnostics 把 zod 的 error.issues 直接 .map() 成 _diagnostics 条目。zod 会把一个失败 z.union 的全部分支折叠成一条顶层 issue —— path 为空、 message 是字面量 "Invalid input" —— 而 ViewMetadataSchema 顶层本身就是 union, 所以库里每一个有缺陷的 view 读出来都退化成这一条没有字段名的记录,模块头承诺的 "内联字段错误"无处可标。 后果是同一份文档在两条路径上判决不一致:#5364(PR #5596)修好写路径之后,保存 一个有缺陷的 view 能看到出错的键名,打开同一份已存库的文档却仍然只有一条 Invalid input。 改法是复用而非再抄一份策略:读路径改调同包 #5596 落地的 zodIssuesToMetadataIssues,分支选取口径由该函数单点定义,读写两路径按构造一致。 展开是纯增量 —— union 自己那条仍在 errors[0]。stripDiagnostics 一段未动。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V7WetGmnfoXNn8cLieKKmx
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 3 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 6, 2026 05:14
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 #5598
问题
computeMetadataDiagnostics(packages/metadata-protocol/src/metadata-diagnostics.ts)把 zod 的error.issues直接.map()成_diagnostics信封条目。zod 会把一个失败z.union的全部分支折叠成一条顶层 issue ——path为空串、message 是字面量"Invalid input"—— 而ViewMetadataSchema顶层本身就是 union(z.preprocess(stripViewConsoleDecorations, z.union([...]))),所以库里每一个有缺陷的 view 文档读出来都退化成这一条没有字段名的记录。该文件模块头承诺的用途正是让 Studio 渲染 validity badge、内联字段错误和治理看板,而内联字段错误无处可标。这不只是"少了点信息",而是同一份文档在两条路径上判决不一致:#5364(PR #5596)修好写路径之后,作者保存一个有缺陷的 view 能看到出错的键名;打开同一份已存在库里的文档却仍然只得到一条
Invalid input。这是同一机制的第 5 个消费者(#4971 / #5014 / #5341 / #5364 是前四个)。改动
metadata-diagnostics.ts一处.map()换成调用同包 #5596 已落地并导出的zodIssuesToMetadataIssues。复用而非再抄一份策略是重点:分支选取口径(丢弃只报根部 KIND 不匹配的分支;报得最少的分支胜出;unrecognized_keys破平局;并列全出且有上限;嵌套 union 按绝对路径递归)由该函数单点定义,读写两路径按构造一致,不可能各自漂移。protocol.ts—— 该函数已是模块级export,无需移动或调整导出。stripDiagnostics一段未动;新增用例专门守住"读两遍不会把信封自己判成非法"。errors[0],后面才跟上解释它的分支条目,读errors[0]的既有代码读到的还是同一条。实测,issue 正文那份 view 输入现在得到:
{ "valid": false, "errors": [ { "path": "", "message": "Invalid input", "code": "invalid_union" }, { "path": "", "code": "unrecognized_keys", "message": "Unrecognized key(s) on this view container: `type`, `columns`. … • `type` belongs to a single VIEW, not to the container. Wrap it: …" } ] }第二条正是 #4001 那批
strictObject的策展处方 —— 以前被.map()生产出来又丢掉。测试
新增
packages/metadata-protocol/src/metadata-diagnostics.union-issues.test.ts(8 例):3 例守 union 展开(展开发生、与共享排序逐字节一致、decorateMetadataItem把它带到 Studio 面前),1 例守 strip 未被破坏,4 例是对照组 —— 没走 union 的普通字段级拒绝、非对象文档、spec 合法文档、未注册类型,行为必须不变。反向验证(方向事先预判:红):把删掉的
.map()限肢放回去,3 条 union 用例转红、4 条对照组保持绿 —— 缺陷本身被写成了一个数字:恢复修复后:
消费半径清扫(该判决在哪里被读就在哪里查 fixture,不按被改包划界):
git grep _diagnostics覆盖 metadata-protocol / objectql / metadata / rest / service-automation —— 除 objectql 外均只断言valid标志或 warning(另一个生产者),不受增量影响;objectql 直接测computeMetadataDiagnostics,已跑:typecheck / 构建 / 门禁:
tsc --noEmit -p packages/metadata-protocol/tsconfig.json—— 改动前后输出逐行相同(159 行,全是该包既有的 test-layer DEBT,check:type-check-coverage已登记),我的两个文件零错误。pnpm --filter @objectstack/metadata-protocol build—— tsup ESM/CJS/DTS 全部 Build success,无循环依赖告警。check:nul-bytesOK(5641 文件)、check:type-check-coverageOK、check:query-options-erasureOK(baseline 对5e3c83b核过,无新增文件)、check:slot-lookupOK、check:published-filesOK、check:error-code-casingOK;两个文件eslint --no-inline-config干净。需要评审注意的一点
metadata-diagnostics.ts现在import { zodIssuesToMetadataIssues } from './protocol.js',而protocol.ts本来就 import 了metadata-diagnostics.js,于是两个模块间形成一个包内循环 import。运行期安全(函数声明提升,zodIssuesToMetadataIssues只在运行期被调用,两个模块都没有模块级互相调用),tsup 打包与 DTS 均无告警,全量测试绿。但方向上是小叶子模块反向依赖了大模块 —— 这正好给 issue 正文那条后续裁决项(「五处策略是否收敛成一个共享实现」)多加一个论据:真正的落点应该是一个中立模块,而不是继续按份数增长。按派单约束我没有动protocol.ts,这条留给 PM 裁决。Generated by Claude Code