从 #5515 拆出。#5515 的第四条诊断(syncConfig.schedule 的裸 cron 字符串编译不过)在那张单里是按"改示例注解"解的(PR 把 SYNC_ARCHITECTURE.md 的 L3 示例改成 const sapConnector: ConnectorInput = …),根因没有动 —— 这里记的就是根因。
事实
packages/spec/src/integration/connector.zod.ts:742/744:
export type Connector = z.infer< typeof ConnectorSchema >;
/** Authoring input for {@link Connector} — defaulted fields are optional. */
export type ConnectorInput = z.input< typeof ConnectorSchema >;
即裸名 = parsed 形状,作者形状挂在 XInput 上。这是仓库里的第三种命名:
| 文件 |
裸名 |
作者形状 |
出处 |
shared/retry-policy.zod.ts 及绝大多数兄弟 |
z.input(作者写的) |
裸名 |
house convention |
automation/etl.zod.ts |
z.input |
裸名,parse 结果是 XParsed |
#4963 / PR #5514 翻过来的 |
integration/connector.zod.ts |
z.infer |
ConnectorInput |
本单 |
后果和 #4963 一模一样:const c: Connector = { … } 这条唯一的裸注解authoring 门编译不过,因为 enabled / status / connectionTimeoutMs / syncConfig.strategy / syncConfig.direction / syncConfig.batchSize / syncConfig.deleteMode / syncConfig.realtimeSync / syncConfig.conflictResolution / 字段映射的 required / syncMode / webhook 的 method / timeoutMs / isActive / signatureAlgorithm 在 z.infer 下全是必填,且 syncConfig.schedule 是 CronExpressionInputSchema 的 transform 输出({ dialect, source } 信封),裸 cron 字符串被拒。文档示例照抄进去就是这个后果,#5515 的红证据是逐字量出来的四条诊断之一。
与 #4963 的差别:迁移面不为空
etl.zod.ts 当时可以直接翻,因为 objectstack / objectui / cloud 里都没有 parse 站点。本文件不是:
- 该文件有 20 个
z.infer 裸名别名(Connector / ConnectorFieldMapping / DataSyncConfig / WebhookConfig / SyncStrategy / ConnectorConflictResolution / …)。
ConnectorSchema 是 live parse path:defineConnector() 就在同文件 748 行 return ConnectorSchema.parse(config),返回类型标的是裸 Connector;DeclarativeConnectorEntrySchema 走 stack.zod.ts。
- 枚举类别名(
SyncStrategy 等)z.input 与 z.infer 同构,翻不翻都一样;真正有形状差的是对象类。
所以这是一次真实的 breaking rename,需要按 #4963 的路数单独裁定后再做,不能顺手带过。
建议的处置
按 #4963 的结论迁移:裸名改为 z.input(作者形状),parse 结果改名 XParsed,ConnectorInput 作为过渡别名保留一版还是直接删,连同 defineConnector 的返回类型一起在同一个 PR 里定。需要先确认 20 个别名里哪些真有形状差(枚举可豁免),以及 objectstack / objectui / cloud 三仓的 importer 面。
现状不是无人看守
#5515 的 PR 加了 packages/spec/src/integration/connector-author-shape.test.ts,里面有一组探针把"同一份字面量在 ConnectorInput 下绿、在 Connector 下红"钉死了。真做这次翻转时,那组探针会直接变红,是迁移的第一处落点。
Blocked-by: #5515
从 #5515 拆出。#5515 的第四条诊断(
syncConfig.schedule的裸 cron 字符串编译不过)在那张单里是按"改示例注解"解的(PR 把SYNC_ARCHITECTURE.md的 L3 示例改成const sapConnector: ConnectorInput = …),根因没有动 —— 这里记的就是根因。事实
packages/spec/src/integration/connector.zod.ts:742/744:即裸名 = parsed 形状,作者形状挂在
XInput上。这是仓库里的第三种命名:shared/retry-policy.zod.ts及绝大多数兄弟z.input(作者写的)automation/etl.zod.tsz.inputXParsedintegration/connector.zod.tsz.inferConnectorInput后果和 #4963 一模一样:
const c: Connector = { … }这条唯一的裸注解authoring 门编译不过,因为enabled/status/connectionTimeoutMs/syncConfig.strategy/syncConfig.direction/syncConfig.batchSize/syncConfig.deleteMode/syncConfig.realtimeSync/syncConfig.conflictResolution/ 字段映射的required/syncMode/ webhook 的method/timeoutMs/isActive/signatureAlgorithm在z.infer下全是必填,且syncConfig.schedule是CronExpressionInputSchema的 transform 输出({ dialect, source }信封),裸 cron 字符串被拒。文档示例照抄进去就是这个后果,#5515 的红证据是逐字量出来的四条诊断之一。与 #4963 的差别:迁移面不为空
etl.zod.ts当时可以直接翻,因为 objectstack / objectui / cloud 里都没有 parse 站点。本文件不是:z.infer裸名别名(Connector/ConnectorFieldMapping/DataSyncConfig/WebhookConfig/SyncStrategy/ConnectorConflictResolution/ …)。ConnectorSchema是 live parse path:defineConnector()就在同文件 748 行return ConnectorSchema.parse(config),返回类型标的是裸Connector;DeclarativeConnectorEntrySchema走stack.zod.ts。SyncStrategy等)z.input与z.infer同构,翻不翻都一样;真正有形状差的是对象类。所以这是一次真实的 breaking rename,需要按 #4963 的路数单独裁定后再做,不能顺手带过。
建议的处置
按 #4963 的结论迁移:裸名改为
z.input(作者形状),parse 结果改名XParsed,ConnectorInput作为过渡别名保留一版还是直接删,连同defineConnector的返回类型一起在同一个 PR 里定。需要先确认 20 个别名里哪些真有形状差(枚举可豁免),以及 objectstack / objectui / cloud 三仓的 importer 面。现状不是无人看守
#5515 的 PR 加了
packages/spec/src/integration/connector-author-shape.test.ts,里面有一组探针把"同一份字面量在ConnectorInput下绿、在Connector下红"钉死了。真做这次翻转时,那组探针会直接变红,是迁移的第一处落点。Blocked-by: #5515