@cosmicdrift/kumiko-framework 0.328.0 → 0.328.1

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 (2089) hide show
  1. package/dist/api/anonymous-cookie.d.ts +8 -0
  2. package/dist/api/anonymous-cookie.js +40 -0
  3. package/dist/api/api-constants.d.ts +47 -0
  4. package/dist/api/api-constants.js +136 -0
  5. package/dist/api/auth-middleware.d.ts +42 -0
  6. package/dist/api/auth-middleware.js +450 -0
  7. package/dist/api/auth-routes.d.ts +83 -0
  8. package/dist/api/auth-routes.js +1003 -0
  9. package/dist/api/client-ip.d.ts +15 -0
  10. package/dist/api/client-ip.js +101 -0
  11. package/dist/api/csrf-middleware.d.ts +9 -0
  12. package/dist/api/csrf-middleware.js +67 -0
  13. package/dist/api/extra-route.d.ts +99 -0
  14. package/dist/api/extra-route.js +48 -0
  15. package/dist/api/http-cache.d.ts +31 -0
  16. package/dist/api/http-cache.js +102 -0
  17. package/dist/api/index.d.ts +32 -0
  18. package/dist/api/index.js +20 -0
  19. package/dist/api/jwt.d.ts +22 -0
  20. package/dist/api/jwt.js +199 -0
  21. package/dist/api/observability-middleware.d.ts +8 -0
  22. package/dist/api/observability-middleware.js +68 -0
  23. package/dist/api/origin-middleware.d.ts +12 -0
  24. package/dist/api/origin-middleware.js +120 -0
  25. package/dist/api/pat-route-guard.d.ts +2 -0
  26. package/dist/api/pat-route-guard.js +43 -0
  27. package/dist/api/pat-scope.d.ts +2 -0
  28. package/dist/api/pat-scope.js +13 -0
  29. package/dist/api/pii-leak-guard.d.ts +2 -0
  30. package/dist/api/pii-leak-guard.js +40 -0
  31. package/dist/api/post-auth-landing.d.ts +14 -0
  32. package/dist/api/post-auth-landing.js +92 -0
  33. package/dist/api/readiness.d.ts +23 -0
  34. package/dist/api/readiness.js +98 -0
  35. package/dist/api/redis-sse-broker.d.ts +13 -0
  36. package/dist/api/redis-sse-broker.js +138 -0
  37. package/dist/api/request-context.d.ts +34 -0
  38. package/dist/api/request-context.js +60 -0
  39. package/dist/api/request-id-middleware.d.ts +37 -0
  40. package/dist/api/request-id-middleware.js +112 -0
  41. package/dist/api/route-registrars.d.ts +24 -0
  42. package/dist/api/route-registrars.js +133 -0
  43. package/dist/api/routes.d.ts +20 -0
  44. package/dist/api/routes.js +373 -0
  45. package/dist/api/server.d.ts +81 -0
  46. package/dist/api/server.js +1068 -0
  47. package/dist/api/sse-broker.d.ts +36 -0
  48. package/dist/api/sse-broker.js +112 -0
  49. package/dist/api/sse-route.d.ts +24 -0
  50. package/dist/api/sse-route.js +61 -0
  51. package/dist/api/tokens.d.ts +1 -0
  52. package/dist/api/tokens.js +15 -0
  53. package/dist/api/websocket-route.d.ts +59 -0
  54. package/dist/api/websocket-route.js +239 -0
  55. package/dist/arg-parser.d.ts +8 -0
  56. package/dist/arg-parser.js +59 -0
  57. package/dist/auth/index.d.ts +2 -0
  58. package/dist/auth/index.js +5 -0
  59. package/dist/auth/roles.d.ts +16 -0
  60. package/dist/auth/roles.js +35 -0
  61. package/dist/bun-db/connection.d.ts +16 -0
  62. package/dist/bun-db/connection.js +54 -0
  63. package/dist/bun-db/index.d.ts +4 -0
  64. package/dist/bun-db/index.js +4 -0
  65. package/dist/bun-db/query.d.ts +64 -0
  66. package/dist/bun-db/query.js +1145 -0
  67. package/dist/compliance/duration-spec.d.ts +7 -0
  68. package/dist/compliance/duration-spec.js +37 -0
  69. package/dist/compliance/index.d.ts +6 -0
  70. package/dist/compliance/index.js +7 -0
  71. package/dist/compliance/override-schema.d.ts +78 -0
  72. package/dist/compliance/override-schema.js +124 -0
  73. package/dist/compliance/profiles.d.ts +125 -0
  74. package/dist/compliance/profiles.js +284 -0
  75. package/dist/compliance/sub-processors.d.ts +69 -0
  76. package/dist/compliance/sub-processors.js +109 -0
  77. package/dist/consumer-cli.d.ts +5 -0
  78. package/dist/consumer-cli.js +116 -0
  79. package/dist/crypto/blind-index.d.ts +10 -0
  80. package/dist/crypto/blind-index.js +97 -0
  81. package/dist/crypto/ciphertext-pattern.d.ts +3 -0
  82. package/dist/crypto/ciphertext-pattern.js +16 -0
  83. package/dist/crypto/event-pii.d.ts +8 -0
  84. package/dist/crypto/event-pii.js +79 -0
  85. package/dist/crypto/in-memory-kms-adapter.d.ts +11 -0
  86. package/dist/crypto/in-memory-kms-adapter.js +33 -0
  87. package/dist/crypto/index.d.ts +11 -0
  88. package/dist/crypto/index.js +11 -0
  89. package/dist/crypto/is-self-pii-field.d.ts +5 -0
  90. package/dist/crypto/is-self-pii-field.js +4 -0
  91. package/dist/crypto/kek-source.d.ts +23 -0
  92. package/dist/crypto/kek-source.js +122 -0
  93. package/dist/crypto/kms-adapter.d.ts +26 -0
  94. package/dist/crypto/kms-adapter.js +46 -0
  95. package/dist/crypto/kms-wiring.d.ts +67 -0
  96. package/dist/crypto/kms-wiring.js +125 -0
  97. package/dist/crypto/pg-kms-adapter.d.ts +55 -0
  98. package/dist/crypto/pg-kms-adapter.js +232 -0
  99. package/dist/crypto/pii-field-encryption.d.ts +20 -0
  100. package/dist/crypto/pii-field-encryption.js +201 -0
  101. package/dist/crypto/request-kms-cache.d.ts +8 -0
  102. package/dist/crypto/request-kms-cache.js +21 -0
  103. package/dist/crypto/subject-resolver.d.ts +30 -0
  104. package/dist/crypto/subject-resolver.js +153 -0
  105. package/dist/crypto/system-event-pii.d.ts +4 -0
  106. package/dist/crypto/system-event-pii.js +37 -0
  107. package/dist/db/api.d.ts +18 -0
  108. package/dist/db/api.js +23 -0
  109. package/dist/db/apply-entity-event.d.ts +21 -0
  110. package/dist/db/apply-entity-event.js +175 -0
  111. package/dist/db/assert-exists-in.d.ts +23 -0
  112. package/dist/db/assert-exists-in.js +34 -0
  113. package/dist/db/blind-index-cleanup.d.ts +5 -0
  114. package/dist/db/blind-index-cleanup.js +112 -0
  115. package/dist/db/bun-provider.d.ts +2 -0
  116. package/dist/db/bun-provider.js +37 -0
  117. package/dist/db/collect-table-metas.d.ts +3 -0
  118. package/dist/db/collect-table-metas.js +76 -0
  119. package/dist/db/compound-types.d.ts +9 -0
  120. package/dist/db/compound-types.js +31 -0
  121. package/dist/db/config-seed.d.ts +19 -0
  122. package/dist/db/config-seed.js +75 -0
  123. package/dist/db/connection.d.ts +10 -0
  124. package/dist/db/connection.js +35 -0
  125. package/dist/db/cursor.d.ts +9 -0
  126. package/dist/db/cursor.js +39 -0
  127. package/dist/db/dialect.d.ts +100 -0
  128. package/dist/db/dialect.js +386 -0
  129. package/dist/db/eagerload.d.ts +18 -0
  130. package/dist/db/eagerload.js +191 -0
  131. package/dist/db/entity-field-encryption.d.ts +15 -0
  132. package/dist/db/entity-field-encryption.js +127 -0
  133. package/dist/db/entity-table-from-registry.d.ts +4 -0
  134. package/dist/db/entity-table-from-registry.js +25 -0
  135. package/dist/db/entity-table-meta-types.d.ts +1 -0
  136. package/dist/db/entity-table-meta-types.js +1 -0
  137. package/dist/db/entity-table-meta.d.ts +30 -0
  138. package/dist/db/entity-table-meta.js +423 -0
  139. package/dist/db/event-store-executor-context.d.ts +49 -0
  140. package/dist/db/event-store-executor-context.js +368 -0
  141. package/dist/db/event-store-executor-read.d.ts +10 -0
  142. package/dist/db/event-store-executor-read.js +683 -0
  143. package/dist/db/event-store-executor-write.d.ts +3 -0
  144. package/dist/db/event-store-executor-write.js +705 -0
  145. package/dist/db/event-store-executor.d.ts +20 -0
  146. package/dist/db/event-store-executor.js +11 -0
  147. package/dist/db/feature-table-sources.d.ts +6 -0
  148. package/dist/db/feature-table-sources.js +24 -0
  149. package/dist/db/index.d.ts +37 -0
  150. package/dist/db/index.js +29 -0
  151. package/dist/db/located-timestamp.d.ts +22 -0
  152. package/dist/db/located-timestamp.js +100 -0
  153. package/dist/db/migrate-generator.d.ts +81 -0
  154. package/dist/db/migrate-generator.js +428 -0
  155. package/dist/db/migrate-runner.d.ts +30 -0
  156. package/dist/db/migrate-runner.js +273 -0
  157. package/dist/db/money.d.ts +30 -0
  158. package/dist/db/money.js +153 -0
  159. package/dist/db/parent-ref-clause.d.ts +10 -0
  160. package/dist/db/parent-ref-clause.js +124 -0
  161. package/dist/db/pg-error.d.ts +10 -0
  162. package/dist/db/pg-error.js +63 -0
  163. package/dist/db/postgres-provider.d.ts +2 -0
  164. package/dist/db/postgres-provider.js +21 -0
  165. package/dist/db/queries/advisory-lock.d.ts +3 -0
  166. package/dist/db/queries/advisory-lock.js +5 -0
  167. package/dist/db/queries/backfill-pii.d.ts +38 -0
  168. package/dist/db/queries/backfill-pii.js +433 -0
  169. package/dist/db/queries/ddl.d.ts +4 -0
  170. package/dist/db/queries/ddl.js +22 -0
  171. package/dist/db/queries/entity-read.d.ts +2 -0
  172. package/dist/db/queries/entity-read.js +5 -0
  173. package/dist/db/queries/es-ops.d.ts +5 -0
  174. package/dist/db/queries/es-ops.js +10 -0
  175. package/dist/db/queries/event-consumer.d.ts +36 -0
  176. package/dist/db/queries/event-consumer.js +261 -0
  177. package/dist/db/queries/event-store-admin.d.ts +24 -0
  178. package/dist/db/queries/event-store-admin.js +71 -0
  179. package/dist/db/queries/event-store-transfer.d.ts +20 -0
  180. package/dist/db/queries/event-store-transfer.js +31 -0
  181. package/dist/db/queries/event-store.d.ts +54 -0
  182. package/dist/db/queries/event-store.js +231 -0
  183. package/dist/db/queries/pii-backfill-state.d.ts +7 -0
  184. package/dist/db/queries/pii-backfill-state.js +14 -0
  185. package/dist/db/queries/projection-rebuild.d.ts +6 -0
  186. package/dist/db/queries/projection-rebuild.js +65 -0
  187. package/dist/db/queries/raw-sql.d.ts +9 -0
  188. package/dist/db/queries/raw-sql.js +16 -0
  189. package/dist/db/queries/seed-context.d.ts +20 -0
  190. package/dist/db/queries/seed-context.js +25 -0
  191. package/dist/db/queries/shadow-swap.d.ts +18 -0
  192. package/dist/db/queries/shadow-swap.js +307 -0
  193. package/dist/db/queries/table-ops.d.ts +4 -0
  194. package/dist/db/queries/table-ops.js +8 -0
  195. package/dist/db/queries/test-stack.d.ts +6 -0
  196. package/dist/db/queries/test-stack.js +20 -0
  197. package/dist/db/query-api.d.ts +2 -0
  198. package/dist/db/query-api.js +6 -0
  199. package/dist/db/query.d.ts +1 -0
  200. package/dist/db/query.js +3 -0
  201. package/dist/db/rebuild-marker.d.ts +4 -0
  202. package/dist/db/rebuild-marker.js +96 -0
  203. package/dist/db/reference-data.d.ts +14 -0
  204. package/dist/db/reference-data.js +66 -0
  205. package/dist/db/render-ddl.d.ts +4 -0
  206. package/dist/db/render-ddl.js +55 -0
  207. package/dist/db/replay-migration-sql.d.ts +12 -0
  208. package/dist/db/replay-migration-sql.js +223 -0
  209. package/dist/db/schema-inspection.d.ts +3 -0
  210. package/dist/db/schema-inspection.js +60 -0
  211. package/dist/db/table-builder.d.ts +194 -0
  212. package/dist/db/table-builder.js +430 -0
  213. package/dist/db/tenant-db-runner.d.ts +4 -0
  214. package/dist/db/tenant-db-runner.js +17 -0
  215. package/dist/db/tenant-db.d.ts +32 -0
  216. package/dist/db/tenant-db.js +501 -0
  217. package/dist/derivatives/delete-stored-file.d.ts +6 -0
  218. package/dist/derivatives/delete-stored-file.js +70 -0
  219. package/dist/derivatives/derivatives-context.d.ts +21 -0
  220. package/dist/derivatives/derivatives-context.js +212 -0
  221. package/dist/derivatives/field-variants.d.ts +3 -0
  222. package/dist/derivatives/field-variants.js +16 -0
  223. package/dist/derivatives/index.d.ts +6 -0
  224. package/dist/derivatives/index.js +4 -0
  225. package/dist/derivatives/variant-key.d.ts +10 -0
  226. package/dist/derivatives/variant-key.js +100 -0
  227. package/dist/engine/access.d.ts +2 -0
  228. package/dist/engine/access.js +25 -0
  229. package/dist/engine/active-membership.d.ts +26 -0
  230. package/dist/engine/active-membership.js +25 -0
  231. package/dist/engine/boot-validator/access-declarations.d.ts +2 -0
  232. package/dist/engine/boot-validator/access-declarations.js +148 -0
  233. package/dist/engine/boot-validator/access-roles.d.ts +2 -0
  234. package/dist/engine/boot-validator/access-roles.js +76 -0
  235. package/dist/engine/boot-validator/action-wiring.d.ts +3 -0
  236. package/dist/engine/boot-validator/action-wiring.js +104 -0
  237. package/dist/engine/boot-validator/api-ext.d.ts +3 -0
  238. package/dist/engine/boot-validator/api-ext.js +54 -0
  239. package/dist/engine/boot-validator/boot-check.d.ts +2 -0
  240. package/dist/engine/boot-validator/boot-check.js +20 -0
  241. package/dist/engine/boot-validator/config-deps.d.ts +10 -0
  242. package/dist/engine/boot-validator/config-deps.js +180 -0
  243. package/dist/engine/boot-validator/custom-screen-write-qns.d.ts +8 -0
  244. package/dist/engine/boot-validator/custom-screen-write-qns.js +75 -0
  245. package/dist/engine/boot-validator/detail-screens.d.ts +6 -0
  246. package/dist/engine/boot-validator/detail-screens.js +31 -0
  247. package/dist/engine/boot-validator/entity-handler.d.ts +23 -0
  248. package/dist/engine/boot-validator/entity-handler.js +754 -0
  249. package/dist/engine/boot-validator/entity-list-screens.d.ts +4 -0
  250. package/dist/engine/boot-validator/entity-list-screens.js +75 -0
  251. package/dist/engine/boot-validator/gdpr-storage.d.ts +2 -0
  252. package/dist/engine/boot-validator/gdpr-storage.js +48 -0
  253. package/dist/engine/boot-validator/global-tenancy.d.ts +2 -0
  254. package/dist/engine/boot-validator/global-tenancy.js +24 -0
  255. package/dist/engine/boot-validator/i18n-keys.d.ts +2 -0
  256. package/dist/engine/boot-validator/i18n-keys.js +88 -0
  257. package/dist/engine/boot-validator/index.d.ts +34 -0
  258. package/dist/engine/boot-validator/index.js +196 -0
  259. package/dist/engine/boot-validator/nav.d.ts +20 -0
  260. package/dist/engine/boot-validator/nav.js +202 -0
  261. package/dist/engine/boot-validator/ownership.d.ts +36 -0
  262. package/dist/engine/boot-validator/ownership.js +268 -0
  263. package/dist/engine/boot-validator/parent-ref.d.ts +3 -0
  264. package/dist/engine/boot-validator/parent-ref.js +73 -0
  265. package/dist/engine/boot-validator/pii-retention.d.ts +2 -0
  266. package/dist/engine/boot-validator/pii-retention.js +204 -0
  267. package/dist/engine/boot-validator/projection-list-screens.d.ts +4 -0
  268. package/dist/engine/boot-validator/projection-list-screens.js +219 -0
  269. package/dist/engine/boot-validator/query-output-columns.d.ts +2 -0
  270. package/dist/engine/boot-validator/query-output-columns.js +160 -0
  271. package/dist/engine/boot-validator/query-refs.d.ts +2 -0
  272. package/dist/engine/boot-validator/query-refs.js +72 -0
  273. package/dist/engine/boot-validator/record-owned.d.ts +2 -0
  274. package/dist/engine/boot-validator/record-owned.js +16 -0
  275. package/dist/engine/boot-validator/screens.d.ts +34 -0
  276. package/dist/engine/boot-validator/screens.js +1665 -0
  277. package/dist/engine/boot-validator/security-baseline.d.ts +3 -0
  278. package/dist/engine/boot-validator/security-baseline.js +18 -0
  279. package/dist/engine/boot-validator/transfer-graph.d.ts +3 -0
  280. package/dist/engine/boot-validator/transfer-graph.js +120 -0
  281. package/dist/engine/boot-validator/url-prefill-fields.d.ts +2 -0
  282. package/dist/engine/boot-validator/url-prefill-fields.js +106 -0
  283. package/dist/engine/boot-validator/workspaces.d.ts +20 -0
  284. package/dist/engine/boot-validator/workspaces.js +81 -0
  285. package/dist/engine/boot-validator/zod-shape.d.ts +5 -0
  286. package/dist/engine/boot-validator/zod-shape.js +110 -0
  287. package/dist/engine/boot-validator.d.ts +1 -0
  288. package/dist/engine/boot-validator.js +1 -0
  289. package/dist/engine/build-app-schema.d.ts +14 -0
  290. package/dist/engine/build-app-schema.js +494 -0
  291. package/dist/engine/build-config-feature-schema.d.ts +15 -0
  292. package/dist/engine/build-config-feature-schema.js +582 -0
  293. package/dist/engine/build-target.d.ts +28 -0
  294. package/dist/engine/build-target.js +43 -0
  295. package/dist/engine/changeset-changes.d.ts +12 -0
  296. package/dist/engine/changeset-changes.js +104 -0
  297. package/dist/engine/codemod/index.d.ts +2 -0
  298. package/dist/engine/codemod/index.js +1 -0
  299. package/dist/engine/codemod/pipeline-codemod.d.ts +50 -0
  300. package/dist/engine/codemod/pipeline-codemod.js +529 -0
  301. package/dist/engine/config-helpers.d.ts +42 -0
  302. package/dist/engine/config-helpers.js +115 -0
  303. package/dist/engine/constants.d.ts +52 -0
  304. package/dist/engine/constants.js +79 -0
  305. package/dist/engine/create-app.d.ts +17 -0
  306. package/dist/engine/create-app.js +119 -0
  307. package/dist/engine/cross-tenant.d.ts +3 -0
  308. package/dist/engine/cross-tenant.js +18 -0
  309. package/dist/engine/dedupe-features.d.ts +2 -0
  310. package/dist/engine/dedupe-features.js +36 -0
  311. package/dist/engine/define-feature.d.ts +7 -0
  312. package/dist/engine/define-feature.js +143 -0
  313. package/dist/engine/define-handler.d.ts +21 -0
  314. package/dist/engine/define-handler.js +117 -0
  315. package/dist/engine/define-roles.d.ts +5 -0
  316. package/dist/engine/define-roles.js +14 -0
  317. package/dist/engine/define-step.d.ts +4 -0
  318. package/dist/engine/define-step.js +22 -0
  319. package/dist/engine/define-workflow.d.ts +89 -0
  320. package/dist/engine/define-workflow.js +70 -0
  321. package/dist/engine/effective-features.d.ts +6 -0
  322. package/dist/engine/effective-features.js +73 -0
  323. package/dist/engine/embedded-derived.d.ts +29 -0
  324. package/dist/engine/embedded-derived.js +82 -0
  325. package/dist/engine/entity-handlers.d.ts +67 -0
  326. package/dist/engine/entity-handlers.js +567 -0
  327. package/dist/engine/escape-hatch-declaration.d.ts +2 -0
  328. package/dist/engine/escape-hatch-declaration.js +5 -0
  329. package/dist/engine/event-helpers.d.ts +11 -0
  330. package/dist/engine/event-helpers.js +47 -0
  331. package/dist/engine/extension-names.d.ts +164 -0
  332. package/dist/engine/extension-names.js +172 -0
  333. package/dist/engine/extension-selector-plugins.d.ts +5 -0
  334. package/dist/engine/extension-selector-plugins.js +14 -0
  335. package/dist/engine/extensions/escape-hatch-usage.d.ts +2 -0
  336. package/dist/engine/extensions/escape-hatch-usage.js +12 -0
  337. package/dist/engine/extensions/storage-provider.d.ts +4 -0
  338. package/dist/engine/extensions/storage-provider.js +1 -0
  339. package/dist/engine/extensions/tenant-data.d.ts +15 -0
  340. package/dist/engine/extensions/tenant-data.js +7 -0
  341. package/dist/engine/extensions/tenant-resource.d.ts +14 -0
  342. package/dist/engine/extensions/tenant-resource.js +6 -0
  343. package/dist/engine/extensions/user-data.d.ts +152 -0
  344. package/dist/engine/extensions/user-data.js +12 -0
  345. package/dist/engine/factories.d.ts +195 -0
  346. package/dist/engine/factories.js +387 -0
  347. package/dist/engine/feature-ast/entity-field-types.d.ts +13 -0
  348. package/dist/engine/feature-ast/entity-field-types.js +35 -0
  349. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +6 -0
  350. package/dist/engine/feature-ast/extractors/ai-steps.js +254 -0
  351. package/dist/engine/feature-ast/extractors/events.d.ts +5 -0
  352. package/dist/engine/feature-ast/extractors/events.js +262 -0
  353. package/dist/engine/feature-ast/extractors/handlers.d.ts +23 -0
  354. package/dist/engine/feature-ast/extractors/handlers.js +319 -0
  355. package/dist/engine/feature-ast/extractors/hooks.d.ts +23 -0
  356. package/dist/engine/feature-ast/extractors/hooks.js +228 -0
  357. package/dist/engine/feature-ast/extractors/index.d.ts +14 -0
  358. package/dist/engine/feature-ast/extractors/index.js +13 -0
  359. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +7 -0
  360. package/dist/engine/feature-ast/extractors/jobs-routes.js +141 -0
  361. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +10 -0
  362. package/dist/engine/feature-ast/extractors/projections-screens.js +195 -0
  363. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +14 -0
  364. package/dist/engine/feature-ast/extractors/resolve-import.js +152 -0
  365. package/dist/engine/feature-ast/extractors/round1.d.ts +10 -0
  366. package/dist/engine/feature-ast/extractors/round1.js +81 -0
  367. package/dist/engine/feature-ast/extractors/round2.d.ts +7 -0
  368. package/dist/engine/feature-ast/extractors/round2.js +158 -0
  369. package/dist/engine/feature-ast/extractors/round3.d.ts +22 -0
  370. package/dist/engine/feature-ast/extractors/round3.js +280 -0
  371. package/dist/engine/feature-ast/extractors/round5.d.ts +8 -0
  372. package/dist/engine/feature-ast/extractors/round5.js +63 -0
  373. package/dist/engine/feature-ast/extractors/round6.d.ts +4 -0
  374. package/dist/engine/feature-ast/extractors/round6.js +17 -0
  375. package/dist/engine/feature-ast/extractors/shared.d.ts +85 -0
  376. package/dist/engine/feature-ast/extractors/shared.js +326 -0
  377. package/dist/engine/feature-ast/index.d.ts +16 -0
  378. package/dist/engine/feature-ast/index.js +10 -0
  379. package/dist/engine/feature-ast/parse.d.ts +30 -0
  380. package/dist/engine/feature-ast/parse.js +464 -0
  381. package/dist/engine/feature-ast/patch.d.ts +207 -0
  382. package/dist/engine/feature-ast/patch.js +771 -0
  383. package/dist/engine/feature-ast/patcher.d.ts +211 -0
  384. package/dist/engine/feature-ast/patcher.js +277 -0
  385. package/dist/engine/feature-ast/pattern-change-schema.d.ts +670 -0
  386. package/dist/engine/feature-ast/pattern-change-schema.js +1196 -0
  387. package/dist/engine/feature-ast/patterns.d.ts +302 -0
  388. package/dist/engine/feature-ast/patterns.js +113 -0
  389. package/dist/engine/feature-ast/render.d.ts +47 -0
  390. package/dist/engine/feature-ast/render.js +681 -0
  391. package/dist/engine/feature-ast/source-location.d.ts +17 -0
  392. package/dist/engine/feature-ast/source-location.js +27 -0
  393. package/dist/engine/feature-builder-state.d.ts +69 -0
  394. package/dist/engine/feature-builder-state.js +64 -0
  395. package/dist/engine/feature-changelog.d.ts +21 -0
  396. package/dist/engine/feature-changelog.js +76 -0
  397. package/dist/engine/feature-config-events-jobs.d.ts +58 -0
  398. package/dist/engine/feature-config-events-jobs.js +318 -0
  399. package/dist/engine/feature-entity-handlers.d.ts +38 -0
  400. package/dist/engine/feature-entity-handlers.js +185 -0
  401. package/dist/engine/feature-manifest.d.ts +73 -0
  402. package/dist/engine/feature-manifest.js +87 -0
  403. package/dist/engine/feature-ui-extensions.d.ts +68 -0
  404. package/dist/engine/feature-ui-extensions.js +488 -0
  405. package/dist/engine/field-access.d.ts +4 -0
  406. package/dist/engine/field-access.js +119 -0
  407. package/dist/engine/field-helpers.d.ts +4 -0
  408. package/dist/engine/field-helpers.js +28 -0
  409. package/dist/engine/handler-helpers.d.ts +19 -0
  410. package/dist/engine/handler-helpers.js +24 -0
  411. package/dist/engine/hook-helpers.d.ts +4 -0
  412. package/dist/engine/hook-helpers.js +13 -0
  413. package/dist/engine/i18n-key.d.ts +2 -0
  414. package/dist/engine/i18n-key.js +10 -0
  415. package/dist/engine/index.d.ts +77 -0
  416. package/dist/engine/index.js +70 -0
  417. package/dist/engine/instruction-fields.d.ts +2 -0
  418. package/dist/engine/instruction-fields.js +9 -0
  419. package/dist/engine/membership-roles.d.ts +5 -0
  420. package/dist/engine/membership-roles.js +48 -0
  421. package/dist/engine/object-form.d.ts +4 -0
  422. package/dist/engine/object-form.js +21 -0
  423. package/dist/engine/ownership.d.ts +12 -0
  424. package/dist/engine/ownership.js +339 -0
  425. package/dist/engine/parse-ref-target.d.ts +6 -0
  426. package/dist/engine/parse-ref-target.js +21 -0
  427. package/dist/engine/pattern-library/index.d.ts +2 -0
  428. package/dist/engine/pattern-library/index.js +3 -0
  429. package/dist/engine/pattern-library/library.d.ts +14 -0
  430. package/dist/engine/pattern-library/library.js +92 -0
  431. package/dist/engine/pattern-library/mixed-schemas.d.ts +16 -0
  432. package/dist/engine/pattern-library/mixed-schemas.js +569 -0
  433. package/dist/engine/pattern-library/opaque-schemas.d.ts +7 -0
  434. package/dist/engine/pattern-library/opaque-schemas.js +115 -0
  435. package/dist/engine/pattern-library/shared-fields.d.ts +120 -0
  436. package/dist/engine/pattern-library/shared-fields.js +71 -0
  437. package/dist/engine/pattern-library/static-schemas.d.ts +19 -0
  438. package/dist/engine/pattern-library/static-schemas.js +435 -0
  439. package/dist/engine/pattern-library/types.d.ts +158 -0
  440. package/dist/engine/pattern-library/types.js +36 -0
  441. package/dist/engine/personal-data-fields.d.ts +5 -0
  442. package/dist/engine/personal-data-fields.js +56 -0
  443. package/dist/engine/pipeline.d.ts +4 -0
  444. package/dist/engine/pipeline.js +87 -0
  445. package/dist/engine/project-app-schema-for-roles.d.ts +2 -0
  446. package/dist/engine/project-app-schema-for-roles.js +679 -0
  447. package/dist/engine/projection-helpers.d.ts +7 -0
  448. package/dist/engine/projection-helpers.js +61 -0
  449. package/dist/engine/qualified-name.d.ts +27 -0
  450. package/dist/engine/qualified-name.js +137 -0
  451. package/dist/engine/read-claim.d.ts +2 -0
  452. package/dist/engine/read-claim.js +28 -0
  453. package/dist/engine/registry-facade.d.ts +3 -0
  454. package/dist/engine/registry-facade.js +231 -0
  455. package/dist/engine/registry-ingest.d.ts +14 -0
  456. package/dist/engine/registry-ingest.js +415 -0
  457. package/dist/engine/registry-state.d.ts +93 -0
  458. package/dist/engine/registry-state.js +233 -0
  459. package/dist/engine/registry-validate.d.ts +25 -0
  460. package/dist/engine/registry-validate.js +669 -0
  461. package/dist/engine/registry.d.ts +2 -0
  462. package/dist/engine/registry.js +52 -0
  463. package/dist/engine/resolve-config-or-param.d.ts +18 -0
  464. package/dist/engine/resolve-config-or-param.js +76 -0
  465. package/dist/engine/role-assignment.d.ts +1 -0
  466. package/dist/engine/role-assignment.js +58 -0
  467. package/dist/engine/run-in.d.ts +2 -0
  468. package/dist/engine/run-in.js +28 -0
  469. package/dist/engine/run-pipeline.d.ts +25 -0
  470. package/dist/engine/run-pipeline.js +111 -0
  471. package/dist/engine/schema-builder.d.ts +8 -0
  472. package/dist/engine/schema-builder.js +406 -0
  473. package/dist/engine/screen-filter-ops.d.ts +3 -0
  474. package/dist/engine/screen-filter-ops.js +55 -0
  475. package/dist/engine/screen-helpers.d.ts +27 -0
  476. package/dist/engine/screen-helpers.js +100 -0
  477. package/dist/engine/soft-delete-cleanup.d.ts +10 -0
  478. package/dist/engine/soft-delete-cleanup.js +114 -0
  479. package/dist/engine/state-machine.d.ts +34 -0
  480. package/dist/engine/state-machine.js +44 -0
  481. package/dist/engine/steps/_duration-utils.d.ts +1 -0
  482. package/dist/engine/steps/_duration-utils.js +28 -0
  483. package/dist/engine/steps/_event-match.d.ts +2 -0
  484. package/dist/engine/steps/_event-match.js +88 -0
  485. package/dist/engine/steps/_no-return-guard.d.ts +2 -0
  486. package/dist/engine/steps/_no-return-guard.js +16 -0
  487. package/dist/engine/steps/_read-source.d.ts +6 -0
  488. package/dist/engine/steps/_read-source.js +7 -0
  489. package/dist/engine/steps/_resolver-utils.d.ts +11 -0
  490. package/dist/engine/steps/_resolver-utils.js +36 -0
  491. package/dist/engine/steps/_step-dispatch-constants.d.ts +13 -0
  492. package/dist/engine/steps/_step-dispatch-constants.js +32 -0
  493. package/dist/engine/steps/aggregate-append-event.d.ts +10 -0
  494. package/dist/engine/steps/aggregate-append-event.js +43 -0
  495. package/dist/engine/steps/aggregate-create.d.ts +6 -0
  496. package/dist/engine/steps/aggregate-create.js +38 -0
  497. package/dist/engine/steps/aggregate-update.d.ts +10 -0
  498. package/dist/engine/steps/aggregate-update.js +38 -0
  499. package/dist/engine/steps/branch.d.ts +8 -0
  500. package/dist/engine/steps/branch.js +66 -0
  501. package/dist/engine/steps/call-feature.d.ts +7 -0
  502. package/dist/engine/steps/call-feature.js +30 -0
  503. package/dist/engine/steps/compute.d.ts +2 -0
  504. package/dist/engine/steps/compute.js +29 -0
  505. package/dist/engine/steps/describe-workflow-step-error.d.ts +1 -0
  506. package/dist/engine/steps/describe-workflow-step-error.js +6 -0
  507. package/dist/engine/steps/for-each.d.ts +9 -0
  508. package/dist/engine/steps/for-each.js +88 -0
  509. package/dist/engine/steps/mail-send.d.ts +10 -0
  510. package/dist/engine/steps/mail-send.js +33 -0
  511. package/dist/engine/steps/read-find-many.d.ts +10 -0
  512. package/dist/engine/steps/read-find-many.js +32 -0
  513. package/dist/engine/steps/read-find-one.d.ts +9 -0
  514. package/dist/engine/steps/read-find-one.js +41 -0
  515. package/dist/engine/steps/retry.d.ts +9 -0
  516. package/dist/engine/steps/retry.js +76 -0
  517. package/dist/engine/steps/return.d.ts +4 -0
  518. package/dist/engine/steps/return.js +25 -0
  519. package/dist/engine/steps/unsafe-projection-delete.d.ts +8 -0
  520. package/dist/engine/steps/unsafe-projection-delete.js +35 -0
  521. package/dist/engine/steps/unsafe-projection-upsert.d.ts +8 -0
  522. package/dist/engine/steps/unsafe-projection-upsert.js +73 -0
  523. package/dist/engine/steps/wait-for-event.d.ts +8 -0
  524. package/dist/engine/steps/wait-for-event.js +63 -0
  525. package/dist/engine/steps/wait.d.ts +6 -0
  526. package/dist/engine/steps/wait.js +50 -0
  527. package/dist/engine/steps/webhook-send.d.ts +24 -0
  528. package/dist/engine/steps/webhook-send.js +38 -0
  529. package/dist/engine/system-user.d.ts +8 -0
  530. package/dist/engine/system-user.js +29 -0
  531. package/dist/engine/tier-resolver-extension.d.ts +62 -0
  532. package/dist/engine/tier-resolver-extension.js +55 -0
  533. package/dist/engine/types/config.d.ts +1 -0
  534. package/dist/engine/types/config.js +1 -0
  535. package/dist/engine/types/define-handler.d.ts +1 -0
  536. package/dist/engine/types/define-handler.js +1 -0
  537. package/dist/engine/types/entity-handlers.d.ts +1 -0
  538. package/dist/engine/types/entity-handlers.js +1 -0
  539. package/dist/engine/types/event-type-map.js +1 -0
  540. package/dist/engine/types/extension-options-map.js +1 -0
  541. package/dist/engine/types/feature.d.ts +1 -0
  542. package/dist/engine/types/feature.js +1 -0
  543. package/dist/engine/types/fields.d.ts +1 -0
  544. package/dist/engine/types/fields.js +1 -0
  545. package/dist/engine/types/handlers.d.ts +2 -0
  546. package/dist/engine/types/handlers.js +1 -0
  547. package/dist/engine/types/hooks.d.ts +1 -0
  548. package/dist/engine/types/hooks.js +1 -0
  549. package/dist/engine/types/http-route.js +1 -0
  550. package/dist/engine/types/identifiers.js +1 -0
  551. package/dist/engine/types/index.d.ts +30 -0
  552. package/dist/engine/types/index.js +10 -0
  553. package/dist/engine/types/nav.d.ts +1 -0
  554. package/dist/engine/types/nav.js +1 -0
  555. package/dist/engine/types/ownership.d.ts +1 -0
  556. package/dist/engine/types/ownership.js +1 -0
  557. package/dist/engine/types/projection.d.ts +1 -0
  558. package/dist/engine/types/projection.js +1 -0
  559. package/dist/engine/types/relations.js +1 -0
  560. package/dist/engine/types/screen.d.ts +2 -0
  561. package/dist/engine/types/screen.js +1 -0
  562. package/dist/engine/types/step.d.ts +1 -0
  563. package/dist/engine/types/step.js +1 -0
  564. package/dist/engine/types/target-ref.js +1 -0
  565. package/dist/engine/types/tree-node.js +1 -0
  566. package/dist/engine/types/workspace.d.ts +1 -0
  567. package/dist/engine/types/workspace.js +1 -0
  568. package/dist/engine/validate-projection-allowlist.d.ts +10 -0
  569. package/dist/engine/validate-projection-allowlist.js +164 -0
  570. package/dist/engine/validation.d.ts +3 -0
  571. package/dist/engine/validation.js +23 -0
  572. package/dist/engine/where-rule-lint.d.ts +2 -0
  573. package/dist/engine/where-rule-lint.js +171 -0
  574. package/dist/engine/write-handler-qn-extract.d.ts +15 -0
  575. package/dist/engine/write-handler-qn-extract.js +36 -0
  576. package/dist/entrypoint/index.d.ts +83 -0
  577. package/dist/entrypoint/index.js +312 -0
  578. package/dist/env/_zod-introspect.d.ts +17 -0
  579. package/dist/env/_zod-introspect.js +35 -0
  580. package/dist/env/dry-run.d.ts +13 -0
  581. package/dist/env/dry-run.js +158 -0
  582. package/dist/env/index.d.ts +98 -0
  583. package/dist/env/index.js +313 -0
  584. package/dist/errors/classes.d.ts +109 -0
  585. package/dist/errors/classes.js +190 -0
  586. package/dist/errors/field-issue.d.ts +6 -0
  587. package/dist/errors/field-issue.js +1 -0
  588. package/dist/errors/index.d.ts +15 -0
  589. package/dist/errors/index.js +9 -0
  590. package/dist/errors/kumiko-error.d.ts +25 -0
  591. package/dist/errors/kumiko-error.js +43 -0
  592. package/dist/errors/member-resolution.d.ts +2 -0
  593. package/dist/errors/member-resolution.js +10 -0
  594. package/dist/errors/reasons.d.ts +23 -0
  595. package/dist/errors/reasons.js +81 -0
  596. package/dist/errors/serialize.d.ts +32 -0
  597. package/dist/errors/serialize.js +76 -0
  598. package/dist/errors/to-kumiko-error.d.ts +2 -0
  599. package/dist/errors/to-kumiko-error.js +9 -0
  600. package/dist/errors/transition-details.d.ts +7 -0
  601. package/dist/errors/transition-details.js +16 -0
  602. package/dist/errors/write-error-info.d.ts +20 -0
  603. package/dist/errors/write-error-info.js +99 -0
  604. package/dist/errors/zod-bridge.d.ts +3 -0
  605. package/dist/errors/zod-bridge.js +58 -0
  606. package/dist/es-ops/context.d.ts +19 -0
  607. package/dist/es-ops/context.js +70 -0
  608. package/dist/es-ops/index.d.ts +4 -0
  609. package/dist/es-ops/index.js +14 -0
  610. package/dist/es-ops/operations-schema.d.ts +5 -0
  611. package/dist/es-ops/operations-schema.js +40 -0
  612. package/dist/es-ops/runner.d.ts +29 -0
  613. package/dist/es-ops/runner.js +195 -0
  614. package/dist/es-ops/types.d.ts +92 -0
  615. package/dist/es-ops/types.js +14 -0
  616. package/dist/event-store/admin-api.d.ts +17 -0
  617. package/dist/event-store/admin-api.js +173 -0
  618. package/dist/event-store/archive.d.ts +14 -0
  619. package/dist/event-store/archive.js +55 -0
  620. package/dist/event-store/errors.d.ts +15 -0
  621. package/dist/event-store/errors.js +49 -0
  622. package/dist/event-store/event-store.d.ts +38 -0
  623. package/dist/event-store/event-store.js +310 -0
  624. package/dist/event-store/events-schema.d.ts +3 -0
  625. package/dist/event-store/events-schema.js +66 -0
  626. package/dist/event-store/index.d.ts +12 -0
  627. package/dist/event-store/index.js +12 -0
  628. package/dist/event-store/provenance-append.d.ts +13 -0
  629. package/dist/event-store/provenance-append.js +49 -0
  630. package/dist/event-store/rebuild-dead-letter.d.ts +25 -0
  631. package/dist/event-store/rebuild-dead-letter.js +71 -0
  632. package/dist/event-store/row-to-stored-event.d.ts +17 -0
  633. package/dist/event-store/row-to-stored-event.js +15 -0
  634. package/dist/event-store/snapshot.d.ts +26 -0
  635. package/dist/event-store/snapshot.js +155 -0
  636. package/dist/event-store/transfer.d.ts +13 -0
  637. package/dist/event-store/transfer.js +62 -0
  638. package/dist/event-store/types.d.ts +1 -0
  639. package/dist/event-store/types.js +1 -0
  640. package/dist/event-store/upcaster-dead-letter.d.ts +27 -0
  641. package/dist/event-store/upcaster-dead-letter.js +76 -0
  642. package/dist/event-store/upcaster.d.ts +14 -0
  643. package/dist/event-store/upcaster.js +86 -0
  644. package/dist/files/content-disposition.d.ts +3 -0
  645. package/dist/files/content-disposition.js +50 -0
  646. package/dist/files/feature.d.ts +9 -0
  647. package/dist/files/feature.js +26 -0
  648. package/dist/files/file-handle.d.ts +7 -0
  649. package/dist/files/file-handle.js +71 -0
  650. package/dist/files/file-ref-entity.d.ts +134 -0
  651. package/dist/files/file-ref-entity.js +32 -0
  652. package/dist/files/file-ref-table.d.ts +134 -0
  653. package/dist/files/file-ref-table.js +12 -0
  654. package/dist/files/file-routes.d.ts +34 -0
  655. package/dist/files/file-routes.js +433 -0
  656. package/dist/files/in-memory-provider.d.ts +7 -0
  657. package/dist/files/in-memory-provider.js +82 -0
  658. package/dist/files/index.d.ts +17 -0
  659. package/dist/files/index.js +13 -0
  660. package/dist/files/local-provider.d.ts +2 -0
  661. package/dist/files/local-provider.js +128 -0
  662. package/dist/files/provider-resolver.d.ts +58 -0
  663. package/dist/files/provider-resolver.js +87 -0
  664. package/dist/files/storage-tracking.d.ts +20 -0
  665. package/dist/files/storage-tracking.js +179 -0
  666. package/dist/files/types.d.ts +59 -0
  667. package/dist/files/types.js +276 -0
  668. package/dist/files/zip-stream.d.ts +31 -0
  669. package/dist/files/zip-stream.js +207 -0
  670. package/dist/http/index.d.ts +2 -0
  671. package/dist/http/index.js +1 -0
  672. package/dist/i18n/index.d.ts +12 -0
  673. package/dist/i18n/index.js +27 -0
  674. package/dist/i18n/mail-registry.d.ts +7 -0
  675. package/dist/i18n/mail-registry.js +34 -0
  676. package/dist/i18n/request-locale.d.ts +22 -0
  677. package/dist/i18n/request-locale.js +62 -0
  678. package/dist/i18n/required-surface-keys.d.ts +33 -0
  679. package/dist/i18n/required-surface-keys.js +416 -0
  680. package/dist/i18n/settings-hub-keys.d.ts +14 -0
  681. package/dist/i18n/settings-hub-keys.js +29 -0
  682. package/dist/jobs/index.d.ts +2 -0
  683. package/dist/jobs/index.js +1 -0
  684. package/dist/jobs/job-runner.d.ts +54 -0
  685. package/dist/jobs/job-runner.js +1110 -0
  686. package/dist/lifecycle/index.d.ts +2 -0
  687. package/dist/lifecycle/index.js +2 -0
  688. package/dist/lifecycle/lifecycle.d.ts +23 -0
  689. package/dist/lifecycle/lifecycle.js +111 -0
  690. package/dist/lifecycle/signal-handlers.d.ts +10 -0
  691. package/dist/lifecycle/signal-handlers.js +40 -0
  692. package/dist/logging/index.d.ts +4 -0
  693. package/dist/logging/index.js +2 -0
  694. package/dist/logging/pino-logger.d.ts +9 -0
  695. package/dist/logging/pino-logger.js +61 -0
  696. package/dist/logging/types.js +1 -0
  697. package/dist/logging/utils.d.ts +8 -0
  698. package/dist/logging/utils.js +41 -0
  699. package/dist/migrations/index.d.ts +4 -0
  700. package/dist/migrations/index.js +8 -0
  701. package/dist/migrations/kumiko-drift.d.ts +26 -0
  702. package/dist/migrations/kumiko-drift.js +151 -0
  703. package/dist/migrations/pending-rebuilds.d.ts +81 -0
  704. package/dist/migrations/pending-rebuilds.js +163 -0
  705. package/dist/migrations/pii-event-backfill.d.ts +40 -0
  706. package/dist/migrations/pii-event-backfill.js +275 -0
  707. package/dist/migrations/projection-table-index.d.ts +5 -0
  708. package/dist/migrations/projection-table-index.js +21 -0
  709. package/dist/observability/console-provider.d.ts +10 -0
  710. package/dist/observability/console-provider.js +101 -0
  711. package/dist/observability/context.d.ts +10 -0
  712. package/dist/observability/context.js +13 -0
  713. package/dist/observability/escape-hatch-report.d.ts +23 -0
  714. package/dist/observability/escape-hatch-report.js +92 -0
  715. package/dist/observability/fallback.d.ts +4 -0
  716. package/dist/observability/fallback.js +28 -0
  717. package/dist/observability/ids.d.ts +2 -0
  718. package/dist/observability/ids.js +22 -0
  719. package/dist/observability/index.d.ts +15 -0
  720. package/dist/observability/index.js +15 -0
  721. package/dist/observability/metric-validator.d.ts +4 -0
  722. package/dist/observability/metric-validator.js +73 -0
  723. package/dist/observability/metrics-handle.d.ts +5 -0
  724. package/dist/observability/metrics-handle.js +102 -0
  725. package/dist/observability/metrics-wiring.d.ts +18 -0
  726. package/dist/observability/metrics-wiring.js +21 -0
  727. package/dist/observability/noop-provider.d.ts +2 -0
  728. package/dist/observability/noop-provider.js +105 -0
  729. package/dist/observability/prometheus-meter.d.ts +26 -0
  730. package/dist/observability/prometheus-meter.js +257 -0
  731. package/dist/observability/recording-meter.d.ts +31 -0
  732. package/dist/observability/recording-meter.js +127 -0
  733. package/dist/observability/recording-tracer.d.ts +32 -0
  734. package/dist/observability/recording-tracer.js +135 -0
  735. package/dist/observability/redis-wrapper.d.ts +3 -0
  736. package/dist/observability/redis-wrapper.js +121 -0
  737. package/dist/observability/sensitive-filter.d.ts +9 -0
  738. package/dist/observability/sensitive-filter.js +92 -0
  739. package/dist/observability/standard-metrics.d.ts +41 -0
  740. package/dist/observability/standard-metrics.js +237 -0
  741. package/dist/observability/types/index.js +1 -0
  742. package/dist/observability/types/metric.js +1 -0
  743. package/dist/observability/types/provider.js +1 -0
  744. package/dist/observability/types/span.js +1 -0
  745. package/dist/pipeline/active-membership.d.ts +12 -0
  746. package/dist/pipeline/active-membership.js +124 -0
  747. package/dist/pipeline/append-event-core.d.ts +12 -0
  748. package/dist/pipeline/append-event-core.js +84 -0
  749. package/dist/pipeline/auth-claims-resolver.d.ts +9 -0
  750. package/dist/pipeline/auth-claims-resolver.js +76 -0
  751. package/dist/pipeline/cascade-handler.d.ts +6 -0
  752. package/dist/pipeline/cascade-handler.js +85 -0
  753. package/dist/pipeline/dispatch-batch.d.ts +5 -0
  754. package/dist/pipeline/dispatch-batch.js +217 -0
  755. package/dist/pipeline/dispatch-query.d.ts +4 -0
  756. package/dist/pipeline/dispatch-query.js +141 -0
  757. package/dist/pipeline/dispatch-shared.d.ts +58 -0
  758. package/dist/pipeline/dispatch-shared.js +924 -0
  759. package/dist/pipeline/dispatch-stream.d.ts +3 -0
  760. package/dist/pipeline/dispatch-stream.js +89 -0
  761. package/dist/pipeline/dispatch-write.d.ts +6 -0
  762. package/dist/pipeline/dispatch-write.js +428 -0
  763. package/dist/pipeline/dispatcher-utils.d.ts +36 -0
  764. package/dist/pipeline/dispatcher-utils.js +139 -0
  765. package/dist/pipeline/dispatcher.d.ts +30 -0
  766. package/dist/pipeline/dispatcher.js +131 -0
  767. package/dist/pipeline/distributed-lock.d.ts +13 -0
  768. package/dist/pipeline/distributed-lock.js +42 -0
  769. package/dist/pipeline/entity-cache.d.ts +7 -0
  770. package/dist/pipeline/entity-cache.js +68 -0
  771. package/dist/pipeline/event-consumer-state.d.ts +16 -0
  772. package/dist/pipeline/event-consumer-state.js +96 -0
  773. package/dist/pipeline/event-dedup.d.ts +11 -0
  774. package/dist/pipeline/event-dedup.js +12 -0
  775. package/dist/pipeline/event-dispatcher-admin.d.ts +46 -0
  776. package/dist/pipeline/event-dispatcher-admin.js +196 -0
  777. package/dist/pipeline/event-dispatcher-delivery.d.ts +68 -0
  778. package/dist/pipeline/event-dispatcher-delivery.js +310 -0
  779. package/dist/pipeline/event-dispatcher.d.ts +52 -0
  780. package/dist/pipeline/event-dispatcher.js +523 -0
  781. package/dist/pipeline/event-retention.d.ts +20 -0
  782. package/dist/pipeline/event-retention.js +78 -0
  783. package/dist/pipeline/idempotency.d.ts +19 -0
  784. package/dist/pipeline/idempotency.js +115 -0
  785. package/dist/pipeline/index.d.ts +34 -0
  786. package/dist/pipeline/index.js +19 -0
  787. package/dist/pipeline/irreversible-operation-gate.d.ts +4 -0
  788. package/dist/pipeline/irreversible-operation-gate.js +57 -0
  789. package/dist/pipeline/lifecycle-pipeline.d.ts +29 -0
  790. package/dist/pipeline/lifecycle-pipeline.js +266 -0
  791. package/dist/pipeline/member-read-only-transaction.d.ts +3 -0
  792. package/dist/pipeline/member-read-only-transaction.js +68 -0
  793. package/dist/pipeline/member-reader.d.ts +7 -0
  794. package/dist/pipeline/member-reader.js +87 -0
  795. package/dist/pipeline/msp-rebuild.d.ts +12 -0
  796. package/dist/pipeline/msp-rebuild.js +163 -0
  797. package/dist/pipeline/multi-stream-apply-context.d.ts +18 -0
  798. package/dist/pipeline/multi-stream-apply-context.js +40 -0
  799. package/dist/pipeline/pending-gap-ranges.d.ts +12 -0
  800. package/dist/pipeline/pending-gap-ranges.js +99 -0
  801. package/dist/pipeline/projection-rebuild.d.ts +55 -0
  802. package/dist/pipeline/projection-rebuild.js +285 -0
  803. package/dist/pipeline/projection-state.d.ts +9 -0
  804. package/dist/pipeline/projection-state.js +51 -0
  805. package/dist/pipeline/projections-runner.d.ts +5 -0
  806. package/dist/pipeline/projections-runner.js +57 -0
  807. package/dist/pipeline/redis-keys.d.ts +8 -0
  808. package/dist/pipeline/redis-keys.js +10 -0
  809. package/dist/pipeline/system-hooks.d.ts +25 -0
  810. package/dist/pipeline/system-hooks.js +590 -0
  811. package/dist/pipeline/system-identity-switch.d.ts +30 -0
  812. package/dist/pipeline/system-identity-switch.js +248 -0
  813. package/dist/pipeline/tenant-timezone-cache.d.ts +17 -0
  814. package/dist/pipeline/tenant-timezone-cache.js +55 -0
  815. package/dist/pipeline/write-origin.d.ts +10 -0
  816. package/dist/pipeline/write-origin.js +110 -0
  817. package/dist/random/generate.d.ts +56 -0
  818. package/dist/random/generate.js +92 -0
  819. package/dist/random/index.d.ts +2 -0
  820. package/dist/random/index.js +2 -0
  821. package/dist/random/words.d.ts +2 -0
  822. package/dist/random/words.js +391 -0
  823. package/dist/rate-limit/bucket.d.ts +14 -0
  824. package/dist/rate-limit/bucket.js +20 -0
  825. package/dist/rate-limit/index.d.ts +3 -0
  826. package/dist/rate-limit/index.js +3 -0
  827. package/dist/rate-limit/middleware.d.ts +24 -0
  828. package/dist/rate-limit/middleware.js +101 -0
  829. package/dist/rate-limit/resolver.d.ts +9 -0
  830. package/dist/rate-limit/resolver.js +177 -0
  831. package/dist/redis/client.d.ts +9 -0
  832. package/dist/redis/client.js +44 -0
  833. package/dist/redis/index.d.ts +4 -0
  834. package/dist/redis/index.js +2 -0
  835. package/dist/redis/pubsub-signal.d.ts +11 -0
  836. package/dist/redis/pubsub-signal.js +79 -0
  837. package/dist/schema-cli.d.ts +21 -0
  838. package/dist/schema-cli.js +438 -0
  839. package/dist/scripts/codemod/crypto-shredding-testing-move.d.ts +2 -0
  840. package/dist/scripts/codemod/crypto-shredding-testing-move.js +109 -0
  841. package/dist/scripts/codemod/migrate-cross-tenant.d.ts +19 -0
  842. package/dist/scripts/codemod/migrate-cross-tenant.js +266 -0
  843. package/dist/scripts/codemod/migrate-db-raw.d.ts +23 -0
  844. package/dist/scripts/codemod/migrate-db-raw.js +345 -0
  845. package/dist/scripts/codemod/migrate-open-to-all.d.ts +22 -0
  846. package/dist/scripts/codemod/migrate-open-to-all.js +194 -0
  847. package/dist/scripts/codemod/pii-personal-migration.d.ts +11 -0
  848. package/dist/scripts/codemod/pii-personal-migration.js +615 -0
  849. package/dist/scripts/codemod/unprocessable-error-details-reason.d.ts +2 -0
  850. package/dist/scripts/codemod/unprocessable-error-details-reason.js +235 -0
  851. package/dist/search/derive-search-adapter-config.d.ts +3 -0
  852. package/dist/search/derive-search-adapter-config.js +23 -0
  853. package/dist/search/in-memory-adapter.d.ts +2 -0
  854. package/dist/search/in-memory-adapter.js +96 -0
  855. package/dist/search/index.d.ts +6 -0
  856. package/dist/search/index.js +8 -0
  857. package/dist/search/meilisearch-adapter.d.ts +10 -0
  858. package/dist/search/meilisearch-adapter.js +175 -0
  859. package/dist/search/purge-subject.d.ts +7 -0
  860. package/dist/search/purge-subject.js +178 -0
  861. package/dist/search/reindex-entity.d.ts +18 -0
  862. package/dist/search/reindex-entity.js +139 -0
  863. package/dist/search/types.js +1 -0
  864. package/dist/secrets/dek-cache.d.ts +13 -0
  865. package/dist/secrets/dek-cache.js +97 -0
  866. package/dist/secrets/derive-purpose-secret.d.ts +1 -0
  867. package/dist/secrets/derive-purpose-secret.js +16 -0
  868. package/dist/secrets/env-master-key-provider.d.ts +6 -0
  869. package/dist/secrets/env-master-key-provider.js +134 -0
  870. package/dist/secrets/envelope-cipher.d.ts +8 -0
  871. package/dist/secrets/envelope-cipher.js +36 -0
  872. package/dist/secrets/envelope.d.ts +3 -0
  873. package/dist/secrets/envelope.js +44 -0
  874. package/dist/secrets/index.d.ts +9 -0
  875. package/dist/secrets/index.js +9 -0
  876. package/dist/secrets/leak-guard.d.ts +1 -0
  877. package/dist/secrets/leak-guard.js +79 -0
  878. package/dist/secrets/rotation.d.ts +2 -0
  879. package/dist/secrets/rotation.js +29 -0
  880. package/dist/secrets/stored-envelope.d.ts +11 -0
  881. package/dist/secrets/stored-envelope.js +32 -0
  882. package/dist/secrets/types.d.ts +1 -0
  883. package/dist/seeding/entity-seed.d.ts +19 -0
  884. package/dist/seeding/entity-seed.js +12 -0
  885. package/dist/seeding/index.d.ts +2 -0
  886. package/dist/seeding/index.js +2 -0
  887. package/dist/seeding/types.d.ts +7 -0
  888. package/dist/seeding/types.js +1 -0
  889. package/dist/stack/db.d.ts +19 -0
  890. package/dist/stack/db.js +61 -0
  891. package/dist/stack/drain-event-consumers.d.ts +4 -0
  892. package/dist/stack/drain-event-consumers.js +48 -0
  893. package/dist/stack/drain-jobs.d.ts +20 -0
  894. package/dist/stack/drain-jobs.js +99 -0
  895. package/dist/stack/event-collector.d.ts +9 -0
  896. package/dist/stack/event-collector.js +12 -0
  897. package/dist/stack/index.d.ts +9 -0
  898. package/dist/stack/index.js +19 -0
  899. package/dist/stack/push-entity-projection-tables.d.ts +24 -0
  900. package/dist/stack/push-entity-projection-tables.js +73 -0
  901. package/dist/stack/redis.d.ts +11 -0
  902. package/dist/stack/redis.js +38 -0
  903. package/dist/stack/request-helper.d.ts +35 -0
  904. package/dist/stack/request-helper.js +144 -0
  905. package/dist/stack/table-helpers.d.ts +32 -0
  906. package/dist/stack/table-helpers.js +138 -0
  907. package/dist/stack/test-stack.d.ts +161 -0
  908. package/dist/stack/test-stack.js +398 -0
  909. package/dist/stack/test-users.d.ts +33 -0
  910. package/dist/stack/test-users.js +29 -0
  911. package/dist/testing/access-assertions.d.ts +2 -0
  912. package/dist/testing/access-assertions.js +13 -0
  913. package/dist/testing/assertions.d.ts +10 -0
  914. package/dist/testing/assertions.js +22 -0
  915. package/dist/testing/boot-validator-fixture.d.ts +3 -0
  916. package/dist/testing/boot-validator-fixture.js +101 -0
  917. package/dist/testing/closed-connection-error.d.ts +7 -0
  918. package/dist/testing/closed-connection-error.js +47 -0
  919. package/dist/testing/db-cleanup.d.ts +9 -0
  920. package/dist/testing/db-cleanup.js +31 -0
  921. package/dist/testing/e2e-generator.d.ts +49 -0
  922. package/dist/testing/e2e-generator.js +377 -0
  923. package/dist/testing/expect-error.d.ts +2 -0
  924. package/dist/testing/expect-error.js +22 -0
  925. package/dist/testing/file-provider-contract.d.ts +2 -0
  926. package/dist/testing/file-provider-contract.js +102 -0
  927. package/dist/testing/handler-context.d.ts +4 -0
  928. package/dist/testing/handler-context.js +72 -0
  929. package/dist/testing/http-cookies.d.ts +7 -0
  930. package/dist/testing/http-cookies.js +47 -0
  931. package/dist/testing/index.d.ts +24 -0
  932. package/dist/testing/index.js +32 -0
  933. package/dist/testing/late-bound.d.ts +9 -0
  934. package/dist/testing/late-bound.js +31 -0
  935. package/dist/testing/multipart-helper.d.ts +22 -0
  936. package/dist/testing/multipart-helper.js +77 -0
  937. package/dist/testing/mutable-master-key-provider.d.ts +7 -0
  938. package/dist/testing/mutable-master-key-provider.js +35 -0
  939. package/dist/testing/observability-recorder.d.ts +9 -0
  940. package/dist/testing/observability-recorder.js +29 -0
  941. package/dist/testing/real-providers.d.ts +3 -0
  942. package/dist/testing/real-providers.js +21 -0
  943. package/dist/testing/seed.d.ts +9 -0
  944. package/dist/testing/seed.js +21 -0
  945. package/dist/testing/shared-entities.d.ts +256 -0
  946. package/dist/testing/shared-entities.js +56 -0
  947. package/dist/testing/utils.d.ts +1 -0
  948. package/dist/testing/utils.js +1 -0
  949. package/dist/testing/wait-for.d.ts +20 -0
  950. package/dist/testing/wait-for.js +46 -0
  951. package/dist/testing/without-ambient-temporal.d.ts +5 -0
  952. package/dist/testing/without-ambient-temporal.js +17 -0
  953. package/dist/time/boot-tz-warning.d.ts +5 -0
  954. package/dist/time/boot-tz-warning.js +24 -0
  955. package/dist/time/geo-tz.js +1 -0
  956. package/dist/time/iana.d.ts +1 -0
  957. package/dist/time/iana.js +18 -0
  958. package/dist/time/index.d.ts +6 -0
  959. package/dist/time/index.js +15 -0
  960. package/dist/time/legacy-date.d.ts +5 -0
  961. package/dist/time/legacy-date.js +15 -0
  962. package/dist/time/polyfill.d.ts +9 -0
  963. package/dist/time/polyfill.js +52 -0
  964. package/dist/time/tz-context.d.ts +13 -0
  965. package/dist/time/tz-context.js +80 -0
  966. package/dist/ui-types/app-schema.d.ts +26 -0
  967. package/dist/ui-types/app-schema.js +9 -0
  968. package/dist/ui-types/formality.d.ts +2 -0
  969. package/dist/ui-types/formality.js +5 -0
  970. package/dist/ui-types/index.d.ts +22 -0
  971. package/dist/ui-types/index.js +31 -0
  972. package/dist/ui-types/list-row-meta.d.ts +18 -0
  973. package/dist/ui-types/list-row-meta.js +65 -0
  974. package/dist/ui-types/plural.d.ts +12 -0
  975. package/dist/ui-types/plural.js +57 -0
  976. package/dist/upgrade-cli.d.ts +11 -0
  977. package/dist/upgrade-cli.js +532 -0
  978. package/dist/utils/assert.d.ts +1 -0
  979. package/dist/utils/assert.js +18 -0
  980. package/dist/utils/case.d.ts +1 -0
  981. package/dist/utils/case.js +6 -0
  982. package/dist/utils/compare.d.ts +1 -0
  983. package/dist/utils/compare.js +10 -0
  984. package/dist/utils/env-parse.d.ts +1 -0
  985. package/dist/utils/env-parse.js +13 -0
  986. package/dist/utils/ids.d.ts +2 -0
  987. package/dist/utils/ids.js +23 -0
  988. package/dist/utils/index.d.ts +9 -0
  989. package/dist/utils/index.js +9 -0
  990. package/dist/utils/is-plain-object.d.ts +2 -0
  991. package/dist/utils/is-plain-object.js +4 -0
  992. package/dist/utils/parse-string-array-json.d.ts +2 -0
  993. package/dist/utils/parse-string-array-json.js +11 -0
  994. package/dist/utils/safe-json.d.ts +17 -0
  995. package/dist/utils/safe-json.js +47 -0
  996. package/dist/utils/serialization.d.ts +1 -0
  997. package/dist/utils/serialization.js +13 -0
  998. package/package.json +274 -93
  999. package/src/changes.json +6 -0
  1000. package/src/scripts/codemod/pii-personal-migration.ts +5 -5
  1001. package/src/__tests__/anonymous-access.integration.test.ts +0 -513
  1002. package/src/__tests__/consumer-cli.integration.test.ts +0 -172
  1003. package/src/__tests__/derived-fields.integration.test.ts +0 -126
  1004. package/src/__tests__/entity-list-limits.integration.test.ts +0 -84
  1005. package/src/__tests__/entity-permalink-open.integration.test.ts +0 -99
  1006. package/src/__tests__/error-contract.integration.test.ts +0 -436
  1007. package/src/__tests__/field-access.integration.test.ts +0 -273
  1008. package/src/__tests__/fixtures/migrate-cross-tenant/manual-only.expected.ts +0 -44
  1009. package/src/__tests__/fixtures/migrate-cross-tenant/manual-only.input.ts +0 -44
  1010. package/src/__tests__/fixtures/migrate-cross-tenant/rewrite.expected.ts +0 -41
  1011. package/src/__tests__/fixtures/migrate-cross-tenant/rewrite.input.ts +0 -41
  1012. package/src/__tests__/fixtures/migrate-db-raw/global-fetch.expected.ts +0 -9
  1013. package/src/__tests__/fixtures/migrate-db-raw/global-fetch.input.ts +0 -10
  1014. package/src/__tests__/fixtures/migrate-db-raw/global-select.expected.ts +0 -6
  1015. package/src/__tests__/fixtures/migrate-db-raw/global-select.input.ts +0 -12
  1016. package/src/__tests__/fixtures/migrate-db-raw/import-pruning.expected.ts +0 -12
  1017. package/src/__tests__/fixtures/migrate-db-raw/import-pruning.input.ts +0 -12
  1018. package/src/__tests__/fixtures/migrate-db-raw/manual-only.expected.ts +0 -26
  1019. package/src/__tests__/fixtures/migrate-db-raw/manual-only.input.ts +0 -26
  1020. package/src/__tests__/fixtures/migrate-db-raw/own-tenant-const-shorthand.expected.ts +0 -10
  1021. package/src/__tests__/fixtures/migrate-db-raw/own-tenant-const-shorthand.input.ts +0 -11
  1022. package/src/__tests__/fixtures/migrate-db-raw/own-tenant-event.expected.ts +0 -9
  1023. package/src/__tests__/fixtures/migrate-db-raw/own-tenant-event.input.ts +0 -15
  1024. package/src/__tests__/fixtures/migrate-open-to-all/manual-only.expected.ts +0 -16
  1025. package/src/__tests__/fixtures/migrate-open-to-all/manual-only.input.ts +0 -16
  1026. package/src/__tests__/fixtures/migrate-open-to-all/test-nested-shorthand.expected.ts +0 -12
  1027. package/src/__tests__/fixtures/migrate-open-to-all/test-nested-shorthand.input.ts +0 -12
  1028. package/src/__tests__/fixtures/migrate-open-to-all/test-simple.expected.ts +0 -7
  1029. package/src/__tests__/fixtures/migrate-open-to-all/test-simple.input.ts +0 -7
  1030. package/src/__tests__/full-stack.integration.test.ts +0 -924
  1031. package/src/__tests__/migrate-cross-tenant-codemod.test.ts +0 -106
  1032. package/src/__tests__/migrate-db-raw-codemod.test.ts +0 -132
  1033. package/src/__tests__/migrate-open-to-all-codemod.test.ts +0 -84
  1034. package/src/__tests__/ownership-where-write-path.integration.test.ts +0 -147
  1035. package/src/__tests__/ownership.integration.test.ts +0 -454
  1036. package/src/__tests__/pii-personal-migration-report-codemod.test.ts +0 -160
  1037. package/src/__tests__/reference-data.integration.test.ts +0 -243
  1038. package/src/__tests__/related-list-parent-filter.integration.test.ts +0 -103
  1039. package/src/__tests__/schema-cli-kms-slots.integration.test.ts +0 -172
  1040. package/src/__tests__/schema-cli-rebuild.integration.test.ts +0 -189
  1041. package/src/__tests__/schema-cli-status.integration.test.ts +0 -96
  1042. package/src/__tests__/schema-cli-temporal-polyfill.test.ts +0 -48
  1043. package/src/__tests__/schema-cli.integration.test.ts +0 -485
  1044. package/src/__tests__/store-table.integration.test.ts +0 -94
  1045. package/src/__tests__/transition-guard.integration.test.ts +0 -342
  1046. package/src/__tests__/unprocessable-error-details-reason-codemod.test.ts +0 -205
  1047. package/src/__tests__/upgrade-cli.test.ts +0 -723
  1048. package/src/api/__tests__/api-constants-completeness.test.ts +0 -63
  1049. package/src/api/__tests__/api.test.ts +0 -869
  1050. package/src/api/__tests__/auth-middleware-anonymous-access-boot.test.ts +0 -40
  1051. package/src/api/__tests__/auth-middleware-transport.test.ts +0 -102
  1052. package/src/api/__tests__/auth-routes-cookie.test.ts +0 -330
  1053. package/src/api/__tests__/auth-routes-invalid-body-invite.test.ts +0 -263
  1054. package/src/api/__tests__/auth-routes-mfa-preauth-confirm.test.ts +0 -230
  1055. package/src/api/__tests__/auth-routes-mfa-preauth-enable-start.test.ts +0 -263
  1056. package/src/api/__tests__/auth-routes-mfa-verify.test.ts +0 -221
  1057. package/src/api/__tests__/auth-routes-trusted-proxy.test.ts +0 -164
  1058. package/src/api/__tests__/batch.integration.test.ts +0 -548
  1059. package/src/api/__tests__/body-limit.test.ts +0 -184
  1060. package/src/api/__tests__/client-ip.test.ts +0 -184
  1061. package/src/api/__tests__/csrf-constants-sync.test.ts +0 -20
  1062. package/src/api/__tests__/csrf-middleware.test.ts +0 -97
  1063. package/src/api/__tests__/dispatcher-live.integration.test.ts +0 -292
  1064. package/src/api/__tests__/extra-route-rejection.test.ts +0 -38
  1065. package/src/api/__tests__/extra-routes.integration.test.ts +0 -663
  1066. package/src/api/__tests__/http-cache.test.ts +0 -173
  1067. package/src/api/__tests__/http-route-entry.integration.test.ts +0 -114
  1068. package/src/api/__tests__/http-route-rate-limit.integration.test.ts +0 -148
  1069. package/src/api/__tests__/jwt.test.ts +0 -316
  1070. package/src/api/__tests__/login-rate-limiter-sweep.test.ts +0 -50
  1071. package/src/api/__tests__/metrics-endpoint.test.ts +0 -132
  1072. package/src/api/__tests__/nested-write-ownership.integration.test.ts +0 -268
  1073. package/src/api/__tests__/nested-write.integration.test.ts +0 -210
  1074. package/src/api/__tests__/origin-middleware.integration.test.ts +0 -273
  1075. package/src/api/__tests__/origin-middleware.test.ts +0 -279
  1076. package/src/api/__tests__/pat-route-guard.integration.test.ts +0 -126
  1077. package/src/api/__tests__/pat-scope.test.ts +0 -36
  1078. package/src/api/__tests__/pii-leak-guard.integration.test.ts +0 -112
  1079. package/src/api/__tests__/post-auth-landing.test.ts +0 -100
  1080. package/src/api/__tests__/readiness.test.ts +0 -76
  1081. package/src/api/__tests__/redis-login-rate-limiter.integration.test.ts +0 -138
  1082. package/src/api/__tests__/redis-sse-broker.integration.test.ts +0 -321
  1083. package/src/api/__tests__/request-id-middleware.test.ts +0 -229
  1084. package/src/api/__tests__/request-locale.integration.test.ts +0 -146
  1085. package/src/api/__tests__/schema-route.integration.test.ts +0 -157
  1086. package/src/api/__tests__/server-boot-guards.test.ts +0 -308
  1087. package/src/api/__tests__/server-error-logging.test.ts +0 -342
  1088. package/src/api/__tests__/server-jwt-ttl.test.ts +0 -58
  1089. package/src/api/__tests__/sse-broker.test.ts +0 -267
  1090. package/src/api/__tests__/sse-route.test.ts +0 -245
  1091. package/src/api/__tests__/stream-escape-hatch.integration.test.ts +0 -203
  1092. package/src/api/__tests__/websocket-route.test.ts +0 -552
  1093. package/src/api/anonymous-cookie.ts +0 -61
  1094. package/src/api/api-constants.ts +0 -153
  1095. package/src/api/auth-middleware.ts +0 -694
  1096. package/src/api/auth-routes.ts +0 -1590
  1097. package/src/api/client-ip.ts +0 -131
  1098. package/src/api/csrf-middleware.ts +0 -74
  1099. package/src/api/extra-route.ts +0 -178
  1100. package/src/api/http-cache.ts +0 -122
  1101. package/src/api/index.ts +0 -117
  1102. package/src/api/jwt.ts +0 -277
  1103. package/src/api/observability-middleware.ts +0 -89
  1104. package/src/api/origin-middleware.ts +0 -137
  1105. package/src/api/pat-route-guard.ts +0 -51
  1106. package/src/api/pat-scope.ts +0 -14
  1107. package/src/api/pii-leak-guard.ts +0 -46
  1108. package/src/api/post-auth-landing.ts +0 -105
  1109. package/src/api/readiness.ts +0 -132
  1110. package/src/api/redis-sse-broker.ts +0 -171
  1111. package/src/api/request-context.ts +0 -137
  1112. package/src/api/request-id-middleware.ts +0 -138
  1113. package/src/api/route-registrars.ts +0 -193
  1114. package/src/api/routes.ts +0 -432
  1115. package/src/api/server.ts +0 -1550
  1116. package/src/api/sse-broker.ts +0 -175
  1117. package/src/api/sse-route.ts +0 -74
  1118. package/src/api/tokens.ts +0 -16
  1119. package/src/api/websocket-route.ts +0 -327
  1120. package/src/arg-parser.ts +0 -66
  1121. package/src/auth/__tests__/roles.test.ts +0 -24
  1122. package/src/auth/index.ts +0 -7
  1123. package/src/auth/roles.ts +0 -42
  1124. package/src/bun-db/__tests__/PATTERN.md +0 -72
  1125. package/src/bun-db/__tests__/_helpers.ts +0 -104
  1126. package/src/bun-db/__tests__/batch-methods.integration.test.ts +0 -143
  1127. package/src/bun-db/__tests__/batch-methods.test.ts +0 -21
  1128. package/src/bun-db/__tests__/bun-test-db.ts +0 -19
  1129. package/src/bun-db/__tests__/closed-connection-retry.integration.test.ts +0 -252
  1130. package/src/bun-db/__tests__/coerce-row-plain-date.test.ts +0 -70
  1131. package/src/bun-db/__tests__/coerce-row-temporal.test.ts +0 -41
  1132. package/src/bun-db/__tests__/column-types.integration.test.ts +0 -132
  1133. package/src/bun-db/__tests__/compound-types.integration.test.ts +0 -134
  1134. package/src/bun-db/__tests__/decimal-field.integration.test.ts +0 -81
  1135. package/src/bun-db/__tests__/extract-table-info.test.ts +0 -71
  1136. package/src/bun-db/__tests__/jsonb-edge-cases.integration.test.ts +0 -235
  1137. package/src/bun-db/__tests__/postgres-closed-socket-write.integration.test.ts +0 -87
  1138. package/src/bun-db/__tests__/query-guards.test.ts +0 -111
  1139. package/src/bun-db/__tests__/run-in-savepoint-if-supported.integration.test.ts +0 -47
  1140. package/src/bun-db/__tests__/select-many-retry.integration.test.ts +0 -138
  1141. package/src/bun-db/__tests__/smoke.integration.test.ts +0 -43
  1142. package/src/bun-db/__tests__/sql-expr-brand.test.ts +0 -115
  1143. package/src/bun-db/__tests__/sql-methods.integration.test.ts +0 -231
  1144. package/src/bun-db/__tests__/where-patterns.integration.test.ts +0 -213
  1145. package/src/bun-db/__tests__/write-brand.test.ts +0 -72
  1146. package/src/bun-db/connection.ts +0 -87
  1147. package/src/bun-db/index.ts +0 -36
  1148. package/src/bun-db/query.ts +0 -1394
  1149. package/src/compliance/__tests__/duration-spec.test.ts +0 -72
  1150. package/src/compliance/__tests__/profiles.test.ts +0 -308
  1151. package/src/compliance/__tests__/sub-processors.test.ts +0 -149
  1152. package/src/compliance/duration-spec.ts +0 -44
  1153. package/src/compliance/index.ts +0 -31
  1154. package/src/compliance/override-schema.ts +0 -136
  1155. package/src/compliance/profiles.ts +0 -424
  1156. package/src/compliance/sub-processors.ts +0 -165
  1157. package/src/consumer-cli.ts +0 -134
  1158. package/src/crypto/__tests__/blind-index.test.ts +0 -132
  1159. package/src/crypto/__tests__/event-pii.test.ts +0 -417
  1160. package/src/crypto/__tests__/kek-rotation.integration.test.ts +0 -180
  1161. package/src/crypto/__tests__/kek-source.test.ts +0 -441
  1162. package/src/crypto/__tests__/kms-adapter-contract.ts +0 -134
  1163. package/src/crypto/__tests__/kms-adapter.contract.test.ts +0 -4
  1164. package/src/crypto/__tests__/kms-wiring.test.ts +0 -203
  1165. package/src/crypto/__tests__/pg-kms-adapter.integration.test.ts +0 -154
  1166. package/src/crypto/__tests__/pii-field-encryption.test.ts +0 -403
  1167. package/src/crypto/__tests__/request-kms-cache.test.ts +0 -74
  1168. package/src/crypto/__tests__/subject-id-schema.test.ts +0 -60
  1169. package/src/crypto/__tests__/subject-key-record.test.ts +0 -109
  1170. package/src/crypto/__tests__/subject-resolver.test.ts +0 -250
  1171. package/src/crypto/__tests__/system-event-pii.test.ts +0 -77
  1172. package/src/crypto/blind-index.ts +0 -118
  1173. package/src/crypto/ciphertext-pattern.ts +0 -19
  1174. package/src/crypto/event-pii.ts +0 -99
  1175. package/src/crypto/in-memory-kms-adapter.ts +0 -50
  1176. package/src/crypto/index.ts +0 -84
  1177. package/src/crypto/is-self-pii-field.ts +0 -8
  1178. package/src/crypto/kek-source.ts +0 -180
  1179. package/src/crypto/kms-adapter.ts +0 -51
  1180. package/src/crypto/kms-wiring.ts +0 -208
  1181. package/src/crypto/pg-kms-adapter.ts +0 -303
  1182. package/src/crypto/pii-field-encryption.ts +0 -266
  1183. package/src/crypto/request-kms-cache.ts +0 -38
  1184. package/src/crypto/subject-resolver.ts +0 -232
  1185. package/src/crypto/system-event-pii.ts +0 -57
  1186. package/src/db/__tests__/apply-entity-event-removed-column.integration.test.ts +0 -109
  1187. package/src/db/__tests__/apply-entity-event-tenant.integration.test.ts +0 -159
  1188. package/src/db/__tests__/assert-exists-in.integration.test.ts +0 -120
  1189. package/src/db/__tests__/assert-no-unreachable-live-rows.integration.test.ts +0 -190
  1190. package/src/db/__tests__/big-int-field.test.ts +0 -132
  1191. package/src/db/__tests__/blind-index.integration.test.ts +0 -280
  1192. package/src/db/__tests__/build-filter-where.test.ts +0 -50
  1193. package/src/db/__tests__/collect-table-metas.test.ts +0 -188
  1194. package/src/db/__tests__/column-ddl.integration.test.ts +0 -122
  1195. package/src/db/__tests__/compound-types.test.ts +0 -126
  1196. package/src/db/__tests__/config-seed.integration.test.ts +0 -292
  1197. package/src/db/__tests__/connection-close-outage.integration.test.ts +0 -110
  1198. package/src/db/__tests__/connection-options.test.ts +0 -68
  1199. package/src/db/__tests__/cursor.test.ts +0 -42
  1200. package/src/db/__tests__/decimal-field.test.ts +0 -109
  1201. package/src/db/__tests__/dialect-instant.test.ts +0 -47
  1202. package/src/db/__tests__/eagerload.integration.test.ts +0 -374
  1203. package/src/db/__tests__/entity-field-encryption.test.ts +0 -74
  1204. package/src/db/__tests__/entity-table-from-registry.test.ts +0 -79
  1205. package/src/db/__tests__/entity-table-meta-source.test.ts +0 -92
  1206. package/src/db/__tests__/entity-table-types.test.ts +0 -162
  1207. package/src/db/__tests__/event-store-executor-context.pii-roundtrip.test.ts +0 -67
  1208. package/src/db/__tests__/event-store-executor-global-tenancy.integration.test.ts +0 -73
  1209. package/src/db/__tests__/event-store-executor-list.integration.test.ts +0 -791
  1210. package/src/db/__tests__/event-store-executor-money-rehydrate.integration.test.ts +0 -153
  1211. package/src/db/__tests__/event-store-executor-reference-search.integration.test.ts +0 -643
  1212. package/src/db/__tests__/event-store-executor-reference-sort.integration.test.ts +0 -256
  1213. package/src/db/__tests__/event-store-executor-write-verbs.integration.test.ts +0 -788
  1214. package/src/db/__tests__/event-store-executor.integration.test.ts +0 -844
  1215. package/src/db/__tests__/event-store-system-stream.integration.test.ts +0 -96
  1216. package/src/db/__tests__/feature-table-sources.test.ts +0 -34
  1217. package/src/db/__tests__/implicit-projection-equivalence.integration.test.ts +0 -393
  1218. package/src/db/__tests__/instant-to-driver-temporal.test.ts +0 -21
  1219. package/src/db/__tests__/list-filter-field-access.integration.test.ts +0 -218
  1220. package/src/db/__tests__/list-pagination.test.ts +0 -28
  1221. package/src/db/__tests__/list-row-meta-drift.test.ts +0 -15
  1222. package/src/db/__tests__/located-timestamp.test.ts +0 -203
  1223. package/src/db/__tests__/managed-recreate.integration.test.ts +0 -78
  1224. package/src/db/__tests__/migrate-generator.test.ts +0 -383
  1225. package/src/db/__tests__/migrate-runner.test.ts +0 -118
  1226. package/src/db/__tests__/money.test.ts +0 -291
  1227. package/src/db/__tests__/multi-row-insert.integration.test.ts +0 -88
  1228. package/src/db/__tests__/number-field-fractional.integration.test.ts +0 -58
  1229. package/src/db/__tests__/parent-ref-clause.test.ts +0 -213
  1230. package/src/db/__tests__/parse-auto-verb.test.ts +0 -70
  1231. package/src/db/__tests__/pg-error.test.ts +0 -57
  1232. package/src/db/__tests__/rebuild-marker.test.ts +0 -180
  1233. package/src/db/__tests__/replay-migration-sql.test.ts +0 -401
  1234. package/src/db/__tests__/required-not-null-migration-safety.integration.test.ts +0 -109
  1235. package/src/db/__tests__/run-in-own-transaction.integration.test.ts +0 -166
  1236. package/src/db/__tests__/schema-inspection.test.ts +0 -27
  1237. package/src/db/__tests__/schema-migration.integration.test.ts +0 -354
  1238. package/src/db/__tests__/source-shadow-create.integration.test.ts +0 -59
  1239. package/src/db/__tests__/system-db-view-export.test.ts +0 -107
  1240. package/src/db/__tests__/table-builder-indexes.test.ts +0 -189
  1241. package/src/db/__tests__/table-builder-meta-lockstep.test.ts +0 -224
  1242. package/src/db/__tests__/table-builder-required.test.ts +0 -214
  1243. package/src/db/__tests__/tenant-db-convention-cross-tenant.test.ts +0 -72
  1244. package/src/db/__tests__/tenant-db-count.integration.test.ts +0 -92
  1245. package/src/db/__tests__/tenant-db-declared-unsafe-raw.test.ts +0 -163
  1246. package/src/db/__tests__/tenant-db-global.integration.test.ts +0 -134
  1247. package/src/db/__tests__/tenant-db-global.test.ts +0 -352
  1248. package/src/db/__tests__/tenant-db-no-raw.test.ts +0 -85
  1249. package/src/db/__tests__/tenant-db-where-merge.integration.test.ts +0 -123
  1250. package/src/db/__tests__/tenant-db-where-merge.test.ts +0 -164
  1251. package/src/db/__tests__/tenant-db.integration.test.ts +0 -575
  1252. package/src/db/__tests__/unchecked-system-db.test.ts +0 -259
  1253. package/src/db/__tests__/unique-violation-mapping.integration.test.ts +0 -200
  1254. package/src/db/__tests__/with-systemdb-unsafe-raw-grant.test.ts +0 -71
  1255. package/src/db/api.ts +0 -52
  1256. package/src/db/apply-entity-event.ts +0 -211
  1257. package/src/db/assert-exists-in.ts +0 -52
  1258. package/src/db/blind-index-cleanup.ts +0 -145
  1259. package/src/db/bun-provider.ts +0 -42
  1260. package/src/db/collect-table-metas.ts +0 -98
  1261. package/src/db/compound-types.ts +0 -47
  1262. package/src/db/config-seed.ts +0 -104
  1263. package/src/db/connection.ts +0 -57
  1264. package/src/db/cursor.ts +0 -47
  1265. package/src/db/dialect.ts +0 -544
  1266. package/src/db/eagerload.ts +0 -260
  1267. package/src/db/entity-field-encryption.ts +0 -158
  1268. package/src/db/entity-table-from-registry.ts +0 -31
  1269. package/src/db/entity-table-meta-types.ts +0 -2
  1270. package/src/db/entity-table-meta.ts +0 -491
  1271. package/src/db/event-store-executor-context.ts +0 -510
  1272. package/src/db/event-store-executor-read.ts +0 -916
  1273. package/src/db/event-store-executor-write.ts +0 -920
  1274. package/src/db/event-store-executor.ts +0 -50
  1275. package/src/db/feature-table-sources.ts +0 -35
  1276. package/src/db/index.ts +0 -162
  1277. package/src/db/located-timestamp.ts +0 -118
  1278. package/src/db/migrate-generator.ts +0 -549
  1279. package/src/db/migrate-runner.ts +0 -348
  1280. package/src/db/money.ts +0 -211
  1281. package/src/db/parent-ref-clause.ts +0 -182
  1282. package/src/db/pg-error.ts +0 -74
  1283. package/src/db/postgres-provider.ts +0 -28
  1284. package/src/db/queries/__tests__/event-store-idempotency-index.integration.test.ts +0 -78
  1285. package/src/db/queries/__tests__/shadow-swap.test.ts +0 -43
  1286. package/src/db/queries/__tests__/unsafe-read-retrying.integration.test.ts +0 -115
  1287. package/src/db/queries/advisory-lock.ts +0 -11
  1288. package/src/db/queries/backfill-pii.ts +0 -578
  1289. package/src/db/queries/ddl.ts +0 -45
  1290. package/src/db/queries/entity-read.ts +0 -15
  1291. package/src/db/queries/es-ops.ts +0 -17
  1292. package/src/db/queries/event-consumer.ts +0 -418
  1293. package/src/db/queries/event-store-admin.ts +0 -130
  1294. package/src/db/queries/event-store-transfer.ts +0 -73
  1295. package/src/db/queries/event-store.ts +0 -354
  1296. package/src/db/queries/pii-backfill-state.ts +0 -33
  1297. package/src/db/queries/projection-rebuild.ts +0 -104
  1298. package/src/db/queries/raw-sql.ts +0 -28
  1299. package/src/db/queries/seed-context.ts +0 -62
  1300. package/src/db/queries/shadow-swap.ts +0 -378
  1301. package/src/db/queries/table-ops.ts +0 -11
  1302. package/src/db/queries/test-stack.ts +0 -32
  1303. package/src/db/query-api.ts +0 -24
  1304. package/src/db/query.ts +0 -35
  1305. package/src/db/rebuild-marker.ts +0 -103
  1306. package/src/db/reference-data.ts +0 -73
  1307. package/src/db/render-ddl.ts +0 -57
  1308. package/src/db/replay-migration-sql.ts +0 -257
  1309. package/src/db/schema-inspection.ts +0 -81
  1310. package/src/db/table-builder.ts +0 -692
  1311. package/src/db/tenant-db-runner.ts +0 -23
  1312. package/src/db/tenant-db.ts +0 -727
  1313. package/src/derivatives/__tests__/derivatives-context.integration.test.ts +0 -231
  1314. package/src/derivatives/__tests__/derivatives-context.test.ts +0 -369
  1315. package/src/derivatives/__tests__/field-variants.test.ts +0 -62
  1316. package/src/derivatives/__tests__/variant-key.test.ts +0 -183
  1317. package/src/derivatives/__tests__/variant-route.integration.test.ts +0 -268
  1318. package/src/derivatives/delete-stored-file.ts +0 -86
  1319. package/src/derivatives/derivatives-context.ts +0 -314
  1320. package/src/derivatives/field-variants.ts +0 -20
  1321. package/src/derivatives/index.ts +0 -14
  1322. package/src/derivatives/variant-key.ts +0 -108
  1323. package/src/engine/__tests__/_pipeline-test-utils.ts +0 -23
  1324. package/src/engine/__tests__/auth-claims-registrar.test.ts +0 -74
  1325. package/src/engine/__tests__/boot-validator-action-wiring.test.ts +0 -362
  1326. package/src/engine/__tests__/boot-validator-api-exposure.test.ts +0 -142
  1327. package/src/engine/__tests__/boot-validator-boot-check.test.ts +0 -104
  1328. package/src/engine/__tests__/boot-validator-dashboard.test.ts +0 -381
  1329. package/src/engine/__tests__/boot-validator-detail-for.test.ts +0 -106
  1330. package/src/engine/__tests__/boot-validator-entity-list.test.ts +0 -120
  1331. package/src/engine/__tests__/boot-validator-gdpr-storage.test.ts +0 -85
  1332. package/src/engine/__tests__/boot-validator-i18n-keys.test.ts +0 -153
  1333. package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +0 -92
  1334. package/src/engine/__tests__/boot-validator-nav-area.test.ts +0 -116
  1335. package/src/engine/__tests__/boot-validator-pii-retention.test.ts +0 -994
  1336. package/src/engine/__tests__/boot-validator-projection-list.test.ts +0 -629
  1337. package/src/engine/__tests__/boot-validator-query-output-schema.test.ts +0 -578
  1338. package/src/engine/__tests__/boot-validator-query-refs.test.ts +0 -151
  1339. package/src/engine/__tests__/boot-validator-ref-entity.test.ts +0 -196
  1340. package/src/engine/__tests__/boot-validator-s0-integration.test.ts +0 -172
  1341. package/src/engine/__tests__/boot-validator.test.ts +0 -5984
  1342. package/src/engine/__tests__/build-app-schema-settings-hub.test.ts +0 -246
  1343. package/src/engine/__tests__/build-app-schema-url-prefill.test.ts +0 -222
  1344. package/src/engine/__tests__/build-app-schema.test.ts +0 -1167
  1345. package/src/engine/__tests__/build-config-feature-schema-extension-selector.test.ts +0 -395
  1346. package/src/engine/__tests__/build-config-feature-schema-secrets.test.ts +0 -188
  1347. package/src/engine/__tests__/build-config-feature-schema.test.ts +0 -511
  1348. package/src/engine/__tests__/build-target.test.ts +0 -127
  1349. package/src/engine/__tests__/changeset-changes.test.ts +0 -64
  1350. package/src/engine/__tests__/claim-keys.test.ts +0 -274
  1351. package/src/engine/__tests__/codemod-pipeline.test.ts +0 -682
  1352. package/src/engine/__tests__/config-helpers.test.ts +0 -309
  1353. package/src/engine/__tests__/content-collection.test.ts +0 -307
  1354. package/src/engine/__tests__/decimal-field.test.ts +0 -59
  1355. package/src/engine/__tests__/dedupe-features.test.ts +0 -85
  1356. package/src/engine/__tests__/define-feature-entity-mapping.test.ts +0 -53
  1357. package/src/engine/__tests__/define-roles.test.ts +0 -21
  1358. package/src/engine/__tests__/define-workflow.test.ts +0 -79
  1359. package/src/engine/__tests__/describe-workflow-step-error.test.ts +0 -17
  1360. package/src/engine/__tests__/duration-utils.test.ts +0 -16
  1361. package/src/engine/__tests__/effective-features.test.ts +0 -86
  1362. package/src/engine/__tests__/embedded-derived.test.ts +0 -35
  1363. package/src/engine/__tests__/engine.test.ts +0 -2406
  1364. package/src/engine/__tests__/entity-create-caller-id.integration.test.ts +0 -87
  1365. package/src/engine/__tests__/entity-exclude-fields.integration.test.ts +0 -134
  1366. package/src/engine/__tests__/entity-handlers-escape-hatch.test.ts +0 -91
  1367. package/src/engine/__tests__/entity-handlers.test.ts +0 -562
  1368. package/src/engine/__tests__/entity-presave-wiring.integration.test.ts +0 -153
  1369. package/src/engine/__tests__/entity-restore-tenant-isolation.integration.test.ts +0 -168
  1370. package/src/engine/__tests__/entity-write-crosstenant.integration.test.ts +0 -317
  1371. package/src/engine/__tests__/event-helpers.test.ts +0 -68
  1372. package/src/engine/__tests__/event-migration-declarative.test.ts +0 -67
  1373. package/src/engine/__tests__/event-type-map-augmentation.test.ts +0 -24
  1374. package/src/engine/__tests__/extend-entity-projection.test.ts +0 -133
  1375. package/src/engine/__tests__/extends-registrar.test.ts +0 -279
  1376. package/src/engine/__tests__/factories-long-text.test.ts +0 -95
  1377. package/src/engine/__tests__/factories-number-unit.test.ts +0 -23
  1378. package/src/engine/__tests__/factories-personal.test.ts +0 -216
  1379. package/src/engine/__tests__/factories-time.test.ts +0 -94
  1380. package/src/engine/__tests__/feature-crud-shorthand.test.ts +0 -73
  1381. package/src/engine/__tests__/feature-crud-verb-access.integration.test.ts +0 -83
  1382. package/src/engine/__tests__/feature-manifest.test.ts +0 -137
  1383. package/src/engine/__tests__/field-access.test.ts +0 -65
  1384. package/src/engine/__tests__/field-predicates.test.ts +0 -48
  1385. package/src/engine/__tests__/form-money-currency-types.test.ts +0 -90
  1386. package/src/engine/__tests__/hook-identity-switch-grant.test.ts +0 -188
  1387. package/src/engine/__tests__/hook-phases.test.ts +0 -172
  1388. package/src/engine/__tests__/http-route-anonymous-required.test.ts +0 -43
  1389. package/src/engine/__tests__/identifiers.test.ts +0 -35
  1390. package/src/engine/__tests__/lifecycle-hooks.test.ts +0 -243
  1391. package/src/engine/__tests__/membership-roles.test.ts +0 -67
  1392. package/src/engine/__tests__/metric-navigate-tab.test.ts +0 -167
  1393. package/src/engine/__tests__/multiselect-filter.integration.test.ts +0 -141
  1394. package/src/engine/__tests__/nav.test.ts +0 -497
  1395. package/src/engine/__tests__/no-return-guard.test.ts +0 -17
  1396. package/src/engine/__tests__/ownership.test.ts +0 -475
  1397. package/src/engine/__tests__/parse-ref-target.test.ts +0 -43
  1398. package/src/engine/__tests__/pipeline-engine.test.ts +0 -215
  1399. package/src/engine/__tests__/pipeline-handler.integration.test.ts +0 -880
  1400. package/src/engine/__tests__/pipeline-observability.integration.test.ts +0 -142
  1401. package/src/engine/__tests__/pipeline-performance.integration.test.ts +0 -152
  1402. package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +0 -288
  1403. package/src/engine/__tests__/post-query-hook.test.ts +0 -144
  1404. package/src/engine/__tests__/project-app-schema-for-roles.test.ts +0 -500
  1405. package/src/engine/__tests__/projection-detail-actions.test.ts +0 -145
  1406. package/src/engine/__tests__/projection-detail-singleton.test.ts +0 -86
  1407. package/src/engine/__tests__/projection-detail-tabs.test.ts +0 -314
  1408. package/src/engine/__tests__/projection-helpers.test.ts +0 -75
  1409. package/src/engine/__tests__/projection-list-filter.integration.test.ts +0 -115
  1410. package/src/engine/__tests__/projection.test.ts +0 -191
  1411. package/src/engine/__tests__/qualified-name.test.ts +0 -306
  1412. package/src/engine/__tests__/read-steps-tenant-filter.integration.test.ts +0 -215
  1413. package/src/engine/__tests__/registrar-object-form.test.ts +0 -141
  1414. package/src/engine/__tests__/registry.test.ts +0 -326
  1415. package/src/engine/__tests__/required-surface-keys.test.ts +0 -477
  1416. package/src/engine/__tests__/resolve-config-or-param.test.ts +0 -315
  1417. package/src/engine/__tests__/role-assignment.test.ts +0 -71
  1418. package/src/engine/__tests__/row-action-navigate-tab.test.ts +0 -107
  1419. package/src/engine/__tests__/run-in.test.ts +0 -38
  1420. package/src/engine/__tests__/schema-builder-date-bounds.test.ts +0 -47
  1421. package/src/engine/__tests__/schema-builder.test.ts +0 -1211
  1422. package/src/engine/__tests__/screen-definition-exports.test.ts +0 -102
  1423. package/src/engine/__tests__/screen-filter-ops.test.ts +0 -31
  1424. package/src/engine/__tests__/screen-helpers.test.ts +0 -52
  1425. package/src/engine/__tests__/screen.test.ts +0 -1684
  1426. package/src/engine/__tests__/search-payload-extension.test.ts +0 -288
  1427. package/src/engine/__tests__/soft-delete-cleanup-job-tenant-db.integration.test.ts +0 -82
  1428. package/src/engine/__tests__/soft-delete-cleanup.test.ts +0 -167
  1429. package/src/engine/__tests__/state-machine.test.ts +0 -148
  1430. package/src/engine/__tests__/steps-aggregate-append-event.test.ts +0 -115
  1431. package/src/engine/__tests__/steps-aggregate-create.test.ts +0 -92
  1432. package/src/engine/__tests__/steps-aggregate-update.test.ts +0 -127
  1433. package/src/engine/__tests__/steps-call-feature.test.ts +0 -123
  1434. package/src/engine/__tests__/steps-mail-send.test.ts +0 -137
  1435. package/src/engine/__tests__/steps-read.test.ts +0 -332
  1436. package/src/engine/__tests__/steps-resolver-utils.test.ts +0 -50
  1437. package/src/engine/__tests__/steps-unsafe-projection-delete.test.ts +0 -77
  1438. package/src/engine/__tests__/steps-unsafe-projection-upsert.test.ts +0 -131
  1439. package/src/engine/__tests__/steps-webhook-send.test.ts +0 -143
  1440. package/src/engine/__tests__/steps-workflow.test.ts +0 -353
  1441. package/src/engine/__tests__/store-table.test.ts +0 -247
  1442. package/src/engine/__tests__/system-user.test.ts +0 -57
  1443. package/src/engine/__tests__/tier-resolver-extension.test.ts +0 -69
  1444. package/src/engine/__tests__/toolbar-navigate-tab.test.ts +0 -233
  1445. package/src/engine/__tests__/tree-actions-patterns.test.ts +0 -163
  1446. package/src/engine/__tests__/validate-custom-screen-write-qns.test.ts +0 -43
  1447. package/src/engine/__tests__/validate-projection-allowlist.test.ts +0 -498
  1448. package/src/engine/__tests__/validation-hooks.test.ts +0 -77
  1449. package/src/engine/__tests__/where-rule-lint.test.ts +0 -79
  1450. package/src/engine/__tests__/write-handler-qn-extract.test.ts +0 -50
  1451. package/src/engine/access.ts +0 -27
  1452. package/src/engine/active-membership.ts +0 -70
  1453. package/src/engine/boot-validator/__tests__/access-declarations.test.ts +0 -707
  1454. package/src/engine/boot-validator/__tests__/access-roles.test.ts +0 -84
  1455. package/src/engine/boot-validator/__tests__/action-icon.test.ts +0 -81
  1456. package/src/engine/boot-validator/__tests__/anonymous-rate-limit-required.test.ts +0 -63
  1457. package/src/engine/boot-validator/__tests__/config-deps.test.ts +0 -92
  1458. package/src/engine/boot-validator/__tests__/global-tenancy.test.ts +0 -73
  1459. package/src/engine/boot-validator/__tests__/i18n-keys.test.ts +0 -340
  1460. package/src/engine/boot-validator/__tests__/nav.test.ts +0 -290
  1461. package/src/engine/boot-validator/__tests__/no-all-role-in-handler-access.test.ts +0 -77
  1462. package/src/engine/boot-validator/__tests__/ownership.test.ts +0 -87
  1463. package/src/engine/boot-validator/__tests__/parent-ref.test.ts +0 -161
  1464. package/src/engine/boot-validator/__tests__/rate-limit-disabled-reason.test.ts +0 -45
  1465. package/src/engine/boot-validator/__tests__/record-owned.test.ts +0 -65
  1466. package/src/engine/boot-validator/__tests__/security-baseline.test.ts +0 -107
  1467. package/src/engine/boot-validator/__tests__/transfer-graph.test.ts +0 -138
  1468. package/src/engine/boot-validator/access-declarations.ts +0 -211
  1469. package/src/engine/boot-validator/access-roles.ts +0 -85
  1470. package/src/engine/boot-validator/action-wiring.ts +0 -163
  1471. package/src/engine/boot-validator/api-ext.ts +0 -81
  1472. package/src/engine/boot-validator/boot-check.ts +0 -21
  1473. package/src/engine/boot-validator/config-deps.ts +0 -246
  1474. package/src/engine/boot-validator/custom-screen-write-qns.ts +0 -87
  1475. package/src/engine/boot-validator/detail-screens.ts +0 -49
  1476. package/src/engine/boot-validator/entity-handler.ts +0 -1011
  1477. package/src/engine/boot-validator/entity-list-screens.ts +0 -100
  1478. package/src/engine/boot-validator/gdpr-storage.ts +0 -59
  1479. package/src/engine/boot-validator/global-tenancy.ts +0 -29
  1480. package/src/engine/boot-validator/i18n-keys.ts +0 -101
  1481. package/src/engine/boot-validator/index.ts +0 -301
  1482. package/src/engine/boot-validator/nav.ts +0 -241
  1483. package/src/engine/boot-validator/ownership.ts +0 -352
  1484. package/src/engine/boot-validator/parent-ref.ts +0 -96
  1485. package/src/engine/boot-validator/pii-retention.ts +0 -272
  1486. package/src/engine/boot-validator/projection-list-screens.ts +0 -293
  1487. package/src/engine/boot-validator/query-output-columns.ts +0 -273
  1488. package/src/engine/boot-validator/query-refs.ts +0 -141
  1489. package/src/engine/boot-validator/record-owned.ts +0 -21
  1490. package/src/engine/boot-validator/screens.ts +0 -2604
  1491. package/src/engine/boot-validator/security-baseline.ts +0 -26
  1492. package/src/engine/boot-validator/transfer-graph.ts +0 -135
  1493. package/src/engine/boot-validator/url-prefill-fields.ts +0 -178
  1494. package/src/engine/boot-validator/workspaces.ts +0 -106
  1495. package/src/engine/boot-validator/zod-shape.ts +0 -142
  1496. package/src/engine/boot-validator.ts +0 -8
  1497. package/src/engine/build-app-schema.ts +0 -542
  1498. package/src/engine/build-config-feature-schema.ts +0 -815
  1499. package/src/engine/build-target.ts +0 -99
  1500. package/src/engine/changeset-changes.ts +0 -117
  1501. package/src/engine/codemod/index.ts +0 -15
  1502. package/src/engine/codemod/pipeline-codemod.ts +0 -641
  1503. package/src/engine/config-helpers.ts +0 -217
  1504. package/src/engine/constants.ts +0 -117
  1505. package/src/engine/create-app.ts +0 -177
  1506. package/src/engine/cross-tenant.test.ts +0 -32
  1507. package/src/engine/cross-tenant.ts +0 -22
  1508. package/src/engine/dedupe-features.ts +0 -46
  1509. package/src/engine/define-feature.ts +0 -169
  1510. package/src/engine/define-handler.ts +0 -194
  1511. package/src/engine/define-roles.ts +0 -19
  1512. package/src/engine/define-step.ts +0 -28
  1513. package/src/engine/define-workflow.ts +0 -147
  1514. package/src/engine/effective-features.ts +0 -97
  1515. package/src/engine/embedded-derived.ts +0 -93
  1516. package/src/engine/entity-handlers.ts +0 -782
  1517. package/src/engine/escape-hatch-declaration.ts +0 -7
  1518. package/src/engine/event-helpers.ts +0 -73
  1519. package/src/engine/extension-names.ts +0 -242
  1520. package/src/engine/extension-selector-plugins.ts +0 -24
  1521. package/src/engine/extensions/__tests__/hook-ctx-db-tenant-scoped.test.ts +0 -76
  1522. package/src/engine/extensions/escape-hatch-usage.ts +0 -16
  1523. package/src/engine/extensions/storage-provider.ts +0 -16
  1524. package/src/engine/extensions/tenant-data.ts +0 -34
  1525. package/src/engine/extensions/tenant-resource.ts +0 -40
  1526. package/src/engine/extensions/user-data.ts +0 -181
  1527. package/src/engine/factories.ts +0 -559
  1528. package/src/engine/feature-ast/__tests__/canonical-form.test.ts +0 -416
  1529. package/src/engine/feature-ast/__tests__/fixtures/cross-file-name-const/constants.ts +0 -1
  1530. package/src/engine/feature-ast/__tests__/fixtures/cross-file-name-const/feature.ts +0 -8
  1531. package/src/engine/feature-ast/__tests__/fixtures/cross-file-patch-const/constants.ts +0 -2
  1532. package/src/engine/feature-ast/__tests__/fixtures/cross-file-patch-const/feature.ts +0 -8
  1533. package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/feature.ts +0 -9
  1534. package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/screens.ts +0 -4
  1535. package/src/engine/feature-ast/__tests__/fixtures/resolve-import/alias-reexport.ts +0 -1
  1536. package/src/engine/feature-ast/__tests__/fixtures/resolve-import/cycle-a.ts +0 -1
  1537. package/src/engine/feature-ast/__tests__/fixtures/resolve-import/cycle-b.ts +0 -1
  1538. package/src/engine/feature-ast/__tests__/fixtures/resolve-import/entry.ts +0 -3
  1539. package/src/engine/feature-ast/__tests__/fixtures/resolve-import/local-rebind.ts +0 -3
  1540. package/src/engine/feature-ast/__tests__/fixtures/resolve-import/origin.ts +0 -1
  1541. package/src/engine/feature-ast/__tests__/fixtures/resolve-import/star-barrel.ts +0 -1
  1542. package/src/engine/feature-ast/__tests__/handler-header-roundtrip.test.ts +0 -669
  1543. package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +0 -196
  1544. package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +0 -138
  1545. package/src/engine/feature-ast/__tests__/parse.test.ts +0 -2841
  1546. package/src/engine/feature-ast/__tests__/patch-update.test.ts +0 -718
  1547. package/src/engine/feature-ast/__tests__/patch.test.ts +0 -780
  1548. package/src/engine/feature-ast/__tests__/patcher.test.ts +0 -468
  1549. package/src/engine/feature-ast/__tests__/pattern-change-schema.test.ts +0 -819
  1550. package/src/engine/feature-ast/__tests__/read-optional-access-rule.test.ts +0 -42
  1551. package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +0 -947
  1552. package/src/engine/feature-ast/__tests__/resolve-import.test.ts +0 -138
  1553. package/src/engine/feature-ast/entity-field-types.ts +0 -41
  1554. package/src/engine/feature-ast/extractors/ai-steps.ts +0 -352
  1555. package/src/engine/feature-ast/extractors/events.ts +0 -349
  1556. package/src/engine/feature-ast/extractors/handlers.ts +0 -459
  1557. package/src/engine/feature-ast/extractors/hooks.ts +0 -331
  1558. package/src/engine/feature-ast/extractors/index.ts +0 -92
  1559. package/src/engine/feature-ast/extractors/jobs-routes.ts +0 -225
  1560. package/src/engine/feature-ast/extractors/projections-screens.ts +0 -269
  1561. package/src/engine/feature-ast/extractors/resolve-import.ts +0 -187
  1562. package/src/engine/feature-ast/extractors/round1.ts +0 -150
  1563. package/src/engine/feature-ast/extractors/round2.ts +0 -276
  1564. package/src/engine/feature-ast/extractors/round3.ts +0 -474
  1565. package/src/engine/feature-ast/extractors/round5.ts +0 -114
  1566. package/src/engine/feature-ast/extractors/round6.ts +0 -32
  1567. package/src/engine/feature-ast/extractors/shared.ts +0 -356
  1568. package/src/engine/feature-ast/index.ts +0 -113
  1569. package/src/engine/feature-ast/parse.ts +0 -615
  1570. package/src/engine/feature-ast/patch.ts +0 -979
  1571. package/src/engine/feature-ast/patcher.ts +0 -546
  1572. package/src/engine/feature-ast/pattern-change-schema.ts +0 -1411
  1573. package/src/engine/feature-ast/patterns.ts +0 -803
  1574. package/src/engine/feature-ast/render.ts +0 -767
  1575. package/src/engine/feature-ast/source-location.ts +0 -45
  1576. package/src/engine/feature-builder-state.ts +0 -174
  1577. package/src/engine/feature-changelog.ts +0 -95
  1578. package/src/engine/feature-config-events-jobs.ts +0 -472
  1579. package/src/engine/feature-entity-handlers.ts +0 -269
  1580. package/src/engine/feature-manifest.ts +0 -173
  1581. package/src/engine/feature-ui-extensions.ts +0 -648
  1582. package/src/engine/field-access.ts +0 -140
  1583. package/src/engine/field-helpers.ts +0 -35
  1584. package/src/engine/handler-helpers.ts +0 -26
  1585. package/src/engine/hook-helpers.ts +0 -16
  1586. package/src/engine/i18n-key.ts +0 -12
  1587. package/src/engine/index.ts +0 -585
  1588. package/src/engine/instruction-fields.ts +0 -11
  1589. package/src/engine/membership-roles.ts +0 -61
  1590. package/src/engine/object-form.ts +0 -27
  1591. package/src/engine/ownership.ts +0 -404
  1592. package/src/engine/parse-ref-target.ts +0 -28
  1593. package/src/engine/pattern-library/__tests__/library.test.ts +0 -399
  1594. package/src/engine/pattern-library/index.ts +0 -24
  1595. package/src/engine/pattern-library/library.ts +0 -140
  1596. package/src/engine/pattern-library/mixed-schemas.ts +0 -588
  1597. package/src/engine/pattern-library/opaque-schemas.ts +0 -124
  1598. package/src/engine/pattern-library/shared-fields.ts +0 -79
  1599. package/src/engine/pattern-library/static-schemas.ts +0 -456
  1600. package/src/engine/pattern-library/types.ts +0 -255
  1601. package/src/engine/personal-data-fields.ts +0 -66
  1602. package/src/engine/pipeline.ts +0 -111
  1603. package/src/engine/project-app-schema-for-roles.ts +0 -950
  1604. package/src/engine/projection-helpers.ts +0 -79
  1605. package/src/engine/qualified-name.ts +0 -165
  1606. package/src/engine/read-claim.ts +0 -31
  1607. package/src/engine/registry-facade.ts +0 -381
  1608. package/src/engine/registry-ingest.ts +0 -479
  1609. package/src/engine/registry-state.ts +0 -410
  1610. package/src/engine/registry-validate.ts +0 -810
  1611. package/src/engine/registry.ts +0 -94
  1612. package/src/engine/resolve-config-or-param.ts +0 -157
  1613. package/src/engine/role-assignment.ts +0 -63
  1614. package/src/engine/run-in.ts +0 -29
  1615. package/src/engine/run-pipeline.ts +0 -162
  1616. package/src/engine/schema-builder.ts +0 -428
  1617. package/src/engine/screen-filter-ops.ts +0 -60
  1618. package/src/engine/screen-helpers.ts +0 -161
  1619. package/src/engine/soft-delete-cleanup.ts +0 -126
  1620. package/src/engine/state-machine.ts +0 -71
  1621. package/src/engine/steps/__tests__/duration-utils.test.ts +0 -20
  1622. package/src/engine/steps/_duration-utils.ts +0 -35
  1623. package/src/engine/steps/_event-match.ts +0 -98
  1624. package/src/engine/steps/_no-return-guard.ts +0 -21
  1625. package/src/engine/steps/_read-source.ts +0 -12
  1626. package/src/engine/steps/_resolver-utils.ts +0 -42
  1627. package/src/engine/steps/_step-dispatch-constants.ts +0 -38
  1628. package/src/engine/steps/aggregate-append-event.ts +0 -56
  1629. package/src/engine/steps/aggregate-create.ts +0 -56
  1630. package/src/engine/steps/aggregate-update.ts +0 -68
  1631. package/src/engine/steps/branch.ts +0 -84
  1632. package/src/engine/steps/call-feature.ts +0 -49
  1633. package/src/engine/steps/compute.ts +0 -41
  1634. package/src/engine/steps/describe-workflow-step-error.ts +0 -6
  1635. package/src/engine/steps/for-each.ts +0 -111
  1636. package/src/engine/steps/mail-send.ts +0 -48
  1637. package/src/engine/steps/read-find-many.ts +0 -57
  1638. package/src/engine/steps/read-find-one.ts +0 -59
  1639. package/src/engine/steps/retry.ts +0 -99
  1640. package/src/engine/steps/return.ts +0 -35
  1641. package/src/engine/steps/unsafe-projection-delete.ts +0 -50
  1642. package/src/engine/steps/unsafe-projection-upsert.ts +0 -88
  1643. package/src/engine/steps/wait-for-event.ts +0 -90
  1644. package/src/engine/steps/wait.ts +0 -69
  1645. package/src/engine/steps/webhook-send.ts +0 -63
  1646. package/src/engine/system-user.ts +0 -38
  1647. package/src/engine/tier-resolver-extension.ts +0 -107
  1648. package/src/engine/types/config.ts +0 -2
  1649. package/src/engine/types/define-handler.ts +0 -2
  1650. package/src/engine/types/entity-handlers.ts +0 -2
  1651. package/src/engine/types/feature.ts +0 -2
  1652. package/src/engine/types/fields.ts +0 -2
  1653. package/src/engine/types/handlers.ts +0 -3
  1654. package/src/engine/types/hooks.ts +0 -2
  1655. package/src/engine/types/index.ts +0 -394
  1656. package/src/engine/types/nav.ts +0 -2
  1657. package/src/engine/types/ownership.ts +0 -2
  1658. package/src/engine/types/projection.ts +0 -2
  1659. package/src/engine/types/screen.ts +0 -3
  1660. package/src/engine/types/step.ts +0 -2
  1661. package/src/engine/types/workspace.ts +0 -2
  1662. package/src/engine/validate-projection-allowlist.ts +0 -191
  1663. package/src/engine/validation.ts +0 -33
  1664. package/src/engine/where-rule-lint.ts +0 -196
  1665. package/src/engine/write-handler-qn-extract.ts +0 -47
  1666. package/src/entrypoint/__tests__/entrypoint-attach-dispatcher.integration.test.ts +0 -140
  1667. package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.test.ts +0 -292
  1668. package/src/entrypoint/__tests__/split-deploy.integration.test.ts +0 -467
  1669. package/src/entrypoint/index.ts +0 -541
  1670. package/src/env/__tests__/compose-env-schema.test.ts +0 -410
  1671. package/src/env/__tests__/dry-run.test.ts +0 -161
  1672. package/src/env/__tests__/parse-env-dry-run.test.ts +0 -40
  1673. package/src/env/_zod-introspect.ts +0 -51
  1674. package/src/env/dry-run.ts +0 -204
  1675. package/src/env/index.ts +0 -435
  1676. package/src/errors/__tests__/classes.test.ts +0 -442
  1677. package/src/errors/__tests__/error-helpers.test.ts +0 -58
  1678. package/src/errors/__tests__/reason-i18n.test.ts +0 -46
  1679. package/src/errors/__tests__/write-failures.test.ts +0 -167
  1680. package/src/errors/classes.ts +0 -311
  1681. package/src/errors/field-issue.ts +0 -8
  1682. package/src/errors/i18n/de.yaml +0 -244
  1683. package/src/errors/i18n/en.yaml +0 -234
  1684. package/src/errors/index.ts +0 -47
  1685. package/src/errors/kumiko-error.ts +0 -67
  1686. package/src/errors/member-resolution.ts +0 -12
  1687. package/src/errors/reasons.ts +0 -102
  1688. package/src/errors/serialize.ts +0 -136
  1689. package/src/errors/to-kumiko-error.ts +0 -8
  1690. package/src/errors/transition-details.ts +0 -30
  1691. package/src/errors/write-error-info.ts +0 -124
  1692. package/src/errors/zod-bridge.ts +0 -62
  1693. package/src/es-ops/README.md +0 -179
  1694. package/src/es-ops/__tests__/context.integration.test.ts +0 -378
  1695. package/src/es-ops/__tests__/runner.integration.test.ts +0 -483
  1696. package/src/es-ops/__tests__/runner.test.ts +0 -202
  1697. package/src/es-ops/context.ts +0 -98
  1698. package/src/es-ops/index.ts +0 -34
  1699. package/src/es-ops/operations-schema.ts +0 -57
  1700. package/src/es-ops/runner.ts +0 -253
  1701. package/src/es-ops/types.ts +0 -124
  1702. package/src/event-store/__tests__/admin-api.integration.test.ts +0 -412
  1703. package/src/event-store/__tests__/backfill-pii.integration.test.ts +0 -880
  1704. package/src/event-store/__tests__/event-attribution.integration.test.ts +0 -236
  1705. package/src/event-store/__tests__/event-store.integration.test.ts +0 -932
  1706. package/src/event-store/__tests__/get-stream-version-perf.integration.test.ts +0 -87
  1707. package/src/event-store/__tests__/perf.integration.test.ts +0 -283
  1708. package/src/event-store/__tests__/provenance-append.integration.test.ts +0 -140
  1709. package/src/event-store/__tests__/row-to-stored-event.test.ts +0 -68
  1710. package/src/event-store/__tests__/snapshot.integration.test.ts +0 -328
  1711. package/src/event-store/__tests__/transfer.integration.test.ts +0 -236
  1712. package/src/event-store/__tests__/unscoped-stream-primitives.guard.test.ts +0 -62
  1713. package/src/event-store/__tests__/upcaster-dead-letter.integration.test.ts +0 -202
  1714. package/src/event-store/__tests__/upcaster.integration.test.ts +0 -491
  1715. package/src/event-store/admin-api.ts +0 -241
  1716. package/src/event-store/archive.ts +0 -83
  1717. package/src/event-store/errors.ts +0 -58
  1718. package/src/event-store/event-store.ts +0 -449
  1719. package/src/event-store/events-schema.ts +0 -89
  1720. package/src/event-store/index.ts +0 -80
  1721. package/src/event-store/provenance-append.ts +0 -67
  1722. package/src/event-store/rebuild-dead-letter.ts +0 -111
  1723. package/src/event-store/row-to-stored-event.ts +0 -34
  1724. package/src/event-store/snapshot.ts +0 -235
  1725. package/src/event-store/transfer.ts +0 -84
  1726. package/src/event-store/types.ts +0 -2
  1727. package/src/event-store/upcaster-dead-letter.ts +0 -120
  1728. package/src/event-store/upcaster.ts +0 -147
  1729. package/src/files/__tests__/build-storage-key.test.ts +0 -28
  1730. package/src/files/__tests__/content-disposition.test.ts +0 -123
  1731. package/src/files/__tests__/file-field-pipeline.integration.test.ts +0 -229
  1732. package/src/files/__tests__/file-handle.test.ts +0 -175
  1733. package/src/files/__tests__/file-ref-entity.test.ts +0 -42
  1734. package/src/files/__tests__/files.integration.test.ts +0 -1749
  1735. package/src/files/__tests__/in-memory-provider.contract.test.ts +0 -4
  1736. package/src/files/__tests__/in-memory-provider.test.ts +0 -94
  1737. package/src/files/__tests__/local-provider.contract.test.ts +0 -14
  1738. package/src/files/__tests__/local-provider.test.ts +0 -31
  1739. package/src/files/__tests__/provider-resolver.test.ts +0 -70
  1740. package/src/files/__tests__/read-stream.test.ts +0 -105
  1741. package/src/files/__tests__/storage-tracking.integration.test.ts +0 -238
  1742. package/src/files/__tests__/storage-tracking.test.ts +0 -46
  1743. package/src/files/__tests__/write-stream.test.ts +0 -250
  1744. package/src/files/__tests__/zip-stream.test.ts +0 -357
  1745. package/src/files/content-disposition.ts +0 -55
  1746. package/src/files/feature.ts +0 -44
  1747. package/src/files/file-handle.ts +0 -83
  1748. package/src/files/file-ref-entity.ts +0 -33
  1749. package/src/files/file-ref-table.ts +0 -13
  1750. package/src/files/file-routes.ts +0 -579
  1751. package/src/files/in-memory-provider.ts +0 -113
  1752. package/src/files/index.ts +0 -57
  1753. package/src/files/local-provider.ts +0 -132
  1754. package/src/files/provider-resolver.ts +0 -176
  1755. package/src/files/storage-tracking.ts +0 -245
  1756. package/src/files/types.ts +0 -336
  1757. package/src/files/zip-stream.ts +0 -251
  1758. package/src/http/index.ts +0 -10
  1759. package/src/i18n/__tests__/i18n.test.ts +0 -113
  1760. package/src/i18n/__tests__/mail-registry.test.ts +0 -54
  1761. package/src/i18n/__tests__/request-locale.test.ts +0 -19
  1762. package/src/i18n/__tests__/required-surface-keys.test.ts +0 -17
  1763. package/src/i18n/index.ts +0 -51
  1764. package/src/i18n/mail-registry.ts +0 -42
  1765. package/src/i18n/request-locale.ts +0 -72
  1766. package/src/i18n/required-surface-keys.ts +0 -459
  1767. package/src/i18n/settings-hub-keys.ts +0 -31
  1768. package/src/jobs/__tests__/job-attempt-context.integration.test.ts +0 -76
  1769. package/src/jobs/__tests__/job-backoff.integration.test.ts +0 -147
  1770. package/src/jobs/__tests__/job-event-trigger.integration.test.ts +0 -175
  1771. package/src/jobs/__tests__/job-last-success.integration.test.ts +0 -135
  1772. package/src/jobs/__tests__/job-multi-trigger.integration.test.ts +0 -147
  1773. package/src/jobs/__tests__/job-public-intake-origin.integration.test.ts +0 -536
  1774. package/src/jobs/__tests__/job-queue-depth.integration.test.ts +0 -82
  1775. package/src/jobs/__tests__/job-retention.integration.test.ts +0 -316
  1776. package/src/jobs/__tests__/job-retry-enqueue-paths.integration.test.ts +0 -309
  1777. package/src/jobs/__tests__/job-runner-boot-timeout.test.ts +0 -55
  1778. package/src/jobs/__tests__/job-systemdb.integration.test.ts +0 -153
  1779. package/src/jobs/__tests__/job-tenant-db.integration.test.ts +0 -162
  1780. package/src/jobs/__tests__/job-write-as.integration.test.ts +0 -251
  1781. package/src/jobs/__tests__/jobs.integration.test.ts +0 -1563
  1782. package/src/jobs/__tests__/scheduler-id.test.ts +0 -30
  1783. package/src/jobs/index.ts +0 -8
  1784. package/src/jobs/job-runner.ts +0 -1390
  1785. package/src/lifecycle/__tests__/create-test-lifecycle.ts +0 -19
  1786. package/src/lifecycle/__tests__/lifecycle-server.integration.test.ts +0 -108
  1787. package/src/lifecycle/__tests__/lifecycle.test.ts +0 -212
  1788. package/src/lifecycle/__tests__/signal-handlers.test.ts +0 -98
  1789. package/src/lifecycle/index.ts +0 -13
  1790. package/src/lifecycle/lifecycle.ts +0 -157
  1791. package/src/lifecycle/signal-handlers.ts +0 -64
  1792. package/src/logging/__tests__/fallback-logger.test.ts +0 -90
  1793. package/src/logging/__tests__/pino-trace-bridge.test.ts +0 -50
  1794. package/src/logging/index.ts +0 -4
  1795. package/src/logging/pino-logger.ts +0 -68
  1796. package/src/logging/utils.ts +0 -50
  1797. package/src/migrations/__tests__/kumiko-drift.integration.test.ts +0 -238
  1798. package/src/migrations/__tests__/kumiko-drift.report.test.ts +0 -105
  1799. package/src/migrations/__tests__/pending-rebuilds.integration.test.ts +0 -412
  1800. package/src/migrations/__tests__/pii-event-backfill.integration.test.ts +0 -457
  1801. package/src/migrations/index.ts +0 -36
  1802. package/src/migrations/kumiko-drift.ts +0 -187
  1803. package/src/migrations/pending-rebuilds.ts +0 -251
  1804. package/src/migrations/pii-event-backfill.ts +0 -422
  1805. package/src/migrations/projection-table-index.ts +0 -23
  1806. package/src/observability/__tests__/console-provider.test.ts +0 -67
  1807. package/src/observability/__tests__/escape-hatch-report.test.ts +0 -149
  1808. package/src/observability/__tests__/metric-validator.test.ts +0 -95
  1809. package/src/observability/__tests__/metrics-handle.test.ts +0 -30
  1810. package/src/observability/__tests__/metrics-wiring.test.ts +0 -61
  1811. package/src/observability/__tests__/noop-provider.test.ts +0 -82
  1812. package/src/observability/__tests__/observability.integration.test.ts +0 -639
  1813. package/src/observability/__tests__/prometheus-meter.test.ts +0 -144
  1814. package/src/observability/__tests__/recording-meter.test.ts +0 -101
  1815. package/src/observability/__tests__/recording-tracer.test.ts +0 -112
  1816. package/src/observability/__tests__/sensitive-filter.test.ts +0 -98
  1817. package/src/observability/console-provider.ts +0 -130
  1818. package/src/observability/context.ts +0 -26
  1819. package/src/observability/escape-hatch-report.ts +0 -129
  1820. package/src/observability/fallback.ts +0 -34
  1821. package/src/observability/ids.ts +0 -25
  1822. package/src/observability/index.ts +0 -88
  1823. package/src/observability/metric-validator.ts +0 -98
  1824. package/src/observability/metrics-handle.ts +0 -105
  1825. package/src/observability/metrics-wiring.ts +0 -32
  1826. package/src/observability/noop-provider.ts +0 -137
  1827. package/src/observability/prometheus-meter.ts +0 -286
  1828. package/src/observability/recording-meter.ts +0 -156
  1829. package/src/observability/recording-tracer.ts +0 -186
  1830. package/src/observability/redis-wrapper.ts +0 -132
  1831. package/src/observability/sensitive-filter.ts +0 -108
  1832. package/src/observability/standard-metrics.ts +0 -295
  1833. package/src/pipeline/__tests__/archive-stream.integration.test.ts +0 -299
  1834. package/src/pipeline/__tests__/auth-claims-resolver.test.ts +0 -279
  1835. package/src/pipeline/__tests__/blind-index-rebuild-guard.integration.test.ts +0 -94
  1836. package/src/pipeline/__tests__/cascade-handler.integration.test.ts +0 -435
  1837. package/src/pipeline/__tests__/cascade-handler.test.ts +0 -67
  1838. package/src/pipeline/__tests__/causation-chain.integration.test.ts +0 -207
  1839. package/src/pipeline/__tests__/ctx-bridge.integration.test.ts +0 -507
  1840. package/src/pipeline/__tests__/ctx-systemdb.integration.test.ts +0 -120
  1841. package/src/pipeline/__tests__/dispatcher-utils.test.ts +0 -132
  1842. package/src/pipeline/__tests__/dispatcher.test.ts +0 -1091
  1843. package/src/pipeline/__tests__/distributed-lock.integration.test.ts +0 -110
  1844. package/src/pipeline/__tests__/domain-events-projections.integration.test.ts +0 -323
  1845. package/src/pipeline/__tests__/escape-hatch-audit.integration.test.ts +0 -254
  1846. package/src/pipeline/__tests__/escape-hatch.integration.test.ts +0 -90
  1847. package/src/pipeline/__tests__/event-consumer-state.integration.test.ts +0 -81
  1848. package/src/pipeline/__tests__/event-dedup.integration.test.ts +0 -153
  1849. package/src/pipeline/__tests__/event-define-event-strict.integration.test.ts +0 -196
  1850. package/src/pipeline/__tests__/event-dispatcher-batch-delivery.test.ts +0 -178
  1851. package/src/pipeline/__tests__/event-dispatcher-batch-handler.integration.test.ts +0 -143
  1852. package/src/pipeline/__tests__/event-dispatcher-commit-order.integration.test.ts +0 -278
  1853. package/src/pipeline/__tests__/event-dispatcher-db-outage.integration.test.ts +0 -224
  1854. package/src/pipeline/__tests__/event-dispatcher-delivery-max-attempts.test.ts +0 -127
  1855. package/src/pipeline/__tests__/event-dispatcher-idle.integration.test.ts +0 -94
  1856. package/src/pipeline/__tests__/event-dispatcher-lifecycle.integration.test.ts +0 -209
  1857. package/src/pipeline/__tests__/event-dispatcher-multi-instance.integration.test.ts +0 -424
  1858. package/src/pipeline/__tests__/event-dispatcher-pass-failure.integration.test.ts +0 -266
  1859. package/src/pipeline/__tests__/event-dispatcher-per-consumer-turns.integration.test.ts +0 -126
  1860. package/src/pipeline/__tests__/event-dispatcher-pg-listen.integration.test.ts +0 -106
  1861. package/src/pipeline/__tests__/event-dispatcher-rearm.integration.test.ts +0 -263
  1862. package/src/pipeline/__tests__/event-dispatcher-recovery.integration.test.ts +0 -202
  1863. package/src/pipeline/__tests__/event-dispatcher-second-audit.integration.test.ts +0 -282
  1864. package/src/pipeline/__tests__/event-dispatcher-start-from.integration.test.ts +0 -276
  1865. package/src/pipeline/__tests__/event-dispatcher-strict.test.ts +0 -67
  1866. package/src/pipeline/__tests__/event-dispatcher.integration.test.ts +0 -290
  1867. package/src/pipeline/__tests__/event-retention.integration.test.ts +0 -242
  1868. package/src/pipeline/__tests__/fetch-for-writing.integration.test.ts +0 -364
  1869. package/src/pipeline/__tests__/hook-systemdb-escape-hatch.integration.test.ts +0 -246
  1870. package/src/pipeline/__tests__/idempotency-transient-failure.integration.test.ts +0 -198
  1871. package/src/pipeline/__tests__/instruction-field-gate.integration.test.ts +0 -213
  1872. package/src/pipeline/__tests__/irreversible-operation-gate.integration.test.ts +0 -249
  1873. package/src/pipeline/__tests__/job-trigger-consumer.integration.test.ts +0 -235
  1874. package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +0 -800
  1875. package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +0 -281
  1876. package/src/pipeline/__tests__/member-resolution-read-only.test.ts +0 -79
  1877. package/src/pipeline/__tests__/msp-error-mode.integration.test.ts +0 -149
  1878. package/src/pipeline/__tests__/msp-multi-hop.integration.test.ts +0 -231
  1879. package/src/pipeline/__tests__/msp-rebuild.integration.test.ts +0 -510
  1880. package/src/pipeline/__tests__/multi-stream-projection.integration.test.ts +0 -313
  1881. package/src/pipeline/__tests__/pending-gap-ranges.test.ts +0 -94
  1882. package/src/pipeline/__tests__/perf-rebuild.integration.test.ts +0 -147
  1883. package/src/pipeline/__tests__/post-query-hook.integration.test.ts +0 -165
  1884. package/src/pipeline/__tests__/projection-rebuild.integration.test.ts +0 -1033
  1885. package/src/pipeline/__tests__/projections-runner-systemscope.integration.test.ts +0 -101
  1886. package/src/pipeline/__tests__/public-intake-runtime-gate.integration.test.ts +0 -684
  1887. package/src/pipeline/__tests__/query-projection.integration.test.ts +0 -357
  1888. package/src/pipeline/__tests__/rate-limit-default.integration.test.ts +0 -118
  1889. package/src/pipeline/__tests__/rate-limit-default.test.ts +0 -117
  1890. package/src/pipeline/__tests__/rebuild-poison-quarantine.integration.test.ts +0 -275
  1891. package/src/pipeline/__tests__/redis-keys.test.ts +0 -12
  1892. package/src/pipeline/__tests__/redis-pipeline.integration.test.ts +0 -490
  1893. package/src/pipeline/__tests__/search-consumer-named-events.integration.test.ts +0 -274
  1894. package/src/pipeline/__tests__/system-identity-switch.integration.test.ts +0 -583
  1895. package/src/pipeline/__tests__/system-identity-switch.test.ts +0 -645
  1896. package/src/pipeline/__tests__/tenant-timezone-cache.test.ts +0 -89
  1897. package/src/pipeline/__tests__/try-append-event.integration.test.ts +0 -168
  1898. package/src/pipeline/__tests__/unsafe-raw-escape-hatch.integration.test.ts +0 -103
  1899. package/src/pipeline/active-membership.ts +0 -190
  1900. package/src/pipeline/append-event-core.ts +0 -117
  1901. package/src/pipeline/auth-claims-resolver.ts +0 -103
  1902. package/src/pipeline/cascade-handler.ts +0 -109
  1903. package/src/pipeline/dispatch-batch.ts +0 -269
  1904. package/src/pipeline/dispatch-query.ts +0 -195
  1905. package/src/pipeline/dispatch-shared.ts +0 -1242
  1906. package/src/pipeline/dispatch-stream.ts +0 -129
  1907. package/src/pipeline/dispatch-write.ts +0 -599
  1908. package/src/pipeline/dispatcher-utils.ts +0 -199
  1909. package/src/pipeline/dispatcher.ts +0 -278
  1910. package/src/pipeline/distributed-lock.ts +0 -66
  1911. package/src/pipeline/entity-cache.ts +0 -82
  1912. package/src/pipeline/event-consumer-state.ts +0 -190
  1913. package/src/pipeline/event-dedup.ts +0 -23
  1914. package/src/pipeline/event-dispatcher-admin.ts +0 -320
  1915. package/src/pipeline/event-dispatcher-delivery.ts +0 -499
  1916. package/src/pipeline/event-dispatcher.ts +0 -817
  1917. package/src/pipeline/event-retention.ts +0 -144
  1918. package/src/pipeline/idempotency.ts +0 -158
  1919. package/src/pipeline/index.ts +0 -83
  1920. package/src/pipeline/irreversible-operation-gate.ts +0 -76
  1921. package/src/pipeline/lifecycle-pipeline.ts +0 -421
  1922. package/src/pipeline/member-read-only-transaction.ts +0 -71
  1923. package/src/pipeline/member-reader.ts +0 -110
  1924. package/src/pipeline/msp-rebuild.ts +0 -312
  1925. package/src/pipeline/multi-stream-apply-context.ts +0 -85
  1926. package/src/pipeline/pending-gap-ranges.ts +0 -120
  1927. package/src/pipeline/projection-rebuild.ts +0 -539
  1928. package/src/pipeline/projection-state.ts +0 -60
  1929. package/src/pipeline/projections-runner.ts +0 -66
  1930. package/src/pipeline/redis-keys.ts +0 -11
  1931. package/src/pipeline/system-hooks.ts +0 -695
  1932. package/src/pipeline/system-identity-switch.ts +0 -401
  1933. package/src/pipeline/tenant-timezone-cache.ts +0 -92
  1934. package/src/pipeline/write-origin.ts +0 -128
  1935. package/src/random/__tests__/generate.test.ts +0 -149
  1936. package/src/random/__tests__/words.test.ts +0 -44
  1937. package/src/random/generate.ts +0 -141
  1938. package/src/random/index.ts +0 -8
  1939. package/src/random/words.ts +0 -393
  1940. package/src/rate-limit/__tests__/dispatcher-l3.integration.test.ts +0 -111
  1941. package/src/rate-limit/__tests__/middleware.integration.test.ts +0 -246
  1942. package/src/rate-limit/__tests__/resolver.integration.test.ts +0 -211
  1943. package/src/rate-limit/bucket.ts +0 -36
  1944. package/src/rate-limit/index.ts +0 -14
  1945. package/src/rate-limit/middleware.ts +0 -179
  1946. package/src/rate-limit/resolver.ts +0 -251
  1947. package/src/redis/__tests__/redis-options.test.ts +0 -54
  1948. package/src/redis/client.ts +0 -77
  1949. package/src/redis/index.ts +0 -4
  1950. package/src/redis/pubsub-signal.ts +0 -107
  1951. package/src/schema-cli.ts +0 -510
  1952. package/src/search/__tests__/derive-search-adapter-config.test.ts +0 -65
  1953. package/src/search/__tests__/meilisearch-adapter.integration.test.ts +0 -413
  1954. package/src/search/__tests__/meilisearch-ids.test.ts +0 -30
  1955. package/src/search/__tests__/reindex-entity.integration.test.ts +0 -243
  1956. package/src/search/__tests__/search-adapter.test.ts +0 -271
  1957. package/src/search/__tests__/search-consumer-batch.integration.test.ts +0 -306
  1958. package/src/search/__tests__/search-pii-derived-index.integration.test.ts +0 -208
  1959. package/src/search/derive-search-adapter-config.ts +0 -27
  1960. package/src/search/in-memory-adapter.ts +0 -129
  1961. package/src/search/index.ts +0 -20
  1962. package/src/search/meilisearch-adapter.ts +0 -213
  1963. package/src/search/purge-subject.ts +0 -253
  1964. package/src/search/reindex-entity.ts +0 -190
  1965. package/src/secrets/__tests__/contains-secret.test.ts +0 -108
  1966. package/src/secrets/__tests__/dek-cache.test.ts +0 -211
  1967. package/src/secrets/__tests__/derive-purpose-secret.test.ts +0 -52
  1968. package/src/secrets/__tests__/env-master-key-provider.test.ts +0 -119
  1969. package/src/secrets/__tests__/envelope-cipher.test.ts +0 -59
  1970. package/src/secrets/__tests__/envelope.test.ts +0 -74
  1971. package/src/secrets/__tests__/leak-guard.test.ts +0 -104
  1972. package/src/secrets/__tests__/rotation.test.ts +0 -149
  1973. package/src/secrets/dek-cache.ts +0 -137
  1974. package/src/secrets/derive-purpose-secret.ts +0 -17
  1975. package/src/secrets/env-master-key-provider.ts +0 -162
  1976. package/src/secrets/envelope-cipher.ts +0 -53
  1977. package/src/secrets/envelope.ts +0 -57
  1978. package/src/secrets/index.ts +0 -33
  1979. package/src/secrets/leak-guard.ts +0 -87
  1980. package/src/secrets/rotation.ts +0 -34
  1981. package/src/secrets/stored-envelope.ts +0 -46
  1982. package/src/seeding/__tests__/entity-seed.test.ts +0 -70
  1983. package/src/seeding/entity-seed.ts +0 -31
  1984. package/src/seeding/index.ts +0 -6
  1985. package/src/seeding/types.ts +0 -8
  1986. package/src/stack/__tests__/drain-event-consumers.integration.test.ts +0 -166
  1987. package/src/stack/__tests__/drain-jobs.integration.test.ts +0 -159
  1988. package/src/stack/__tests__/event-collector.test.ts +0 -42
  1989. package/src/stack/__tests__/ownership-boot-guard.integration.test.ts +0 -108
  1990. package/src/stack/__tests__/push-entity-projection-tables-column-sync.integration.test.ts +0 -107
  1991. package/src/stack/__tests__/request-helper.integration.test.ts +0 -140
  1992. package/src/stack/__tests__/request-helper.test.ts +0 -159
  1993. package/src/stack/__tests__/setup-test-stack-entity-tables.integration.test.ts +0 -65
  1994. package/src/stack/__tests__/setup-test-stack-jobs.integration.test.ts +0 -185
  1995. package/src/stack/__tests__/setup-test-stack-metrics.integration.test.ts +0 -79
  1996. package/src/stack/db.ts +0 -82
  1997. package/src/stack/drain-event-consumers.ts +0 -74
  1998. package/src/stack/drain-jobs.ts +0 -129
  1999. package/src/stack/event-collector.ts +0 -23
  2000. package/src/stack/index.ts +0 -34
  2001. package/src/stack/push-entity-projection-tables.ts +0 -95
  2002. package/src/stack/redis.ts +0 -55
  2003. package/src/stack/request-helper.ts +0 -298
  2004. package/src/stack/table-helpers.ts +0 -175
  2005. package/src/stack/test-stack.ts +0 -620
  2006. package/src/stack/test-users.ts +0 -37
  2007. package/src/testing/__tests__/db-cleanup.test.ts +0 -40
  2008. package/src/testing/__tests__/e2e-generator.test.ts +0 -349
  2009. package/src/testing/__tests__/ensure-entity-table.integration.test.ts +0 -52
  2010. package/src/testing/__tests__/late-bound.test.ts +0 -32
  2011. package/src/testing/__tests__/multipart-helper.test.ts +0 -49
  2012. package/src/testing/__tests__/real-providers.test.ts +0 -62
  2013. package/src/testing/__tests__/wait-for.test.ts +0 -104
  2014. package/src/testing/access-assertions.ts +0 -15
  2015. package/src/testing/assertions.ts +0 -35
  2016. package/src/testing/boot-validator-fixture.ts +0 -124
  2017. package/src/testing/closed-connection-error.ts +0 -62
  2018. package/src/testing/db-cleanup.ts +0 -45
  2019. package/src/testing/e2e-generator.ts +0 -494
  2020. package/src/testing/expect-error.ts +0 -25
  2021. package/src/testing/file-provider-contract.ts +0 -123
  2022. package/src/testing/handler-context.ts +0 -143
  2023. package/src/testing/http-cookies.ts +0 -52
  2024. package/src/testing/index.ts +0 -60
  2025. package/src/testing/late-bound.ts +0 -41
  2026. package/src/testing/multipart-helper.ts +0 -94
  2027. package/src/testing/mutable-master-key-provider.ts +0 -57
  2028. package/src/testing/observability-recorder.ts +0 -54
  2029. package/src/testing/real-providers.ts +0 -30
  2030. package/src/testing/seed.ts +0 -50
  2031. package/src/testing/shared-entities.ts +0 -65
  2032. package/src/testing/utils.ts +0 -1
  2033. package/src/testing/wait-for.ts +0 -49
  2034. package/src/testing/without-ambient-temporal.ts +0 -14
  2035. package/src/time/__tests__/boot-tz-warning.test.ts +0 -46
  2036. package/src/time/__tests__/geo-tz.test.ts +0 -71
  2037. package/src/time/__tests__/iana.test.ts +0 -35
  2038. package/src/time/__tests__/polyfill-reinstall.test.ts +0 -17
  2039. package/src/time/__tests__/polyfill.test.ts +0 -73
  2040. package/src/time/__tests__/tz-context.test.ts +0 -121
  2041. package/src/time/__tests__/tz-dateline.test.ts +0 -34
  2042. package/src/time/boot-tz-warning.ts +0 -30
  2043. package/src/time/iana.ts +0 -19
  2044. package/src/time/index.ts +0 -23
  2045. package/src/time/legacy-date.ts +0 -18
  2046. package/src/time/polyfill.ts +0 -59
  2047. package/src/time/tz-context.ts +0 -100
  2048. package/src/ui-types/__tests__/plural.test.ts +0 -108
  2049. package/src/ui-types/app-schema.ts +0 -91
  2050. package/src/ui-types/formality.ts +0 -7
  2051. package/src/ui-types/index.ts +0 -159
  2052. package/src/ui-types/list-row-meta.ts +0 -87
  2053. package/src/ui-types/plural.ts +0 -69
  2054. package/src/upgrade-cli.ts +0 -651
  2055. package/src/utils/__tests__/assert.test.ts +0 -17
  2056. package/src/utils/__tests__/case.test.ts +0 -16
  2057. package/src/utils/__tests__/compare.test.ts +0 -20
  2058. package/src/utils/__tests__/env-parse.test.ts +0 -54
  2059. package/src/utils/__tests__/ids.test.ts +0 -52
  2060. package/src/utils/__tests__/is-plain-object.test.ts +0 -16
  2061. package/src/utils/__tests__/parse-string-array-json.test.ts +0 -16
  2062. package/src/utils/__tests__/safe-json-temporal.test.ts +0 -28
  2063. package/src/utils/__tests__/safe-json.test.ts +0 -22
  2064. package/src/utils/__tests__/serialization.test.ts +0 -30
  2065. package/src/utils/assert.ts +0 -18
  2066. package/src/utils/case.ts +0 -6
  2067. package/src/utils/compare.ts +0 -10
  2068. package/src/utils/env-parse.ts +0 -16
  2069. package/src/utils/ids.ts +0 -26
  2070. package/src/utils/index.ts +0 -9
  2071. package/src/utils/is-plain-object.ts +0 -4
  2072. package/src/utils/parse-string-array-json.ts +0 -14
  2073. package/src/utils/safe-json.ts +0 -50
  2074. package/src/utils/serialization.ts +0 -14
  2075. /package/{src/engine/types/event-type-map.ts → dist/engine/types/event-type-map.d.ts} +0 -0
  2076. /package/{src/engine/types/extension-options-map.ts → dist/engine/types/extension-options-map.d.ts} +0 -0
  2077. /package/{src/engine/types/http-route.ts → dist/engine/types/http-route.d.ts} +0 -0
  2078. /package/{src/engine/types/identifiers.ts → dist/engine/types/identifiers.d.ts} +0 -0
  2079. /package/{src/engine/types/relations.ts → dist/engine/types/relations.d.ts} +0 -0
  2080. /package/{src/engine/types/target-ref.ts → dist/engine/types/target-ref.d.ts} +0 -0
  2081. /package/{src/engine/types/tree-node.ts → dist/engine/types/tree-node.d.ts} +0 -0
  2082. /package/{src/logging/types.ts → dist/logging/types.d.ts} +0 -0
  2083. /package/{src/observability/types/index.ts → dist/observability/types/index.d.ts} +0 -0
  2084. /package/{src/observability/types/metric.ts → dist/observability/types/metric.d.ts} +0 -0
  2085. /package/{src/observability/types/provider.ts → dist/observability/types/provider.d.ts} +0 -0
  2086. /package/{src/observability/types/span.ts → dist/observability/types/span.d.ts} +0 -0
  2087. /package/{src/search/types.ts → dist/search/types.d.ts} +0 -0
  2088. /package/{src/secrets/types.ts → dist/secrets/types.js} +0 -0
  2089. /package/{src/time/geo-tz.ts → dist/time/geo-tz.d.ts} +0 -0
