@cosmicdrift/kumiko-framework 0.388.0 → 0.390.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (711) hide show
  1. package/AGENTS.md +12 -4
  2. package/README.md +1 -1
  3. package/agents/examples/apex-surface-auth.md +2 -3
  4. package/agents/examples/api-worker-split.md +9 -2
  5. package/agents/examples/auth-claims.md +1 -1
  6. package/agents/examples/cross-feature-events.md +12 -12
  7. package/agents/examples/crypto-shredding-hr.md +2 -2
  8. package/agents/examples/encrypted-tenant-config.md +1 -1
  9. package/agents/examples/error-contract.md +12 -7
  10. package/agents/examples/event-sourcing.md +29 -29
  11. package/agents/examples/files-post-processing.md +10 -8
  12. package/agents/examples/golden-path.md +13 -1
  13. package/agents/examples/inbound-mail-triage.md +1 -0
  14. package/agents/examples/lane-routing.md +2 -1
  15. package/agents/examples/legal-pages.md +2 -2
  16. package/agents/examples/lifecycle-hooks.md +55 -2
  17. package/agents/examples/list-table-options.md +466 -0
  18. package/agents/examples/managed-config.md +4 -4
  19. package/agents/examples/managed-pages.md +1 -1
  20. package/agents/examples/pdf-audit-export.md +4 -2
  21. package/agents/examples/relations.md +19 -4
  22. package/agents/examples/search.md +4 -4
  23. package/agents/examples/secrets-demo.md +9 -6
  24. package/agents/examples/state-machine.md +5 -4
  25. package/agents/examples/tenant-isolation.md +73 -1
  26. package/agents/examples/tenant-settings.md +1 -1
  27. package/agents/examples/user-data-rights.md +3 -6
  28. package/agents/examples/workflow-engine.md +53 -47
  29. package/agents/examples.md +5 -4
  30. package/agents/features.md +1 -1
  31. package/agents/widgets.md +1 -0
  32. package/dist/api/api-constants.d.ts +1 -0
  33. package/dist/api/api-constants.js +2 -0
  34. package/dist/api/auth-middleware.js +1 -1
  35. package/dist/api/auth-routes-invite.js +2 -1
  36. package/dist/api/auth-routes-shared.d.ts +2 -0
  37. package/dist/api/auth-routes-shared.js +5 -0
  38. package/dist/api/client-error-route.js +2 -3
  39. package/dist/api/entity-read-access.d.ts +4 -1
  40. package/dist/api/entity-read-access.js +14 -0
  41. package/dist/api/export/export-cells-reference.d.ts +9 -0
  42. package/dist/api/export/export-cells-reference.js +21 -0
  43. package/dist/api/export/export-cells.d.ts +11 -0
  44. package/dist/api/export/export-cells.js +136 -0
  45. package/dist/api/export/export-ciphertext-guard.d.ts +2 -0
  46. package/dist/api/export/export-ciphertext-guard.js +27 -0
  47. package/dist/api/export/export-columns.d.ts +31 -0
  48. package/dist/api/export/export-columns.js +85 -0
  49. package/dist/api/export/export-errors.d.ts +4 -0
  50. package/dist/api/export/export-errors.js +14 -0
  51. package/dist/api/export/export-route.d.ts +4 -0
  52. package/dist/api/export/export-route.js +75 -0
  53. package/dist/api/export/export-rows.d.ts +13 -0
  54. package/dist/api/export/export-rows.js +62 -0
  55. package/dist/api/export/export-screen.d.ts +13 -0
  56. package/dist/api/export/export-screen.js +47 -0
  57. package/dist/api/export/export-xlsx-writer.d.ts +4 -0
  58. package/dist/api/export/export-xlsx-writer.js +21 -0
  59. package/dist/api/extra-route.d.ts +7 -1
  60. package/dist/api/index.d.ts +23 -27
  61. package/dist/api/index.js +13 -15
  62. package/dist/api/jwt.js +1 -1
  63. package/dist/api/observability-middleware.d.ts +1 -1
  64. package/dist/api/observability-middleware.js +2 -1
  65. package/dist/api/pii-leak-guard.d.ts +3 -0
  66. package/dist/api/pii-leak-guard.js +3 -2
  67. package/dist/api/request-context-internals.d.ts +31 -0
  68. package/dist/api/request-context-internals.js +11 -0
  69. package/dist/api/request-context-scopes.d.ts +14 -0
  70. package/dist/api/request-context-scopes.js +69 -0
  71. package/dist/api/request-context.d.ts +1 -40
  72. package/dist/api/request-context.js +22 -51
  73. package/dist/api/request-id-middleware.d.ts +1 -1
  74. package/dist/api/route-registrars.d.ts +2 -1
  75. package/dist/api/route-registrars.js +1 -1
  76. package/dist/api/routes.d.ts +16 -0
  77. package/dist/api/routes.js +9 -5
  78. package/dist/api/server-boot-checks.d.ts +1 -1
  79. package/dist/api/server-boot-checks.js +2 -2
  80. package/dist/api/server-event-dispatcher.d.ts +6 -1
  81. package/dist/api/server-event-dispatcher.js +3 -4
  82. package/dist/api/server-extra-routes.d.ts +1 -1
  83. package/dist/api/server-extra-routes.js +5 -1
  84. package/dist/api/server-middleware.js +3 -1
  85. package/dist/api/server-routes.d.ts +3 -2
  86. package/dist/api/server-routes.js +8 -2
  87. package/dist/api/server-wiring.js +8 -4
  88. package/dist/api/server.d.ts +2 -1
  89. package/dist/api/sse-route.d.ts +3 -1
  90. package/dist/api/sse-route.js +11 -1
  91. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  92. package/dist/api/tenant-scoped-secrets.js +13 -0
  93. package/dist/api/websocket-route.d.ts +1 -1
  94. package/dist/auth/index.d.ts +0 -1
  95. package/dist/auth/roles.d.ts +0 -5
  96. package/dist/compliance/duration-spec.d.ts +0 -1
  97. package/dist/compliance/duration-spec.js +0 -5
  98. package/dist/compliance/index.d.ts +4 -4
  99. package/dist/compliance/index.js +2 -2
  100. package/dist/compliance/profiles.d.ts +0 -15
  101. package/dist/compliance/profiles.js +0 -23
  102. package/dist/config/index.d.ts +11 -9
  103. package/dist/config/index.js +13 -1
  104. package/dist/config/internals.d.ts +9 -0
  105. package/dist/config/internals.js +1 -0
  106. package/dist/consumer-cli-internals.d.ts +4 -0
  107. package/dist/consumer-cli-internals.js +1 -0
  108. package/dist/consumer-cli.d.ts +1 -4
  109. package/dist/consumer-cli.js +5 -1
  110. package/dist/crypto/event-pii.js +1 -1
  111. package/dist/crypto/index.d.ts +8 -9
  112. package/dist/crypto/index.js +7 -8
  113. package/dist/crypto/pg-kms-adapter.d.ts +1 -0
  114. package/dist/crypto/pg-kms-adapter.js +17 -18
  115. package/dist/db/aggregate-sql.d.ts +2 -0
  116. package/dist/db/aggregate-sql.js +10 -0
  117. package/dist/db/apply-entity-event.d.ts +1 -1
  118. package/dist/db/apply-entity-event.js +15 -47
  119. package/dist/db/blind-index-cleanup.js +91 -77
  120. package/dist/db/closed-connection.js +12 -19
  121. package/dist/db/collect-table-metas.js +1 -1
  122. package/dist/db/compound-types.d.ts +1 -1
  123. package/dist/db/compound-types.js +0 -7
  124. package/dist/db/config-seed.d.ts +2 -1
  125. package/dist/db/config-seed.js +6 -1
  126. package/dist/db/connection.d.ts +7 -6
  127. package/dist/db/connection.js +43 -24
  128. package/dist/db/cross-tenant-reads.d.ts +1 -1
  129. package/dist/db/cross-tenant-reads.js +1 -1
  130. package/dist/db/dialect.d.ts +0 -5
  131. package/dist/db/dialect.js +0 -3
  132. package/dist/db/driver-row-coercion.js +4 -4
  133. package/dist/db/driver-value-preparation.js +6 -4
  134. package/dist/db/eagerload.d.ts +2 -1
  135. package/dist/db/entity-field-encryption.d.ts +1 -1
  136. package/dist/db/entity-table-meta.d.ts +1 -1
  137. package/dist/db/event-store-executor-context.d.ts +3 -1
  138. package/dist/db/event-store-executor-context.js +4 -3
  139. package/dist/db/event-store-executor-read-aggregate-currencies.d.ts +17 -0
  140. package/dist/db/event-store-executor-read-aggregate-currencies.js +40 -0
  141. package/dist/db/event-store-executor-read-aggregate.js +36 -5
  142. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  143. package/dist/db/event-store-executor-read-filter.js +6 -3
  144. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  145. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  146. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  147. package/dist/db/event-store-executor-read.js +2 -2
  148. package/dist/db/event-store-executor-write-atomic.d.ts +4 -0
  149. package/dist/db/event-store-executor-write-atomic.js +42 -0
  150. package/dist/db/event-store-executor-write-steps.d.ts +3 -5
  151. package/dist/db/event-store-executor-write-steps.js +0 -5
  152. package/dist/db/event-store-executor-write.js +22 -19
  153. package/dist/db/event-store-executor.d.ts +1 -1
  154. package/dist/db/event-store-executor.js +2 -1
  155. package/dist/db/executor-managed-tables.d.ts +7 -1
  156. package/dist/db/executor-managed-tables.js +12 -3
  157. package/dist/db/index.d.ts +29 -28
  158. package/dist/db/index.js +22 -20
  159. package/dist/db/known-table-names.d.ts +6 -0
  160. package/dist/db/known-table-names.js +21 -0
  161. package/dist/db/list-aggregate-labels.d.ts +1 -1
  162. package/dist/db/located-timestamp.d.ts +1 -1
  163. package/dist/db/located-timestamp.js +0 -5
  164. package/dist/db/migrate-generator.d.ts +17 -1
  165. package/dist/db/migrate-generator.js +50 -20
  166. package/dist/db/migrate-primary-key.d.ts +12 -0
  167. package/dist/db/migrate-primary-key.js +45 -0
  168. package/dist/db/migrate-rls-diff.d.ts +20 -0
  169. package/dist/db/migrate-rls-diff.js +61 -0
  170. package/dist/db/migrate-runner.js +7 -3
  171. package/dist/db/money.d.ts +1 -1
  172. package/dist/db/money.js +1 -1
  173. package/dist/db/parent-ref-clause.d.ts +2 -1
  174. package/dist/db/pg-error.d.ts +2 -0
  175. package/dist/db/pg-error.js +37 -21
  176. package/dist/db/queries/backfill-pii.js +3 -6
  177. package/dist/db/queries/database-now.js +2 -1
  178. package/dist/db/queries/ddl.d.ts +3 -0
  179. package/dist/db/queries/ddl.js +34 -1
  180. package/dist/db/queries/event-store.js +4 -2
  181. package/dist/db/queries/event-tenants.d.ts +2 -0
  182. package/dist/db/queries/event-tenants.js +17 -0
  183. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  184. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  185. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  186. package/dist/db/queries/rls-boot-catalog.js +39 -0
  187. package/dist/db/queries/rls-catalog.d.ts +6 -0
  188. package/dist/db/queries/rls-catalog.js +82 -0
  189. package/dist/db/queries/rls-scope.d.ts +3 -0
  190. package/dist/db/queries/rls-scope.js +17 -0
  191. package/dist/db/queries/rls-shape.d.ts +10 -0
  192. package/dist/db/queries/rls-shape.js +42 -0
  193. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  194. package/dist/db/queries/session-advisory-lock.js +23 -0
  195. package/dist/db/queries/shadow-swap.d.ts +1 -2
  196. package/dist/db/queries/shadow-swap.js +11 -28
  197. package/dist/db/queries/test-stack.d.ts +4 -1
  198. package/dist/db/queries/test-stack.js +83 -2
  199. package/dist/db/query.d.ts +14 -0
  200. package/dist/db/query.js +77 -48
  201. package/dist/db/reference-data.d.ts +1 -1
  202. package/dist/db/reference-data.js +20 -3
  203. package/dist/db/render-ddl.d.ts +6 -2
  204. package/dist/db/render-ddl.js +7 -7
  205. package/dist/db/render-rls-ddl.d.ts +35 -0
  206. package/dist/db/render-rls-ddl.js +127 -0
  207. package/dist/db/replay-migration-sql.d.ts +3 -1
  208. package/dist/db/replay-migration-sql.js +22 -5
  209. package/dist/db/replay-rls.d.ts +25 -0
  210. package/dist/db/replay-rls.js +156 -0
  211. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  212. package/dist/db/row-level-security-boot-check.js +85 -0
  213. package/dist/db/row-level-security-connection.d.ts +3 -0
  214. package/dist/db/row-level-security-connection.js +213 -0
  215. package/dist/db/row-level-security-scope.d.ts +33 -0
  216. package/dist/db/row-level-security-scope.js +127 -0
  217. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  218. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  219. package/dist/db/sql-identifier.d.ts +1 -0
  220. package/dist/db/sql-identifier.js +3 -0
  221. package/dist/db/statement-timeout.js +2 -1
  222. package/dist/db/table-builder.d.ts +2 -1
  223. package/dist/db/table-builder.js +1 -1
  224. package/dist/db/table-info.js +1 -1
  225. package/dist/db/table-push.d.ts +11 -2
  226. package/dist/db/table-push.js +15 -2
  227. package/dist/db/tenant-db-runner.d.ts +3 -1
  228. package/dist/db/tenant-db-runner.js +4 -3
  229. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  230. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  231. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  232. package/dist/db/tenant-db-statement-runner.js +48 -0
  233. package/dist/db/tenant-db-upsert.d.ts +5 -0
  234. package/dist/db/tenant-db-upsert.js +91 -0
  235. package/dist/db/tenant-db.d.ts +17 -12
  236. package/dist/db/tenant-db.js +60 -121
  237. package/dist/db/tenant-id-filter.d.ts +3 -0
  238. package/dist/db/tenant-id-filter.js +30 -0
  239. package/dist/db/transaction-serialization.d.ts +6 -0
  240. package/dist/db/transaction-serialization.js +60 -0
  241. package/dist/derivatives/delete-stored-file.js +1 -1
  242. package/dist/derivatives/index.d.ts +2 -5
  243. package/dist/derivatives/index.js +2 -3
  244. package/dist/engine/access.d.ts +2 -1
  245. package/dist/engine/access.js +1 -1
  246. package/dist/engine/boot-validator/bundled-lists-table.d.ts +2 -0
  247. package/dist/engine/boot-validator/bundled-lists-table.js +36 -0
  248. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  249. package/dist/engine/boot-validator/entity-handler.js +1 -1
  250. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +3 -0
  251. package/dist/engine/boot-validator/entity-list-aggregate-options.js +23 -0
  252. package/dist/engine/boot-validator/list-bulk-actions.d.ts +3 -0
  253. package/dist/engine/boot-validator/list-bulk-actions.js +49 -0
  254. package/dist/engine/boot-validator/list-column-layout.d.ts +8 -0
  255. package/dist/engine/boot-validator/list-column-layout.js +41 -0
  256. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +24 -0
  257. package/dist/engine/boot-validator/list-table-aggregate-options.js +145 -0
  258. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +11 -0
  259. package/dist/engine/boot-validator/list-table-aggregate-query.js +31 -0
  260. package/dist/engine/boot-validator/list-table-export-options.d.ts +1 -0
  261. package/dist/engine/boot-validator/list-table-export-options.js +27 -0
  262. package/dist/engine/boot-validator/list-table-options.d.ts +3 -0
  263. package/dist/engine/boot-validator/list-table-options.js +77 -0
  264. package/dist/engine/boot-validator/list-table-reject-unknown-keys.d.ts +1 -0
  265. package/dist/engine/boot-validator/list-table-reject-unknown-keys.js +7 -0
  266. package/dist/engine/boot-validator/nav.d.ts +3 -1
  267. package/dist/engine/boot-validator/nav.js +1 -1
  268. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  269. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  270. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  271. package/dist/engine/boot-validator/projection-list-screens.js +3 -13
  272. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  273. package/dist/engine/boot-validator/related-list-table-rules.d.ts +4 -0
  274. package/dist/engine/boot-validator/related-list-table-rules.js +42 -0
  275. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  276. package/dist/engine/boot-validator/screens-kind-entity-list.js +7 -0
  277. package/dist/engine/boot-validator/screens-kind-projection-list.js +4 -0
  278. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  279. package/dist/engine/boot-validator/screens-lists.js +12 -2
  280. package/dist/engine/boot-validator/screens.d.ts +2 -1
  281. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  282. package/dist/engine/bridge-stub.d.ts +5 -2
  283. package/dist/engine/bridge-stub.js +39 -24
  284. package/dist/engine/build-app-schema.d.ts +2 -1
  285. package/dist/engine/build-app-schema.js +9 -1
  286. package/dist/engine/build-config-feature-schema.js +6 -1
  287. package/dist/engine/config-helpers.d.ts +2 -2
  288. package/dist/engine/config-helpers.js +0 -9
  289. package/dist/engine/constants.d.ts +0 -10
  290. package/dist/engine/constants.js +0 -8
  291. package/dist/engine/create-app.js +1 -1
  292. package/dist/engine/define-feature.d.ts +2 -1
  293. package/dist/engine/define-feature.js +5 -2
  294. package/dist/engine/define-handler.d.ts +1 -1
  295. package/dist/engine/define-step.d.ts +0 -1
  296. package/dist/engine/define-step.js +0 -3
  297. package/dist/engine/embedded-derived.d.ts +1 -1
  298. package/dist/engine/entity-handlers.d.ts +2 -1
  299. package/dist/engine/entity-handlers.js +7 -7
  300. package/dist/engine/entity-list-runtime-options.js +3 -1
  301. package/dist/engine/entity-list-searchability.d.ts +2 -1
  302. package/dist/engine/event-def.d.ts +2 -1
  303. package/dist/engine/event-helpers.d.ts +3 -1
  304. package/dist/engine/event-helpers.js +3 -3
  305. package/dist/engine/extension-names.d.ts +2 -8
  306. package/dist/engine/extension-names.js +2 -2
  307. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  308. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  309. package/dist/engine/extensions/user-data.d.ts +0 -8
  310. package/dist/engine/factories.d.ts +2 -1
  311. package/dist/engine/feature-builder-state.d.ts +9 -1
  312. package/dist/engine/feature-builder-state.js +1 -0
  313. package/dist/engine/feature-changelog.d.ts +1 -1
  314. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  315. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  316. package/dist/engine/feature-manifest.d.ts +1 -0
  317. package/dist/engine/feature-manifest.js +2 -1
  318. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  319. package/dist/engine/feature-ui-extensions.js +6 -4
  320. package/dist/engine/field-access.d.ts +3 -1
  321. package/dist/engine/field-access.js +12 -0
  322. package/dist/engine/handler-field-references.d.ts +0 -4
  323. package/dist/engine/index.d.ts +58 -55
  324. package/dist/engine/index.js +23 -28
  325. package/dist/engine/instruction-fields.d.ts +1 -1
  326. package/dist/engine/personal-data-fields.d.ts +1 -1
  327. package/dist/engine/qualified-name.d.ts +0 -1
  328. package/dist/engine/read-claim.d.ts +2 -1
  329. package/dist/engine/registry-facade.js +0 -3
  330. package/dist/engine/registry-ingest.d.ts +2 -1
  331. package/dist/engine/registry-ingest.js +1 -2
  332. package/dist/engine/registry-state.d.ts +12 -2
  333. package/dist/engine/registry-state.js +2 -3
  334. package/dist/engine/registry-validate.d.ts +3 -1
  335. package/dist/engine/registry-validate.js +7 -7
  336. package/dist/engine/run-in.d.ts +1 -1
  337. package/dist/engine/run-in.js +0 -1
  338. package/dist/engine/schema-builder.d.ts +1 -1
  339. package/dist/engine/schema-builder.js +1 -1
  340. package/dist/engine/screen-filter-ops.d.ts +2 -1
  341. package/dist/engine/screen-filter-ops.js +2 -5
  342. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  343. package/dist/engine/soft-delete-cleanup.js +4 -4
  344. package/dist/engine/state-machine.js +2 -1
  345. package/dist/engine/steps/_read-source.js +1 -1
  346. package/dist/engine/steps/aggregate-append-event.js +2 -2
  347. package/dist/engine/steps/call-feature.js +2 -2
  348. package/dist/engine/steps/mail-send.js +1 -1
  349. package/dist/engine/steps/retry.js +1 -1
  350. package/dist/engine/steps/wait-for-event.js +1 -1
  351. package/dist/engine/steps/wait.js +1 -1
  352. package/dist/engine/steps/webhook-send.js +1 -1
  353. package/dist/engine/strip-disabled-features-from-app-schema.js +7 -3
  354. package/dist/engine/template-variables.d.ts +2 -1
  355. package/dist/engine/transfer-adjacency.d.ts +1 -1
  356. package/dist/engine/types/feature.d.ts +1 -0
  357. package/dist/engine/types/index.d.ts +8 -30
  358. package/dist/engine/types/index.js +2 -10
  359. package/dist/engine/types/screen.d.ts +1 -1
  360. package/dist/engine/types/screen.js +1 -1
  361. package/dist/engine/validation.d.ts +2 -1
  362. package/dist/entrypoint/index.d.ts +9 -35
  363. package/dist/entrypoint/index.js +10 -1
  364. package/dist/entrypoint/internals.d.ts +40 -0
  365. package/dist/entrypoint/internals.js +1 -0
  366. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  367. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  368. package/dist/env/dry-run-internals.d.ts +10 -0
  369. package/dist/env/dry-run-internals.js +1 -0
  370. package/dist/env/dry-run.d.ts +1 -10
  371. package/dist/env/dry-run.js +2 -1
  372. package/dist/env/index.d.ts +1 -85
  373. package/dist/env/index.js +6 -50
  374. package/dist/env/internals.d.ts +87 -0
  375. package/dist/env/internals.js +53 -0
  376. package/dist/errors/classes.js +2 -2
  377. package/dist/errors/index.d.ts +5 -14
  378. package/dist/errors/index.js +4 -9
  379. package/dist/errors/member-resolution.js +1 -1
  380. package/dist/errors/reasons.d.ts +0 -1
  381. package/dist/errors/reasons.js +7 -7
  382. package/dist/errors/serialize.d.ts +0 -18
  383. package/dist/errors/serialize.js +0 -27
  384. package/dist/es-ops/index.d.ts +4 -4
  385. package/dist/es-ops/index.js +2 -2
  386. package/dist/es-ops/operations-schema.d.ts +1 -1
  387. package/dist/es-ops/types.d.ts +4 -5
  388. package/dist/event-store/admin-api-internals.d.ts +14 -0
  389. package/dist/event-store/admin-api-internals.js +1 -0
  390. package/dist/event-store/admin-api.d.ts +1 -14
  391. package/dist/event-store/admin-api.js +11 -6
  392. package/dist/event-store/archive.js +4 -2
  393. package/dist/event-store/errors.js +2 -2
  394. package/dist/event-store/event-store.d.ts +1 -0
  395. package/dist/event-store/event-store.js +42 -32
  396. package/dist/event-store/events-schema.js +4 -1
  397. package/dist/event-store/index.d.ts +11 -13
  398. package/dist/event-store/index.js +7 -9
  399. package/dist/event-store/provenance-append.js +1 -1
  400. package/dist/event-store/rebuild-dead-letter.js +4 -2
  401. package/dist/event-store/snapshot.js +4 -3
  402. package/dist/event-store/stream-scope.d.ts +2 -0
  403. package/dist/event-store/stream-scope.js +6 -0
  404. package/dist/event-store/upcaster-dead-letter.js +4 -2
  405. package/dist/event-store/upcaster.d.ts +2 -1
  406. package/dist/files/action-form-upload.d.ts +2 -1
  407. package/dist/files/action-form-upload.js +1 -1
  408. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  409. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  410. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  411. package/dist/files/bind-pending-file-refs.js +2 -1
  412. package/dist/files/bind-referenced-files.write.js +1 -1
  413. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  414. package/dist/files/create-file-ref-from-bytes.js +6 -3
  415. package/dist/files/create-file-ref.d.ts +6 -2
  416. package/dist/files/create-file-ref.js +13 -4
  417. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  418. package/dist/files/dispose-removed-file-refs.js +1 -1
  419. package/dist/files/feature.js +2 -2
  420. package/dist/files/file-handle.js +1 -1
  421. package/dist/files/file-routes.d.ts +3 -1
  422. package/dist/files/file-routes.js +41 -4
  423. package/dist/files/index.d.ts +11 -13
  424. package/dist/files/index.js +5 -7
  425. package/dist/files/load-save-file-refs.d.ts +2 -1
  426. package/dist/files/load-save-file-refs.js +1 -1
  427. package/dist/files/provider-resolver.d.ts +6 -4
  428. package/dist/files/provider-resolver.js +5 -5
  429. package/dist/files/record-write-check.d.ts +6 -0
  430. package/dist/files/record-write-check.js +13 -0
  431. package/dist/files/storage-tracking.js +4 -2
  432. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  433. package/dist/files/sweep-orphaned-uploads.js +1 -1
  434. package/dist/files/upload-ledger.d.ts +2 -2
  435. package/dist/files/upload-ledger.js +4 -4
  436. package/dist/i18n/index.d.ts +2 -8
  437. package/dist/i18n/index.js +1 -1
  438. package/dist/i18n/internals.d.ts +7 -0
  439. package/dist/i18n/internals.js +1 -0
  440. package/dist/i18n/required-surface-keys.d.ts +4 -1
  441. package/dist/i18n/required-surface-keys.js +7 -2
  442. package/dist/internal/row-level-security.d.ts +3 -0
  443. package/dist/internal/row-level-security.js +3 -0
  444. package/dist/internal/stack-support.d.ts +1 -1
  445. package/dist/internal/stack-support.js +1 -1
  446. package/dist/internal/testing.d.ts +1 -0
  447. package/dist/internal/testing.js +10 -6
  448. package/dist/jobs/index.d.ts +1 -1
  449. package/dist/jobs/job-append-event.d.ts +12 -0
  450. package/dist/jobs/job-append-event.js +30 -0
  451. package/dist/jobs/job-runner-context.d.ts +2 -2
  452. package/dist/jobs/job-runner-context.js +46 -16
  453. package/dist/jobs/job-runner-execution.d.ts +1 -1
  454. package/dist/jobs/job-runner-execution.js +6 -4
  455. package/dist/jobs/job-runner-gates.d.ts +1 -1
  456. package/dist/jobs/job-runner-gates.js +0 -1
  457. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  458. package/dist/jobs/job-runner-helpers.js +10 -1
  459. package/dist/jobs/job-runner-scope.d.ts +5 -2
  460. package/dist/jobs/job-runner-scope.js +6 -6
  461. package/dist/jobs/job-runner-types.d.ts +2 -1
  462. package/dist/jobs/job-runner.js +22 -6
  463. package/dist/jobs/max-per-tenant.d.ts +1 -1
  464. package/dist/logging/index.d.ts +1 -2
  465. package/dist/logging/index.js +1 -1
  466. package/dist/logging/pino-logger.js +1 -1
  467. package/dist/logging/utils.d.ts +1 -0
  468. package/dist/logging/utils.js +6 -0
  469. package/dist/migrations/index.d.ts +3 -3
  470. package/dist/migrations/index.js +3 -3
  471. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  472. package/dist/migrations/pending-rebuilds.js +1 -1
  473. package/dist/migrations/pii-event-backfill.js +4 -1
  474. package/dist/observability/escape-hatch-report.d.ts +2 -1
  475. package/dist/observability/escape-hatch-report.js +9 -2
  476. package/dist/observability/index.d.ts +7 -15
  477. package/dist/observability/index.js +4 -12
  478. package/dist/observability/metric-validator.js +1 -1
  479. package/dist/observability/metrics-handle.d.ts +0 -1
  480. package/dist/observability/metrics-handle.js +2 -15
  481. package/dist/observability/recording-tracer.d.ts +1 -2
  482. package/dist/observability/recording-tracer.js +0 -6
  483. package/dist/observability/sensitive-filter.d.ts +0 -2
  484. package/dist/observability/sensitive-filter.js +0 -29
  485. package/dist/pipeline/active-membership.d.ts +2 -1
  486. package/dist/pipeline/active-membership.js +6 -2
  487. package/dist/pipeline/after-rollback-sink.d.ts +6 -0
  488. package/dist/pipeline/after-rollback-sink.js +32 -0
  489. package/dist/pipeline/append-event-core.d.ts +2 -1
  490. package/dist/pipeline/append-event-core.js +2 -2
  491. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  492. package/dist/pipeline/attach-outside-transaction.js +13 -0
  493. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  494. package/dist/pipeline/cascade-handler.d.ts +2 -1
  495. package/dist/pipeline/cascade-handler.js +3 -2
  496. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  497. package/dist/pipeline/config-accessor-factory.js +1 -1
  498. package/dist/pipeline/context-services.d.ts +56 -0
  499. package/dist/pipeline/context-services.js +73 -0
  500. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  501. package/dist/pipeline/dispatch-batch.js +39 -19
  502. package/dist/pipeline/dispatch-query.js +5 -4
  503. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  504. package/dist/pipeline/dispatch-scope.js +27 -0
  505. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  506. package/dist/pipeline/dispatch-shared.js +75 -194
  507. package/dist/pipeline/dispatch-stream.js +8 -4
  508. package/dist/pipeline/dispatch-write.d.ts +2 -1
  509. package/dist/pipeline/dispatch-write.js +10 -8
  510. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  511. package/dist/pipeline/dispatcher-utils.js +8 -2
  512. package/dist/pipeline/dispatcher.d.ts +3 -2
  513. package/dist/pipeline/dispatcher.js +4 -3
  514. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  515. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  516. package/dist/pipeline/event-dispatcher-delivery.js +7 -3
  517. package/dist/pipeline/event-dispatcher.d.ts +3 -2
  518. package/dist/pipeline/event-dispatcher.js +13 -12
  519. package/dist/pipeline/event-retention.js +59 -56
  520. package/dist/pipeline/handler-access-error.js +2 -1
  521. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  522. package/dist/pipeline/handler-context-auth.js +7 -4
  523. package/dist/pipeline/handler-context-config.d.ts +2 -5
  524. package/dist/pipeline/handler-context-config.js +2 -2
  525. package/dist/pipeline/handler-context-db.d.ts +32 -7
  526. package/dist/pipeline/handler-context-db.js +26 -17
  527. package/dist/pipeline/handler-context-dispatch.d.ts +14 -6
  528. package/dist/pipeline/handler-context-dispatch.js +18 -5
  529. package/dist/pipeline/handler-context-events.d.ts +22 -38
  530. package/dist/pipeline/handler-context-events.js +42 -35
  531. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  532. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  533. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  534. package/dist/pipeline/handler-context-notify.js +1 -1
  535. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  536. package/dist/pipeline/handler-context-observability.js +7 -5
  537. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  538. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  539. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  540. package/dist/pipeline/handler-context-scope.js +18 -20
  541. package/dist/pipeline/index.d.ts +9 -21
  542. package/dist/pipeline/index.js +5 -7
  543. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  544. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  545. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  546. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  547. package/dist/pipeline/member-read-only-transaction.js +11 -3
  548. package/dist/pipeline/member-reader.d.ts +1 -1
  549. package/dist/pipeline/member-reader.js +2 -2
  550. package/dist/pipeline/msp-rebuild.js +5 -3
  551. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  552. package/dist/pipeline/notify-scope.d.ts +2 -1
  553. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  554. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  555. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  556. package/dist/pipeline/projection-rebuild.js +12 -5
  557. package/dist/pipeline/projection-state.d.ts +0 -6
  558. package/dist/pipeline/projection-state.js +0 -5
  559. package/dist/pipeline/projections-runner.d.ts +2 -1
  560. package/dist/pipeline/projections-runner.js +10 -6
  561. package/dist/pipeline/system-hooks.d.ts +6 -2
  562. package/dist/pipeline/system-hooks.js +61 -10
  563. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  564. package/dist/pipeline/system-identity-switch.js +51 -36
  565. package/dist/pipeline/typed-append-event.d.ts +2 -0
  566. package/dist/pipeline/typed-append-event.js +4 -0
  567. package/dist/pipeline/write-origin.js +2 -2
  568. package/dist/pipeline/write-result-masking.d.ts +1 -1
  569. package/dist/pipeline/write-result-masking.js +13 -10
  570. package/dist/random/index.d.ts +1 -2
  571. package/dist/random/index.js +1 -2
  572. package/dist/rate-limit/bucket.d.ts +2 -1
  573. package/dist/rate-limit/middleware.js +2 -1
  574. package/dist/redis/index.d.ts +3 -4
  575. package/dist/redis/index.js +2 -2
  576. package/dist/schema-cli/apply-command.js +5 -2
  577. package/dist/schema-cli/baseline-command.js +7 -2
  578. package/dist/schema-cli/generate-command.js +7 -9
  579. package/dist/schema-cli/shared.d.ts +4 -0
  580. package/dist/schema-cli/shared.js +21 -2
  581. package/dist/schema-cli/status-command.js +8 -2
  582. package/dist/schema-cli/validate-command.js +52 -4
  583. package/dist/schema-cli.d.ts +0 -1
  584. package/dist/search/configure-tenant-index.d.ts +1 -3
  585. package/dist/search/configure-tenant-index.js +0 -4
  586. package/dist/search/index.d.ts +1 -4
  587. package/dist/search/index.js +0 -2
  588. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  589. package/dist/search/meilisearch-adapter-internals.js +9 -0
  590. package/dist/search/meilisearch-adapter.d.ts +1 -8
  591. package/dist/search/meilisearch-adapter.js +6 -7
  592. package/dist/search/meilisearch-peer.d.ts +2 -0
  593. package/dist/search/meilisearch-peer.js +5 -0
  594. package/dist/search/reindex-entity.js +107 -91
  595. package/dist/secrets/index.d.ts +3 -4
  596. package/dist/secrets/index.js +2 -3
  597. package/dist/seeding/index.d.ts +2 -2
  598. package/dist/seeding/index.js +1 -2
  599. package/dist/time/index.d.ts +2 -2
  600. package/dist/time/index.js +1 -1
  601. package/dist/time/tz-context.d.ts +0 -5
  602. package/dist/time/tz-context.js +0 -9
  603. package/dist/ui-types/index.d.ts +8 -11
  604. package/dist/ui-types/index.js +3 -3
  605. package/dist/upgrade-changelog.d.ts +3 -0
  606. package/dist/upgrade-changelog.js +18 -0
  607. package/dist/upgrade-cli-internals.d.ts +8 -0
  608. package/dist/upgrade-cli-internals.js +63 -0
  609. package/dist/upgrade-cli.d.ts +1 -18
  610. package/dist/upgrade-cli.js +29 -137
  611. package/dist/upgrade-marker-parse.d.ts +32 -0
  612. package/dist/upgrade-marker-parse.js +73 -0
  613. package/dist/utils/import-optional-peer.d.ts +6 -0
  614. package/dist/utils/import-optional-peer.js +19 -0
  615. package/dist/utils/index.d.ts +1 -4
  616. package/dist/utils/index.js +1 -4
  617. package/package.json +27 -20
  618. package/src/changes.json +451 -0
  619. package/dist/crypto/request-kms-cache.d.ts +0 -8
  620. package/dist/crypto/request-kms-cache.js +0 -21
  621. package/dist/engine/codemod/index.d.ts +0 -2
  622. package/dist/engine/codemod/index.js +0 -1
  623. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  624. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  625. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  626. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  627. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  628. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  629. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  630. package/dist/engine/feature-ast/extractors/events.js +0 -275
  631. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  632. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  633. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  634. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  635. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  636. package/dist/engine/feature-ast/extractors/index.js +0 -13
  637. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  638. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  639. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  640. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  641. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  642. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  643. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -10
  644. package/dist/engine/feature-ast/extractors/round1.js +0 -81
  645. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  646. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  647. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  648. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  649. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  650. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  651. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  652. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  653. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  654. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  655. package/dist/engine/feature-ast/index.d.ts +0 -16
  656. package/dist/engine/feature-ast/index.js +0 -10
  657. package/dist/engine/feature-ast/parse.d.ts +0 -31
  658. package/dist/engine/feature-ast/parse.js +0 -483
  659. package/dist/engine/feature-ast/patch.d.ts +0 -210
  660. package/dist/engine/feature-ast/patch.js +0 -610
  661. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  662. package/dist/engine/feature-ast/patcher.js +0 -281
  663. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1476
  664. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1226
  665. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  666. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -210
  667. package/dist/engine/feature-ast/patterns.d.ts +0 -318
  668. package/dist/engine/feature-ast/patterns.js +0 -106
  669. package/dist/engine/feature-ast/render.d.ts +0 -47
  670. package/dist/engine/feature-ast/render.js +0 -662
  671. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  672. package/dist/engine/feature-ast/source-location.js +0 -27
  673. package/dist/engine/pattern-library/index.d.ts +0 -2
  674. package/dist/engine/pattern-library/index.js +0 -3
  675. package/dist/engine/pattern-library/library.d.ts +0 -14
  676. package/dist/engine/pattern-library/library.js +0 -93
  677. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  678. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  679. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  680. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  681. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  682. package/dist/engine/pattern-library/shared-fields.js +0 -88
  683. package/dist/engine/pattern-library/static-schemas.d.ts +0 -20
  684. package/dist/engine/pattern-library/static-schemas.js +0 -478
  685. package/dist/engine/pattern-library/types.d.ts +0 -158
  686. package/dist/engine/pattern-library/types.js +0 -36
  687. package/dist/engine/provider-plugin-context.d.ts +0 -3
  688. package/dist/engine/provider-plugin-context.js +0 -28
  689. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  690. package/dist/engine/resolve-config-or-param.js +0 -76
  691. package/src/scripts/codemod/README.md +0 -187
  692. package/src/scripts/codemod/codemod-support.ts +0 -334
  693. package/src/scripts/codemod/collect-source-files.ts +0 -48
  694. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  695. package/src/scripts/codemod/db-factory.ts +0 -810
  696. package/src/scripts/codemod/feature-factory.ts +0 -429
  697. package/src/scripts/codemod/feature-layout.ts +0 -424
  698. package/src/scripts/codemod/import-extensions.ts +0 -118
  699. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  700. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  701. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  702. package/src/scripts/codemod/object-form.ts +0 -746
  703. package/src/scripts/codemod/package-merge.ts +0 -299
  704. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  705. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  706. package/src/scripts/codemod/s3-imports.ts +0 -236
  707. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  708. package/src/scripts/codemod/testing-injection.ts +0 -215
  709. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  710. package/src/scripts/codemod/testing-move.ts +0 -542
  711. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -1,1226 +0,0 @@