@@ -0,0 +1,1665 @@
1
+ // Screen validation, including the dashboard-panel sub-validators.
2
+ // Dashboard stays here (not a separate dashboard.ts) — validateScreens
3
+ // calls validateDashboardScreen and the dashboard validators call back
4
+ // into validateColumnRendererForm, splitting them would create a
5
+ // same-folder require cycle.
6
+ import { resolveActionIcon } from "@cosmicdrift/kumiko-types/action-icon";
7
+ import { NO_WIDGET_FIELD_TYPES } from "@cosmicdrift/kumiko-types/fields";
8
+ import { NAV_ICON_KEYS } from "@cosmicdrift/kumiko-types/nav-icon";
9
+ import { rowMetaFieldNames } from "../../db/table-builder.js";
10
+ import { LIST_ROW_META_COLUMNS } from "../../ui-types/list-row-meta.js";
11
+ import { parseRefTarget } from "../parse-ref-target.js";
12
+ import { isKebabSegment, isValidQn, qualifyEntityName } from "../qualified-name.js";
13
+ import { getAllowedFilterOps, isFieldFilterable } from "../screen-filter-ops.js";
14
+ import { isExtensionEditSection, isWriteFormEditSection, normalizeEditField, normalizeListColumn, resolveNavParentScreen, sectionFieldSpecs, } from "../screen-helpers.js";
15
+ import { metricField } from "../types/index.js";
16
+ // entityList columns accept exactly the row-meta columns the renderer
17
+ // (computeListViewModel) knows how to type — LIST_ROW_META_COLUMNS, NOT the
18
+ // wider rowMetaFieldNames(softDelete) used below for rowAction payload/visible
19
+ // field refs. Those two checks guard different things: a screen column must
20
+ // be renderable, a payload/visible field reference only needs to exist on the
21
+ // row. Using the wider set here would let a softDelete column like
22
+ // "deletedAt" pass the boot gate and then throw at render-time instead.
23
+ const LIST_ROW_META_COLUMN_NAMES = new Set(Object.keys(LIST_ROW_META_COLUMNS));
24
+ // entityList and projectionList both allow a rowAction to double as the
25
+ // row-body click target (rowClick: true, fw#1708/#2164) — at most one per
26
+ // screen, or the renderer can't tell which one should fire.
27
+ function validateAtMostOneRowClick(featureName, screenId, screenType, rowActions) {
28
+ const rowClickActions = rowActions.filter((a) => a.kind === "navigate" && a.rowClick === true);
29
+ if (rowClickActions.length > 1) {
30
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) has ${rowClickActions.length} ` +
31
+ "rowActions marked rowClick:true — at most one may fire on a row-body click.");
32
+ }
33
+ }
34
+ // A field type in NO_WIDGET_FIELD_TYPES renders read-only on the auto-wired
35
+ // entityEdit path (#1925) — a required field the user can never fill would
36
+ // block every save. Only the statically-resolvable case is caught here: a
37
+ // literal `required: true` (screen-spec override or entity-level default).
38
+ // A dynamic FieldCondition depends on runtime form values and can't be
39
+ // evaluated at boot; buildFormSchema() silently skips presence-checking it.
40
+ function validateNoWidgetRequiredField(featureName, screenId, entityDef, fieldSpec) {
41
+ const fieldDef = entityDef.fields[fieldSpec.field];
42
+ // skip: field doesn't exist or its type already has a widget — nothing to validate.
43
+ if (fieldDef === undefined || !NO_WIDGET_FIELD_TYPES.includes(fieldDef.type))
44
+ return;
45
+ // Embedded LIST fields (`multiple: true`) get their own EmbeddedListField
46
+ // grid widget (#1838) — only plain (non-list) embedded has no widget.
47
+ const isEmbeddedList = fieldDef.type === "embedded" && fieldDef.multiple === true;
48
+ // skip: list variant has a widget — not the no-widget case this guard targets.
49
+ if (isEmbeddedList)
50
+ return;
51
+ // skip: already read-only by spec — no fillable widget needed regardless of type.
52
+ if (fieldSpec.readOnly === true)
53
+ return;
54
+ const entityRequired = "required" in fieldDef && fieldDef.required === true;
55
+ const isStaticallyRequired = fieldSpec.required === undefined ? entityRequired : fieldSpec.required === true;
56
+ // skip: not required — a read-only widget-less field is fine to leave empty.
57
+ if (!isStaticallyRequired)
58
+ return;
59
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (entityEdit) field "${fieldSpec.field}" is ` +
60
+ `type "${fieldDef.type}", which renders read-only on the auto-wired entityEdit path — a ` +
61
+ `required field the user could never fill would block every save. Set required: false, ` +
62
+ `move the field to a custom-component section, or drop the required constraint.`);
63
+ }
64
+ export function rowFieldExtractorKeys(params) {
65
+ return "pick" in params ? params.pick : Object.keys(params.map);
66
+ }
67
+ // Mirrors the renderer's navigate: an explicit entityId, or a same-entity
68
+ // entityEdit target (row["id"] auto-fill), opens UPDATE mode, which ignores params.
69
+ export function readsNavigateParamsAsFormPrefill(target, explicitEntityId, sourceScreenEntity) {
70
+ if (target.type === "actionForm" || target.type === "secretMint")
71
+ return true;
72
+ if (target.type !== "entityEdit")
73
+ return false;
74
+ if (explicitEntityId !== undefined)
75
+ return false;
76
+ return sourceScreenEntity === undefined || target.entity !== sourceScreenEntity;
77
+ }
78
+ // Tier 2.7e navigate rowAction → target-screen params validity. Shared by
79
+ // entityList and projectionList (framework#1708) — projectionList has no
80
+ // `screen.entity`, so there's no same-entity row["id"] auto-fill case: any
81
+ // entityEdit target without an explicit entityId reaches create there.
82
+ //
83
+ // dashboard targets (framework#1708 follow-up, commit 4e0d6cb26) also read
84
+ // URL search params — but only for the single `filter.id` a dashboard
85
+ // declares (useFilterParams in dashboard-body.tsx seeds its value from
86
+ // `nav.searchParams[filter.id]`). A dashboard with no `filter` has nowhere
87
+ // for the value to land, and a params extractor whose keys don't include
88
+ // the filter's id would silently miss it — both are boot errors instead of
89
+ // a silently-empty dashboard.
90
+ function validateRowActionNavigateParams(featureName, screenId, screenType, screenEntity, action, target) {
91
+ // skip: not a navigate-with-params action — nothing to validate here.
92
+ if (action.kind !== "navigate" || action.params === undefined)
93
+ return;
94
+ // skip: unresolvable/custom target already reported (or exempt) elsewhere.
95
+ if (target === undefined || target.screen.type === "custom")
96
+ return;
97
+ // skip: entityList/projectionList targets also read URL search params (Tier
98
+ // 2.7c filter-prefill, see use-list-url-state.ts: `<screenId>.q/.sort/
99
+ // .dir/.page/.f.<field>`), not just actionForm/entityEdit-create.
100
+ if (target.screen.type === "entityList" || target.screen.type === "projectionList")
101
+ return;
102
+ if (target.screen.type === "dashboard") {
103
+ const targetDescriptor = action.screen !== undefined ? `"${action.screen}"` : `entity "${action.entity}"`;
104
+ const filter = target.screen.filter;
105
+ if (filter === undefined) {
106
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) rowAction "${action.id}" sets ` +
107
+ `params on navigate-target ${targetDescriptor} (dashboard) — target dashboard declares no ` +
108
+ `filter — params would be a no-op. Remove the params extractor, or add a \`filter\` to the ` +
109
+ `target dashboard so it has somewhere to read the value from.`);
110
+ }
111
+ const extractedKeys = rowFieldExtractorKeys(action.params);
112
+ if (!extractedKeys.includes(filter.id)) {
113
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) rowAction "${action.id}" sets ` +
114
+ `params [${extractedKeys.join(", ")}] on navigate-target ${targetDescriptor} (dashboard) whose ` +
115
+ `filter id is "${filter.id}" — none of the extracted keys match, so the filter would stay ` +
116
+ `unset. Fix the params extractor to produce a "${filter.id}" key, or remove it.`);
117
+ }
118
+ // skip: filter present and the extractor's keys cover it — valid dashboard deep-link.
119
+ return;
120
+ }
121
+ if (!readsNavigateParamsAsFormPrefill(target.screen, action.entityId, screenEntity)) {
122
+ const isEntityEditUpdate = target.screen.type === "entityEdit";
123
+ const reason = isEntityEditUpdate
124
+ ? `resolves to UPDATE mode (${action.entityId !== undefined
125
+ ? `explicit entityId "${action.entityId}"`
126
+ : `same entity "${screenEntity}" auto-fills row["id"]`})`
127
+ : `screen type "${target.screen.type}"`;
128
+ const targetDescriptor = action.screen !== undefined ? `"${action.screen}"` : `entity "${action.entity}"`;
129
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) rowAction "${action.id}" ` +
130
+ `sets params on navigate-target ${targetDescriptor} which ${reason} — only actionForm, ` +
131
+ `secretMint and entityEdit-create targets read URL search params as initial values. Remove ` +
132
+ `the params extractor or retarget to an actionForm / secretMint / cross-entity ` +
133
+ `entityEdit-create screen.`);
134
+ }
135
+ }
136
+ // Shared by projectionDetail and entityEdit: a tab strip needs something to
137
+ // label each tab with and a stable id per tab — the id anchors the ?tab=
138
+ // param on projectionDetail and the jump-to-erroring-tab logic on entityEdit
139
+ // (fw#3134).
140
+ function validateTabSections(featureName, screenId, screenType, sections) {
141
+ if (sections.length < 2) {
142
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) has mode: "tabs" but only ` +
143
+ `${sections.length} section(s) — tabs need at least 2 sections.`);
144
+ }
145
+ const tabIds = new Set();
146
+ sections.forEach((section, index) => {
147
+ if (section.title === undefined || section.title.trim().length === 0) {
148
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) has mode: "tabs" but ` +
149
+ `sections[${index}] has no title — every tab needs a title.`);
150
+ }
151
+ if (section.id === undefined || section.id.trim().length === 0) {
152
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) has mode: "tabs" but ` +
153
+ `sections[${index}] ("${section.title}") has no id — every tab needs a stable id.`);
154
+ }
155
+ if (!isKebabSegment(section.id)) {
156
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) sections[${index}] ` +
157
+ `("${section.title}") has id "${section.id}" — must be kebab-case.`);
158
+ }
159
+ if (tabIds.has(section.id)) {
160
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) has duplicate tab id ` +
161
+ `"${section.id}" (sections[${index}]).`);
162
+ }
163
+ tabIds.add(section.id);
164
+ });
165
+ }
166
+ // Wizard layouts (mode: "wizard") need >= 2 titled sections — a single or
167
+ // untitled step would leave the progress indicator blank, so both fail at
168
+ // boot rather than as a broken step UI.
169
+ function validateWizardLayout(featureName, screenId, screenType, layout, featureMap) {
170
+ // entityEdit renders tabs like wizard steps: every section stays mounted,
171
+ // submit validates across all of them, and a field error jumps to the tab
172
+ // holding it (fw#3134). The other three have no such jump — actionForm and
173
+ // secretMint are one-shot forms, configEdit fires a write per field — so a
174
+ // required field on a hidden tab would still block their submit silently.
175
+ if (layout.mode === "tabs") {
176
+ if (screenType !== "entityEdit") {
177
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) sets mode: "tabs" — tabs are only ` +
178
+ `supported on projectionDetail and entityEdit. Use mode: "wizard" or "single" instead.`);
179
+ }
180
+ validateTabSections(featureName, screenId, screenType, layout.sections);
181
+ }
182
+ // "form-draft" is hardcoded because the framework layer must not depend on
183
+ // @cosmicdrift/kumiko-bundled-features — same precedence as the
184
+ // "user-data-rights" check in gdpr-storage.ts.
185
+ if (layout.draft === true) {
186
+ if (layout.mode !== "wizard") {
187
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) sets draft: true but ` +
188
+ `mode is not "wizard" — draft persistence only applies to wizard layouts. Remove ` +
189
+ `draft: true or set mode: "wizard".`);
190
+ }
191
+ if (!featureMap.has("form-draft")) {
192
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) sets draft: true but the ` +
193
+ `bundled feature "form-draft" is not mounted — every resume would silently lose its ` +
194
+ `values. Add formDraftFeature() from @cosmicdrift/kumiko-bundled-features to the app's ` +
195
+ `feature list.`);
196
+ }
197
+ }
198
+ // skip: mode omitted/"single" — no wizard constraints apply.
199
+ if (layout.mode !== "wizard")
200
+ return;
201
+ if (layout.sections.length < 2) {
202
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) has mode: "wizard" but only ` +
203
+ `${layout.sections.length} section(s) — a wizard needs at least 2 sections (one per step).`);
204
+ }
205
+ layout.sections.forEach((section, index) => {
206
+ if (section.title === undefined || section.title.trim().length === 0) {
207
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) has mode: "wizard" but ` +
208
+ `sections[${index}] has no title — every wizard step needs a title.`);
209
+ }
210
+ });
211
+ }
212
+ // --- Screen validation ---
213
+ //
214
+ // For every r.screen() declaration check what's locally knowable at boot:
215
+ // - entityList / entityEdit: the referenced entity must exist in the
216
+ // feature (cross-feature entity-refs aren't allowed — a feature owns
217
+ // the screens over its own entities) and every column/field ref must
218
+ // name a real field on that entity
219
+ // - custom: the renderer must at least have one platform component set
220
+ // (react OR native), otherwise the screen is structurally empty
221
+ //
222
+ // Field-level renderer QN strings (cross-feature `component:` references)
223
+ // are NOT validated here — the r.uiComponent registry that would resolve
224
+ // them ships in M4/M5. Until then those are kept opaque on purpose.
225
+ // every action rendered in a Card title row (screen-level
226
+ // `actions`, section-level `actions`, `emptyState.action`) must draw an
227
+ // icon — declared or id-derived (resolveActionIcon, same resolver the
228
+ // renderer uses). Uncovered here: entityList/projectionList rowActions —
229
+ // those render inside a DataTable row, not a Card title row, so they keep
230
+ // today's "icon optional" behavior.
231
+ //
232
+ // Registration check (not just "resolved is not undefined"): action.icon is
233
+ // typed IconKey, a closed union — but that only protects call sites this
234
+ // repo's own `tsc --build` actually covers (samples and external consumers
235
+ // aren't in that project graph). The renderer's actionIconFor
236
+ // (renderer-web/src/primitives/index.tsx) already falls back to "no icon"
237
+ // for an unregistered key instead of crashing — this check makes the same
238
+ // gap fail loudly at boot instead of silently at render.
239
+ function isRegisteredIcon(icon) {
240
+ return NAV_ICON_KEYS.includes(icon);
241
+ }
242
+ export function validateActionHasIcon(featureName, screenId, screenType, context, action) {
243
+ const resolved = resolveActionIcon(action.id, action.icon);
244
+ if (resolved === undefined || !isRegisteredIcon(resolved)) {
245
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${context} "${action.id}" has no ` +
246
+ `resolvable icon — set icon to a key registered in NAV_ICONS, or use an id that resolves one of ` +
247
+ `its kebab segments via the default icon map (resolveActionIcon).`);
248
+ }
249
+ }
250
+ // Tier 2.7e-3: deklarative Feld-Referenzen einer Action gegen die Entity-
251
+ // Felder pinnen — ein Tippfehler in pick/map-Quellfeldern oder
252
+ // visible.field erzeugte sonst still `undefined` im Payload bzw. dauerhaft
253
+ // falsche Sichtbarkeit (gleiche "Typo fällt erst beim Klick"-Klasse wie
254
+ // navigate/handler). Exported for query-output-columns.ts, which reuses it
255
+ // against a projectionDetail's outputSchema-derived record shape instead of
256
+ // an entity's field map (relatedList toolbarActions' visible/params).
257
+ export function validateActionFieldRefs(featureName, screenId, actionKind, actionId, action, fieldNames, rowMeta) {
258
+ // ToolbarAction.payload ist ein STATISCHER Record (kein Row-Context) —
259
+ // nur echte pick/map-Extractoren werden gegen die Feldnamen geprüft.
260
+ const isExtractor = (v) => typeof v === "object" && v !== null && ("pick" in v || "map" in v);
261
+ const payload = "payload" in action && isExtractor(action.payload) ? action.payload : undefined;
262
+ const params = "params" in action && isExtractor(action.params) ? action.params : undefined;
263
+ const visible = "visible" in action ? action.visible : undefined;
264
+ const entityId = "entityId" in action ? action.entityId : undefined;
265
+ const known = () => [...fieldNames].sort().join(", ") || "(none)";
266
+ const checkExtractor = (label, extractor) => {
267
+ // skip: extractor ist ein optionaler Action-Slot — ohne ihn gibt es
268
+ // keine Feld-Referenzen zu validieren.
269
+ if (extractor === undefined) {
270
+ return;
271
+ }
272
+ const sources = "pick" in extractor ? extractor.pick : Object.values(extractor.map);
273
+ for (const source of sources) {
274
+ if (rowMeta.has(source))
275
+ continue;
276
+ if (!fieldNames.has(source)) {
277
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" ${actionKind} "${actionId}" ` +
278
+ `${label} references unknown field "${source}". Known fields: ${known()}.`);
279
+ }
280
+ }
281
+ };
282
+ checkExtractor("payload", payload);
283
+ checkExtractor("params", params);
284
+ if (visible !== undefined &&
285
+ typeof visible !== "boolean" &&
286
+ !rowMeta.has(visible.field) &&
287
+ !fieldNames.has(visible.field)) {
288
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" ${actionKind} "${actionId}" ` +
289
+ `visible.field references unknown field "${visible.field}". Known fields: ${known()}.`);
290
+ }
291
+ if (entityId !== undefined && entityId !== "id" && !fieldNames.has(entityId)) {
292
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" ${actionKind} "${actionId}" ` +
293
+ `entityId references unknown field "${entityId}". Known fields: ${known()}.`);
294
+ }
295
+ }
296
+ // Two features registering the same short screen-id is a silent routing
297
+ // footgun: create-app.tsx's runtime router resolves a bare navigate-target
298
+ // id by scanning features[] and taking the first match — the collision
299
+ // never surfaces as an error, the second feature's screen is just
300
+ // unreachable by that id (and always the same one that loses, in whatever
301
+ // order the app composed its features).
302
+ export function validateScreenShortIdCollisions(screensByShortId) {
303
+ for (const [shortId, entries] of screensByShortId) {
304
+ const featureNames = new Set(entries.map((e) => e.featureName));
305
+ if (featureNames.size > 1) {
306
+ throw new Error(`Screen short-id "${shortId}" is registered by ${featureNames.size} features ` +
307
+ `(${[...featureNames].join(", ")}) — the runtime router resolves a bare navigate-target ` +
308
+ `id by taking the first match, so all but one of these screens would be unreachable by ` +
309
+ `that id. Give each screen a distinct id.`);
310
+ }
311
+ }
312
+ }
313
+ // redirect/cancelTarget accept either a same-feature short id (unchanged
314
+ // behavior, qualified against the owning feature) or a fully-qualified
315
+ // cross-feature screen QN (`<feature>:screen:<id>`) given verbatim — a
316
+ // short id can never itself be a valid QN (QN_SEGMENT forbids colons), so
317
+ // the two forms don't collide.
318
+ export function resolveScreenTargetQn(featureName, target) {
319
+ return isValidQn(target) ? target : qualifyEntityName(featureName, "screen", target);
320
+ }
321
+ function validateScreenNavTarget(featureName, screenId, screenKind, fieldName, value, allScreenQns, screens) {
322
+ const candidateQn = resolveScreenTargetQn(featureName, value);
323
+ if (!allScreenQns.has(candidateQn)) {
324
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenKind}) ${fieldName} "${value}" ` +
325
+ `does not resolve to a registered screen (checked "${candidateQn}"). Known screens ` +
326
+ `in this feature: ${[...Object.keys(screens)].sort().join(", ") || "(none)"}.`);
327
+ }
328
+ }
329
+ // kind:"drawer" resolves same-feature only — unlike navigate/redirect,
330
+ // which the runtime router resolves app-wide (see the comment on
331
+ // validateScreens below), the drawer mounts the target inline using this
332
+ // feature's schema, so a cross-feature reference could never actually
333
+ // render. Two distinct failure messages: dangling reference vs. wrong
334
+ // screen type. Shared by ToolbarAction (fw#2225) and RowAction (fw#2710)
335
+ // drawer variants — same target-resolution rule, only the label in the
336
+ // error message ("toolbarAction" vs. "rowAction" vs. "action") differs.
337
+ function validateDrawerTargetAction(featureName, screenId, screenKind, actionLabel, action, screens) {
338
+ const target = screens[action.screen];
339
+ if (target === undefined) {
340
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenKind}) ${actionLabel} "${action.id}" ` +
341
+ `drawer-target "${action.screen}" does not resolve to a registered screen in this feature. ` +
342
+ `kind:"drawer" only resolves same-feature screens (unlike kind:"navigate", which can target ` +
343
+ `screens in any feature) — the drawer mounts the target inline using this feature's schema. ` +
344
+ `Known screens in this feature: ${[...Object.keys(screens)].sort().join(", ") || "(none)"}.`);
345
+ }
346
+ // secretMint is intentionally excluded — a one-time secret reveal belongs on
347
+ // its own page, not layered in a Drawer above a list.
348
+ if (target.type !== "actionForm") {
349
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenKind}) ${actionLabel} "${action.id}" ` +
350
+ `drawer-target "${action.screen}" is a "${target.type}" screen, not an actionForm. ` +
351
+ `kind:"drawer" mounts an actionForm inside a Drawer widget — point "screen" at an ` +
352
+ `actionForm screen, or use kind:"navigate" for a full-page target.`);
353
+ }
354
+ // A prefill key the target form doesn't declare is dropped silently by the
355
+ // renderer (mergeSearchParamsIntoInitial iterates the target's fields), so
356
+ // the typo would only show up as an empty field at click time.
357
+ // skip: no params extractor — nothing to check against the target's fields.
358
+ if (action.params === undefined)
359
+ return;
360
+ for (const fieldName of rowFieldExtractorKeys(action.params)) {
361
+ if (Object.hasOwn(target.fields, fieldName))
362
+ continue;
363
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenKind}) ${actionLabel} "${action.id}" ` +
364
+ `params prefills "${fieldName}", which drawer-target "${action.screen}" does not declare as a ` +
365
+ `field — the renderer would drop it and leave the form empty. Target fields: ` +
366
+ `${Object.keys(target.fields).sort().join(", ") || "(none)"}.`);
367
+ }
368
+ }
369
+ // The target can be any screen, so this checks the resolved target's
370
+ // sections, not the host's.
371
+ function validateRowActionNavigateTab(featureName, screenId, screenType, actionLabel, action, target) {
372
+ // skip: no tab declared — nothing to check against the target's sections
373
+ if (action.tab === undefined)
374
+ return;
375
+ if (target === undefined) {
376
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
377
+ `sets tab "${action.tab}", but its navigate-target could not be resolved to a screen.`);
378
+ }
379
+ if (target.screen.type !== "projectionDetail" || target.screen.layout.mode !== "tabs") {
380
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
381
+ `sets tab "${action.tab}", but navigate-target screen "${target.screen.id}" is not a ` +
382
+ `projectionDetail with layout.mode "tabs" — only those read the tab param.`);
383
+ }
384
+ const sectionIds = target.screen.layout.sections
385
+ .map((section) => section.id)
386
+ .filter((id) => id !== undefined);
387
+ if (!sectionIds.includes(action.tab)) {
388
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
389
+ `navigates to tab "${action.tab}", which is not a section id on target screen ` +
390
+ `"${target.screen.id}". Available: ${sectionIds.join(", ") || "(none)"}.`);
391
+ }
392
+ }
393
+ function resolveRowActionNavigateTarget(featureName, screenId, screenType, actionLabel, action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens) {
394
+ if (action.entity !== undefined) {
395
+ if (action.screen !== undefined) {
396
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
397
+ `sets both "screen" and "entity" — exactly one navigate-target form is allowed.`);
398
+ }
399
+ if (screenType !== "entityList" && action.entityId === undefined) {
400
+ // entityList rows are always a real entity record, so row["id"] is a
401
+ // safe implicit default. projectionList/projectionDetail rows come from
402
+ // an arbitrary query projection with no guaranteed "id" field — an
403
+ // entity-target there needs an explicit entityId, or navigation silently
404
+ // opens the detail screen with no entity context at runtime.
405
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
406
+ `navigate-target entity "${action.entity}" needs an explicit "entityId" — ${screenType} rows ` +
407
+ `come from a query projection with no guaranteed "id" field.`);
408
+ }
409
+ const detail = detailForScreens.get(action.entity);
410
+ if (detail === undefined) {
411
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
412
+ `navigate-target entity "${action.entity}" has no screen declaring ` +
413
+ `detailFor: "${action.entity}".`);
414
+ }
415
+ validateRowActionNavigateTab(featureName, screenId, screenType, actionLabel, action, detail);
416
+ return detail;
417
+ }
418
+ if (action.screen === undefined) {
419
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
420
+ `sets neither "screen" nor "entity" — exactly one navigate-target form is required.`);
421
+ }
422
+ const candidateQn = qualifyEntityName(featureName, "screen", action.screen);
423
+ if (!allScreenQns.has(candidateQn) && !navTargetShortIds.has(action.screen)) {
424
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${screenType}) ${actionLabel} "${action.id}" ` +
425
+ `navigate-target "${action.screen}" does not resolve to a registered screen in any feature.`);
426
+ }
427
+ const target = screensByShortId.get(action.screen)?.[0];
428
+ validateRowActionNavigateTab(featureName, screenId, screenType, actionLabel, action, target);
429
+ return target;
430
+ }
431
+ // Shared by the mint step's own handler (screen.handler) and its optional
432
+ // confirm step (confirm.handler) — both are a bare write-handler QN with the
433
+ // same registration requirement.
434
+ function validateWriteHandlerRegistered(featureName, screenId, context, handler, allWriteHandlerQns) {
435
+ if (!handler || typeof handler !== "string") {
436
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) has empty or non-string handler.`);
437
+ }
438
+ if (!allWriteHandlerQns.has(handler)) {
439
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) handler "${handler}" ` +
440
+ `is not a registered write-handler. Check the QN spelling (expected ` +
441
+ `"<feature>:write:<short>") and that the handler is declared via r.writeHandler(...).`);
442
+ }
443
+ }
444
+ // Every field entry must carry a `type` discriminator. An author typo
445
+ // (`title: { required: true }` without a type) would otherwise let
446
+ // RenderField silently fall through to the default renderer and submit an
447
+ // empty string — failing at boot is clearer. `type as unknown` because
448
+ // FieldDefinition, as a union, only allows known type strings; here we're
449
+ // checking author code that may have circumvented the type check.
450
+ //
451
+ // Parametrized over (fields, layout) instead of a whole screen so a
452
+ // secretMint's own `confirm` step — a second, independent inline form on the
453
+ // same screen — can reuse the same checks as its `fields`/`layout` pair.
454
+ // `allowEmpty` is only ever true for a secretMint's own mint step (an
455
+ // input-less mint, fw#2838): the secret is server-generated and the mint
456
+ // step is just its submit button — actionForm and the confirm step always
457
+ // require at least one field.
458
+ function validateFormFieldsMap(featureName, screenId, context, fields, allowEmpty) {
459
+ const fieldNames = new Set(Object.keys(fields));
460
+ if (fieldNames.size === 0 && !allowEmpty) {
461
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) has empty fields map — ` +
462
+ `declare at least one field.`);
463
+ }
464
+ for (const [fname, fdef] of Object.entries(fields)) {
465
+ // @cast-boundary schema-walk — feature-config inspection (Author may circumvent type-check)
466
+ const ftype = fdef.type;
467
+ if (typeof ftype !== "string" || ftype.length === 0) {
468
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) field "${fname}" has no ` +
469
+ `\`type\` set. Each field must declare a type (e.g. "text", "number", "select").`);
470
+ }
471
+ if (ftype === "money") {
472
+ validateFormMoneyCurrency(featureName, screenId, context, fname, fdef);
473
+ }
474
+ }
475
+ return fieldNames;
476
+ }
477
+ // Fail-closed currency-source gate (fw#2839), the runtime half of the
478
+ // narrowed `FormFieldDefinition` — an untyped JS consumer has no compiler to
479
+ // stop it. An inline form screen has no entity, so a money field there can't
480
+ // borrow `entity.defaultCurrency`: without a declared source the renderer
481
+ // seeds a bare `0` and the handler's zod schema rejects the submit. Entity
482
+ // money fields are exempt — create-app already refuses an entity that holds
483
+ // money without a `defaultCurrency`.
484
+ function validateFormMoneyCurrency(featureName, screenId, context, fieldName, fdef) {
485
+ const where = `[Feature ${featureName}] Screen "${screenId}" (${context}) money field "${fieldName}"`;
486
+ const validForms = `Declare \`currency: { kind: "literal", code: "EUR" }\` for a fixed currency, or ` +
487
+ `\`currency: { kind: "tenant" }\` to take the tenant-settings bundle's per-tenant currency.`;
488
+ // @cast-boundary schema-walk — feature-config inspection (Author may circumvent type-check)
489
+ const currency = fdef.currency;
490
+ if (currency === undefined) {
491
+ throw new Error(`${where} must declare where its currency comes from — this screen has no entity whose ` +
492
+ `\`defaultCurrency\` it could inherit, so the form would seed a bare \`0\` that the ` +
493
+ `handler's schema rejects. ${validForms}`);
494
+ }
495
+ if (typeof currency !== "object" || currency === null) {
496
+ throw new Error(`${where} has a non-object \`currency\`. ${validForms}`);
497
+ }
498
+ const kind = currency.kind;
499
+ if (kind === "literal") {
500
+ const code = currency.code;
501
+ if (typeof code !== "string" || code.trim() === "") {
502
+ throw new Error(`${where} declares \`currency: { kind: "literal" }\` with an empty or non-string \`code\`. ` +
503
+ `Pass the ISO code, e.g. { kind: "literal", code: "EUR" }.`);
504
+ }
505
+ }
506
+ else if (kind !== "tenant") {
507
+ throw new Error(`${where} declares an unknown currency kind ${JSON.stringify(kind)}. ${validForms}`);
508
+ }
509
+ }
510
+ // `allowEmptySections` mirrors `validateFormFieldsMap`'s `allowEmpty` — the
511
+ // caller only ever passes true together with an actually-empty fields map
512
+ // (an input-less secretMint declares BOTH `fields: {}` and
513
+ // `layout.sections: []`; fields declared with no layout to show them stays
514
+ // an error).
515
+ // `fields`/`groups` are mutually exclusive on a fields-kind section; shared by
516
+ // every EditLayout-walking screen type instead of four hand-rolled copies.
517
+ function validateFieldsXorGroups(errorPrefix, section) {
518
+ if (section.fields.length > 0 && section.groups !== undefined) {
519
+ throw new Error(`${errorPrefix} section "${section.title}" declares both fields and groups — pass fields: [] ` +
520
+ `when using groups.`);
521
+ }
522
+ if (section.fields.length === 0 && section.groups === undefined) {
523
+ throw new Error(`${errorPrefix} has a section "${section.title}" with zero fields — drop the section or add ` +
524
+ `fields (or groups) to it.`);
525
+ }
526
+ }
527
+ function validateFormLayoutSections(featureName, screenId, context, layout, fieldNames, allowEmptySections) {
528
+ if (layout.sections.length === 0) {
529
+ // skip: an input-less secretMint declares fields: {} and sections: [] together — no sections to validate.
530
+ if (allowEmptySections)
531
+ return;
532
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) has an empty sections list — ` +
533
+ `declare at least one section.`);
534
+ }
535
+ for (const section of layout.sections) {
536
+ if (isExtensionEditSection(section)) {
537
+ if (section.component?.react === undefined && section.component?.native === undefined) {
538
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) extension section ` +
539
+ `"${section.title}" has no component — declare a react/native component marker.`);
540
+ }
541
+ continue;
542
+ }
543
+ if (section.kind === "relatedList") {
544
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) relatedList section ` +
545
+ `"${section.title}" is not supported — relatedList is a projectionDetail-only ` +
546
+ `primitive (fw#2166).`);
547
+ }
548
+ if (isWriteFormEditSection(section)) {
549
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) writeForm section ` +
550
+ `"${section.title}" is not supported — writeForm is a projectionDetail-only primitive.`);
551
+ }
552
+ validateFieldsXorGroups(`[Feature ${featureName}] Screen "${screenId}" (${context})`, section);
553
+ for (const fieldSpec of sectionFieldSpecs(section)) {
554
+ const normalized = normalizeEditField(fieldSpec);
555
+ if (!fieldNames.has(normalized.field)) {
556
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (${context}) layout references unknown field ` +
557
+ `"${normalized.field}". Known fields: ${[...fieldNames].sort().join(", ")}`);
558
+ }
559
+ }
560
+ }
561
+ }
562
+ // redirect is either a short screen id (same-feature, e.g. "item-list") or
563
+ // a fully-qualified cross-feature QN (`<feature>:screen:<id>`) — the
564
+ // renderer strips the latter to the short id (lastSegment) when
565
+ // navigating, which the nav-router resolves app-wide (#1946). The object
566
+ // form (fw#2670) carries the same target under `screen` plus the payload
567
+ // field `idFrom`. Shared by actionForm/secretMint (validateInlineFormNavTargets)
568
+ // and entityEdit — same rule, same error message, one place to keep them in sync.
569
+ function validateRedirectTarget(feature, screenId, screenKind, redirect, allScreenQns) {
570
+ const redirectTarget = typeof redirect === "string" ? redirect : redirect.screen;
571
+ if (typeof redirect !== "string" &&
572
+ (typeof redirect.idFrom !== "string" || redirect.idFrom.trim() === "")) {
573
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (${screenKind}) redirect.idFrom is empty or not a string — ` +
574
+ `name the success-payload field carrying the navigation id, or use the plain string ` +
575
+ `redirect form to navigate with the handler's own "id".`);
576
+ }
577
+ validateScreenNavTarget(feature.name, screenId, screenKind, "redirect", redirectTarget, allScreenQns, feature.screens);
578
+ }
579
+ function validateInlineFormNavTargets(feature, screenId, screen, kind, allScreenQns) {
580
+ if (screen.redirect !== undefined) {
581
+ validateRedirectTarget(feature, screenId, kind, screen.redirect, allScreenQns);
582
+ }
583
+ if (typeof screen.cancelTarget === "string") {
584
+ // Same rule as redirect — `false` (no Cancel button) needs no validation.
585
+ validateScreenNavTarget(feature.name, screenId, kind, "cancelTarget", screen.cancelTarget, allScreenQns, feature.screens);
586
+ }
587
+ }
588
+ // actionForm/secretMint have no entity link, only a write-handler QN +
589
+ // inline fields: checks handler registration, field types, layout refs, and nav targets.
590
+ function validateInlineFormScreen(feature, screenId, screen, kind, allWriteHandlerQns, allScreenQns, featureMap) {
591
+ validateWriteHandlerRegistered(feature.name, screenId, kind, screen.handler, allWriteHandlerQns);
592
+ // Only a secretMint's own mint step may skip fields/sections entirely
593
+ // (input-less mint, fw#2838) — actionForm always needs at least one field.
594
+ const allowEmptyMintForm = kind === "secretMint";
595
+ const fieldNames = validateFormFieldsMap(feature.name, screenId, kind, screen.fields, allowEmptyMintForm);
596
+ validateFormLayoutSections(feature.name, screenId, kind, screen.layout, fieldNames, allowEmptyMintForm && fieldNames.size === 0);
597
+ validateWizardLayout(feature.name, screenId, kind, screen.layout, featureMap);
598
+ validateInlineFormNavTargets(feature, screenId, screen, kind, allScreenQns);
599
+ }
600
+ // SecretMintConfirmStep (fw#2838): an optional proof-of-receipt form rendered
601
+ // on the reveal card in place of the bare acknowledge button (TOTP enrollment:
602
+ // scan the code, then enter one). Unlike the mint step, confirm always needs
603
+ // at least one field — a step whose only job is proving receipt with no input
604
+ // would be meaningless — and its layout is a single plain form, never a
605
+ // wizard/tabs flow and never a persisted draft: a one-time reveal-confirm is
606
+ // not a multi-step flow, and persisting a draft of it would re-open the leak
607
+ // fw#2548 closed (a lingering copy of the just-revealed secret in storage).
608
+ function validateSecretMintConfirm(feature, screenId, screen, allWriteHandlerQns) {
609
+ const confirm = screen.confirm;
610
+ // skip: the screen declares no confirm step — nothing to validate.
611
+ if (confirm === undefined)
612
+ return;
613
+ const context = "secretMint confirm";
614
+ validateWriteHandlerRegistered(feature.name, screenId, context, confirm.handler, allWriteHandlerQns);
615
+ const fieldNames = validateFormFieldsMap(feature.name, screenId, context, confirm.fields, false);
616
+ validateFormLayoutSections(feature.name, screenId, context, confirm.layout, fieldNames, false);
617
+ if (confirm.layout.mode !== undefined && confirm.layout.mode !== "single") {
618
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (${context}) sets layout.mode: ` +
619
+ `"${confirm.layout.mode}" — a one-time reveal confirm step must stay a single-step form. ` +
620
+ `Remove mode or set it to "single".`);
621
+ }
622
+ if (confirm.layout.draft === true) {
623
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (${context}) sets layout.draft: true — ` +
624
+ `persisting a draft of the reveal-confirm step would leak the one-time secret into storage, ` +
625
+ `the exact leak fw#2548 closed. Remove draft: true.`);
626
+ }
627
+ // skip: no carry list declared — no carried fields to cross-check against confirm.fields.
628
+ if (confirm.carry === undefined)
629
+ return;
630
+ for (const carryField of confirm.carry) {
631
+ if (typeof carryField !== "string" || carryField.trim() === "") {
632
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (${context}) has an empty or non-string ` +
633
+ `entry in "carry".`);
634
+ }
635
+ if (fieldNames.has(carryField)) {
636
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (${context}) carry field "${carryField}" ` +
637
+ `also names a confirm.fields entry — a carried mint-payload value would silently ` +
638
+ `overwrite the user-entered field of the same name. Rename one of them.`);
639
+ }
640
+ }
641
+ }
642
+ // nav.screen is a full QN (cross-feature), so a standalone r.nav() pointing
643
+ // at `targetQn` must be found by scanning every feature's nav entries and actions.
644
+ function hasStandaloneNavEntry(targetQn, featureMap) {
645
+ for (const f of featureMap.values()) {
646
+ for (const nav of Object.values(f.navs)) {
647
+ if (nav.screen === targetQn)
648
+ return true;
649
+ if (nav.createAction?.screen === targetQn)
650
+ return true;
651
+ if (nav.actions?.some((a) => a.screen === targetQn))
652
+ return true;
653
+ }
654
+ }
655
+ return false;
656
+ }
657
+ // Every screen must resolve nav via `nav`, `r.nav()`, a parent list, or
658
+ // `dormant: true`. Skipped when the composed set has no nav entries at all.
659
+ function validateScreenHasNavArea(feature, screenId, screen, featureMap) {
660
+ // skip: the screen already declares its own nav entry.
661
+ if (screen.nav !== undefined)
662
+ return;
663
+ // skip: explicitly opted out via `dormant: true`.
664
+ if (screen.dormant === true)
665
+ return;
666
+ const anyNavRegistered = [...featureMap.values()].some((f) => Object.keys(f.navs).length > 0);
667
+ // skip: no nav entries exist anywhere in the composed set — a feature/
668
+ // recipe/test fixture booted without an app shell, not an omission.
669
+ if (!anyNavRegistered)
670
+ return;
671
+ const targetQn = qualifyEntityName(feature.name, "screen", screenId);
672
+ // skip: a standalone r.nav() elsewhere already points at this screen.
673
+ if (hasStandaloneNavEntry(targetQn, featureMap))
674
+ return;
675
+ const allScreens = [...featureMap.values()].flatMap((f) => Object.values(f.screens));
676
+ // skip: resolves to a parent list via listScreenId/rowAction-target/same-entity.
677
+ if (resolveNavParentScreen(allScreens, screen, (s) => s.id) !== undefined)
678
+ return;
679
+ throw new Error(`[Feature ${feature.name}] Screen "${targetQn}" has no nav entry and no resolvable list — ` +
680
+ `declare listScreenId (or a rowAction/toolbarAction navigate target from a list screen), add ` +
681
+ `a standalone r.nav() pointing at it, or set dormant: true if it's intentionally reachable ` +
682
+ `only via a direct link/redirect or a consuming app's own r.nav().`);
683
+ }
684
+ export function validateScreens(feature, featureMap, allWriteHandlerQns, allScreenQns, allConfigKeyQns, screensByShortId, detailForScreens) {
685
+ // navigate-Targets (rowAction/toolbarAction) dürfen cross-feature zeigen —
686
+ // der Runtime-Router (create-app) löst eine bare screenId app-weit über ALLE
687
+ // Features auf (eine deklarative Liste im owning-Feature der Entity navigiert
688
+ // so zu den Custom-Editoren der Consumer-App). Der Validator spiegelt das:
689
+ // same-feature ODER irgendein Feature. redirect/cancelTarget akzeptieren
690
+ // zusätzlich eine voll-qualifizierte Cross-Feature-QN (resolveScreenTargetQn,
691
+ // #1946) — kurze IDs bleiben same-feature wie zuvor.
692
+ const navTargetShortIds = screenShortIdsFrom(allScreenQns);
693
+ for (const [screenId, screen] of Object.entries(feature.screens)) {
694
+ validateScreenHasNavArea(feature, screenId, screen, featureMap);
695
+ if (screen.type === "custom") {
696
+ if (!screen.renderer.react && !screen.renderer.native) {
697
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" has type="custom" but the renderer ` +
698
+ `declares neither a react nor a native component — at least one platform must be set.`);
699
+ }
700
+ continue;
701
+ }
702
+ if (screen.type === "projectionList") {
703
+ // Query-getrieben, keine Entity → nur query + columns prüfen (die
704
+ // Column-Felder können nicht gegen eine Entity gecheckt werden; sie
705
+ // werden zur Render-Zeit gegen die Projection-Rows aufgelöst).
706
+ if (!screen.query || typeof screen.query !== "string") {
707
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionList) has empty or non-string query.`);
708
+ }
709
+ if (screen.columns.length === 0) {
710
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionList) has an empty columns list — ` +
711
+ `declare at least one column.`);
712
+ }
713
+ for (const col of screen.columns) {
714
+ const normalizedCol = normalizeListColumn(col);
715
+ validateColumnRendererForm(feature.name, screenId, normalizedCol);
716
+ if (normalizedCol.refEntity !== undefined) {
717
+ assertRefTargetRegistered(`[Feature ${feature.name}] Screen "${screenId}" (projectionList)`, `column "${normalizedCol.field}" (refEntity)`, normalizedCol.refEntity, feature.name, featureMap);
718
+ }
719
+ }
720
+ // Screen filter (fw#2224) — field existence can't be checked without
721
+ // an entity (columns aren't a complete field inventory of the
722
+ // underlying query), so only pin the structure: "in" requires an
723
+ // array. Field validity is documented in the PR body.
724
+ if (screen.filter !== undefined &&
725
+ screen.filter.op === "in" &&
726
+ !Array.isArray(screen.filter.value)) {
727
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionList) filter.op "in" requires ` +
728
+ `filter.value to be a readonly array.`);
729
+ }
730
+ if (screen.facets !== undefined) {
731
+ validateListFacets(`[Feature ${feature.name}] Screen "${screenId}" (projectionList)`, screen.facets, screen.columns, feature.name, featureMap);
732
+ }
733
+ if (screen.rowActions !== undefined) {
734
+ for (const action of screen.rowActions) {
735
+ if (action.kind === "navigate") {
736
+ const target = resolveRowActionNavigateTarget(feature.name, screenId, "projectionList", "rowAction", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
737
+ validateRowActionNavigateParams(feature.name, screenId, "projectionList", undefined, action, target);
738
+ }
739
+ else if (action.kind === "drawer") {
740
+ validateDrawerTargetAction(feature.name, screenId, "projectionList", "rowAction", action, feature.screens);
741
+ }
742
+ }
743
+ validateAtMostOneRowClick(feature.name, screenId, "projectionList", screen.rowActions);
744
+ }
745
+ // Only drawer-kind and navigate actions that set tab are validated
746
+ // here — plain navigate (no tab) and writeHandler toolbarActions on
747
+ // projectionList have no boot check yet (pre-existing gap).
748
+ if (screen.toolbarActions !== undefined) {
749
+ for (const action of screen.toolbarActions) {
750
+ if (action.kind === "drawer") {
751
+ validateDrawerTargetAction(feature.name, screenId, "projectionList", "toolbarAction", action, feature.screens);
752
+ }
753
+ if (action.kind === "navigate" && action.tab !== undefined) {
754
+ resolveRowActionNavigateTarget(feature.name, screenId, "projectionList", "toolbarAction", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
755
+ }
756
+ }
757
+ }
758
+ continue;
759
+ }
760
+ if (screen.type === "projectionDetail") {
761
+ // Query-getrieben wie projectionList, aber Single-Row + Layout statt
762
+ // Columns. Kein Entity-Check möglich — Felder werden render-seitig
763
+ // gegen die Query-Response aufgelöst, nicht gegen eine Entity.
764
+ if (!screen.query || typeof screen.query !== "string") {
765
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) has empty or non-string query.`);
766
+ }
767
+ if (screen.singleton === true && screen.idParam !== undefined) {
768
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) sets both singleton: true ` +
769
+ `and idParam — singleton means the server picks the row from the caller's context, so there ` +
770
+ `is no row id to send under idParam. Remove idParam.`);
771
+ }
772
+ // singleton has no row id in the path, but the auto-generated "Edit"
773
+ // action (fw#2166, defaultEditAction in kumiko-screen.tsx) navigates
774
+ // to the detailFor entity's entityEdit screen using that path id —
775
+ // under singleton it would silently open that screen in CREATE mode
776
+ // instead of editing the singleton row. Reject rather than let that
777
+ // win silently, same as the idParam check above.
778
+ if (screen.singleton === true && screen.detailFor !== undefined) {
779
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) sets both singleton: true ` +
780
+ `and detailFor — the auto-generated "Edit" action navigates using the path's row id, which a ` +
781
+ `singleton screen never has. Remove detailFor, or declare an explicit "edit" action instead.`);
782
+ }
783
+ if (screen.layout.sections.length === 0) {
784
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) has an empty sections list — ` +
785
+ `declare at least one section.`);
786
+ }
787
+ if (screen.layout.mode === "tabs") {
788
+ validateTabSections(feature.name, screenId, "projectionDetail", screen.layout.sections);
789
+ for (const section of screen.layout.sections) {
790
+ const isFieldsSection = section.kind === undefined || section.kind === "fields";
791
+ if (isFieldsSection && section.groups !== undefined && section.actions !== undefined) {
792
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.id}" ` +
793
+ `declares both groups and actions in tabs mode — actions has no single group's Card to sit ` +
794
+ `in, and an extra title-less Card around the group cards would nest a Card inside a Card. ` +
795
+ `Move the actions onto one group's title, or drop groups for a flat fields grid.`);
796
+ }
797
+ }
798
+ }
799
+ if (screen.metrics !== undefined) {
800
+ for (const metric of screen.metrics) {
801
+ const field = metricField(metric);
802
+ const hasOwnLabel = typeof metric !== "string" && metric.label !== undefined;
803
+ if (!hasOwnLabel && screen.fieldLabels?.[field] === undefined) {
804
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) metric "${field}" has ` +
805
+ `no entry in fieldLabels and no own "label" — every metrics field needs one of the two, ` +
806
+ `there is no fallback to the raw column name.`);
807
+ }
808
+ const navigate = typeof metric === "string" ? undefined : metric.navigate;
809
+ if (navigate?.tab !== undefined) {
810
+ if (navigate.screen === undefined && navigate.entity === undefined) {
811
+ if (!screen.layout.sections.some((section) => section.id === navigate.tab)) {
812
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) metric "${field}" ` +
813
+ `navigates to tab "${navigate.tab}", which is not a section id on this screen.`);
814
+ }
815
+ }
816
+ else {
817
+ resolveRowActionNavigateTarget(feature.name, screenId, "projectionDetail", "metric", {
818
+ kind: "navigate",
819
+ id: field,
820
+ label: field,
821
+ ...(navigate.screen !== undefined ? { screen: navigate.screen } : {}),
822
+ ...(navigate.entity !== undefined ? { entity: navigate.entity } : {}),
823
+ ...(navigate.entityId !== undefined ? { entityId: navigate.entityId } : {}),
824
+ tab: navigate.tab,
825
+ }, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
826
+ }
827
+ }
828
+ }
829
+ }
830
+ for (const section of screen.layout.sections) {
831
+ const sectionLabel = section.title ?? section.id ?? "(untitled)";
832
+ if (section.actions !== undefined) {
833
+ for (const action of section.actions) {
834
+ validateActionHasIcon(feature.name, screenId, "projectionDetail", `section "${sectionLabel}" action`, action);
835
+ if (action.kind === "navigate" && action.tab !== undefined) {
836
+ resolveRowActionNavigateTarget(feature.name, screenId, "projectionDetail", `section "${sectionLabel}" action`, action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
837
+ }
838
+ }
839
+ }
840
+ if (section.kind === "relatedList" && section.emptyState?.action !== undefined) {
841
+ validateActionHasIcon(feature.name, screenId, "projectionDetail", `section "${sectionLabel}" emptyState action`, section.emptyState.action);
842
+ if (section.emptyState.action.kind === "navigate" &&
843
+ section.emptyState.action.tab !== undefined) {
844
+ resolveRowActionNavigateTarget(feature.name, screenId, "projectionDetail", `section "${sectionLabel}" emptyState action`, section.emptyState.action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
845
+ }
846
+ }
847
+ if (isExtensionEditSection(section)) {
848
+ // projectionDetail is read-only (no composed form submit) — an
849
+ // extension that persists through the host's Save button has
850
+ // nothing to save against. Extensions that persist themselves
851
+ // (e.g. notes-history NotesSection, via their own dispatcher
852
+ // writes) are fine (solon#264).
853
+ if (section.contributesToFormSubmit === true) {
854
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) extension section ` +
855
+ `"${section.title}" sets contributesToFormSubmit: true, but projectionDetail has no ` +
856
+ `form submit to contribute to (read-only screen). Omit contributesToFormSubmit and ` +
857
+ `persist through the extension's own dispatcher writes instead.`);
858
+ }
859
+ if (section.component?.react === undefined && section.component?.native === undefined) {
860
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) extension section ` +
861
+ `"${section.title}" has no component — declare a react/native component marker.`);
862
+ }
863
+ // The host-derived entity name on projectionDetail is an internal
864
+ // placeholder (no real entity backs this screen) — a self-
865
+ // persisting extension needs the real domain entity name declared
866
+ // explicitly, or it silently reads/writes against the wrong type.
867
+ if (section.entityName === undefined || section.entityName.trim().length === 0) {
868
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) extension section ` +
869
+ `"${section.title}" has no entityName — projectionDetail has no real entity, so the ` +
870
+ `extension must declare entityName explicitly (the domain entity it persists against).`);
871
+ }
872
+ continue;
873
+ }
874
+ if (section.kind === "relatedList") {
875
+ if (!section.query || typeof section.query !== "string") {
876
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
877
+ `(relatedList) has empty or non-string query.`);
878
+ }
879
+ for (const col of section.columns) {
880
+ const normalizedCol = normalizeListColumn(col);
881
+ if (normalizedCol.refEntity !== undefined) {
882
+ assertRefTargetRegistered(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" (relatedList)`, `column "${normalizedCol.field}" (refEntity)`, normalizedCol.refEntity, feature.name, featureMap);
883
+ }
884
+ }
885
+ if (screen.layout.mode === "wizard") {
886
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
887
+ `is kind "relatedList" in a wizard layout — a read-only list is not supported in a ` +
888
+ `stepped form. Remove mode: "wizard" or drop the relatedList section.`);
889
+ }
890
+ if (section.rowClick !== undefined) {
891
+ const targetEntity = section.rowClick.entity;
892
+ const hasDetailScreen = [...featureMap.values()].some((f) => Object.values(f.screens).some((s) => s.detailFor === targetEntity));
893
+ if (!hasDetailScreen) {
894
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
895
+ `(relatedList) rowClick targets entity "${targetEntity}", but no screen declares ` +
896
+ `detailFor: "${targetEntity}". Add detailFor: "${targetEntity}" to the screen that shows it.`);
897
+ }
898
+ }
899
+ if (section.rowActions !== undefined) {
900
+ for (const action of section.rowActions) {
901
+ if (action.kind === "navigate") {
902
+ const target = resolveRowActionNavigateTarget(feature.name, screenId, "projectionDetail", "rowAction", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
903
+ validateRowActionNavigateParams(feature.name, screenId, "projectionDetail", undefined, action, target);
904
+ }
905
+ else if (action.kind === "drawer") {
906
+ validateDrawerTargetAction(feature.name, screenId, "projectionDetail", "rowAction", action, feature.screens);
907
+ }
908
+ else if (!allWriteHandlerQns.has(action.handler)) {
909
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section ` +
910
+ `"${section.title}" (relatedList) rowAction "${action.id}" handler "${action.handler}" ` +
911
+ `is not a registered write-handler. Check the QN spelling (expected ` +
912
+ `"<feature>:write:<short>") and that the handler is declared via r.writeHandler(...).`);
913
+ }
914
+ }
915
+ // section.rowClick (legacy, navigate-only) and a rowActions entry
916
+ // marked rowClick:true both claim the row-body click — same
917
+ // at-most-one constraint as entityList/projectionList's
918
+ // validateAtMostOneRowClick, just spanning two fields instead of one.
919
+ const rowClickActionCount = section.rowActions.filter((a) => a.kind === "navigate" && a.rowClick === true).length;
920
+ const legacyRowClickCount = section.rowClick !== undefined ? 1 : 0;
921
+ if (rowClickActionCount + legacyRowClickCount > 1) {
922
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
923
+ `(relatedList) has both a rowClick and ${rowClickActionCount} rowActions marked ` +
924
+ `rowClick:true — at most one may fire on a row-body click.`);
925
+ }
926
+ }
927
+ if (section.defaultSort !== undefined) {
928
+ const sortField = section.defaultSort.field;
929
+ const col = section.columns.find((c) => normalizeListColumn(c).field === sortField);
930
+ if (col === undefined) {
931
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
932
+ `(relatedList) defaultSort.field "${sortField}" is not a listed column.`);
933
+ }
934
+ if (normalizeListColumn(col).sortable !== true) {
935
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
936
+ `(relatedList) defaultSort.field "${sortField}" is not sortable. Set sortable: true on ` +
937
+ `the column or pick another field.`);
938
+ }
939
+ }
940
+ if (section.facets !== undefined) {
941
+ validateListFacets(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) relatedList section "${section.title}"`, section.facets, section.columns, feature.name, featureMap);
942
+ }
943
+ // Only drawer-kind and navigate actions that set tab are validated
944
+ // here — plain navigate (no tab) and writeHandler toolbarActions
945
+ // have no boot check yet, same gap as above.
946
+ if (section.toolbarActions !== undefined) {
947
+ for (const action of section.toolbarActions) {
948
+ if (action.kind === "drawer") {
949
+ validateDrawerTargetAction(feature.name, screenId, "projectionDetail", "toolbarAction", action, feature.screens);
950
+ }
951
+ if (action.kind === "navigate" && action.tab !== undefined) {
952
+ resolveRowActionNavigateTarget(feature.name, screenId, "projectionDetail", "toolbarAction", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
953
+ }
954
+ }
955
+ }
956
+ continue;
957
+ }
958
+ if (isWriteFormEditSection(section)) {
959
+ if (Object.keys(section.fieldDefs).length === 0) {
960
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
961
+ `(writeForm) has an empty fieldDefs map — declare at least one field type.`);
962
+ }
963
+ if (section.fields.length === 0) {
964
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
965
+ `(writeForm) has zero fields — drop the section or add fields to it.`);
966
+ }
967
+ // kumiko-lint-ignore section-fields-raw writeForm sections carry no groups (EditWriteFormSection)
968
+ for (const f of section.fields) {
969
+ const fieldName = normalizeEditField(f).field;
970
+ if (section.fieldDefs[fieldName] === undefined) {
971
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
972
+ `(writeForm) field "${fieldName}" has no entry in fieldDefs — every rendered field needs ` +
973
+ `a type declared there.`);
974
+ }
975
+ }
976
+ if (screen.layout.mode === "wizard") {
977
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
978
+ `is kind "writeForm" in a wizard layout — a self-persisting form is not supported in a ` +
979
+ `stepped form. Remove mode: "wizard" or drop the writeForm section.`);
980
+ }
981
+ if (!allWriteHandlerQns.has(section.handler)) {
982
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) section "${section.title}" ` +
983
+ `(writeForm) handler "${section.handler}" is not a registered write-handler. Check the QN ` +
984
+ `spelling (expected "<feature>:write:<short>") and that the handler is declared via ` +
985
+ `r.writeHandler(...).`);
986
+ }
987
+ continue;
988
+ }
989
+ validateFieldsXorGroups(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail)`, section);
990
+ for (const fieldSpec of sectionFieldSpecs(section)) {
991
+ const normalizedField = normalizeEditField(fieldSpec);
992
+ if (normalizedField.refEntity !== undefined) {
993
+ assertRefTargetRegistered(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail)`, `field "${normalizedField.field}" (refEntity)`, normalizedField.refEntity, feature.name, featureMap);
994
+ }
995
+ }
996
+ }
997
+ // Header actions reuse RowAction (the displayed record stands in for
998
+ // the row), so the same navigate/writeHandler existence checks as
999
+ // entityList/projectionList apply. `rowClick` is rejected outright —
1000
+ // a detail screen has no row to click.
1001
+ if (screen.actions !== undefined) {
1002
+ for (const action of screen.actions) {
1003
+ validateActionHasIcon(feature.name, screenId, "projectionDetail", "action", action);
1004
+ if (action.kind === "navigate" && action.rowClick === true) {
1005
+ throw new Error(`[Feature ${feature.name}] Screen "${qualifyEntityName(feature.name, "screen", screenId)}" ` +
1006
+ `(projectionDetail) action "${action.id}" sets rowClick: true — there is no row to ` +
1007
+ `click on a detail screen. Remove rowClick.`);
1008
+ }
1009
+ if (action.kind === "navigate") {
1010
+ const target = resolveRowActionNavigateTarget(feature.name, screenId, "projectionDetail", "action", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
1011
+ validateRowActionNavigateParams(feature.name, screenId, "projectionDetail", screen.detailFor, action, target);
1012
+ }
1013
+ else if (action.kind === "drawer") {
1014
+ validateDrawerTargetAction(feature.name, screenId, "projectionDetail", "action", action, feature.screens);
1015
+ }
1016
+ else {
1017
+ if (!allWriteHandlerQns.has(action.handler)) {
1018
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (projectionDetail) action "${action.id}" ` +
1019
+ `handler "${action.handler}" is not a registered write-handler. Check the QN spelling ` +
1020
+ `(expected "<feature>:write:<short>") and that the handler is declared via r.writeHandler(...).`);
1021
+ }
1022
+ }
1023
+ }
1024
+ }
1025
+ continue;
1026
+ }
1027
+ if (screen.type === "dashboard") {
1028
+ validateDashboardScreen(feature.name, screenId, screen, featureMap);
1029
+ continue;
1030
+ }
1031
+ if (screen.type === "configEdit") {
1032
+ // configEdit: layout/fields wie actionForm validieren, plus
1033
+ // Cross-Check dass jeder qualifizierte Config-Key registriert
1034
+ // ist und der scope mit dem Key matcht.
1035
+ const fieldNames = new Set(Object.keys(screen.fields));
1036
+ if (fieldNames.size === 0) {
1037
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) has empty fields map — ` +
1038
+ `declare at least one field.`);
1039
+ }
1040
+ for (const [fname, fdef] of Object.entries(screen.fields)) {
1041
+ // @cast-boundary schema-walk — feature-config inspection
1042
+ const ftype = fdef.type;
1043
+ if (typeof ftype !== "string" || ftype.length === 0) {
1044
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) field "${fname}" has no ` +
1045
+ `\`type\` set. Each field must declare a type (e.g. "text", "number", "select").`);
1046
+ }
1047
+ }
1048
+ if (screen.layout.sections.length === 0) {
1049
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) has an empty sections list — ` +
1050
+ `declare at least one section.`);
1051
+ }
1052
+ for (const section of screen.layout.sections) {
1053
+ if (isExtensionEditSection(section)) {
1054
+ if (section.component?.react === undefined && section.component?.native === undefined) {
1055
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) extension section ` +
1056
+ `"${section.title}" has no component — declare a react/native component marker.`);
1057
+ }
1058
+ continue;
1059
+ }
1060
+ if (section.kind === "relatedList") {
1061
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) relatedList section ` +
1062
+ `"${section.title}" is not supported — relatedList is a projectionDetail-only ` +
1063
+ `primitive (fw#2166).`);
1064
+ }
1065
+ if (isWriteFormEditSection(section)) {
1066
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) writeForm section ` +
1067
+ `"${section.title}" is not supported — writeForm is a projectionDetail-only primitive.`);
1068
+ }
1069
+ validateFieldsXorGroups(`[Feature ${feature.name}] Screen "${screenId}" (configEdit)`, section);
1070
+ for (const fieldSpec of sectionFieldSpecs(section)) {
1071
+ const normalized = normalizeEditField(fieldSpec);
1072
+ if (!fieldNames.has(normalized.field)) {
1073
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) layout references unknown ` +
1074
+ `field "${normalized.field}". Known fields: ${[...fieldNames].sort().join(", ")}`);
1075
+ }
1076
+ }
1077
+ }
1078
+ validateWizardLayout(feature.name, screenId, "configEdit", screen.layout, featureMap);
1079
+ // configKeys: jeder fieldName muss einen Mapping-Eintrag haben,
1080
+ // jeder qualifizierte Key muss in der Registry existieren.
1081
+ for (const fname of fieldNames) {
1082
+ const qualified = screen.configKeys[fname];
1083
+ if (qualified === undefined) {
1084
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) field "${fname}" hat ` +
1085
+ `keinen Eintrag in configKeys-Map. Jedes deklarierte Field braucht ein Mapping zu ` +
1086
+ `einem qualifizierten Config-Key (\`<feature>:config:<short>\`).`);
1087
+ }
1088
+ if (!allConfigKeyQns.has(qualified)) {
1089
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (configEdit) field "${fname}" → ` +
1090
+ `Config-Key "${qualified}" ist in keiner Feature-Registry deklariert. Tippfehler? ` +
1091
+ `Erwartetes Format: "<feature>:config:<short>". Bekannte Keys: ${[...allConfigKeyQns].sort().join(", ") || "(keine)"}`);
1092
+ }
1093
+ }
1094
+ continue;
1095
+ }
1096
+ if (screen.type === "actionForm") {
1097
+ validateInlineFormScreen(feature, screenId, screen, "actionForm", allWriteHandlerQns, allScreenQns, featureMap);
1098
+ continue;
1099
+ }
1100
+ if (screen.type === "secretMint") {
1101
+ validateInlineFormScreen(feature, screenId, screen, "secretMint", allWriteHandlerQns, allScreenQns, featureMap);
1102
+ if (screen.reveal.fields.length === 0) {
1103
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (secretMint) has an empty reveal.fields ` +
1104
+ `list — declare at least one field to reveal.`);
1105
+ }
1106
+ const revealFieldNames = new Set();
1107
+ for (const revealField of screen.reveal.fields) {
1108
+ if (typeof revealField.field !== "string" || revealField.field.trim() === "") {
1109
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (secretMint) has a reveal.fields entry ` +
1110
+ `with an empty or non-string "field".`);
1111
+ }
1112
+ if (revealFieldNames.has(revealField.field)) {
1113
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (secretMint) reveal.fields has a ` +
1114
+ `duplicate field "${revealField.field}" — each revealed field must be unique.`);
1115
+ }
1116
+ revealFieldNames.add(revealField.field);
1117
+ if (typeof revealField.label !== "string" || revealField.label.trim() === "") {
1118
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (secretMint) reveal.fields entry ` +
1119
+ `"${revealField.field}" has an empty or non-string "label".`);
1120
+ }
1121
+ }
1122
+ validateSecretMintConfirm(feature, screenId, screen, allWriteHandlerQns);
1123
+ continue;
1124
+ }
1125
+ // secretsEdit is generator-only (buildConfigFeatureSchema) — never
1126
+ // authored via r.screen, so feature.screens never actually carries one.
1127
+ // Kept here only so this loop's type narrowing stays exhaustive.
1128
+ if (screen.type === "secretsEdit")
1129
+ continue;
1130
+ // entityList / entityEdit: entity-refs are feature-local.
1131
+ const entityDef = feature.entities?.[screen.entity];
1132
+ if (!entityDef) {
1133
+ const known = Object.keys(feature.entities ?? {})
1134
+ .sort()
1135
+ .join(", ") || "(none)";
1136
+ const crossFeature = findEntityFeature(screen.entity, featureMap);
1137
+ const hint = crossFeature
1138
+ ? ` Entity "${screen.entity}" is owned by feature "${crossFeature}" — cross-feature screen ownership is not supported.`
1139
+ : "";
1140
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" references entity "${screen.entity}" ` +
1141
+ `which is not declared in this feature (known: ${known}).${hint}`);
1142
+ }
1143
+ const fieldNames = new Set(Object.keys(entityDef.fields));
1144
+ // List columns may also name a read-time derived field (not a stored
1145
+ // column). Allowed for display; deliberately NOT added to `fieldNames`, so
1146
+ // defaultSort/filter on a derived field still fails — server-side sort over
1147
+ // a non-column is a silent no-op (see DerivedFieldDef).
1148
+ const columnFieldNames = entityDef.derivedFields !== undefined
1149
+ ? new Set([...fieldNames, ...Object.keys(entityDef.derivedFields)])
1150
+ : fieldNames;
1151
+ const rowMeta = rowMetaFieldNames(entityDef.softDelete ?? false);
1152
+ if (screen.type === "entityList") {
1153
+ // Empty column list would render as a blank table — almost always the
1154
+ // sign of an in-progress screen the author forgot to fill in. Fail
1155
+ // loud: ui-core's computeListViewModel can't do anything useful with
1156
+ // zero columns either.
1157
+ if (screen.columns.length === 0) {
1158
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) has an empty columns list — ` +
1159
+ `declare at least one column.`);
1160
+ }
1161
+ for (const col of screen.columns) {
1162
+ const normalized = normalizeListColumn(col);
1163
+ // A row-meta column (id/tenantId/version/insertedAt/modifiedAt/...) is a
1164
+ // real DB column without being a declared entity field — e.g. a
1165
+ // SystemAdmin cross-tenant list exposing tenantId. Accept it like a
1166
+ // regular field name — but only the columns computeListViewModel can
1167
+ // actually render (LIST_ROW_META_COLUMN_NAMES), not the wider
1168
+ // softDelete-aware rowMeta set used below for payload/visible refs.
1169
+ //
1170
+ // A virtual presentational column (drawn by a columnRenderer component
1171
+ // from the row, e.g. tag chips) needs BOTH a label AND a renderer —
1172
+ // renderer is what actually makes it "virtual" (label alone still
1173
+ // needs list.ts's virtual-branch to have something to draw; without
1174
+ // a renderer the column would render nothing). A column with neither
1175
+ // matching a real field/row-meta column NOR a renderer is a typo worth
1176
+ // failing the boot.
1177
+ if (!columnFieldNames.has(normalized.field) &&
1178
+ !LIST_ROW_META_COLUMN_NAMES.has(normalized.field) &&
1179
+ !(normalized.label !== undefined && normalized.renderer !== undefined)) {
1180
+ throw new Error(buildUnknownFieldMessage(feature.name, screenId, normalized.field, screen.entity, columnFieldNames));
1181
+ }
1182
+ validateColumnRendererForm(feature.name, screenId, normalized);
1183
+ }
1184
+ // Pagination/Sort/Search-Validierung: Author-Fehler beim Boot
1185
+ // fangen, damit kein "warum kommt die Liste leer / falsch
1186
+ // sortiert"-Debug-Cycle zur Laufzeit losgeht.
1187
+ if (screen.pageSize !== undefined && screen.pageSize <= 0) {
1188
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) has pageSize=${screen.pageSize} — ` +
1189
+ `must be a positive integer.`);
1190
+ }
1191
+ if (screen.defaultSort !== undefined) {
1192
+ const sortField = screen.defaultSort.field;
1193
+ if (!fieldNames.has(sortField)) {
1194
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) defaultSort references unknown ` +
1195
+ `field "${sortField}". Known fields: ${[...fieldNames].sort().join(", ")}`);
1196
+ }
1197
+ // sortable: true Pflicht — verhindert dass das UI auf einer
1198
+ // Spalte sortiert, die Server-Side gar keinen DB-Index hat
1199
+ // oder im Schema absichtlich nicht sortiert werden soll
1200
+ // (Audit-Felder, Computed-Werte). `sortable` lebt heute nur
1201
+ // auf TextFieldDef; "in"-narrow lässt das auch für andere
1202
+ // Field-Types ohne explizites Flag durchfallen, was ok ist:
1203
+ // Number/Date sind natürlich sortierbar, der Author kann sie
1204
+ // im Author-Code als sortable markieren wenn das Field-Type
1205
+ // es trägt (Erweiterung folgt).
1206
+ const fieldDef = entityDef.fields[sortField];
1207
+ const isSortable = fieldDef !== undefined && "sortable" in fieldDef && fieldDef.sortable === true;
1208
+ if (!isSortable) {
1209
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) defaultSort.field "${sortField}" ` +
1210
+ `is not sortable. Set sortable: true on the field definition or pick another field.`);
1211
+ }
1212
+ }
1213
+ // Screen-Filter (Tier 2.7c) — drei Layer Author-Code-Check:
1214
+ // 1) Field existiert auf der Entity (Tippfehler = leere Liste
1215
+ // statt Crash; Boot-Fail ist deutlich besser).
1216
+ // 2) Field hat `filterable: true` (Author opt-in, analog zu
1217
+ // `sortable`). Verhindert dass Audit-/Computed-/encrypted-
1218
+ // Felder unbeabsichtigt filterbar werden.
1219
+ // 3) Op passt zum Field-Type. Lt/gt auf text-Feldern → Boot-
1220
+ // Fail mit Hinweis statt String-Sort-Surprise zur Laufzeit.
1221
+ // Außerdem: "in" verlangt readonly Array.
1222
+ if (screen.filter !== undefined) {
1223
+ const filterField = screen.filter.field;
1224
+ if (!fieldNames.has(filterField)) {
1225
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) filter references unknown ` +
1226
+ `field "${filterField}". Known fields: ${[...fieldNames].sort().join(", ")}`);
1227
+ }
1228
+ const fieldDef = entityDef.fields[filterField];
1229
+ if (fieldDef !== undefined && !isFieldFilterable(fieldDef)) {
1230
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) filter references field ` +
1231
+ `"${filterField}" which is not filterable. Set filterable: true on the field ` +
1232
+ `definition or pick another field.`);
1233
+ }
1234
+ if (fieldDef !== undefined) {
1235
+ const allowedOps = getAllowedFilterOps(fieldDef);
1236
+ if (!allowedOps.includes(screen.filter.op)) {
1237
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) filter.op ` +
1238
+ `"${screen.filter.op}" is not allowed on field "${filterField}" ` +
1239
+ `(type "${fieldDef.type}"). Allowed ops: ${allowedOps.join(", ") || "(none)"}.`);
1240
+ }
1241
+ }
1242
+ if (screen.filter.op === "in" && !Array.isArray(screen.filter.value)) {
1243
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) filter.op "in" requires ` +
1244
+ `filter.value to be a readonly array.`);
1245
+ }
1246
+ }
1247
+ // Tier 2.7e-1: rowActions pinnen — navigate-target existiert (selbes
1248
+ // Feature), writeHandler-QN ist registriert. Tippfehler fallen sonst
1249
+ // erst beim ersten Klick als "Screen not found" / 404 auf.
1250
+ if (screen.rowActions !== undefined) {
1251
+ for (const action of screen.rowActions) {
1252
+ if (action.kind === "navigate") {
1253
+ const target = resolveRowActionNavigateTarget(feature.name, screenId, "entityList", "rowAction", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
1254
+ // The renderer's default-entityId fallback (row["id"]) only fires
1255
+ // for a same-feature entityEdit target — it can't safely guess
1256
+ // the id for a screen owned by a different feature. Cross-feature
1257
+ // + entityEdit therefore MUST set an explicit entityId, or the
1258
+ // edit screen silently opens with no entity context at runtime.
1259
+ // Entity-targets (fw#2228) are exempt: the renderer always
1260
+ // supplies an id for them (explicit entityId, else row["id"]),
1261
+ // regardless of which feature the resolved detailFor screen
1262
+ // belongs to.
1263
+ if (action.screen !== undefined &&
1264
+ target !== undefined &&
1265
+ target.featureName !== feature.name &&
1266
+ target.screen.type === "entityEdit" &&
1267
+ action.entityId === undefined) {
1268
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) rowAction "${action.id}" ` +
1269
+ `navigates cross-feature to entityEdit screen "${action.screen}" (feature ` +
1270
+ `"${target.featureName}") without an explicit entityId field — the renderer's ` +
1271
+ `same-feature row["id"] fallback does not apply across features. Set entityId to ` +
1272
+ `the row field that names the target entity's id.`);
1273
+ }
1274
+ // params only have a reader in actionForm and entityEdit-CREATE;
1275
+ // on projectionDetail/dashboard/configEdit/entityEdit-update they
1276
+ // are silently ignored at runtime. `custom` is deliberately
1277
+ // exempt: it renders an app-registered component the framework
1278
+ // has no visibility into — the author may read nav.searchParams
1279
+ // directly (real example: publicstatus's MonitorDetailScreen
1280
+ // does exactly that), so flagging it would be a false positive
1281
+ // on working code, not a caught bug.
1282
+ //
1283
+ // Whether an entityEdit target lands in create or update mode is
1284
+ // decided by the same rule the renderer's runNavigate() uses: an
1285
+ // explicit entityId always forces update mode, and (absent an
1286
+ // explicit entityId) a same-entity target gets row["id"] auto-
1287
+ // injected — only a cross-entity target with no explicit
1288
+ // entityId reaches create.
1289
+ validateRowActionNavigateParams(feature.name, screenId, "entityList", screen.entity, action, target);
1290
+ }
1291
+ else if (action.kind === "drawer") {
1292
+ validateDrawerTargetAction(feature.name, screenId, "entityList", "rowAction", action, feature.screens);
1293
+ }
1294
+ else {
1295
+ if (!allWriteHandlerQns.has(action.handler)) {
1296
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) rowAction "${action.id}" ` +
1297
+ `handler "${action.handler}" is not a registered write-handler. Check the QN spelling ` +
1298
+ `(expected "<feature>:write:<short>") and that the handler is declared via r.writeHandler(...).`);
1299
+ }
1300
+ }
1301
+ validateActionFieldRefs(feature.name, screenId, "rowAction", action.id, action, fieldNames, rowMeta);
1302
+ }
1303
+ validateAtMostOneRowClick(feature.name, screenId, "entityList", screen.rowActions);
1304
+ }
1305
+ // Tier 2.7e-2: toolbarActions — analog zu rowActions, aber bisher
1306
+ // ohne Validator. Typo'd navigate-targets und unregistrierte
1307
+ // writeHandler-QNs fallen bis hierhin erst beim Klick auf.
1308
+ if (screen.toolbarActions !== undefined) {
1309
+ for (const action of screen.toolbarActions) {
1310
+ if (action.kind === "navigate") {
1311
+ const candidateQn = qualifyEntityName(feature.name, "screen", action.screen);
1312
+ if (!allScreenQns.has(candidateQn) && !navTargetShortIds.has(action.screen)) {
1313
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) toolbarAction "${action.id}" ` +
1314
+ `navigate-target "${action.screen}" does not resolve to a registered screen in any feature.`);
1315
+ }
1316
+ if (action.tab !== undefined) {
1317
+ resolveRowActionNavigateTarget(feature.name, screenId, "entityList", "toolbarAction", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
1318
+ }
1319
+ }
1320
+ else if (action.kind === "drawer") {
1321
+ validateDrawerTargetAction(feature.name, screenId, "entityList", "toolbarAction", action, feature.screens);
1322
+ }
1323
+ else {
1324
+ if (!allWriteHandlerQns.has(action.handler)) {
1325
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityList) toolbarAction "${action.id}" ` +
1326
+ `handler "${action.handler}" is not a registered write-handler. Check the QN spelling ` +
1327
+ `(expected "<feature>:write:<short>") and that the handler is declared via r.writeHandler(...).`);
1328
+ }
1329
+ }
1330
+ validateActionFieldRefs(feature.name, screenId, "toolbarAction", action.id, action, fieldNames, rowMeta);
1331
+ }
1332
+ }
1333
+ }
1334
+ else {
1335
+ // Same rationale as the columns check: an entityEdit layout with zero
1336
+ // sections (or sections without any fields) renders as nothing — reject
1337
+ // at boot so the author sees it before the blank form surprises them.
1338
+ if (screen.layout.sections.length === 0) {
1339
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityEdit) has an empty sections list — ` +
1340
+ `declare at least one section.`);
1341
+ }
1342
+ for (const section of screen.layout.sections) {
1343
+ if (section.actions !== undefined) {
1344
+ const sectionLabel = section.title ?? section.id ?? "(untitled)";
1345
+ for (const action of section.actions) {
1346
+ validateActionHasIcon(feature.name, screenId, "entityEdit", `section "${sectionLabel}" action`, action);
1347
+ if (action.kind === "navigate" && action.tab !== undefined) {
1348
+ resolveRowActionNavigateTarget(feature.name, screenId, "entityEdit", `section "${sectionLabel}" action`, action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
1349
+ }
1350
+ }
1351
+ }
1352
+ if (isExtensionEditSection(section)) {
1353
+ if (section.component?.react === undefined && section.component?.native === undefined) {
1354
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityEdit) extension section ` +
1355
+ `"${section.title}" has no component — declare a react/native component marker.`);
1356
+ }
1357
+ continue;
1358
+ }
1359
+ if (section.kind === "relatedList") {
1360
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityEdit) relatedList section ` +
1361
+ `"${section.title}" is not supported — relatedList is a projectionDetail-only ` +
1362
+ `primitive (fw#2166).`);
1363
+ }
1364
+ if (isWriteFormEditSection(section)) {
1365
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityEdit) writeForm section ` +
1366
+ `"${section.title}" is not supported — writeForm is a projectionDetail-only primitive.`);
1367
+ }
1368
+ validateFieldsXorGroups(`[Feature ${feature.name}] Screen "${screenId}" (entityEdit)`, section);
1369
+ for (const fieldSpec of sectionFieldSpecs(section)) {
1370
+ const normalized = normalizeEditField(fieldSpec);
1371
+ if (!fieldNames.has(normalized.field)) {
1372
+ throw new Error(buildUnknownFieldMessage(feature.name, screenId, normalized.field, screen.entity, fieldNames));
1373
+ }
1374
+ validateNoWidgetRequiredField(feature.name, screenId, entityDef, normalized);
1375
+ }
1376
+ }
1377
+ validateWizardLayout(feature.name, screenId, "entityEdit", screen.layout, featureMap);
1378
+ // Header actions reuse RowAction — same shape and same checks as
1379
+ // projectionDetail's `actions` above (the loaded record stands in
1380
+ // for the row). `rowClick` is rejected outright — entityEdit has no
1381
+ // row to click either.
1382
+ if (screen.actions !== undefined) {
1383
+ for (const action of screen.actions) {
1384
+ if (action.kind === "navigate" && action.rowClick === true) {
1385
+ throw new Error(`[Feature ${feature.name}] Screen "${qualifyEntityName(feature.name, "screen", screenId)}" ` +
1386
+ `(entityEdit) action "${action.id}" sets rowClick: true — there is no row to click ` +
1387
+ `on an edit screen. Remove rowClick.`);
1388
+ }
1389
+ if (action.kind === "navigate") {
1390
+ const target = resolveRowActionNavigateTarget(feature.name, screenId, "entityEdit", "action", action, allScreenQns, navTargetShortIds, screensByShortId, detailForScreens);
1391
+ validateRowActionNavigateParams(feature.name, screenId, "entityEdit", screen.entity, action, target);
1392
+ }
1393
+ else if (action.kind === "drawer") {
1394
+ validateDrawerTargetAction(feature.name, screenId, "entityEdit", "action", action, feature.screens);
1395
+ }
1396
+ else {
1397
+ if (!allWriteHandlerQns.has(action.handler)) {
1398
+ throw new Error(`[Feature ${feature.name}] Screen "${screenId}" (entityEdit) action "${action.id}" ` +
1399
+ `handler "${action.handler}" is not a registered write-handler. Check the QN spelling ` +
1400
+ `(expected "<feature>:write:<short>") and that the handler is declared via r.writeHandler(...).`);
1401
+ }
1402
+ }
1403
+ }
1404
+ }
1405
+ if (screen.redirect !== undefined) {
1406
+ validateRedirectTarget(feature, screenId, "entityEdit", screen.redirect, allScreenQns);
1407
+ }
1408
+ }
1409
+ }
1410
+ }
1411
+ // Panel-getrieben, keine Entity — Struktur-Checks (eindeutige Panel-Ids,
1412
+ // non-empty Queries/Columns/valueField); die Query-Contracts (Stat-Record,
1413
+ // Points-Envelope, Paged-Rows) werden zur Render-Zeit aufgelöst.
1414
+ function validateDashboardScreen(featureName, screenId, screen, featureMap) {
1415
+ if (screen.panels.length === 0) {
1416
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) has an empty panels list — ` +
1417
+ `declare at least one panel.`);
1418
+ }
1419
+ const panelIds = new Set();
1420
+ const addPanelId = (id, context) => {
1421
+ if (panelIds.has(id)) {
1422
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) has duplicate panel id "${id}" (${context}).`);
1423
+ }
1424
+ panelIds.add(id);
1425
+ };
1426
+ for (const panel of screen.panels) {
1427
+ addPanelId(panel.id, panel.kind);
1428
+ if (panel.kind === "stat-group") {
1429
+ validateDashboardStatGroupPanel(featureName, screenId, panel, addPanelId);
1430
+ }
1431
+ else if (panel.kind === "custom") {
1432
+ validateDashboardCustomPanel(featureName, screenId, panel);
1433
+ }
1434
+ else if (panel.kind === "screen") {
1435
+ validateDashboardScreenPanel(featureName, screenId, panel, featureMap);
1436
+ }
1437
+ else {
1438
+ validateDashboardQueryPanel(featureName, screenId, panel);
1439
+ }
1440
+ }
1441
+ if (screen.filter !== undefined) {
1442
+ validateDashboardFilterDefinition(featureName, screenId, screen.filter);
1443
+ }
1444
+ }
1445
+ const EMBEDDABLE_SCREEN_TYPES = new Set([
1446
+ "projectionList",
1447
+ "actionForm",
1448
+ "secretMint",
1449
+ "configEdit",
1450
+ "secretsEdit",
1451
+ ]);
1452
+ function validateDashboardScreenPanel(featureName, screenId, panel, featureMap) {
1453
+ const context = `[Feature ${featureName}] Screen "${screenId}" (dashboard) screen-panel "${panel.id}"`;
1454
+ const targetQn = resolveScreenTargetQn(featureName, panel.screen);
1455
+ const [targetFeatureName = "", , targetShortId = ""] = targetQn.split(":");
1456
+ const target = featureMap.get(targetFeatureName)?.screens[targetShortId];
1457
+ if (target === undefined) {
1458
+ throw new Error(`${context} screen "${panel.screen}" does not resolve to a registered screen (checked "${targetQn}"). ` +
1459
+ `Use a same-feature short id or a cross-feature QN "<feature>:screen:<id>".`);
1460
+ }
1461
+ if (!EMBEDDABLE_SCREEN_TYPES.has(target.type)) {
1462
+ throw new Error(`${context} embeds "${targetQn}" of type "${target.type}", which can't be embedded — allowed: ` +
1463
+ `${[...EMBEDDABLE_SCREEN_TYPES].join(", ")}. Use a custom panel for app components.`);
1464
+ }
1465
+ const visibleWhen = panel.visibleWhen;
1466
+ if (visibleWhen !== undefined && (visibleWhen.query === "" || visibleWhen.field === "")) {
1467
+ throw new Error(`${context} visibleWhen needs a non-empty query and field.`);
1468
+ }
1469
+ }
1470
+ function validateDashboardStatGroupPanel(featureName, screenId, panel, addPanelId) {
1471
+ if (panel.stats.length === 0) {
1472
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) stat-group "${panel.id}" has an empty stats list.`);
1473
+ }
1474
+ for (const stat of panel.stats) {
1475
+ addPanelId(stat.id, "stat-group child");
1476
+ if (!stat.query || typeof stat.query !== "string") {
1477
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) stat-group "${panel.id}" child "${stat.id}" has empty or non-string query.`);
1478
+ }
1479
+ if (stat.valueField.length === 0) {
1480
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) stat-group "${panel.id}" child "${stat.id}" has empty valueField.`);
1481
+ }
1482
+ }
1483
+ }
1484
+ function validateDashboardCustomPanel(featureName, screenId, panel) {
1485
+ if (panel.component.react === undefined && panel.component.native === undefined) {
1486
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) custom-panel "${panel.id}" has no component — ` +
1487
+ `declare a react/native component marker.`);
1488
+ }
1489
+ }
1490
+ function validateDashboardQueryPanel(featureName, screenId, panel) {
1491
+ if (!panel.query || typeof panel.query !== "string") {
1492
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) panel "${panel.id}" has empty or non-string query.`);
1493
+ }
1494
+ if (panel.kind === "stat" && panel.valueField.length === 0) {
1495
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) stat-panel "${panel.id}" has empty valueField.`);
1496
+ }
1497
+ if (panel.kind === "list") {
1498
+ if (panel.columns.length === 0) {
1499
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) list-panel "${panel.id}" has an empty columns list.`);
1500
+ }
1501
+ for (const col of panel.columns) {
1502
+ validateColumnRendererForm(featureName, screenId, normalizeListColumn(col));
1503
+ }
1504
+ }
1505
+ }
1506
+ function validateDashboardFilterDefinition(featureName, screenId, filter) {
1507
+ if (filter.id.length === 0) {
1508
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) filter has an empty id.`);
1509
+ }
1510
+ if (filter.label.length === 0) {
1511
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) filter has an empty label.`);
1512
+ }
1513
+ const hasOptions = filter.options !== undefined;
1514
+ const hasOptionsQuery = filter.optionsQuery !== undefined;
1515
+ if (hasOptions === hasOptionsQuery) {
1516
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) filter must set exactly one of ` +
1517
+ `options/optionsQuery.`);
1518
+ }
1519
+ if (hasOptions && (filter.options?.length ?? 0) === 0) {
1520
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) filter.options is empty — ` +
1521
+ `declare at least one option or use optionsQuery instead.`);
1522
+ }
1523
+ if (hasOptionsQuery && filter.optionsQuery?.length === 0) {
1524
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" (dashboard) filter.optionsQuery is empty.`);
1525
+ }
1526
+ }
1527
+ // Form-check für ListColumn-Renderer in der PlatformComponent-Form
1528
+ // (`{ react: { __component: "Name" } }`). Der Server kennt die client-
1529
+ // seitige columnRenderers-Map nicht — also nur prüfen ob die Struktur
1530
+ // stimmt: wenn `react` als Object gesetzt ist, MUSS `__component` ein
1531
+ // nicht-leerer String sein. Ein client-seitig ausgelassener Key löst
1532
+ // nur eine Warnung aus, kein Boot-Fail.
1533
+ export function validateColumnRendererForm(featureName, screenId, column) {
1534
+ const renderer = column.renderer;
1535
+ // skip: nur die PlatformComponent-Form ({ react: { __component: "..." } })
1536
+ // wird strukturell validiert. Funktions-, String-QN- und null/undefined-
1537
+ // Renderer sind alle gültige andere Formen — kein Form-Fehler.
1538
+ if (renderer === null || typeof renderer !== "object")
1539
+ return;
1540
+ // @cast-boundary schema-walk — feature-config renderer-shape introspection
1541
+ const react = renderer.react;
1542
+ // skip: kein react-Branch → entweder native-only oder kein
1543
+ // PlatformComponent — beides außerhalb dieses Checks.
1544
+ if (react === undefined || react === null)
1545
+ return;
1546
+ if (typeof react !== "object") {
1547
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" column "${column.field}" has a renderer with ` +
1548
+ `a non-object \`react\` branch — expected \`{ react: { __component: "Name" } }\`.`);
1549
+ }
1550
+ // @cast-boundary schema-walk — feature-config react-branch introspection
1551
+ const component = react.__component;
1552
+ // skip: ohne __component-Schlüssel ist das keine String-Key-Form
1553
+ // (z.B. ein zukünftiger direkter Component-Ref); nicht unsere Domäne.
1554
+ if (component === undefined)
1555
+ return;
1556
+ if (typeof component !== "string" || component.length === 0) {
1557
+ throw new Error(`[Feature ${featureName}] Screen "${screenId}" column "${column.field}" has a renderer with ` +
1558
+ `\`react.__component\` = ${JSON.stringify(component)} — expected a non-empty string identifying ` +
1559
+ `a client-side columnRenderers entry.`);
1560
+ }
1561
+ }
1562
+ // Shared entity-target resolution for reference facets, refEntity columns
1563
+ // (projectionList/relatedList) and refEntity fields (projectionDetail).
1564
+ function assertRefTargetRegistered(prefix, subject, refTarget, currentFeatureName, featureMap) {
1565
+ const target = parseRefTarget(refTarget, currentFeatureName);
1566
+ const targetFeature = featureMap.get(target.featureName);
1567
+ if (targetFeature?.entities?.[target.entityName] === undefined) {
1568
+ throw new Error(`${prefix} ${subject} targets entity "${refTarget}", which does not resolve to a ` +
1569
+ `registered entity. Known entities in feature "${target.featureName}": ` +
1570
+ `${Object.keys(targetFeature?.entities ?? {})
1571
+ .sort()
1572
+ .join(", ") || "(none)"}.`);
1573
+ }
1574
+ }
1575
+ // Facets (fw#2224) — unlike filter, a field inventory IS available here: the
1576
+ // declared columns. A facet on a field with no column is almost always a
1577
+ // typo (the user never sees the field anywhere), so this is hard-checked
1578
+ // rather than just documented. Shared by projectionList and relatedList
1579
+ // (fw#2740) — `prefix` carries the caller's own screen/section message lead-in.
1580
+ //
1581
+ // `type: "reference"` is exempt from the same-name-column rule (fw akte-
1582
+ // bedienkonzept-2): it filters by an id field (e.g. "propertyId") but
1583
+ // displays a different, human-readable column (e.g. "propertyLabel") — a
1584
+ // column named after the filter field would almost never exist, and
1585
+ // requiring one anyway would force apps to add a column no design calls
1586
+ // for just to satisfy this check. Its own `entity` is mandatory on the type
1587
+ // (TS, not just this validator) and is resolved below — that explicit,
1588
+ // checked declaration is this facet type's field inventory, filling the
1589
+ // same "not just a typo" role the column-name check plays for select/
1590
+ // boolean facets. select/boolean facets keep the column requirement
1591
+ // unchanged: both filter and display the same field, so a facet with no
1592
+ // matching column is still almost always a typo.
1593
+ function validateListFacets(prefix, facets, columns, currentFeatureName, featureMap) {
1594
+ const columnFieldNames = new Set(columns.map((col) => normalizeListColumn(col).field));
1595
+ const seenFacetFields = new Set();
1596
+ for (const facet of facets) {
1597
+ if (seenFacetFields.has(facet.field)) {
1598
+ throw new Error(`${prefix} declares facet "${facet.field}" more than once.`);
1599
+ }
1600
+ seenFacetFields.add(facet.field);
1601
+ if (facet.type !== "reference" && !columnFieldNames.has(facet.field)) {
1602
+ throw new Error(`${prefix} facet references field "${facet.field}" which is not a declared column. ` +
1603
+ `Known columns: ${[...columnFieldNames].sort().join(", ")}`);
1604
+ }
1605
+ if (facet.type === "select" && facet.options.length === 0) {
1606
+ throw new Error(`${prefix} facet "${facet.field}" (type "select") has an empty options list — ` +
1607
+ `declare at least one option.`);
1608
+ }
1609
+ if (facet.type === "reference") {
1610
+ assertRefTargetRegistered(prefix, `facet "${facet.field}" (type "reference")`, facet.entity, currentFeatureName, featureMap);
1611
+ }
1612
+ }
1613
+ }
1614
+ export function findEntityFeature(entityName, featureMap) {
1615
+ for (const [name, feature] of featureMap) {
1616
+ if (feature.entities?.[entityName])
1617
+ return name;
1618
+ }
1619
+ return undefined;
1620
+ }
1621
+ export function buildUnknownFieldMessage(featureName, screenId, fieldName, entityName, knownFields) {
1622
+ const known = [...knownFields].sort().join(", ");
1623
+ return (`[Feature ${featureName}] Screen "${screenId}" references field "${fieldName}" ` +
1624
+ `which does not exist on entity "${entityName}" (known: ${known}).`);
1625
+ }
1626
+ export function collectScreenQns(features) {
1627
+ const set = new Set();
1628
+ for (const f of features) {
1629
+ for (const screenId of Object.keys(f.screens)) {
1630
+ set.add(qualifyEntityName(f.name, "screen", screenId));
1631
+ }
1632
+ }
1633
+ return set;
1634
+ }
1635
+ // Bare Screen-ids (ohne `<feature>:screen:`-Prefix) aus den qualifizierten
1636
+ // QNs — für die app-weite Auflösung von navigate-Targets (s. validateScreens).
1637
+ // Spiegelt den Runtime-Router, der bare ids feature-übergreifend matcht.
1638
+ export function screenShortIdsFrom(allScreenQns) {
1639
+ const marker = ":screen:";
1640
+ const set = new Set();
1641
+ for (const qn of allScreenQns) {
1642
+ const at = qn.indexOf(marker);
1643
+ if (at !== -1)
1644
+ set.add(qn.slice(at + marker.length));
1645
+ }
1646
+ return set;
1647
+ }
1648
+ // Short screen-id → every {featureName, screen} that registers it. The
1649
+ // runtime router (create-app.tsx) resolves a bare navigate-target short-id by
1650
+ // scanning ALL features and taking the first match — so two features
1651
+ // registering the same short-id is a silent routing footgun (whichever
1652
+ // feature comes first in the app's features[] array always wins, the other
1653
+ // is unreachable by that id) and a prerequisite for the entityId-check below
1654
+ // (which target screen it resolves to must be unambiguous).
1655
+ export function collectScreensByShortId(features) {
1656
+ const map = new Map();
1657
+ for (const f of features) {
1658
+ for (const [screenId, screen] of Object.entries(f.screens)) {
1659
+ const entries = map.get(screenId) ?? [];
1660
+ entries.push({ featureName: f.name, screen });
1661
+ map.set(screenId, entries);
1662
+ }
1663
+ }
1664
+ return map;
1665
+ }