1
- // Runtime validator for the `unknown → PatternChange[]` boundary. An AI
2
- // tool (or any external caller) hands us JSON; before it ever reaches
3
- // `applyChanges` it must pass through here. Every rejection carries an
4
- // exact dotted/bracketed path so the caller (frequently an LLM) can
5
- // self-correct without a human in the loop.
6
- //
7
- // **Zod v4 constraint driving this file's shape:** every discriminated-
8
- // union member below stays a plain `z.object(...)` (or `.superRefine`
9
- // wrapper around one) — never `.transform()` at the object level. A
10
- // whole-object transform would erase the "which member matched" signal
11
- // `discriminatedUnion` needs to attribute a nested field error to the
12
- // right member, and it would blur per-member `.strict()` unrecognized-key
13
- // detection. Transforms only ever touch a single field (`sourceBody`,
14
- // below) — never the object they live on.
15
- //
16
- // **Deep definitions stay opaque.** EntityDefinition, ScreenDefinition,
17
- // NavDefinition, WorkspaceDefinition, JobDefinition-options, MetricOptions,
18
- // etc. are NOT hand-modeled here — that would fork a second, driftable
19
- // catalogue of their shape. They're accepted via `z.custom` (plain object,
20
- // or a RawRefSentinel/AiStepOpaqueArgs — the extractor's own "couldn't
21
- // resolve this statically" markers) and, for EntityDefinition only,
22
- // additionally checked for field-type membership via the shared
23
- // `findUnknownEntityFieldTypes` helper (kept in sync with `extractEntity`).
24
- import { ESCAPE_HATCH_GRANTS } from "@cosmicdrift/kumiko-types/handlers";
25
- import * as z from "zod";
26
- import { LifecycleHookTypes } from "../constants.js";
27
- import { describeUnknownFieldType, findUnknownEntityFieldTypes } from "./entity-field-types.js";
28
- import { AGENT_RISK_VALUES } from "./extractors/handlers.js";
29
- import { isPlainObject, isRawRefSentinel } from "./extractors/shared.js";
30
- import { SYNTHETIC_LOC } from "./patcher.js";
31
- // Derives an exhaustive literal-value array from a `Record<T, true>` flag
32
- // map: an added/removed union member fails to compile here instead of
33
- // silently producing a schema narrower than the runtime type — same
34
- // rationale as kumiko-types's `NO_WIDGET_FIELD_TYPES`/`FIELD_TYPE_NAMES`.
35
- function keysOf(flags) {
36
- return Object.keys(flags);
37
- }
38
- // =============================================================================
39
- // Shared primitives
40
- // =============================================================================
41
- function isPlainObjectOrSentinel(value) {
42
- return isRawRefSentinel(value) || isPlainObject(value);
43
- }
44
- const sourcePositionSchema = z
45
- .object({ line: z.number(), column: z.number() })
46
- .strict();
47
- const fullSourceLocationSchema = z
48
- .object({
49
- file: z.string(),
50
- start: sourcePositionSchema,
51
- end: sourcePositionSchema,
52
- raw: z.string(),
53
- })
54
- .strict();
55
- // Partial object form — only `raw` is meaningful, `file`/`start`/`end` (if
56
- // present) are accepted but discarded: a wire producer sending a
57
- // half-populated location is telling us "this came from generated code, not
58
- // a real file span" and `rawLoc` is exactly that contract.
59
- const partialSourceLocationSchema = z
60
- .object({
61
- raw: z.string(),
62
- file: z.string().optional(),
63
- start: sourcePositionSchema.optional(),
64
- end: sourcePositionSchema.optional(),
65
- })
66
- .strict()
67
- .transform((value) => ({ ...SYNTHETIC_LOC, raw: value.raw }));
68
- const stringSourceLocationSchema = z
69
- .string()
70
- .transform((raw) => ({ ...SYNTHETIC_LOC, raw }));
71
- // `sourceBody`: string | {raw, file?, start?, end?} | full SourceLocation.
72
- // Order matters — a fully-populated object must match `fullSourceLocationSchema`
73
- // first so it round-trips unchanged; only a partial object falls through to
74
- // the raw-collapsing variant.
75
- const sourceBodySchema = z.union([
76
- fullSourceLocationSchema,
77
- partialSourceLocationSchema,
78
- stringSourceLocationSchema,
79
- ]);
80
- const nonEmptySourceBodySchema = sourceBodySchema.refine((loc) => loc.raw.trim().length > 0, {
81
- message: "source.raw must be non-empty",
82
- });
83
- // The pattern-level `source` field: optional on the wire, defaults to the
84
- // patcher's own synthetic placeholder (mirrors createFeaturePatcher's
85
- // add{Kind} methods, which never have a real file span either).
86
- const sourceFieldSchema = sourceBodySchema
87
- .optional()
88
- .default(SYNTHETIC_LOC);
89
- // `readVarargsOrArrayProp` (extractors/shared.ts) already types a mixed
90
- // string/sentinel array as `readonly string[]` at its own extraction
91
- // boundary (requires.featureNames, readsConfig.qualifiedKeys); mirror that
92
- // same typed lie here instead of re-deriving a wider array type only to
93
- // cast it back down.
94
- const stringOrRawRefListSchema = z.custom((value) => Array.isArray(value) && value.every((el) => typeof el === "string" || isRawRefSentinel(el)), { message: "must be an array of strings or unresolved references" });
95
- // Runtime source of truth for the lifecycle-hook-type literals: the
96
- // engine's own `LifecycleHookTypes` const object (engine/constants.ts) —
97
- // `hook`'s `hookType` is that union plus the AST-only "validation" pseudo-
98
- // type (r.hook(type: "validation", ...) has no runtime LifecycleHookType
99
- // counterpart, it maps to a different registrar call).
100
- const LIFECYCLE_HOOK_TYPE_VALUES = Object.values(LifecycleHookTypes);
101
- const hookTypeSchema = z.enum([...LIFECYCLE_HOOK_TYPE_VALUES, "validation"]);
102
- const hookPhaseSchema = z.enum(keysOf({ inTransaction: true, afterCommit: true }));
103
- const httpRouteMethodSchema = z.enum(keysOf({
104
- GET: true,
105
- POST: true,
106
- PUT: true,
107
- PATCH: true,
108
- DELETE: true,
109
- HEAD: true,
110
- OPTIONS: true,
111
- }));
112
- const runInSchema = z.enum(keysOf({ api: true, worker: true, both: true }));
113
- const claimKeyTypeSchema = z.enum(keysOf({
114
- string: true,
115
- number: true,
116
- boolean: true,
117
- "string[]": true,
118
- object: true,
119
- }));
120
- const agentRiskSchema = z.enum(AGENT_RISK_VALUES);
121
- const rateLimitPerSchema = z.enum(keysOf({
122
- user: true,
123
- tenant: true,
124
- ip: true,
125
- "user+handler": true,
126
- "tenant+handler": true,
127
- "ip+handler": true,
128
- }));
129
- const mspDeliverySchema = z.enum(keysOf({ shared: true, "per-instance": true }));
130
- const escapeHatchSchema = z
131
- .object({
132
- reason: z.string().refine((s) => s.trim().length > 0, {
133
- message: "reason must be non-empty",
134
- }),
135
- grants: z.array(z.enum(ESCAPE_HATCH_GRANTS)).min(1).optional(),
136
- })
137
- .strict();
138
- const rawRefSentinelSchema = z.object({ __raw: z.string() }).strict();
139
- // Adds the raw-ref-sentinel branch a handler header field accepts when the
140
- // extractor couldn't resolve it to a literal (see extractors/hooks.ts).
141
- function orRawRef(schema) {
142
- return z.union([schema, rawRefSentinelSchema]);
143
- }
144
- const rateLimitDisabledSchema = z
145
- .object({
146
- disabled: z.literal(true),
147
- reason: z.string().refine((s) => s.trim().length > 0, {
148
- message: "reason must be non-empty",
149
- }),
150
- })
151
- .strict();
152
- const rateLimitOptionSchema = z
153
- .object({
154
- per: rateLimitPerSchema,
155
- limit: z.number(),
156
- windowSeconds: z.number(),
157
- cost: z.number().optional(),
158
- })
159
- .strict();
160
- const rateLimitOptionListSchema = z.tuple([rateLimitOptionSchema], rateLimitOptionSchema);
161
- const additionalRateLimitsSchema = z.array(z
162
- .object({
163
- per: z.object({ payloadField: z.string() }).strict(),
164
- limit: z.number(),
165
- windowSeconds: z.number(),
166
- cost: z.number().optional(),
167
- normalize: z.literal("email").optional(),
168
- })
169
- .strict());
170
- const agentHandlerHintsSchema = z
171
- .object({
172
- expose: z.boolean().optional(),
173
- risk: agentRiskSchema.optional(),
174
- })
175
- .strict();
176
- // AccessRule — DEFAULT-DENY per its doc in types/handlers.ts; a malformed
177
- // shape must be rejected, not silently narrowed to "no access" (that would
178
- // hide the author's mistake instead of reporting it at the boundary).
179
- const roleAccessRuleSchema = z
180
- .object({
181
- roles: z.array(z.string()),
182
- personalData: z.literal("public-intake").optional(),
183
- })
184
- .strict();
185
- const openToAllAccessRuleSchema = z
186
- .object({
187
- openToAll: z
188
- .object({
189
- reason: z.string().refine((s) => s.trim().length > 0, {
190
- message: "openToAll.reason must be non-empty",
191
- }),
192
- personalData: z.literal("tenant-members").optional(),
193
- })
194
- .strict(),
195
- })
196
- .strict();
197
- const accessRuleSchema = z.union([roleAccessRuleSchema, openToAllAccessRuleSchema]);
198
- // Header keys per handler kind — drift pin against patch.ts's *HeaderKey
199
- // types (via `satisfies`), and the source the schemas below derive from.
200
- const WRITE_HANDLER_HEADER_SHAPE = {
201
- access: accessRuleSchema,
202
- description: z.string(),
203
- agent: agentHandlerHintsSchema,
204
- rateLimit: rateLimitOptionSchema,
205
- additionalRateLimits: additionalRateLimitsSchema,
206
- unsafeSkipTransitionGuard: z.boolean(),
207
- escapeHatch: escapeHatchSchema,
208
- };
209
- const QUERY_HANDLER_HEADER_SHAPE = {
210
- access: accessRuleSchema,
211
- description: z.string(),
212
- agent: agentHandlerHintsSchema,
213
- rateLimit: rateLimitOptionSchema,
214
- escapeHatch: escapeHatchSchema,
215
- };
216
- const STREAM_HANDLER_HEADER_SHAPE = {
217
- access: accessRuleSchema,
218
- rateLimit: rateLimitOptionSchema,
219
- escapeHatch: escapeHatchSchema,
220
- };
221
- const WRITE_HANDLER_HEADER_KEYS = z.object(WRITE_HANDLER_HEADER_SHAPE).keyof().options;
222
- const QUERY_HANDLER_HEADER_KEYS = z.object(QUERY_HANDLER_HEADER_SHAPE).keyof().options;
223
- const STREAM_HANDLER_HEADER_KEYS = z.object(STREAM_HANDLER_HEADER_SHAPE).keyof().options;
224
- // `update`'s set-schema stays exactly as strict as the extractor's own
225
- // output: Designer/AI-authored values must be structured, never a raw
226
- // reference or a partially-literal shape — those only ever come from
227
- // statically parsed source, not from a `set` payload.
228
- const WRITE_HANDLER_UPDATE_SET_SCHEMA = z.object(WRITE_HANDLER_HEADER_SHAPE).partial().strict();
229
- const QUERY_HANDLER_UPDATE_SET_SCHEMA = z.object(QUERY_HANDLER_HEADER_SHAPE).partial().strict();
230
- const STREAM_HANDLER_UPDATE_SET_SCHEMA = z.object(STREAM_HANDLER_HEADER_SHAPE).partial().strict();
231
- // `unset` may name any header field except `access` (always required).
232
- const WRITE_HANDLER_UPDATE_UNSET_ENUM = z
233
- .object(WRITE_HANDLER_HEADER_SHAPE)
234
- .omit({ access: true })
235
- .keyof();
236
- const QUERY_HANDLER_UPDATE_UNSET_ENUM = z
237
- .object(QUERY_HANDLER_HEADER_SHAPE)
238
- .omit({ access: true })
239
- .keyof();
240
- const STREAM_HANDLER_UPDATE_UNSET_ENUM = z
241
- .object(STREAM_HANDLER_HEADER_SHAPE)
242
- .omit({ access: true })
243
- .keyof();
244
- // Full patterns (add/replace) carry whatever the extractor parsed, which
245
- // may be a RawRefSentinel or a disabled-rate-limit shape it can't resolve
246
- // to a literal; widen only here, not on UPDATE_SET_SCHEMA above.
247
- const WRITE_HANDLER_PATTERN_HEADER_SHAPE = {
248
- ...WRITE_HANDLER_HEADER_SHAPE,
249
- access: orRawRef(accessRuleSchema),
250
- agent: orRawRef(agentHandlerHintsSchema),
251
- rateLimit: orRawRef(z.union([rateLimitOptionSchema, rateLimitOptionListSchema, rateLimitDisabledSchema])),
252
- additionalRateLimits: orRawRef(additionalRateLimitsSchema),
253
- escapeHatch: orRawRef(escapeHatchSchema),
254
- };
255
- const QUERY_HANDLER_PATTERN_HEADER_SHAPE = {
256
- ...QUERY_HANDLER_HEADER_SHAPE,
257
- access: orRawRef(accessRuleSchema),
258
- agent: orRawRef(agentHandlerHintsSchema),
259
- rateLimit: orRawRef(z.union([rateLimitOptionSchema, rateLimitOptionListSchema, rateLimitDisabledSchema])),
260
- escapeHatch: orRawRef(escapeHatchSchema),
261
- };
262
- const STREAM_HANDLER_PATTERN_HEADER_SHAPE = {
263
- ...STREAM_HANDLER_HEADER_SHAPE,
264
- access: orRawRef(accessRuleSchema),
265
- rateLimit: orRawRef(z.union([rateLimitOptionSchema, rateLimitOptionListSchema, rateLimitDisabledSchema])),
266
- escapeHatch: orRawRef(escapeHatchSchema),
267
- };
268
- function requireHandlerBody(val, ctx, headerKeys) {
269
- const hasAny = val.handlerName !== undefined ||
270
- val.schemaSource !== undefined ||
271
- val.handlerBody !== undefined;
272
- if (!hasAny) {
273
- if (val.source.raw.trim().length === 0) {
274
- ctx.addIssue({
275
- code: "custom",
276
- path: ["source"],
277
- message: "an opaque handler reference (no handlerName/schemaSource/handlerBody) requires a non-empty source.raw",
278
- });
279
- }
280
- for (const key of headerKeys) {
281
- if (val[key] !== undefined) {
282
- ctx.addIssue({
283
- code: "custom",
284
- path: [key],
285
- message: "not rendered for an opaque handler reference; provide handlerName, schemaSource and handlerBody",
286
- });
287
- }
288
- }
289
- // skip: opaque handler reference carries no name/schema/body to require
290
- return;
291
- }
292
- if (val.handlerName === undefined || val.handlerName.trim().length === 0) {
293
- ctx.addIssue({
294
- code: "custom",
295
- path: ["handlerName"],
296
- message: "handlerName is required and must be non-empty",
297
- });
298
- }
299
- if (val.schemaSource === undefined) {
300
- ctx.addIssue({ code: "custom", path: ["schemaSource"], message: "schemaSource is required" });
301
- }
302
- if (val.handlerBody === undefined) {
303
- ctx.addIssue({ code: "custom", path: ["handlerBody"], message: "handlerBody is required" });
304
- }
305
- }
306
- // =============================================================================
307
- // Static patterns
308
- // =============================================================================
309
- // Deep-definition passthrough: accepts a plain object OR the extractor's
310
- // own "couldn't resolve this statically" sentinel (RawRefSentinel), typed
311
- // as `T` at the boundary — the same "typed lie" the extractors already
312
- // make (e.g. round2.ts's `definition as EntityDefinition`), because a
313
- // sentinel-bearing value is never actually shaped like `T` at runtime, but
314
- // round-trips through `applyChanges`/the renderer unexamined either way.
315
- function passthroughSchema() {
316
- return z.custom(isPlainObjectOrSentinel, {
317
- message: "must be a plain object or unresolved reference",
318
- });
319
- }
320
- const entityDefinitionSchema = passthroughSchema().superRefine((value, ctx) => {
321
- for (const entry of findUnknownEntityFieldTypes(value)) {
322
- ctx.addIssue({
323
- code: "custom",
324
- path: ["fields", entry.fieldName, "type"],
325
- message: describeUnknownFieldType(entry),
326
- });
327
- }
328
- });
329
- const entitySchema = z
330
- .object({
331
- kind: z.literal("entity"),
332
- source: sourceFieldSchema,
333
- entityName: z.string(),
334
- definition: entityDefinitionSchema,
335
- backingTable: passthroughSchema().optional(),
336
- })
337
- .strict();
338
- const relationSchema = z
339
- .object({
340
- kind: z.literal("relation"),
341
- source: sourceFieldSchema,
342
- entityName: z.string(),
343
- relationName: z.string(),
344
- definition: passthroughSchema(),
345
- })
346
- .strict();
347
- const navSchema = z
348
- .object({
349
- kind: z.literal("nav"),
350
- source: sourceFieldSchema,
351
- definition: passthroughSchema(),
352
- })
353
- .strict();
354
- const workspaceSchema = z
355
- .object({
356
- kind: z.literal("workspace"),
357
- source: sourceFieldSchema,
358
- definition: passthroughSchema(),
359
- })
360
- .strict();
361
- const configSchema = z
362
- .object({
363
- kind: z.literal("config"),
364
- source: sourceFieldSchema,
365
- keys: passthroughSchema(),
366
- })
367
- .strict();
368
- const translationsSchema = z
369
- .object({
370
- kind: z.literal("translations"),
371
- source: sourceFieldSchema,
372
- keys: passthroughSchema(),
373
- })
374
- .strict();
375
- const requiresSchema = z
376
- .object({
377
- kind: z.literal("requires"),
378
- source: sourceFieldSchema,
379
- featureNames: stringOrRawRefListSchema,
380
- })
381
- .strict();
382
- const optionalRequiresSchema = z
383
- .object({
384
- kind: z.literal("optionalRequires"),
385
- source: sourceFieldSchema,
386
- featureNames: stringOrRawRefListSchema,
387
- })
388
- .strict();
389
- const systemScopeSchema = z
390
- .object({
391
- kind: z.literal("systemScope"),
392
- source: sourceFieldSchema,
393
- })
394
- .strict();
395
- const toggleableSchema = z
396
- .object({
397
- kind: z.literal("toggleable"),
398
- source: sourceFieldSchema,
399
- default: z.boolean(),
400
- })
401
- .strict();
402
- const describeSchema = z
403
- .object({
404
- kind: z.literal("describe"),
405
- source: sourceFieldSchema,
406
- text: z.string().refine((s) => s.trim().length > 0, { message: "text must be non-empty" }),
407
- })
408
- .strict();
409
- const uiHintsSchema = z
410
- .object({
411
- kind: z.literal("uiHints"),
412
- source: nonEmptySourceBodySchema,
413
- })
414
- .strict();
415
- const metricSchema = z
416
- .object({
417
- kind: z.literal("metric"),
418
- source: sourceFieldSchema,
419
- shortName: z.string(),
420
- options: passthroughSchema(),
421
- })
422
- .strict();
423
- const secretSchema = z
424
- .object({
425
- kind: z.literal("secret"),
426
- source: sourceFieldSchema,
427
- shortName: z.string(),
428
- options: passthroughSchema(),
429
- })
430
- .strict();
431
- const secretNamespaceSchema = z
432
- .object({
433
- kind: z.literal("secretNamespace"),
434
- source: sourceFieldSchema,
435
- shortName: z.string(),
436
- options: passthroughSchema(),
437
- })
438
- .strict();
439
- const claimKeySchema = z
440
- .object({
441
- kind: z.literal("claimKey"),
442
- source: sourceFieldSchema,
443
- shortName: z.string(),
444
- claimType: claimKeyTypeSchema,
445
- })
446
- .strict();
447
- const referenceDataSchema = z
448
- .object({
449
- kind: z.literal("referenceData"),
450
- source: sourceFieldSchema,
451
- entityName: z.string(),
452
- data: z.custom((value) => Array.isArray(value) || isRawRefSentinel(value), { message: "data must be an array or unresolved reference" }),
453
- upsertKey: z.string().optional(),
454
- })
455
- .strict();
456
- const readsConfigSchema = z
457
- .object({
458
- kind: z.literal("readsConfig"),
459
- source: sourceFieldSchema,
460
- qualifiedKeys: stringOrRawRefListSchema,
461
- })
462
- .strict();
463
- const useExtensionSchema = z
464
- .object({
465
- kind: z.literal("useExtension"),
466
- source: sourceFieldSchema,
467
- extensionName: z.string(),
468
- extensionNameRaw: z.string().optional(),
469
- entityName: z.string(),
470
- options: passthroughSchema().optional(),
471
- })
472
- .strict();
473
- const usesApiSchema = z
474
- .object({
475
- kind: z.literal("usesApi"),
476
- source: sourceFieldSchema,
477
- apiName: z.string(),
478
- })
479
- .strict();
480
- const exposesApiSchema = z
481
- .object({
482
- kind: z.literal("exposesApi"),
483
- source: sourceFieldSchema,
484
- apiName: z.string(),
485
- })
486
- .strict();
487
- const treeActionsSchema = z
488
- .object({
489
- kind: z.literal("treeActions"),
490
- source: sourceFieldSchema,
491
- definitions: passthroughSchema(),
492
- })
493
- .strict();
494
- // =============================================================================
495
- // Mixed patterns
496
- // =============================================================================
497
- const screenSchema = z
498
- .object({
499
- kind: z.literal("screen"),
500
- source: sourceFieldSchema,
501
- definition: passthroughSchema(),
502
- opaqueProps: z.record(z.string(), sourceBodySchema).optional().default({}),
503
- })
504
- .strict();
505
- const writeHandlerSchema = z
506
- .object({
507
- kind: z.literal("writeHandler"),
508
- source: sourceFieldSchema,
509
- handlerName: z.string().optional(),
510
- schemaSource: sourceBodySchema.optional(),
511
- handlerBody: sourceBodySchema.optional(),
512
- ...z.object(WRITE_HANDLER_PATTERN_HEADER_SHAPE).partial().shape,
513
- })
514
- .strict()
515
- .superRefine((val, ctx) => requireHandlerBody(val, ctx, WRITE_HANDLER_HEADER_KEYS));
516
- const queryHandlerSchema = z
517
- .object({
518
- kind: z.literal("queryHandler"),
519
- source: sourceFieldSchema,
520
- handlerName: z.string().optional(),
521
- schemaSource: sourceBodySchema.optional(),
522
- handlerBody: sourceBodySchema.optional(),
523
- ...z.object(QUERY_HANDLER_PATTERN_HEADER_SHAPE).partial().shape,
524
- })
525
- .strict()
526
- .superRefine((val, ctx) => requireHandlerBody(val, ctx, QUERY_HANDLER_HEADER_KEYS));
527
- const streamHandlerSchema = z
528
- .object({
529
- kind: z.literal("streamHandler"),
530
- source: sourceFieldSchema,
531
- handlerName: z.string().optional(),
532
- schemaSource: sourceBodySchema.optional(),
533
- handlerBody: sourceBodySchema.optional(),
534
- ...z.object(STREAM_HANDLER_PATTERN_HEADER_SHAPE).partial().shape,
535
- })
536
- .strict()
537
- .superRefine((val, ctx) => requireHandlerBody(val, ctx, STREAM_HANDLER_HEADER_KEYS));
538
- const hookTargetSchema = z.union([
539
- z.string(),
540
- z.array(z.string()),
541
- z.object({ allOf: z.string() }).strict(),
542
- ]);
543
- const hookSchema = z
544
- .object({
545
- kind: z.literal("hook"),
546
- source: sourceFieldSchema,
547
- hookType: hookTypeSchema,
548
- target: hookTargetSchema,
549
- fnBody: sourceBodySchema,
550
- phase: hookPhaseSchema.optional(),
551
- escapeHatch: orRawRef(escapeHatchSchema).optional(),
552
- })
553
- .strict();
554
- const jobSchema = z
555
- .object({
556
- kind: z.literal("job"),
557
- source: sourceFieldSchema,
558
- jobName: z.string(),
559
- options: passthroughSchema(),
560
- handlerBody: sourceBodySchema,
561
- })
562
- .strict();
563
- const notificationSchema = z
564
- .object({
565
- kind: z.literal("notification"),
566
- source: sourceFieldSchema,
567
- notificationName: z.string(),
568
- trigger: z.object({ on: z.string() }).strict().optional(),
569
- recipientBody: sourceBodySchema.optional(),
570
- dataBody: sourceBodySchema.optional(),
571
- templates: z.record(z.string(), sourceBodySchema).optional(),
572
- })
573
- .strict();
574
- const authClaimsSchema = z
575
- .object({
576
- kind: z.literal("authClaims"),
577
- source: sourceFieldSchema,
578
- fnBody: sourceBodySchema,
579
- })
580
- .strict();
581
- const httpRouteSchema = z
582
- .object({
583
- kind: z.literal("httpRoute"),
584
- source: sourceFieldSchema,
585
- method: httpRouteMethodSchema,
586
- path: z.string(),
587
- anonymous: z.boolean(),
588
- handlerBody: sourceBodySchema,
589
- })
590
- .strict();
591
- const projectionSchema = z
592
- .object({
593
- kind: z.literal("projection"),
594
- source: sourceFieldSchema,
595
- name: z.string(),
596
- sourceEntity: z.union([z.string(), z.array(z.string())]),
597
- applyBodies: z.record(z.string(), sourceBodySchema),
598
- })
599
- .strict();
600
- const mspErrorPolicySchema = z.object({ skipApplyErrors: z.boolean().optional() }).strict();
601
- const mspErrorModeSchema = z
602
- .object({
603
- continuous: mspErrorPolicySchema.optional(),
604
- rebuild: mspErrorPolicySchema.optional(),
605
- })
606
- .strict();
607
- const multiStreamProjectionSchema = z
608
- .object({
609
- kind: z.literal("multiStreamProjection"),
610
- source: sourceFieldSchema,
611
- name: z.string(),
612
- applyBodies: z.record(z.string(), sourceBodySchema),
613
- errorMode: mspErrorModeSchema.optional(),
614
- runIn: runInSchema.optional(),
615
- delivery: mspDeliverySchema.optional(),
616
- })
617
- .strict();
618
- const defineEventSchema = z
619
- .object({
620
- kind: z.literal("defineEvent"),
621
- source: sourceFieldSchema,
622
- eventName: z.string(),
623
- eventNameRaw: z.string().optional(),
624
- schemaSource: sourceBodySchema,
625
- version: z.number().optional(),
626
- piiFields: sourceBodySchema,
627
- migrations: z.record(z.string(), sourceBodySchema).optional(),
628
- })
629
- .strict();
630
- const extendsRegistrarSchema = z
631
- .object({
632
- kind: z.literal("extendsRegistrar"),
633
- source: sourceFieldSchema,
634
- extensionName: z.string(),
635
- extensionNameRaw: z.string().optional(),
636
- defBody: sourceBodySchema,
637
- })
638
- .strict();
639
- const envSchemaSchema = z
640
- .object({
641
- kind: z.literal("envSchema"),
642
- source: sourceFieldSchema,
643
- schemaBody: sourceBodySchema,
644
- })
645
- .strict();
646
- const aiStepOpaqueArgsSchema = z.custom(isRawRefSentinel, {
647
- message: "must be an unresolved reference ({ __raw })",
648
- });
649
- const aiStepPolicySchema = z
650
- .object({
651
- enabled: z.boolean(),
652
- providerId: z.string().optional(),
653
- model: z.string().optional(),
654
- params: z.custom(isPlainObject, {
655
- message: "params must be a plain object",
656
- }),
657
- })
658
- .strict();
659
- const stringOrAiOpaqueSchema = z.union([z.string(), aiStepOpaqueArgsSchema]);
660
- const aiStepPolicyOrOpaqueSchema = z.union([aiStepPolicySchema, aiStepOpaqueArgsSchema]);
661
- const aiGenerateSchema = z
662
- .object({
663
- kind: z.literal("ai.generate"),
664
- source: sourceFieldSchema,
665
- argsSource: aiStepOpaqueArgsSchema.optional(),
666
- stepKey: stringOrAiOpaqueSchema.optional(),
667
- promptKey: stringOrAiOpaqueSchema.optional(),
668
- promptFallback: stringOrAiOpaqueSchema.optional(),
669
- defaults: aiStepPolicyOrOpaqueSchema.optional(),
670
- paramsSchemaSource: sourceBodySchema.optional(),
671
- inputBody: sourceBodySchema.optional(),
672
- })
673
- .strict();
674
- const aiExtractSchema = z
675
- .object({
676
- kind: z.literal("ai.extract"),
677
- source: sourceFieldSchema,
678
- argsSource: aiStepOpaqueArgsSchema.optional(),
679
- stepKey: stringOrAiOpaqueSchema.optional(),
680
- promptKey: stringOrAiOpaqueSchema.optional(),
681
- promptFallback: stringOrAiOpaqueSchema.optional(),
682
- defaults: aiStepPolicyOrOpaqueSchema.optional(),
683
- paramsSchemaSource: sourceBodySchema.optional(),
684
- outputSchemaSource: sourceBodySchema.optional(),
685
- instructionsBody: sourceBodySchema.optional(),
686
- documentBody: sourceBodySchema.optional(),
687
- })
688
- .strict();
689
- const aiClassifySchema = z
690
- .object({
691
- kind: z.literal("ai.classify"),
692
- source: sourceFieldSchema,
693
- argsSource: aiStepOpaqueArgsSchema.optional(),
694
- stepKey: stringOrAiOpaqueSchema.optional(),
695
- promptKey: stringOrAiOpaqueSchema.optional(),
696
- promptFallback: stringOrAiOpaqueSchema.optional(),
697
- defaults: aiStepPolicyOrOpaqueSchema.optional(),
698
- paramsSchemaSource: sourceBodySchema.optional(),
699
- actions: z.array(z.object({ type: z.string(), description: z.string() }).strict()).optional(),
700
- inputBody: sourceBodySchema.optional(),
701
- })
702
- .strict();
703
- // =============================================================================
704
- // Catch-all
705
- // =============================================================================
706
- const unknownPatternSchema = z
707
- .object({
708
- kind: z.literal("unknown"),
709
- source: nonEmptySourceBodySchema,
710
- methodName: z.string(),
711
- })
712
- .strict();
713
- // =============================================================================
714
- // Pattern union — Record keyed by kind doubles as the exhaustiveness pin
715
- // consumed by the compile-time typtest (a missing/renamed kind fails to
716
- // compile here, same contract as patterns.ts's own switch statements).
717
- // =============================================================================
718
- export const PATTERN_SCHEMAS_BY_KIND = {
719
- entity: entitySchema,
720
- relation: relationSchema,
721
- nav: navSchema,
722
- workspace: workspaceSchema,
723
- config: configSchema,
724
- translations: translationsSchema,
725
- requires: requiresSchema,
726
- optionalRequires: optionalRequiresSchema,
727
- systemScope: systemScopeSchema,
728
- toggleable: toggleableSchema,
729
- describe: describeSchema,
730
- uiHints: uiHintsSchema,
731
- metric: metricSchema,
732
- secret: secretSchema,
733
- secretNamespace: secretNamespaceSchema,
734
- claimKey: claimKeySchema,
735
- referenceData: referenceDataSchema,
736
- readsConfig: readsConfigSchema,
737
- useExtension: useExtensionSchema,
738
- usesApi: usesApiSchema,
739
- exposesApi: exposesApiSchema,
740
- treeActions: treeActionsSchema,
741
- screen: screenSchema,
742
- writeHandler: writeHandlerSchema,
743
- queryHandler: queryHandlerSchema,
744
- streamHandler: streamHandlerSchema,
745
- hook: hookSchema,
746
- job: jobSchema,
747
- notification: notificationSchema,
748
- authClaims: authClaimsSchema,
749
- httpRoute: httpRouteSchema,
750
- projection: projectionSchema,
751
- multiStreamProjection: multiStreamProjectionSchema,
752
- defineEvent: defineEventSchema,
753
- extendsRegistrar: extendsRegistrarSchema,
754
- envSchema: envSchemaSchema,
755
- "ai.generate": aiGenerateSchema,
756
- "ai.extract": aiExtractSchema,
757
- "ai.classify": aiClassifySchema,
758
- unknown: unknownPatternSchema,
759
- };
760
- export const patternSchema = z.discriminatedUnion("kind", [
761
- entitySchema,
762
- relationSchema,
763
- navSchema,
764
- workspaceSchema,
765
- configSchema,
766
- translationsSchema,
767
- requiresSchema,
768
- optionalRequiresSchema,
769
- systemScopeSchema,
770
- toggleableSchema,
771
- describeSchema,
772
- uiHintsSchema,
773
- metricSchema,
774
- secretSchema,
775
- secretNamespaceSchema,
776
- claimKeySchema,
777
- referenceDataSchema,
778
- readsConfigSchema,
779
- useExtensionSchema,
780
- usesApiSchema,
781
- exposesApiSchema,
782
- treeActionsSchema,
783
- screenSchema,
784
- writeHandlerSchema,
785
- queryHandlerSchema,
786
- streamHandlerSchema,
787
- hookSchema,
788
- jobSchema,
789
- notificationSchema,
790
- authClaimsSchema,
791
- httpRouteSchema,
792
- projectionSchema,
793
- multiStreamProjectionSchema,
794
- defineEventSchema,
795
- extendsRegistrarSchema,
796
- envSchemaSchema,
797
- aiGenerateSchema,
798
- aiExtractSchema,
799
- aiClassifySchema,
800
- unknownPatternSchema,
801
- ]);
802
- // =============================================================================
803
- // PatternId union
804
- // =============================================================================
805
- const patternIdEntitySchema = z
806
- .object({ kind: z.literal("entity"), entityName: z.string() })
807
- .strict();
808
- const patternIdRelationSchema = z
809
- .object({ kind: z.literal("relation"), entityName: z.string(), relationName: z.string() })
810
- .strict();
811
- const patternIdNavSchema = z.object({ kind: z.literal("nav"), id: z.string() }).strict();
812
- const patternIdWorkspaceSchema = z
813
- .object({ kind: z.literal("workspace"), id: z.string() })
814
- .strict();
815
- const patternIdScreenSchema = z.object({ kind: z.literal("screen"), id: z.string() }).strict();
816
- const patternIdWriteHandlerSchema = z
817
- .object({ kind: z.literal("writeHandler"), handlerName: z.string() })
818
- .strict();
819
- const patternIdQueryHandlerSchema = z
820
- .object({ kind: z.literal("queryHandler"), handlerName: z.string() })
821
- .strict();
822
- const patternIdStreamHandlerSchema = z
823
- .object({ kind: z.literal("streamHandler"), handlerName: z.string() })
824
- .strict();
825
- const patternIdHookSchema = z
826
- .object({
827
- kind: z.literal("hook"),
828
- hookType: z.string(),
829
- target: z.union([z.string(), z.object({ allOf: z.string() }).strict()]),
830
- })
831
- .strict();
832
- const patternIdMetricSchema = z
833
- .object({ kind: z.literal("metric"), shortName: z.string() })
834
- .strict();
835
- const patternIdSecretSchema = z
836
- .object({ kind: z.literal("secret"), shortName: z.string() })
837
- .strict();
838
- const patternIdSecretNamespaceSchema = z
839
- .object({ kind: z.literal("secretNamespace"), shortName: z.string() })
840
- .strict();
841
- const patternIdClaimKeySchema = z
842
- .object({ kind: z.literal("claimKey"), shortName: z.string() })
843
- .strict();
844
- const patternIdReferenceDataSchema = z
845
- .object({ kind: z.literal("referenceData"), entityName: z.string() })
846
- .strict();
847
- const patternIdUseExtensionSchema = z
848
- .object({ kind: z.literal("useExtension"), extensionName: z.string(), entityName: z.string() })
849
- .strict();
850
- const patternIdJobSchema = z.object({ kind: z.literal("job"), jobName: z.string() }).strict();
851
- const patternIdNotificationSchema = z
852
- .object({ kind: z.literal("notification"), notificationName: z.string() })
853
- .strict();
854
- const patternIdHttpRouteSchema = z
855
- .object({ kind: z.literal("httpRoute"), method: z.string(), path: z.string() })
856
- .strict();
857
- const patternIdProjectionSchema = z
858
- .object({ kind: z.literal("projection"), name: z.string() })
859
- .strict();
860
- const patternIdMultiStreamProjectionSchema = z
861
- .object({ kind: z.literal("multiStreamProjection"), name: z.string() })
862
- .strict();
863
- const patternIdDefineEventSchema = z
864
- .object({ kind: z.literal("defineEvent"), eventName: z.string() })
865
- .strict();
866
- const patternIdExtendsRegistrarSchema = z
867
- .object({ kind: z.literal("extendsRegistrar"), extensionName: z.string() })
868
- .strict();
869
- const patternIdAiGenerateSchema = z
870
- .object({ kind: z.literal("ai.generate"), stepKey: z.string() })
871
- .strict();
872
- const patternIdAiExtractSchema = z
873
- .object({ kind: z.literal("ai.extract"), stepKey: z.string() })
874
- .strict();
875
- const patternIdAiClassifySchema = z
876
- .object({ kind: z.literal("ai.classify"), stepKey: z.string() })
877
- .strict();
878
- const patternIdRequiresSchema = z.object({ kind: z.literal("requires") }).strict();
879
- const patternIdOptionalRequiresSchema = z.object({ kind: z.literal("optionalRequires") }).strict();
880
- const patternIdReadsConfigSchema = z.object({ kind: z.literal("readsConfig") }).strict();
881
- const patternIdSystemScopeSchema = z.object({ kind: z.literal("systemScope") }).strict();
882
- const patternIdToggleableSchema = z.object({ kind: z.literal("toggleable") }).strict();
883
- const patternIdDescribeSchema = z.object({ kind: z.literal("describe") }).strict();
884
- const patternIdUiHintsSchema = z.object({ kind: z.literal("uiHints") }).strict();
885
- const patternIdConfigSchema = z.object({ kind: z.literal("config") }).strict();
886
- const patternIdTranslationsSchema = z.object({ kind: z.literal("translations") }).strict();
887
- const patternIdAuthClaimsSchema = z.object({ kind: z.literal("authClaims") }).strict();
888
- const patternIdTreeActionsSchema = z.object({ kind: z.literal("treeActions") }).strict();
889
- export const PATTERN_ID_SCHEMAS_BY_KIND = {
890
- entity: patternIdEntitySchema,
891
- relation: patternIdRelationSchema,
892
- nav: patternIdNavSchema,
893
- workspace: patternIdWorkspaceSchema,
894
- screen: patternIdScreenSchema,
895
- writeHandler: patternIdWriteHandlerSchema,
896
- queryHandler: patternIdQueryHandlerSchema,
897
- streamHandler: patternIdStreamHandlerSchema,
898
- hook: patternIdHookSchema,
899
- metric: patternIdMetricSchema,
900
- secret: patternIdSecretSchema,
901
- secretNamespace: patternIdSecretNamespaceSchema,
902
- claimKey: patternIdClaimKeySchema,
903
- referenceData: patternIdReferenceDataSchema,
904
- useExtension: patternIdUseExtensionSchema,
905
- job: patternIdJobSchema,
906
- notification: patternIdNotificationSchema,
907
- httpRoute: patternIdHttpRouteSchema,
908
- projection: patternIdProjectionSchema,
909
- multiStreamProjection: patternIdMultiStreamProjectionSchema,
910
- defineEvent: patternIdDefineEventSchema,
911
- extendsRegistrar: patternIdExtendsRegistrarSchema,
912
- "ai.generate": patternIdAiGenerateSchema,
913
- "ai.extract": patternIdAiExtractSchema,
914
- "ai.classify": patternIdAiClassifySchema,
915
- requires: patternIdRequiresSchema,
916
- optionalRequires: patternIdOptionalRequiresSchema,
917
- readsConfig: patternIdReadsConfigSchema,
918
- systemScope: patternIdSystemScopeSchema,
919
- toggleable: patternIdToggleableSchema,
920
- describe: patternIdDescribeSchema,
921
- uiHints: patternIdUiHintsSchema,
922
- config: patternIdConfigSchema,
923
- translations: patternIdTranslationsSchema,
924
- authClaims: patternIdAuthClaimsSchema,
925
- treeActions: patternIdTreeActionsSchema,
926
- };
927
- export const patternIdSchema = z.discriminatedUnion("kind", [
928
- patternIdEntitySchema,
929
- patternIdRelationSchema,
930
- patternIdNavSchema,
931
- patternIdWorkspaceSchema,
932
- patternIdScreenSchema,
933
- patternIdWriteHandlerSchema,
934
- patternIdQueryHandlerSchema,
935
- patternIdStreamHandlerSchema,
936
- patternIdHookSchema,
937
- patternIdMetricSchema,
938
- patternIdSecretSchema,
939
- patternIdSecretNamespaceSchema,
940
- patternIdClaimKeySchema,
941
- patternIdReferenceDataSchema,
942
- patternIdUseExtensionSchema,
943
- patternIdJobSchema,
944
- patternIdNotificationSchema,
945
- patternIdHttpRouteSchema,
946
- patternIdProjectionSchema,
947
- patternIdMultiStreamProjectionSchema,
948
- patternIdDefineEventSchema,
949
- patternIdExtendsRegistrarSchema,
950
- patternIdAiGenerateSchema,
951
- patternIdAiExtractSchema,
952
- patternIdAiClassifySchema,
953
- patternIdRequiresSchema,
954
- patternIdOptionalRequiresSchema,
955
- patternIdReadsConfigSchema,
956
- patternIdSystemScopeSchema,
957
- patternIdToggleableSchema,
958
- patternIdDescribeSchema,
959
- patternIdUiHintsSchema,
960
- patternIdConfigSchema,
961
- patternIdTranslationsSchema,
962
- patternIdAuthClaimsSchema,
963
- patternIdTreeActionsSchema,
964
- ]);
965
- // =============================================================================
966
- // Change union — `rationale` is accepted (optional, on every member) and
967
- // dropped when the final PatternChange is assembled below (plain field
968
- // selection, not a schema-level transform — see file-header rationale).
969
- // =============================================================================
970
- const addChangeSchema = z
971
- .object({
972
- op: z.literal("add"),
973
- pattern: patternSchema,
974
- rationale: z.string().optional(),
975
- })
976
- .strict();
977
- const replaceChangeSchema = z
978
- .object({
979
- op: z.literal("replace"),
980
- id: patternIdSchema,
981
- pattern: patternSchema,
982
- rationale: z.string().optional(),
983
- })
984
- .strict();
985
- const removeChangeSchema = z
986
- .object({
987
- op: z.literal("remove"),
988
- id: patternIdSchema,
989
- rationale: z.string().optional(),
990
- })
991
- .strict();
992
- // `set`/`unset` are validated loosely here; the real per-kind check happens
993
- // in a second pass once `id.kind` is known (see parseUpdateChange).
994
- const updateChangeSchema = z
995
- .object({
996
- op: z.literal("update"),
997
- id: patternIdSchema,
998
- set: z.record(z.string(), z.unknown()).optional(),
999
- unset: z.array(z.string()).optional(),
1000
- rationale: z.string().optional(),
1001
- })
1002
- .strict();
1003
- const changeSchema = z.discriminatedUnion("op", [
1004
- addChangeSchema,
1005
- replaceChangeSchema,
1006
- removeChangeSchema,
1007
- updateChangeSchema,
1008
- ]);
1009
- function prefixIssuePath(issues, prefix) {
1010
- return issues.map((issue) => ({ ...issue, path: [prefix, ...issue.path] }));
1011
- }
1012
- // Shared per-`unset[j]` checks ("access" is fixed-required, overlap with
1013
- // `set`) ahead of the kind-specific enum parse in parseHeaderSetAndUnset.
1014
- function unsetElementIssue(key, j, index, setKeys) {
1015
- if (key === "access") {
1016
- return {
1017
- path: `changes[${index}].unset[${j}]`,
1018
- message: "access is required and cannot be unset",
1019
- };
1020
- }
1021
- if (setKeys.has(key)) {
1022
- return { path: `changes[${index}].unset[${j}]`, message: "key is also in set" };
1023
- }
1024
- return undefined;
1025
- }
1026
- // Shared set/unset validation for one handler kind's Set-schema/Unset-enum —
1027
- // the only thing that differs per kind (see the switch below).
1028
- function parseHeaderSetAndUnset(setSchema, unsetEnum, kindLabel, value, index, rawItem) {
1029
- const issues = [];
1030
- const setResult = setSchema.safeParse(value.set ?? {});
1031
- if (!setResult.success) {
1032
- issues.push(...formatZodIssues(prefixIssuePath(setResult.error.issues, "set"), index, rawItem));
1033
- }
1034
- const setKeys = new Set(Object.keys(value.set ?? {}));
1035
- const unsetInput = value.unset ?? [];
1036
- const validatedUnset = [];
1037
- unsetInput.forEach((key, j) => {
1038
- const preIssue = unsetElementIssue(key, j, index, setKeys);
1039
- if (preIssue) {
1040
- issues.push(preIssue);
1041
- // skip: already reported, no further checks apply to this element
1042
- return;
1043
- }
1044
- const parsed = unsetEnum.safeParse(key);
1045
- if (!parsed.success) {
1046
- issues.push({
1047
- path: `changes[${index}].unset[${j}]`,
1048
- message: `"${key}" is not a header field of ${kindLabel}`,
1049
- });
1050
- // skip: already reported, no further checks apply to this element
1051
- return;
1052
- }
1053
- validatedUnset.push(parsed.data);
1054
- });
1055
- const hasSet = value.set !== undefined && Object.keys(value.set).length > 0;
1056
- if (!hasSet && unsetInput.length === 0) {
1057
- issues.push({
1058
- path: `changes[${index}].set`,
1059
- message: "update needs at least one key in set or unset",
1060
- });
1061
- }
1062
- if (!setResult.success || issues.length > 0)
1063
- return { ok: false, issues };
1064
- return { ok: true, set: setResult.data, unset: validatedUnset };
1065
- }
1066
- // Per-kind switch so `value.id` narrows and `change` needs no cast.
1067
- function parseUpdateChange(value, index, rawItem) {
1068
- switch (value.id.kind) {
1069
- case "writeHandler": {
1070
- const result = parseHeaderSetAndUnset(WRITE_HANDLER_UPDATE_SET_SCHEMA, WRITE_HANDLER_UPDATE_UNSET_ENUM, "writeHandler", value, index, rawItem);
1071
- if (!result.ok)
1072
- return { issues: result.issues };
1073
- const change = {
1074
- op: "update",
1075
- id: value.id,
1076
- set: result.set,
1077
- ...(result.unset.length > 0 ? { unset: result.unset } : {}),
1078
- };
1079
- return { change, issues: [] };
1080
- }
1081
- case "queryHandler": {
1082
- const result = parseHeaderSetAndUnset(QUERY_HANDLER_UPDATE_SET_SCHEMA, QUERY_HANDLER_UPDATE_UNSET_ENUM, "queryHandler", value, index, rawItem);
1083
- if (!result.ok)
1084
- return { issues: result.issues };
1085
- const change = {
1086
- op: "update",
1087
- id: value.id,
1088
- set: result.set,
1089
- ...(result.unset.length > 0 ? { unset: result.unset } : {}),
1090
- };
1091
- return { change, issues: [] };
1092
- }
1093
- case "streamHandler": {
1094
- const result = parseHeaderSetAndUnset(STREAM_HANDLER_UPDATE_SET_SCHEMA, STREAM_HANDLER_UPDATE_UNSET_ENUM, "streamHandler", value, index, rawItem);
1095
- if (!result.ok)
1096
- return { issues: result.issues };
1097
- const change = {
1098
- op: "update",
1099
- id: value.id,
1100
- set: result.set,
1101
- ...(result.unset.length > 0 ? { unset: result.unset } : {}),
1102
- };
1103
- return { change, issues: [] };
1104
- }
1105
- default:
1106
- return {
1107
- issues: [
1108
- {
1109
- path: `changes[${index}].id.kind`,
1110
- message: `update is not supported for kind "${value.id.kind}"; use replace`,
1111
- },
1112
- ],
1113
- };
1114
- }
1115
- }
1116
- // =============================================================================
1117
- // Issue formatting
1118
- // =============================================================================
1119
- function formatPath(index, path) {
1120
- let out = `changes[${index}]`;
1121
- for (const segment of path) {
1122
- out += typeof segment === "number" ? `[${segment}]` : `.${String(segment)}`;
1123
- }
1124
- return out;
1125
- }
1126
- function getAtPath(root, path) {
1127
- let current = root;
1128
- for (const segment of path) {
1129
- if (isPlainObject(current)) {
1130
- current = current[String(segment)];
1131
- }
1132
- else if (Array.isArray(current) && typeof segment === "number") {
1133
- current = current[segment];
1134
- }
1135
- else {
1136
- return undefined;
1137
- }
1138
- }
1139
- return current;
1140
- }
1141
- // zod v4 reports `.strict()` violations as a single `unrecognized_keys`
1142
- // issue per offending object, carrying all extra key names at once. We
1143
- // split it into one PatternChangeIssue per key so each unexpected key gets
1144
- // its own actionable path — except `definition` on a handler-kind pattern
1145
- // nesting an `access` sub-key, which gets the more specific message the
1146
- // spec calls for (a caller who nests `access` under a stray `definition`
1147
- // key is making one specific, common mistake, not an arbitrary unknown key).
1148
- // Only these kinds render a top-level `access`; on any other kind the hint
1149
- // would send the caller into a second rejection.
1150
- function isKindWithTopLevelAccess(kind) {
1151
- return kind === "writeHandler" || kind === "queryHandler" || kind === "streamHandler";
1152
- }
1153
- function formatZodIssues(issues, index, rawItem) {
1154
- const out = [];
1155
- for (const issue of issues) {
1156
- if (issue.code === "unrecognized_keys") {
1157
- const parentValue = getAtPath(rawItem, issue.path);
1158
- for (const key of issue.keys) {
1159
- const keyValue = isPlainObject(parentValue) ? parentValue[key] : undefined;
1160
- if (key === "definition" &&
1161
- isPlainObject(parentValue) &&
1162
- isKindWithTopLevelAccess(parentValue["kind"]) &&
1163
- isPlainObject(keyValue) &&
1164
- "access" in keyValue) {
1165
- out.push({
1166
- path: `${formatPath(index, issue.path)}.definition.access`,
1167
- message: "unexpected key; access belongs at top level of the pattern",
1168
- });
1169
- continue;
1170
- }
1171
- out.push({
1172
- path: `${formatPath(index, issue.path)}.${key}`,
1173
- message: "unexpected key",
1174
- });
1175
- }
1176
- continue;
1177
- }
1178
- out.push({ path: formatPath(index, issue.path), message: issue.message });
1179
- }
1180
- return out;
1181
- }
1182
- // =============================================================================
1183
- // Public API
1184
- // =============================================================================
1185
- export function parsePatternChanges(input) {
1186
- if (!Array.isArray(input)) {
1187
- return { ok: false, issues: [{ path: "changes", message: "must be an array" }] };
1188
- }
1189
- const issues = [];
1190
- const changes = [];
1191
- input.forEach((item, index) => {
1192
- const result = changeSchema.safeParse(item);
1193
- if (!result.success) {
1194
- issues.push(...formatZodIssues(result.error.issues, index, item));
1195
- // skip: schema violations already reported as issues
1196
- return;
1197
- }
1198
- const value = result.data;
1199
- if (value.op === "replace" && value.id.kind !== value.pattern.kind) {
1200
- issues.push({
1201
- path: `changes[${index}].pattern.kind`,
1202
- message: `pattern.kind "${value.pattern.kind}" does not match id.kind "${value.id.kind}"`,
1203
- });
1204
- // skip: id/pattern kind mismatch already reported as an issue
1205
- return;
1206
- }
1207
- if (value.op === "add") {
1208
- changes.push({ op: "add", pattern: value.pattern });
1209
- }
1210
- else if (value.op === "replace") {
1211
- changes.push({ op: "replace", id: value.id, pattern: value.pattern });
1212
- }
1213
- else if (value.op === "remove") {
1214
- changes.push({ op: "remove", id: value.id });
1215
- }
1216
- else {
1217
- const outcome = parseUpdateChange(value, index, item);
1218
- issues.push(...outcome.issues);
1219
- if (outcome.change)
1220
- changes.push(outcome.change);
1221
- }
1222
- });
1223
- if (issues.length > 0)
1224
- return { ok: false, issues };
1225
- return { ok: true, changes };
1226
- }