@cosmicdrift/kumiko-framework 0.389.0 → 0.390.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/AGENTS.md +9 -4
  2. package/README.md +1 -1
  3. package/agents/examples/apex-surface-auth.md +2 -3
  4. package/agents/examples/api-worker-split.md +9 -2
  5. package/agents/examples/auth-claims.md +1 -1
  6. package/agents/examples/cross-feature-events.md +12 -12
  7. package/agents/examples/crypto-shredding-hr.md +2 -2
  8. package/agents/examples/encrypted-tenant-config.md +1 -1
  9. package/agents/examples/error-contract.md +12 -7
  10. package/agents/examples/event-sourcing.md +29 -29
  11. package/agents/examples/files-post-processing.md +10 -8
  12. package/agents/examples/inbound-mail-triage.md +1 -0
  13. package/agents/examples/lane-routing.md +2 -1
  14. package/agents/examples/legal-pages.md +2 -2
  15. package/agents/examples/lifecycle-hooks.md +3 -3
  16. package/agents/examples/managed-config.md +4 -4
  17. package/agents/examples/managed-pages.md +1 -1
  18. package/agents/examples/relations.md +19 -4
  19. package/agents/examples/search.md +4 -4
  20. package/agents/examples/secrets-demo.md +9 -6
  21. package/agents/examples/state-machine.md +2 -2
  22. package/agents/examples/tenant-settings.md +1 -1
  23. package/agents/examples/user-data-rights.md +3 -6
  24. package/agents/examples/workflow-engine.md +53 -47
  25. package/agents/examples.md +4 -4
  26. package/agents/features.md +1 -1
  27. package/dist/api/auth-middleware.js +1 -1
  28. package/dist/api/auth-routes-invite.js +2 -1
  29. package/dist/api/entity-read-access.d.ts +3 -1
  30. package/dist/api/export/export-columns.d.ts +3 -1
  31. package/dist/api/export/export-route.js +3 -2
  32. package/dist/api/export/export-screen.d.ts +2 -1
  33. package/dist/api/extra-route.d.ts +3 -1
  34. package/dist/api/index.d.ts +23 -27
  35. package/dist/api/index.js +13 -15
  36. package/dist/api/jwt.js +1 -1
  37. package/dist/api/observability-middleware.d.ts +1 -1
  38. package/dist/api/observability-middleware.js +2 -1
  39. package/dist/api/request-context-internals.d.ts +31 -0
  40. package/dist/api/request-context-internals.js +11 -0
  41. package/dist/api/request-context-scopes.d.ts +14 -0
  42. package/dist/api/request-context-scopes.js +69 -0
  43. package/dist/api/request-context.d.ts +1 -40
  44. package/dist/api/request-context.js +22 -51
  45. package/dist/api/request-id-middleware.d.ts +1 -1
  46. package/dist/api/route-registrars.d.ts +2 -1
  47. package/dist/api/route-registrars.js +1 -1
  48. package/dist/api/routes.js +7 -3
  49. package/dist/api/server-boot-checks.d.ts +1 -1
  50. package/dist/api/server-boot-checks.js +2 -2
  51. package/dist/api/server-event-dispatcher.d.ts +6 -1
  52. package/dist/api/server-event-dispatcher.js +3 -4
  53. package/dist/api/server-extra-routes.d.ts +1 -1
  54. package/dist/api/server-extra-routes.js +2 -1
  55. package/dist/api/server-middleware.js +3 -1
  56. package/dist/api/server-routes.d.ts +2 -1
  57. package/dist/api/server-wiring.js +6 -4
  58. package/dist/api/server.d.ts +2 -1
  59. package/dist/api/sse-route.d.ts +2 -1
  60. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  61. package/dist/api/tenant-scoped-secrets.js +13 -0
  62. package/dist/api/websocket-route.d.ts +1 -1
  63. package/dist/auth/index.d.ts +0 -1
  64. package/dist/auth/roles.d.ts +0 -5
  65. package/dist/compliance/duration-spec.d.ts +0 -1
  66. package/dist/compliance/duration-spec.js +0 -5
  67. package/dist/compliance/index.d.ts +4 -4
  68. package/dist/compliance/index.js +2 -2
  69. package/dist/compliance/profiles.d.ts +0 -15
  70. package/dist/compliance/profiles.js +0 -23
  71. package/dist/config/index.d.ts +10 -10
  72. package/dist/config/index.js +13 -1
  73. package/dist/config/internals.d.ts +9 -0
  74. package/dist/config/internals.js +1 -0
  75. package/dist/consumer-cli-internals.d.ts +4 -0
  76. package/dist/consumer-cli-internals.js +1 -0
  77. package/dist/consumer-cli.d.ts +1 -4
  78. package/dist/consumer-cli.js +5 -1
  79. package/dist/crypto/event-pii.js +1 -1
  80. package/dist/crypto/index.d.ts +8 -9
  81. package/dist/crypto/index.js +7 -8
  82. package/dist/crypto/pg-kms-adapter.js +6 -1
  83. package/dist/db/apply-entity-event.d.ts +1 -1
  84. package/dist/db/apply-entity-event.js +15 -47
  85. package/dist/db/blind-index-cleanup.js +91 -77
  86. package/dist/db/collect-table-metas.js +1 -1
  87. package/dist/db/compound-types.d.ts +1 -1
  88. package/dist/db/compound-types.js +0 -7
  89. package/dist/db/config-seed.d.ts +2 -1
  90. package/dist/db/config-seed.js +6 -1
  91. package/dist/db/connection.d.ts +3 -1
  92. package/dist/db/connection.js +15 -5
  93. package/dist/db/cross-tenant-reads.d.ts +1 -1
  94. package/dist/db/cross-tenant-reads.js +1 -1
  95. package/dist/db/dialect.d.ts +0 -5
  96. package/dist/db/dialect.js +0 -3
  97. package/dist/db/eagerload.d.ts +2 -1
  98. package/dist/db/entity-field-encryption.d.ts +1 -1
  99. package/dist/db/entity-table-meta.d.ts +1 -1
  100. package/dist/db/event-store-executor-context.d.ts +3 -1
  101. package/dist/db/event-store-executor-context.js +4 -3
  102. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  103. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  104. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  105. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  106. package/dist/db/event-store-executor-read.js +2 -2
  107. package/dist/db/event-store-executor-write-atomic.js +8 -7
  108. package/dist/db/event-store-executor-write-steps.d.ts +3 -2
  109. package/dist/db/event-store-executor-write.js +7 -4
  110. package/dist/db/event-store-executor.d.ts +1 -1
  111. package/dist/db/executor-managed-tables.d.ts +7 -1
  112. package/dist/db/executor-managed-tables.js +11 -2
  113. package/dist/db/index.d.ts +29 -28
  114. package/dist/db/index.js +22 -20
  115. package/dist/db/known-table-names.d.ts +6 -0
  116. package/dist/db/known-table-names.js +21 -0
  117. package/dist/db/list-aggregate-labels.d.ts +1 -1
  118. package/dist/db/located-timestamp.d.ts +1 -1
  119. package/dist/db/located-timestamp.js +0 -5
  120. package/dist/db/migrate-generator.d.ts +17 -1
  121. package/dist/db/migrate-generator.js +50 -20
  122. package/dist/db/migrate-primary-key.d.ts +12 -0
  123. package/dist/db/migrate-primary-key.js +45 -0
  124. package/dist/db/migrate-rls-diff.d.ts +20 -0
  125. package/dist/db/migrate-rls-diff.js +61 -0
  126. package/dist/db/migrate-runner.js +4 -0
  127. package/dist/db/money.d.ts +1 -1
  128. package/dist/db/money.js +1 -1
  129. package/dist/db/parent-ref-clause.d.ts +2 -1
  130. package/dist/db/pg-error.d.ts +2 -0
  131. package/dist/db/pg-error.js +11 -0
  132. package/dist/db/queries/ddl.d.ts +3 -0
  133. package/dist/db/queries/ddl.js +34 -1
  134. package/dist/db/queries/event-store.js +4 -2
  135. package/dist/db/queries/event-tenants.d.ts +2 -0
  136. package/dist/db/queries/event-tenants.js +17 -0
  137. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  138. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  139. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  140. package/dist/db/queries/rls-boot-catalog.js +39 -0
  141. package/dist/db/queries/rls-catalog.d.ts +6 -0
  142. package/dist/db/queries/rls-catalog.js +82 -0
  143. package/dist/db/queries/rls-scope.d.ts +3 -0
  144. package/dist/db/queries/rls-scope.js +17 -0
  145. package/dist/db/queries/rls-shape.d.ts +10 -0
  146. package/dist/db/queries/rls-shape.js +42 -0
  147. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  148. package/dist/db/queries/session-advisory-lock.js +23 -0
  149. package/dist/db/queries/shadow-swap.d.ts +1 -2
  150. package/dist/db/queries/shadow-swap.js +9 -25
  151. package/dist/db/queries/test-stack.d.ts +4 -1
  152. package/dist/db/queries/test-stack.js +83 -2
  153. package/dist/db/query.js +11 -7
  154. package/dist/db/reference-data.d.ts +1 -1
  155. package/dist/db/reference-data.js +6 -1
  156. package/dist/db/render-ddl.d.ts +6 -2
  157. package/dist/db/render-ddl.js +7 -7
  158. package/dist/db/render-rls-ddl.d.ts +35 -0
  159. package/dist/db/render-rls-ddl.js +127 -0
  160. package/dist/db/replay-migration-sql.d.ts +3 -1
  161. package/dist/db/replay-migration-sql.js +22 -5
  162. package/dist/db/replay-rls.d.ts +25 -0
  163. package/dist/db/replay-rls.js +156 -0
  164. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  165. package/dist/db/row-level-security-boot-check.js +85 -0
  166. package/dist/db/row-level-security-connection.d.ts +3 -0
  167. package/dist/db/row-level-security-connection.js +213 -0
  168. package/dist/db/row-level-security-scope.d.ts +33 -0
  169. package/dist/db/row-level-security-scope.js +127 -0
  170. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  171. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  172. package/dist/db/sql-identifier.d.ts +1 -0
  173. package/dist/db/sql-identifier.js +3 -0
  174. package/dist/db/table-builder.d.ts +2 -1
  175. package/dist/db/table-builder.js +1 -1
  176. package/dist/db/table-info.js +1 -1
  177. package/dist/db/table-push.d.ts +11 -2
  178. package/dist/db/table-push.js +15 -2
  179. package/dist/db/tenant-db-runner.d.ts +3 -1
  180. package/dist/db/tenant-db-runner.js +4 -3
  181. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  182. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  183. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  184. package/dist/db/tenant-db-statement-runner.js +48 -0
  185. package/dist/db/tenant-db.d.ts +17 -12
  186. package/dist/db/tenant-db.js +49 -120
  187. package/dist/db/tenant-id-filter.d.ts +3 -0
  188. package/dist/db/tenant-id-filter.js +30 -0
  189. package/dist/db/transaction-serialization.d.ts +6 -0
  190. package/dist/db/transaction-serialization.js +60 -0
  191. package/dist/derivatives/delete-stored-file.js +1 -1
  192. package/dist/derivatives/index.d.ts +2 -5
  193. package/dist/derivatives/index.js +2 -3
  194. package/dist/engine/access.d.ts +2 -1
  195. package/dist/engine/access.js +1 -1
  196. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  197. package/dist/engine/boot-validator/entity-handler.js +1 -1
  198. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
  199. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
  200. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
  201. package/dist/engine/boot-validator/nav.d.ts +3 -1
  202. package/dist/engine/boot-validator/nav.js +1 -1
  203. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  204. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  205. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  206. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  207. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  208. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  209. package/dist/engine/boot-validator/screens.d.ts +2 -1
  210. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  211. package/dist/engine/bridge-stub.d.ts +5 -2
  212. package/dist/engine/bridge-stub.js +39 -24
  213. package/dist/engine/config-helpers.d.ts +2 -2
  214. package/dist/engine/config-helpers.js +0 -9
  215. package/dist/engine/constants.d.ts +0 -10
  216. package/dist/engine/constants.js +0 -8
  217. package/dist/engine/create-app.js +1 -1
  218. package/dist/engine/define-feature.d.ts +2 -1
  219. package/dist/engine/define-feature.js +1 -2
  220. package/dist/engine/define-handler.d.ts +1 -1
  221. package/dist/engine/define-step.d.ts +0 -1
  222. package/dist/engine/define-step.js +0 -3
  223. package/dist/engine/embedded-derived.d.ts +1 -1
  224. package/dist/engine/entity-handlers.d.ts +2 -1
  225. package/dist/engine/entity-handlers.js +7 -7
  226. package/dist/engine/entity-list-runtime-options.js +3 -1
  227. package/dist/engine/entity-list-searchability.d.ts +2 -1
  228. package/dist/engine/event-def.d.ts +2 -1
  229. package/dist/engine/event-helpers.d.ts +3 -1
  230. package/dist/engine/event-helpers.js +3 -3
  231. package/dist/engine/extension-names.d.ts +2 -8
  232. package/dist/engine/extension-names.js +2 -2
  233. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  234. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  235. package/dist/engine/extensions/user-data.d.ts +0 -8
  236. package/dist/engine/factories.d.ts +2 -1
  237. package/dist/engine/feature-builder-state.d.ts +8 -1
  238. package/dist/engine/feature-changelog.d.ts +1 -1
  239. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  240. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  241. package/dist/engine/feature-manifest.js +1 -1
  242. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  243. package/dist/engine/feature-ui-extensions.js +6 -4
  244. package/dist/engine/field-access.d.ts +2 -1
  245. package/dist/engine/handler-field-references.d.ts +0 -4
  246. package/dist/engine/index.d.ts +57 -54
  247. package/dist/engine/index.js +22 -27
  248. package/dist/engine/instruction-fields.d.ts +1 -1
  249. package/dist/engine/personal-data-fields.d.ts +1 -1
  250. package/dist/engine/qualified-name.d.ts +0 -1
  251. package/dist/engine/read-claim.d.ts +2 -1
  252. package/dist/engine/registry-facade.js +0 -3
  253. package/dist/engine/registry-ingest.d.ts +2 -1
  254. package/dist/engine/registry-ingest.js +1 -2
  255. package/dist/engine/registry-state.d.ts +12 -2
  256. package/dist/engine/registry-state.js +2 -3
  257. package/dist/engine/registry-validate.d.ts +3 -1
  258. package/dist/engine/registry-validate.js +7 -7
  259. package/dist/engine/run-in.d.ts +1 -1
  260. package/dist/engine/run-in.js +0 -1
  261. package/dist/engine/schema-builder.d.ts +1 -1
  262. package/dist/engine/schema-builder.js +1 -1
  263. package/dist/engine/screen-filter-ops.d.ts +2 -1
  264. package/dist/engine/screen-filter-ops.js +0 -5
  265. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  266. package/dist/engine/soft-delete-cleanup.js +4 -4
  267. package/dist/engine/state-machine.js +2 -1
  268. package/dist/engine/steps/_read-source.js +1 -1
  269. package/dist/engine/steps/aggregate-append-event.js +2 -2
  270. package/dist/engine/steps/call-feature.js +2 -2
  271. package/dist/engine/steps/mail-send.js +1 -1
  272. package/dist/engine/steps/retry.js +1 -1
  273. package/dist/engine/steps/wait-for-event.js +1 -1
  274. package/dist/engine/steps/wait.js +1 -1
  275. package/dist/engine/steps/webhook-send.js +1 -1
  276. package/dist/engine/template-variables.d.ts +2 -1
  277. package/dist/engine/transfer-adjacency.d.ts +1 -1
  278. package/dist/engine/types/index.d.ts +8 -31
  279. package/dist/engine/types/index.js +2 -10
  280. package/dist/engine/validation.d.ts +2 -1
  281. package/dist/entrypoint/index.d.ts +7 -35
  282. package/dist/entrypoint/index.js +7 -1
  283. package/dist/entrypoint/internals.d.ts +40 -0
  284. package/dist/entrypoint/internals.js +1 -0
  285. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  286. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  287. package/dist/env/dry-run-internals.d.ts +10 -0
  288. package/dist/env/dry-run-internals.js +1 -0
  289. package/dist/env/dry-run.d.ts +1 -10
  290. package/dist/env/dry-run.js +2 -1
  291. package/dist/env/index.d.ts +1 -85
  292. package/dist/env/index.js +6 -50
  293. package/dist/env/internals.d.ts +87 -0
  294. package/dist/env/internals.js +53 -0
  295. package/dist/errors/classes.js +2 -2
  296. package/dist/errors/index.d.ts +5 -14
  297. package/dist/errors/index.js +4 -9
  298. package/dist/errors/member-resolution.js +1 -1
  299. package/dist/errors/reasons.d.ts +0 -1
  300. package/dist/errors/reasons.js +7 -7
  301. package/dist/errors/serialize.d.ts +0 -18
  302. package/dist/errors/serialize.js +0 -27
  303. package/dist/es-ops/index.d.ts +4 -4
  304. package/dist/es-ops/index.js +2 -2
  305. package/dist/es-ops/operations-schema.d.ts +1 -1
  306. package/dist/es-ops/types.d.ts +4 -5
  307. package/dist/event-store/admin-api-internals.d.ts +14 -0
  308. package/dist/event-store/admin-api-internals.js +1 -0
  309. package/dist/event-store/admin-api.d.ts +1 -14
  310. package/dist/event-store/admin-api.js +11 -6
  311. package/dist/event-store/archive.js +4 -2
  312. package/dist/event-store/errors.js +2 -2
  313. package/dist/event-store/event-store.js +41 -34
  314. package/dist/event-store/events-schema.js +4 -1
  315. package/dist/event-store/index.d.ts +11 -13
  316. package/dist/event-store/index.js +7 -9
  317. package/dist/event-store/rebuild-dead-letter.js +4 -2
  318. package/dist/event-store/snapshot.js +4 -3
  319. package/dist/event-store/stream-scope.d.ts +2 -0
  320. package/dist/event-store/stream-scope.js +6 -0
  321. package/dist/event-store/upcaster-dead-letter.js +4 -2
  322. package/dist/event-store/upcaster.d.ts +2 -1
  323. package/dist/files/action-form-upload.d.ts +2 -1
  324. package/dist/files/action-form-upload.js +1 -1
  325. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  326. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  327. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  328. package/dist/files/bind-pending-file-refs.js +2 -1
  329. package/dist/files/bind-referenced-files.write.js +1 -1
  330. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  331. package/dist/files/create-file-ref-from-bytes.js +3 -3
  332. package/dist/files/create-file-ref.d.ts +3 -2
  333. package/dist/files/create-file-ref.js +2 -2
  334. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  335. package/dist/files/dispose-removed-file-refs.js +1 -1
  336. package/dist/files/feature.js +2 -2
  337. package/dist/files/file-handle.js +1 -1
  338. package/dist/files/file-routes.d.ts +1 -1
  339. package/dist/files/file-routes.js +12 -2
  340. package/dist/files/index.d.ts +11 -13
  341. package/dist/files/index.js +5 -7
  342. package/dist/files/load-save-file-refs.d.ts +2 -1
  343. package/dist/files/load-save-file-refs.js +1 -1
  344. package/dist/files/provider-resolver.d.ts +5 -4
  345. package/dist/files/provider-resolver.js +4 -4
  346. package/dist/files/storage-tracking.js +4 -2
  347. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  348. package/dist/files/sweep-orphaned-uploads.js +1 -1
  349. package/dist/i18n/index.d.ts +2 -8
  350. package/dist/i18n/index.js +1 -1
  351. package/dist/i18n/internals.d.ts +7 -0
  352. package/dist/i18n/internals.js +1 -0
  353. package/dist/i18n/required-surface-keys.d.ts +4 -1
  354. package/dist/internal/row-level-security.d.ts +3 -0
  355. package/dist/internal/row-level-security.js +3 -0
  356. package/dist/internal/stack-support.d.ts +1 -1
  357. package/dist/internal/stack-support.js +1 -1
  358. package/dist/internal/testing.d.ts +1 -0
  359. package/dist/internal/testing.js +9 -5
  360. package/dist/jobs/index.d.ts +1 -1
  361. package/dist/jobs/job-append-event.d.ts +12 -0
  362. package/dist/jobs/job-append-event.js +30 -0
  363. package/dist/jobs/job-runner-context.d.ts +2 -2
  364. package/dist/jobs/job-runner-context.js +46 -16
  365. package/dist/jobs/job-runner-execution.d.ts +1 -1
  366. package/dist/jobs/job-runner-execution.js +6 -4
  367. package/dist/jobs/job-runner-gates.d.ts +1 -1
  368. package/dist/jobs/job-runner-gates.js +0 -1
  369. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  370. package/dist/jobs/job-runner-helpers.js +10 -1
  371. package/dist/jobs/job-runner-scope.d.ts +5 -2
  372. package/dist/jobs/job-runner-types.d.ts +2 -1
  373. package/dist/jobs/job-runner.js +19 -6
  374. package/dist/jobs/max-per-tenant.d.ts +1 -1
  375. package/dist/logging/index.d.ts +1 -2
  376. package/dist/logging/index.js +1 -1
  377. package/dist/logging/pino-logger.js +1 -1
  378. package/dist/logging/utils.d.ts +1 -0
  379. package/dist/logging/utils.js +6 -0
  380. package/dist/migrations/index.d.ts +3 -3
  381. package/dist/migrations/index.js +3 -3
  382. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  383. package/dist/migrations/pending-rebuilds.js +1 -1
  384. package/dist/migrations/pii-event-backfill.js +4 -1
  385. package/dist/observability/escape-hatch-report.d.ts +2 -1
  386. package/dist/observability/index.d.ts +7 -15
  387. package/dist/observability/index.js +4 -12
  388. package/dist/observability/metric-validator.js +1 -1
  389. package/dist/observability/metrics-handle.d.ts +0 -1
  390. package/dist/observability/metrics-handle.js +2 -15
  391. package/dist/observability/recording-tracer.d.ts +1 -2
  392. package/dist/observability/recording-tracer.js +0 -6
  393. package/dist/observability/sensitive-filter.d.ts +0 -2
  394. package/dist/observability/sensitive-filter.js +0 -29
  395. package/dist/pipeline/active-membership.d.ts +2 -1
  396. package/dist/pipeline/active-membership.js +6 -2
  397. package/dist/pipeline/append-event-core.d.ts +2 -1
  398. package/dist/pipeline/append-event-core.js +2 -2
  399. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  400. package/dist/pipeline/attach-outside-transaction.js +13 -0
  401. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  402. package/dist/pipeline/cascade-handler.d.ts +2 -1
  403. package/dist/pipeline/cascade-handler.js +3 -2
  404. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  405. package/dist/pipeline/config-accessor-factory.js +1 -1
  406. package/dist/pipeline/context-services.d.ts +56 -0
  407. package/dist/pipeline/context-services.js +73 -0
  408. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  409. package/dist/pipeline/dispatch-batch.js +31 -18
  410. package/dist/pipeline/dispatch-query.js +5 -4
  411. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  412. package/dist/pipeline/dispatch-scope.js +27 -0
  413. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  414. package/dist/pipeline/dispatch-shared.js +75 -198
  415. package/dist/pipeline/dispatch-stream.js +8 -4
  416. package/dist/pipeline/dispatch-write.d.ts +2 -1
  417. package/dist/pipeline/dispatch-write.js +10 -8
  418. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  419. package/dist/pipeline/dispatcher-utils.js +8 -2
  420. package/dist/pipeline/dispatcher.d.ts +3 -2
  421. package/dist/pipeline/dispatcher.js +4 -3
  422. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  423. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  424. package/dist/pipeline/event-dispatcher-delivery.js +4 -2
  425. package/dist/pipeline/event-dispatcher.d.ts +2 -2
  426. package/dist/pipeline/event-dispatcher.js +7 -3
  427. package/dist/pipeline/event-retention.js +59 -56
  428. package/dist/pipeline/handler-access-error.js +2 -1
  429. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  430. package/dist/pipeline/handler-context-auth.js +7 -4
  431. package/dist/pipeline/handler-context-config.d.ts +2 -5
  432. package/dist/pipeline/handler-context-config.js +2 -2
  433. package/dist/pipeline/handler-context-db.d.ts +32 -7
  434. package/dist/pipeline/handler-context-db.js +26 -17
  435. package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
  436. package/dist/pipeline/handler-context-dispatch.js +9 -8
  437. package/dist/pipeline/handler-context-events.d.ts +22 -36
  438. package/dist/pipeline/handler-context-events.js +36 -31
  439. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  440. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  441. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  442. package/dist/pipeline/handler-context-notify.js +1 -1
  443. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  444. package/dist/pipeline/handler-context-observability.js +7 -5
  445. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  446. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  447. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  448. package/dist/pipeline/handler-context-scope.js +18 -20
  449. package/dist/pipeline/index.d.ts +9 -21
  450. package/dist/pipeline/index.js +5 -7
  451. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  452. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  453. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  454. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  455. package/dist/pipeline/member-read-only-transaction.js +11 -3
  456. package/dist/pipeline/member-reader.d.ts +1 -1
  457. package/dist/pipeline/member-reader.js +2 -2
  458. package/dist/pipeline/msp-rebuild.js +5 -3
  459. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  460. package/dist/pipeline/notify-scope.d.ts +2 -1
  461. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  462. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  463. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  464. package/dist/pipeline/projection-rebuild.js +12 -5
  465. package/dist/pipeline/projection-state.d.ts +0 -6
  466. package/dist/pipeline/projection-state.js +0 -5
  467. package/dist/pipeline/projections-runner.d.ts +2 -1
  468. package/dist/pipeline/projections-runner.js +10 -6
  469. package/dist/pipeline/system-hooks.d.ts +3 -1
  470. package/dist/pipeline/system-hooks.js +6 -4
  471. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  472. package/dist/pipeline/system-identity-switch.js +51 -36
  473. package/dist/pipeline/typed-append-event.d.ts +2 -0
  474. package/dist/pipeline/typed-append-event.js +4 -0
  475. package/dist/pipeline/write-origin.js +2 -2
  476. package/dist/pipeline/write-result-masking.d.ts +1 -1
  477. package/dist/random/index.d.ts +1 -2
  478. package/dist/random/index.js +1 -2
  479. package/dist/rate-limit/bucket.d.ts +2 -1
  480. package/dist/rate-limit/middleware.js +2 -1
  481. package/dist/redis/index.d.ts +3 -4
  482. package/dist/redis/index.js +2 -2
  483. package/dist/schema-cli/apply-command.js +5 -2
  484. package/dist/schema-cli/baseline-command.js +7 -2
  485. package/dist/schema-cli/generate-command.js +7 -9
  486. package/dist/schema-cli/shared.d.ts +4 -0
  487. package/dist/schema-cli/shared.js +21 -2
  488. package/dist/schema-cli/status-command.js +8 -2
  489. package/dist/schema-cli/validate-command.js +52 -4
  490. package/dist/schema-cli.d.ts +0 -1
  491. package/dist/search/configure-tenant-index.d.ts +1 -3
  492. package/dist/search/configure-tenant-index.js +0 -4
  493. package/dist/search/index.d.ts +1 -4
  494. package/dist/search/index.js +0 -2
  495. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  496. package/dist/search/meilisearch-adapter-internals.js +9 -0
  497. package/dist/search/meilisearch-adapter.d.ts +1 -8
  498. package/dist/search/meilisearch-adapter.js +6 -7
  499. package/dist/search/meilisearch-peer.d.ts +2 -0
  500. package/dist/search/meilisearch-peer.js +5 -0
  501. package/dist/search/reindex-entity.js +93 -87
  502. package/dist/secrets/index.d.ts +3 -4
  503. package/dist/secrets/index.js +2 -3
  504. package/dist/seeding/index.d.ts +2 -2
  505. package/dist/seeding/index.js +1 -2
  506. package/dist/time/index.d.ts +2 -2
  507. package/dist/time/index.js +1 -1
  508. package/dist/time/tz-context.d.ts +0 -5
  509. package/dist/time/tz-context.js +0 -9
  510. package/dist/ui-types/index.d.ts +8 -11
  511. package/dist/ui-types/index.js +3 -3
  512. package/dist/upgrade-changelog.d.ts +3 -2
  513. package/dist/upgrade-changelog.js +12 -8
  514. package/dist/upgrade-cli-internals.d.ts +8 -0
  515. package/dist/upgrade-cli-internals.js +63 -0
  516. package/dist/upgrade-cli.d.ts +1 -9
  517. package/dist/upgrade-cli.js +10 -64
  518. package/dist/utils/import-optional-peer.d.ts +6 -0
  519. package/dist/utils/import-optional-peer.js +19 -0
  520. package/dist/utils/index.d.ts +1 -4
  521. package/dist/utils/index.js +1 -4
  522. package/package.json +22 -18
  523. package/src/changes.json +206 -0
  524. package/dist/crypto/request-kms-cache.d.ts +0 -8
  525. package/dist/crypto/request-kms-cache.js +0 -21
  526. package/dist/engine/codemod/index.d.ts +0 -2
  527. package/dist/engine/codemod/index.js +0 -1
  528. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  529. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  530. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  531. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  532. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  533. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  534. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  535. package/dist/engine/feature-ast/extractors/events.js +0 -275
  536. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  537. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  538. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  539. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  540. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  541. package/dist/engine/feature-ast/extractors/index.js +0 -13
  542. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  543. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  544. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  545. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  546. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  547. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  548. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
  549. package/dist/engine/feature-ast/extractors/round1.js +0 -87
  550. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  551. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  552. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  553. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  554. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  555. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  556. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  557. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  558. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  559. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  560. package/dist/engine/feature-ast/index.d.ts +0 -16
  561. package/dist/engine/feature-ast/index.js +0 -10
  562. package/dist/engine/feature-ast/parse.d.ts +0 -31
  563. package/dist/engine/feature-ast/parse.js +0 -485
  564. package/dist/engine/feature-ast/patch.d.ts +0 -212
  565. package/dist/engine/feature-ast/patch.js +0 -611
  566. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  567. package/dist/engine/feature-ast/patcher.js +0 -281
  568. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
  569. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
  570. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  571. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
  572. package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
  573. package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
  574. package/dist/engine/feature-ast/patterns.d.ts +0 -322
  575. package/dist/engine/feature-ast/patterns.js +0 -107
  576. package/dist/engine/feature-ast/render.d.ts +0 -47
  577. package/dist/engine/feature-ast/render.js +0 -666
  578. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  579. package/dist/engine/feature-ast/source-location.js +0 -27
  580. package/dist/engine/pattern-library/index.d.ts +0 -2
  581. package/dist/engine/pattern-library/index.js +0 -3
  582. package/dist/engine/pattern-library/library.d.ts +0 -14
  583. package/dist/engine/pattern-library/library.js +0 -94
  584. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  585. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  586. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  587. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  588. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  589. package/dist/engine/pattern-library/shared-fields.js +0 -88
  590. package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
  591. package/dist/engine/pattern-library/static-schemas.js +0 -487
  592. package/dist/engine/pattern-library/types.d.ts +0 -158
  593. package/dist/engine/pattern-library/types.js +0 -36
  594. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  595. package/dist/engine/resolve-config-or-param.js +0 -76
  596. package/src/scripts/codemod/README.md +0 -187
  597. package/src/scripts/codemod/codemod-support.ts +0 -334
  598. package/src/scripts/codemod/collect-source-files.ts +0 -48
  599. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  600. package/src/scripts/codemod/db-factory.ts +0 -810
  601. package/src/scripts/codemod/feature-factory.ts +0 -429
  602. package/src/scripts/codemod/feature-layout.ts +0 -424
  603. package/src/scripts/codemod/import-extensions.ts +0 -118
  604. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  605. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  606. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  607. package/src/scripts/codemod/object-form.ts +0 -746
  608. package/src/scripts/codemod/package-merge.ts +0 -299
  609. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  610. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  611. package/src/scripts/codemod/s3-imports.ts +0 -236
  612. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  613. package/src/scripts/codemod/testing-injection.ts +0 -215
  614. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  615. package/src/scripts/codemod/testing-move.ts +0 -542
  616. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -2,11 +2,20 @@ import { AccessDeniedError, InternalError } from "../errors/index.js";
2
2
  import { asEntityTableMeta, tableNameOf } from "./table-introspection.js";
3
3
  const executorManagedTables = new WeakSet();
4
4
  const executorManagedWriteRunners = new WeakSet();
5
- export function markExecutorManagedTable(table) {
5
+ const entitySourceByTable = new WeakMap();
6
+ // Projection tables (r.projection) have no entity source; only entity tables can take a created event.
7
+ export function markExecutorManagedTable(table, entitySource) {
6
8
  executorManagedTables.add(table);
7
9
  const meta = asEntityTableMeta(table);
8
10
  if (meta !== undefined)
9
11
  executorManagedTables.add(meta);
12
+ if (entitySource !== undefined)
13
+ entitySourceByTable.set(table, entitySource);
14
+ }
15
+ export function executorManagedEntitySourceOf(table) {
16
+ if (typeof table !== "object" || table === null)
17
+ return undefined;
18
+ return entitySourceByTable.get(table);
10
19
  }
11
20
  export function isExecutorManagedTable(table) {
12
21
  if (typeof table !== "object" || table === null)
@@ -34,7 +43,7 @@ export function executorManagedWriteDenied(runner, table, operation) {
34
43
  const tableName = tableNameOf(table);
35
44
  return new AccessDeniedError({
36
45
  message: `${operation}(${tableName}): "${tableName}" is fed by events (r.entity / r.projection). ` +
37
- "Write it through the entity executor (r.crud, ctx.write, createEventStoreExecutor) or inside a " +
46
+ "Write it through the entity executor (r.crud, ctx.dispatch.write, createEventStoreExecutor) or inside a " +
38
47
  "projection apply; a direct write drifts from the event stream and a rebuild drops or resurrects the row.",
39
48
  });
40
49
  }
@@ -3,44 +3,45 @@ export { applyEntityEvent } from "./apply-entity-event.ts";
3
3
  export { assertExistsIn } from "./assert-exists-in.ts";
4
4
  export { nullBlindIndexesForSubject, recordEventsOwnedExclusivelyByTenant, recordRowExistsInTenant, recordRowOwningTenantId, subjectRowExistsInTenant, } from "./blind-index-cleanup.ts";
5
5
  export { collectTableMetas } from "./collect-table-metas.ts";
6
- export { flattenCompoundTypes, rehydrateCompoundTypes } from "./compound-types.ts";
7
6
  export { seedConfigValues } from "./config-seed.ts";
8
- export type { CreateDbConnectionOptions, DbConnection, DbConnectionHandle, DbConnectionOptions, DbRow, DbRunner, DbTx, } from "./connection.ts";
7
+ export type { DbConnection, DbRow, DbRunner, DbTx, } from "./connection.ts";
9
8
  export { createDbConnection, DEFAULT_OUTSIDE_TRANSACTION_POOL_MAX, dbConnectionOptionsFromEnv, outsideTransactionPoolOptionsFromEnv, serverTimeoutOptionsFromEnv, } from "./connection.ts";
10
- export type { CursorQueryOptions, CursorResult, DecodedKeysetCursor } from "./cursor.ts";
11
9
  export { decodeCursor, decodeKeysetCursor, encodeCursor, encodeKeysetCursor } from "./cursor.ts";
12
- export type { SchemaTable, SelectQuery, TableColumns } from "./dialect.ts";
13
- export { bigint, bigserial, boolean, extractTableName, index, instant, instantToDriver, integer, jsonb, moneyAmount, numeric, primaryKey, serial, sql, table, text, timestamp, uniqueIndex, uuid, } from "./dialect.ts";
10
+ export type { SchemaTable } from "./dialect.ts";
11
+ export { boolean, extractTableName, index, instant, integer, jsonb, primaryKey, serial, sql, table, text, timestamp, uniqueIndex, uuid, } from "./dialect.ts";
14
12
  export { instantToTimestamptzParam } from "./driver-value-preparation.ts";
15
- export type { EagerLoadEntityResolver, EagerLoadViewer, EagerloadedRow } from "./eagerload.ts";
16
- export { collectReferenceFields, enrichRowWithReferences, enrichWithReferences, } from "./eagerload.ts";
17
- export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, encryptEntityFieldValues, } from "./entity-field-encryption.ts";
13
+ export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, } from "./entity-field-encryption.ts";
18
14
  export { entityTableFromRegistry } from "./entity-table-from-registry.ts";
19
- export type { BuildEntityTableMetaOptions, ColumnMeta, CompositePrimaryKeyMeta, EntityTableMeta, IndexMeta, PgType, UnmanagedTableInput, } from "./entity-table-meta.ts";
15
+ export type { ColumnMeta, EntityTableMeta, } from "./entity-table-meta.ts";
20
16
  export { defineUnmanagedTable, deriveEntityTableMeta, } from "./entity-table-meta.ts";
21
- export type { EntityLifecycleVerb, EventStoreExecutor, EventStoreExecutorOptions, LockGuardOption, WritePurpose, } from "./event-store-executor.ts";
17
+ export type { EventStoreExecutor, WritePurpose, } from "./event-store-executor.ts";
22
18
  export { createEventStoreExecutor, entityEventName, WritePurposes, } from "./event-store-executor.ts";
23
- export { enumerateFeatureTableSources, type FeatureTableSource, } from "./feature-table-sources.ts";
24
- export { answerListAggregate, labelListAggregateGroups } from "./list-aggregate-labels.ts";
25
- export { flattenLocatedTimestamp, type LocatedTimestampRead, rehydrateLocatedTimestamp, } from "./located-timestamp.ts";
26
- export { assertUniqueTableNames, assertValidMigrationName, diffSnapshots, type GenerateMigrationInput, type GenerateMigrationOutput, generateMigration, loadSnapshotJson, renderMigrationSql, type SchemaDiff, type Snapshot, snapshotFromMetas, writeSnapshotJson, } from "./migrate-generator.ts";
27
- export { type AppliedMigration, type ApplyResult, type BaselineResult, baselineMigrations, fetchAppliedMigrations, loadMigrationsFromDir, type Migration, MigrationChecksumMismatchError, readMigrationSqlTexts, runMigrations, runMigrationsFromDir, splitSqlStatements, } from "./migrate-runner.ts";
28
- export { flattenMoney, type MoneyRead, moneyPayloadToMinorUnits, rehydrateMoney } from "./money.ts";
29
- export { constraintOf, extractPgError, isTableAlreadyExists, isUndefinedTable, isUniqueViolation, type PgErrorInfo, } from "./pg-error.ts";
19
+ export { enumerateFeatureTableSources } from "./feature-table-sources.ts";
20
+ export { type KnownTables, knownTablesOf } from "./known-table-names.ts";
21
+ export { answerListAggregate } from "./list-aggregate-labels.ts";
22
+ export { generateMigration, loadSnapshotJson, writeSnapshotJson, } from "./migrate-generator.ts";
23
+ export { runMigrationsFromDir } from "./migrate-runner.ts";
24
+ export { type MoneyRead, rehydrateMoney } from "./money.ts";
25
+ export { extractPgError, isUndefinedTable, isUniqueViolation, } from "./pg-error.ts";
30
26
  export { acquireNamespacedAdvisoryLock } from "./queries/advisory-lock.ts";
31
27
  export { readDatabaseNow } from "./queries/database-now.ts";
28
+ export { listEventTenantIds } from "./queries/event-tenants.ts";
32
29
  export { toPostgresArrayLiteral } from "./queries/postgres-array-literal.ts";
33
- export { executeRawQuery, executeRawQueryRead } from "./queries/raw-sql.ts";
34
- export type { DeleteManyBatchedOptions, DeleteManyBatchedResult, IncrementCounterOptions, InnerJoinRow, InnerJoinSpec, InsertOnConflictDoNothingOptions, JoinColumnPair, JsonTextMatch, SelectOptions, UpsertOnConflictOptions, WhereObject, WhereOperator, WhereValue, } from "./query.ts";
35
- export { aggregateWhere, asEntityTableMeta, asRawClient, countWhere, deleteMany, deleteManyBatched, fetchOne, incrementCounter, insertMany, insertOnConflictDoNothing, insertOne, requireEntityTableMeta, runInSavepoint, runInSavepointIfSupported, runnerCanBeginTransaction, selectInnerJoin, selectMany, transaction, unsafeReadRetrying, updateMany, upsertByPk, upsertOnConflict, } from "./query.ts";
36
- export { readRebuildMarker, rebuildTablesFromDiff, writeRebuildMarker, } from "./rebuild-marker.ts";
30
+ export { executeRawQuery } from "./queries/raw-sql.ts";
31
+ export { withSessionAdvisoryLock } from "./queries/session-advisory-lock.ts";
32
+ export type { JsonTextMatch, SelectOptions, WhereObject, } from "./query.ts";
33
+ export { aggregateWhere, asEntityTableMeta, asRawClient, countWhere, deleteMany, deleteManyBatched, fetchOne, incrementCounter, insertMany, insertOnConflictDoNothing, insertOne, requireEntityTableMeta, runInSavepointIfSupported, runnerCanBeginTransaction, selectInnerJoin, selectMany, transaction, unsafeReadRetrying, updateMany, upsertByPk, upsertOnConflict, } from "./query.ts";
37
34
  export { seedReferenceData } from "./reference-data.ts";
38
- export { renderTableDdl, renderTablesDdl } from "./render-ddl.ts";
39
- export { diffReplayAgainstSnapshot, type ReplayedSchema, type ReplayedTable, type ReplayMismatch, replayMigrationsDir, } from "./replay-migration-sql.ts";
40
- export { findCommentedDropTables, isRetiredFrameworkTable, type RetiredFrameworkTable, retiredFrameworkTables, } from "./retired-framework-tables.ts";
35
+ export { renderTablesDdl } from "./render-ddl.ts";
36
+ export { ROW_LEVEL_SECURITY_MODES, type RowLevelSecurityMode } from "./render-rls-ddl.ts";
37
+ export { assertRowLevelSecurityBootState, assertRowLevelSecurityTableState, } from "./row-level-security-boot-check.ts";
38
+ export { rowLevelSecurityModeOf } from "./row-level-security-connection.ts";
39
+ export type { RowLevelSecurityScope } from "./row-level-security-scope.ts";
40
+ export { assertNoActiveRowLevelSecurityScope } from "./row-level-security-scope.ts";
41
41
  export { tableExists } from "./schema-inspection.ts";
42
- export { withoutStatementTimeout } from "./statement-timeout.ts";
43
- export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, type EntityRow, type EntityTable, type ExecutorManagedRunner, type ExecutorManagedWriteCapability, physicalColumnName, toSnakeCase, toTableName, type Writable, type WritableSchemaTable, type WritableTable, } from "./table-builder.ts";
42
+ export { scopeTenantDbToTenant } from "./scope-tenant-db-to-tenant.ts";
43
+ export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, type EntityTable, type ExecutorManagedRunner, physicalColumnName, type WritableSchemaTable, type WritableTable, } from "./table-builder.ts";
44
44
  export { extractTableInfo, type TableInfo } from "./table-info.ts";
45
- export type { CreateTenantDbOptions, ExecutorManagedTenantDb, OutsideTransactionContext, TenantDb, TenantDbGrants, TenantDbMode, UncheckedSystemDb, } from "./tenant-db.ts";
46
- export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb, hasOutsideTransactionDb, requireOutsideTransactionDb, runInOwnTransaction, SYSTEM_SCOPE_CHECK_BRAND, scopeTenantDbToTenant, } from "./tenant-db.ts";
45
+ export type { ExecutorManagedTenantDb, TenantDb, UncheckedSystemDb, } from "./tenant-db.ts";
46
+ export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb, } from "./tenant-db.ts";
47
+ export { runInOwnTransaction } from "./tenant-db-scoped-rebind.ts";
package/dist/db/index.js CHANGED
@@ -3,36 +3,38 @@ export { applyEntityEvent } from "./apply-entity-event.js";
3
3
  export { assertExistsIn } from "./assert-exists-in.js";
4
4
  export { nullBlindIndexesForSubject, recordEventsOwnedExclusivelyByTenant, recordRowExistsInTenant, recordRowOwningTenantId, subjectRowExistsInTenant, } from "./blind-index-cleanup.js";
5
5
  export { collectTableMetas } from "./collect-table-metas.js";
6
- export { flattenCompoundTypes, rehydrateCompoundTypes } from "./compound-types.js";
7
6
  export { seedConfigValues } from "./config-seed.js";
8
7
  export { createDbConnection, DEFAULT_OUTSIDE_TRANSACTION_POOL_MAX, dbConnectionOptionsFromEnv, outsideTransactionPoolOptionsFromEnv, serverTimeoutOptionsFromEnv, } from "./connection.js";
9
8
  export { decodeCursor, decodeKeysetCursor, encodeCursor, encodeKeysetCursor } from "./cursor.js";
10
- export { bigint, bigserial, boolean, extractTableName, index, instant, instantToDriver, integer, jsonb, moneyAmount, numeric, primaryKey, serial, sql, table, text, timestamp, uniqueIndex, uuid, } from "./dialect.js";
9
+ export { boolean, extractTableName, index, instant, integer, jsonb, primaryKey, serial, sql, table, text, timestamp, uniqueIndex, uuid, } from "./dialect.js";
11
10
  export { instantToTimestamptzParam } from "./driver-value-preparation.js";
12
- export { collectReferenceFields, enrichRowWithReferences, enrichWithReferences, } from "./eagerload.js";
13
- export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, encryptEntityFieldValues, } from "./entity-field-encryption.js";
11
+ export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, } from "./entity-field-encryption.js";
14
12
  export { entityTableFromRegistry } from "./entity-table-from-registry.js";
15
13
  export { defineUnmanagedTable, deriveEntityTableMeta, } from "./entity-table-meta.js";
16
14
  export { createEventStoreExecutor, entityEventName, WritePurposes, } from "./event-store-executor.js";
17
- export { enumerateFeatureTableSources, } from "./feature-table-sources.js";
18
- export { answerListAggregate, labelListAggregateGroups } from "./list-aggregate-labels.js";
19
- export { flattenLocatedTimestamp, rehydrateLocatedTimestamp, } from "./located-timestamp.js";
20
- export { assertUniqueTableNames, assertValidMigrationName, diffSnapshots, generateMigration, loadSnapshotJson, renderMigrationSql, snapshotFromMetas, writeSnapshotJson, } from "./migrate-generator.js";
21
- export { baselineMigrations, fetchAppliedMigrations, loadMigrationsFromDir, MigrationChecksumMismatchError, readMigrationSqlTexts, runMigrations, runMigrationsFromDir, splitSqlStatements, } from "./migrate-runner.js";
22
- export { flattenMoney, moneyPayloadToMinorUnits, rehydrateMoney } from "./money.js";
23
- export { constraintOf, extractPgError, isTableAlreadyExists, isUndefinedTable, isUniqueViolation, } from "./pg-error.js";
15
+ export { enumerateFeatureTableSources } from "./feature-table-sources.js";
16
+ export { knownTablesOf } from "./known-table-names.js";
17
+ export { answerListAggregate } from "./list-aggregate-labels.js";
18
+ export { generateMigration, loadSnapshotJson, writeSnapshotJson, } from "./migrate-generator.js";
19
+ export { runMigrationsFromDir } from "./migrate-runner.js";
20
+ export { rehydrateMoney } from "./money.js";
21
+ export { extractPgError, isUndefinedTable, isUniqueViolation, } from "./pg-error.js";
24
22
  export { acquireNamespacedAdvisoryLock } from "./queries/advisory-lock.js";
25
23
  export { readDatabaseNow } from "./queries/database-now.js";
24
+ export { listEventTenantIds } from "./queries/event-tenants.js";
26
25
  export { toPostgresArrayLiteral } from "./queries/postgres-array-literal.js";
27
- export { executeRawQuery, executeRawQueryRead } from "./queries/raw-sql.js";
28
- export { aggregateWhere, asEntityTableMeta, asRawClient, countWhere, deleteMany, deleteManyBatched, fetchOne, incrementCounter, insertMany, insertOnConflictDoNothing, insertOne, requireEntityTableMeta, runInSavepoint, runInSavepointIfSupported, runnerCanBeginTransaction, selectInnerJoin, selectMany, transaction, unsafeReadRetrying, updateMany, upsertByPk, upsertOnConflict, } from "./query.js";
29
- export { readRebuildMarker, rebuildTablesFromDiff, writeRebuildMarker, } from "./rebuild-marker.js";
26
+ export { executeRawQuery } from "./queries/raw-sql.js";
27
+ export { withSessionAdvisoryLock } from "./queries/session-advisory-lock.js";
28
+ export { aggregateWhere, asEntityTableMeta, asRawClient, countWhere, deleteMany, deleteManyBatched, fetchOne, incrementCounter, insertMany, insertOnConflictDoNothing, insertOne, requireEntityTableMeta, runInSavepointIfSupported, runnerCanBeginTransaction, selectInnerJoin, selectMany, transaction, unsafeReadRetrying, updateMany, upsertByPk, upsertOnConflict, } from "./query.js";
30
29
  export { seedReferenceData } from "./reference-data.js";
31
- export { renderTableDdl, renderTablesDdl } from "./render-ddl.js";
32
- export { diffReplayAgainstSnapshot, replayMigrationsDir, } from "./replay-migration-sql.js";
33
- export { findCommentedDropTables, isRetiredFrameworkTable, retiredFrameworkTables, } from "./retired-framework-tables.js";
30
+ export { renderTablesDdl } from "./render-ddl.js";
31
+ export { ROW_LEVEL_SECURITY_MODES } from "./render-rls-ddl.js";
32
+ export { assertRowLevelSecurityBootState, assertRowLevelSecurityTableState, } from "./row-level-security-boot-check.js";
33
+ export { rowLevelSecurityModeOf } from "./row-level-security-connection.js";
34
+ export { assertNoActiveRowLevelSecurityScope } from "./row-level-security-scope.js";
34
35
  export { tableExists } from "./schema-inspection.js";
35
- export { withoutStatementTimeout } from "./statement-timeout.js";
36
- export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, physicalColumnName, toSnakeCase, toTableName, } from "./table-builder.js";
36
+ export { scopeTenantDbToTenant } from "./scope-tenant-db-to-tenant.js";
37
+ export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, physicalColumnName, } from "./table-builder.js";
37
38
  export { extractTableInfo } from "./table-info.js";
38
- export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb, hasOutsideTransactionDb, requireOutsideTransactionDb, runInOwnTransaction, SYSTEM_SCOPE_CHECK_BRAND, scopeTenantDbToTenant, } from "./tenant-db.js";
39
+ export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb, } from "./tenant-db.js";
40
+ export { runInOwnTransaction } from "./tenant-db-scoped-rebind.js";
@@ -0,0 +1,6 @@
1
+ import type { FeatureDefinition } from "../engine/types/index.ts";
2
+ export declare function isLiveFrameworkTable(tableName: string): boolean;
3
+ export type KnownTables = {
4
+ readonly has: (tableName: string) => boolean;
5
+ };
6
+ export declare function knownTablesOf(features: readonly FeatureDefinition[]): KnownTables;
@@ -0,0 +1,21 @@
1
+ import { collectTableMetas } from "./collect-table-metas.js";
2
+ import { isRetiredFrameworkTable } from "./retired-framework-tables.js";
3
+ // The prefix only picks which boot-check message a table gets; both groups still throw, and a second
4
+ // framework table list would be one more source to maintain.
5
+ // Event store and pipeline state (kumiko_events, kumiko_projections, ...) are created by framework
6
+ // boot, not by `schema generate`, so no feature declares them.
7
+ const FRAMEWORK_TABLE_PREFIX = "kumiko_";
8
+ export function isLiveFrameworkTable(tableName) {
9
+ return tableName.startsWith(FRAMEWORK_TABLE_PREFIX) && !isRetiredFrameworkTable(tableName);
10
+ }
11
+ // Same source as `kumiko schema generate`: a tenant table that is not listed here has no owner left.
12
+ export function knownTablesOf(features) {
13
+ // Lazy: a healthy boot finds no unprotected table and never asks, so it skips collecting metas.
14
+ let names;
15
+ return {
16
+ has: (tableName) => {
17
+ names ??= new Set(collectTableMetas(features).map((meta) => meta.tableName));
18
+ return names.has(tableName) || isLiveFrameworkTable(tableName);
19
+ },
20
+ };
21
+ }
@@ -1,5 +1,5 @@
1
+ import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
1
2
  import type { ListAggregateResult } from "@cosmicdrift/kumiko-types/list-aggregate-types";
2
- import type { EntityDefinition } from "../engine/types/index.ts";
3
3
  import type { EagerLoadEntityResolver, EagerLoadViewer } from "./eagerload.ts";
4
4
  import type { EventStoreExecutor } from "./event-store-executor.ts";
5
5
  import type { TenantDb } from "./tenant-db.ts";
@@ -1,4 +1,4 @@
1
- import type { EntityDefinition } from "../engine/types/index.ts";
1
+ import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
2
2
  /**
3
3
  * API → DB: flatten locatedTimestamp fields into two flat columns.
4
4
  *
@@ -1,8 +1,3 @@
1
- // Automatically converts locatedTimestamp fields in the DB layer.
2
- //
3
- // Contract (see also db/money.ts — the same compound-type pattern):
4
- // API form: { at, tz } | { utc, tz }
5
- // DB form: <name>Utc TIMESTAMPTZ + <name>Tz TEXT
6
1
  // Read form: { at, tz, utc }
7
2
  //
8
3
  // Default `at` view on read: local to the pickup location (`utc` projected into
@@ -1,10 +1,14 @@
1
1
  import type { ColumnMeta, EntityTableMeta, IndexMeta } from "./entity-table-meta.ts";
2
+ import { type PrimaryKeyChange } from "./migrate-primary-key.ts";
3
+ import { type RowLevelSecurityChange } from "./migrate-rls-diff.ts";
4
+ import { type RowLevelSecurityMode, type TableRowLevelSecurity } from "./render-rls-ddl.ts";
2
5
  import { type RetiredFrameworkTable } from "./retired-framework-tables.ts";
3
6
  declare const SNAPSHOT_VERSION: 1;
4
7
  export type Snapshot = {
5
8
  readonly version: typeof SNAPSHOT_VERSION;
6
9
  readonly generatedAt?: string;
7
10
  readonly tables: readonly EntityTableMeta[];
11
+ readonly rowLevelSecurity?: Readonly<Record<string, TableRowLevelSecurity>>;
8
12
  };
9
13
  export type ColumnChange = {
10
14
  readonly name: string;
@@ -48,6 +52,7 @@ export type TableDiff = {
48
52
  readonly newIndexes: readonly IndexMeta[];
49
53
  readonly droppedIndexes: readonly string[];
50
54
  readonly changedIndexes: readonly IndexChange[];
55
+ readonly primaryKeyChanged?: PrimaryKeyChange;
51
56
  readonly nextMeta: EntityTableMeta;
52
57
  };
53
58
  export type SchemaDiff = {
@@ -55,15 +60,24 @@ export type SchemaDiff = {
55
60
  readonly droppedTables: readonly string[];
56
61
  readonly changedTables: readonly TableDiff[];
57
62
  };
58
- export declare function snapshotFromMetas(metas: readonly EntityTableMeta[]): Snapshot;
63
+ export declare function snapshotFromMetas(metas: readonly EntityTableMeta[], options?: {
64
+ readonly rowLevelSecurity?: RowLevelSecurityMode;
65
+ }): Snapshot;
59
66
  export declare function loadSnapshotJson(path: string): Snapshot | null;
60
67
  export declare function writeSnapshotJson(path: string, snapshot: Snapshot): void;
61
68
  export declare function diffSnapshots(prev: Snapshot | null, next: Snapshot): SchemaDiff;
62
69
  export declare function managedChangeRequiresRecreate(td: TableDiff): boolean;
70
+ export declare function isRecreatedManagedTable(td: TableDiff): boolean;
71
+ export declare function hasNoSchemaChanges(input: {
72
+ readonly diff: SchemaDiff;
73
+ readonly retiredDrops: readonly RetiredFrameworkTable[];
74
+ readonly rowLevelSecurityChanges: readonly RowLevelSecurityChange[];
75
+ }): boolean;
63
76
  export declare function renderMigrationSql(diff: SchemaDiff, options: {
64
77
  readonly name: string;
65
78
  readonly sequenceNumber: number;
66
79
  readonly retiredDrops?: readonly RetiredFrameworkTable[];
80
+ readonly rowLevelSecurityChanges?: readonly RowLevelSecurityChange[];
67
81
  }): string;
68
82
  export type GenerateMigrationInput = {
69
83
  readonly metas: readonly EntityTableMeta[];
@@ -73,6 +87,7 @@ export type GenerateMigrationInput = {
73
87
  /** Raw SQL of all earlier migrations, in order — lets the generator decide
74
88
  * whether a retired framework table still needs its executable drop. */
75
89
  readonly priorMigrationsSql?: readonly string[];
90
+ readonly rowLevelSecurity?: RowLevelSecurityMode;
76
91
  };
77
92
  export type GenerateMigrationOutput = {
78
93
  readonly filename: string;
@@ -80,6 +95,7 @@ export type GenerateMigrationOutput = {
80
95
  readonly snapshot: Snapshot;
81
96
  readonly diff: SchemaDiff;
82
97
  readonly retiredDrops: readonly RetiredFrameworkTable[];
98
+ readonly rowLevelSecurityChanges: readonly RowLevelSecurityChange[];
83
99
  };
84
100
  export declare const MIGRATION_NAME_RE: RegExp;
85
101
  export declare function assertValidMigrationName(name: string): void;
@@ -15,17 +15,23 @@
15
15
  // never drop automatically.
16
16
  import { readFileSync, writeFileSync } from "node:fs";
17
17
  import { errorCodeOf, isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
18
- import { compareByCodepoint } from "../utils/index.js";
18
+ import { compareByCodepoint } from "../utils/compare.js";
19
+ import { diffPrimaryKey, renderPrimaryKeyChange, } from "./migrate-primary-key.js";
20
+ import { diffRowLevelSecurity, renderRowLevelSecurityChanges, } from "./migrate-rls-diff.js";
19
21
  import { renderIndex, renderTableDdl } from "./render-ddl.js";
22
+ import { isTableRowLevelSecurityRecord, rowLevelSecurityByTable, } from "./render-rls-ddl.js";
20
23
  import { findRetiredTableDrops } from "./retired-framework-tables.js";
24
+ import { quoteIdent } from "./sql-identifier.js";
21
25
  const SNAPSHOT_VERSION = 1;
22
26
  function isSnapshot(value) {
23
27
  return (isPlainObject(value) &&
24
28
  value["version"] === SNAPSHOT_VERSION &&
25
29
  (value["generatedAt"] === undefined || typeof value["generatedAt"] === "string") &&
26
- Array.isArray(value["tables"]));
30
+ Array.isArray(value["tables"]) &&
31
+ (value["rowLevelSecurity"] === undefined ||
32
+ isTableRowLevelSecurityRecord(value["rowLevelSecurity"])));
27
33
  }
28
- export function snapshotFromMetas(metas) {
34
+ export function snapshotFromMetas(metas, options = {}) {
29
35
  // Stable ordering by tableName so the snapshot.json diff in PRs is
30
36
  // meaningful (table-add isn't a noisy re-sort of everything). Codepoint, not
31
37
  // localeCompare: the snapshot is serialized to byte-exact JSON and the table
@@ -36,6 +42,9 @@ export function snapshotFromMetas(metas) {
36
42
  version: SNAPSHOT_VERSION,
37
43
  generatedAt: new Date().toISOString(),
38
44
  tables: sorted,
45
+ ...(options.rowLevelSecurity === "on" && {
46
+ rowLevelSecurity: rowLevelSecurityByTable(sorted),
47
+ }),
39
48
  };
40
49
  }
41
50
  export function loadSnapshotJson(path) {
@@ -135,18 +144,20 @@ function compareIndexes(name, prevIndex, nextIndex) {
135
144
  };
136
145
  }
137
146
  function hasNoTableChanges(diff) {
138
- return [
139
- diff.newColumns,
140
- diff.droppedColumns,
141
- diff.changedColumns,
142
- diff.newIndexes,
143
- diff.droppedIndexes,
144
- diff.changedIndexes,
145
- ].every((list) => list.length === 0);
147
+ return (diff.primaryKeyChanged === undefined &&
148
+ [
149
+ diff.newColumns,
150
+ diff.droppedColumns,
151
+ diff.changedColumns,
152
+ diff.newIndexes,
153
+ diff.droppedIndexes,
154
+ diff.changedIndexes,
155
+ ].every((list) => list.length === 0));
146
156
  }
147
157
  function diffOneTable(prev, next) {
148
158
  const columns = diffByName(columnsByName(prev), columnsByName(next), compareColumns);
149
159
  const indexes = diffByName(indexesByName(prev), indexesByName(next), compareIndexes);
160
+ const primaryKeyChanged = diffPrimaryKey(prev, next);
150
161
  const diff = {
151
162
  tableName: prev.tableName,
152
163
  newColumns: columns.added,
@@ -155,6 +166,7 @@ function diffOneTable(prev, next) {
155
166
  newIndexes: indexes.added,
156
167
  droppedIndexes: indexes.dropped,
157
168
  changedIndexes: indexes.changed,
169
+ ...(primaryKeyChanged && { primaryKeyChanged }),
158
170
  nextMeta: next,
159
171
  };
160
172
  return hasNoTableChanges(diff) ? null : diff;
@@ -225,15 +237,26 @@ function describeRecreateReasons(td) {
225
237
  if (typeChanged.length > 0) {
226
238
  reasons.push(`column type change: ${typeChanged.join(", ")}`);
227
239
  }
240
+ if (td.primaryKeyChanged) {
241
+ const { from, to } = td.primaryKeyChanged;
242
+ reasons.push(`primary-key change: ${from.columns.join(", ")} → ${to.columns.join(", ")}`);
243
+ }
228
244
  return reasons;
229
245
  }
230
246
  export function managedChangeRequiresRecreate(td) {
231
247
  return describeRecreateReasons(td).length > 0;
232
248
  }
233
- // --- SQL-Render ---------------------------------------------------------
234
- function quoteIdent(name) {
235
- return `"${name.replace(/"/g, '""')}"`;
249
+ export function isRecreatedManagedTable(td) {
250
+ return td.nextMeta.source === "managed" && managedChangeRequiresRecreate(td);
251
+ }
252
+ export function hasNoSchemaChanges(input) {
253
+ return (input.diff.newTables.length === 0 &&
254
+ input.diff.changedTables.length === 0 &&
255
+ input.diff.droppedTables.length === 0 &&
256
+ input.retiredDrops.length === 0 &&
257
+ input.rowLevelSecurityChanges.length === 0);
236
258
  }
259
+ // --- SQL-Render ---------------------------------------------------------
237
260
  function renderColumnInline(col) {
238
261
  const parts = [quoteIdent(col.name), col.pgType];
239
262
  if (col.defaultSql !== undefined)
@@ -347,7 +370,7 @@ export function renderMigrationSql(diff, options) {
347
370
  lines.push("-- === Changed tables ===");
348
371
  for (const td of diff.changedTables) {
349
372
  lines.push(`-- ${td.tableName}`);
350
- if (td.nextMeta.source === "managed" && managedChangeRequiresRecreate(td)) {
373
+ if (isRecreatedManagedTable(td)) {
351
374
  lines.push("-- managed projection — recreated + rebuilt from events (see .rebuild.json)");
352
375
  lines.push(`-- WARN: destructive change (${describeRecreateReasons(td).join("; ")}) forces DROP+CREATE + full event replay.`);
353
376
  lines.push("-- Consider an Expand/Contract split across two releases to avoid the rebuild — see docs/guides/expand-contract-managed-projections.md.");
@@ -363,6 +386,7 @@ export function renderMigrationSql(diff, options) {
363
386
  for (const stmt of renderColumnChange(td.tableName, ch))
364
387
  lines.push(stmt);
365
388
  }
389
+ lines.push(...renderPrimaryKeyChange(td.tableName, td.primaryKeyChanged));
366
390
  for (const idx of td.newIndexes) {
367
391
  lines.push(renderIndex(td.tableName, idx));
368
392
  }
@@ -390,6 +414,7 @@ export function renderMigrationSql(diff, options) {
390
414
  lines.push("");
391
415
  }
392
416
  }
417
+ lines.push(...renderRowLevelSecurityChanges(options.rowLevelSecurityChanges));
393
418
  if (diff.droppedTables.length > 0) {
394
419
  lines.push("-- === Dropped tables ===");
395
420
  for (const name of diff.droppedTables) {
@@ -405,10 +430,11 @@ export function renderMigrationSql(diff, options) {
405
430
  }
406
431
  lines.push("");
407
432
  }
408
- if (diff.newTables.length === 0 &&
409
- diff.changedTables.length === 0 &&
410
- diff.droppedTables.length === 0 &&
411
- retiredDrops.length === 0) {
433
+ if (hasNoSchemaChanges({
434
+ diff,
435
+ retiredDrops,
436
+ rowLevelSecurityChanges: options.rowLevelSecurityChanges ?? [],
437
+ })) {
412
438
  lines.push("-- No schema changes detected.");
413
439
  }
414
440
  return lines.join("\n");
@@ -436,13 +462,16 @@ export function assertUniqueTableNames(metas) {
436
462
  export function generateMigration(input) {
437
463
  assertValidMigrationName(input.name);
438
464
  assertUniqueTableNames(input.metas);
439
- const nextSnapshot = snapshotFromMetas(input.metas);
465
+ const nextSnapshot = snapshotFromMetas(input.metas, { rowLevelSecurity: input.rowLevelSecurity });
440
466
  const diff = diffSnapshots(input.prevSnapshot, nextSnapshot);
467
+ const recreatedTables = new Set(diff.changedTables.filter(isRecreatedManagedTable).map((td) => td.tableName));
468
+ const rowLevelSecurityChanges = diffRowLevelSecurity(input.prevSnapshot, nextSnapshot, recreatedTables);
441
469
  const retiredDrops = findRetiredTableDrops(input.priorMigrationsSql ?? [], nextSnapshot);
442
470
  const sqlContent = renderMigrationSql(diff, {
443
471
  name: input.name,
444
472
  sequenceNumber: input.sequenceNumber,
445
473
  retiredDrops,
474
+ rowLevelSecurityChanges,
446
475
  });
447
476
  const seq = input.sequenceNumber.toString().padStart(4, "0");
448
477
  return {
@@ -451,5 +480,6 @@ export function generateMigration(input) {
451
480
  snapshot: nextSnapshot,
452
481
  diff,
453
482
  retiredDrops,
483
+ rowLevelSecurityChanges,
454
484
  };
455
485
  }
@@ -0,0 +1,12 @@
1
+ import type { EntityTableMeta } from "./entity-table-meta.ts";
2
+ export type PrimaryKey = {
3
+ readonly columns: readonly string[];
4
+ readonly constraintName: string;
5
+ };
6
+ export type PrimaryKeyChange = {
7
+ readonly from: PrimaryKey;
8
+ readonly to: PrimaryKey;
9
+ };
10
+ export declare function primaryKeyOf(meta: EntityTableMeta): PrimaryKey;
11
+ export declare function diffPrimaryKey(prev: EntityTableMeta, next: EntityTableMeta): PrimaryKeyChange | undefined;
12
+ export declare function renderPrimaryKeyChange(tableName: string, change: PrimaryKeyChange | undefined): readonly string[];
@@ -0,0 +1,45 @@
1
+ import { quoteIdent } from "./sql-identifier.js";
2
+ // Postgres names an implicit PK `<table>_pkey` and, past 63 bytes, shortens the table part, never the suffix.
3
+ const MAX_IDENTIFIER_LENGTH = 63;
4
+ const IMPLICIT_PRIMARY_KEY_SUFFIX = "_pkey";
5
+ // Older snapshots may omit `primaryKey: false` and `compositePrimaryKey`, so only a truthy flag counts.
6
+ export function primaryKeyOf(meta) {
7
+ if (meta.compositePrimaryKey !== undefined) {
8
+ return {
9
+ columns: meta.compositePrimaryKey.columns,
10
+ constraintName: meta.compositePrimaryKey.name,
11
+ };
12
+ }
13
+ return {
14
+ columns: meta.columns.filter((col) => col.primaryKey === true).map((col) => col.name),
15
+ constraintName: `${meta.tableName.slice(0, MAX_IDENTIFIER_LENGTH - IMPLICIT_PRIMARY_KEY_SUFFIX.length)}${IMPLICIT_PRIMARY_KEY_SUFFIX}`,
16
+ };
17
+ }
18
+ function primaryKeysEqual(a, b) {
19
+ return (a.constraintName === b.constraintName &&
20
+ a.columns.length === b.columns.length &&
21
+ a.columns.every((col, i) => col === b.columns[i]));
22
+ }
23
+ export function diffPrimaryKey(prev, next) {
24
+ const from = primaryKeyOf(prev);
25
+ const to = primaryKeyOf(next);
26
+ return primaryKeysEqual(from, to) ? undefined : { from, to };
27
+ }
28
+ // Executable, not commented: the change loses no data, and it fails loudly when existing rows are not unique on the new key.
29
+ export function renderPrimaryKeyChange(tableName, change) {
30
+ if (change === undefined)
31
+ return [];
32
+ const table = quoteIdent(tableName);
33
+ const { from, to } = change;
34
+ const lines = [
35
+ `-- WARN: primary-key change (${from.columns.join(", ")} → ${to.columns.join(", ")}). Existing rows must be unique on the new key.`,
36
+ ];
37
+ if (from.columns.length > 0) {
38
+ lines.push(`ALTER TABLE ${table} DROP CONSTRAINT IF EXISTS ${quoteIdent(from.constraintName)};`);
39
+ }
40
+ if (to.columns.length > 0) {
41
+ const columns = to.columns.map(quoteIdent).join(", ");
42
+ lines.push(`ALTER TABLE ${table} ADD CONSTRAINT ${quoteIdent(to.constraintName)} PRIMARY KEY (${columns});`);
43
+ }
44
+ return lines;
45
+ }
@@ -0,0 +1,20 @@
1
+ import { type TableRowLevelSecurity } from "./render-rls-ddl.ts";
2
+ export type RowLevelSecurityChange = {
3
+ readonly kind: "enable";
4
+ readonly tableName: string;
5
+ readonly next: TableRowLevelSecurity;
6
+ readonly previous?: TableRowLevelSecurity;
7
+ } | {
8
+ readonly kind: "disable";
9
+ readonly tableName: string;
10
+ readonly previous: TableRowLevelSecurity;
11
+ };
12
+ type RowLevelSecuritySnapshotView = {
13
+ readonly tables: readonly {
14
+ readonly tableName: string;
15
+ }[];
16
+ readonly rowLevelSecurity?: Readonly<Record<string, TableRowLevelSecurity>>;
17
+ };
18
+ export declare function diffRowLevelSecurity(previous: RowLevelSecuritySnapshotView | null, next: RowLevelSecuritySnapshotView, recreatedTables: ReadonlySet<string>): RowLevelSecurityChange[];
19
+ export declare function renderRowLevelSecurityChanges(changes?: readonly RowLevelSecurityChange[]): string[];
20
+ export {};
@@ -0,0 +1,61 @@
1
+ // Row level security part of the migration generator: diffs the per-table policy
2
+ // specs between two snapshots and renders the resulting DDL section.
3
+ import { isSameTableRowLevelSecurity, renderDisableRowLevelSecurity, renderEnableRowLevelSecurity, } from "./render-rls-ddl.js";
4
+ import { quoteIdent } from "./sql-identifier.js";
5
+ function specOf(view, tableName) {
6
+ const byTable = view?.rowLevelSecurity;
7
+ if (byTable === undefined || !Object.hasOwn(byTable, tableName))
8
+ return undefined;
9
+ return byTable[tableName];
10
+ }
11
+ function changeForTable(tableName, previous, next, recreatedTables) {
12
+ const nextSpec = specOf(next, tableName);
13
+ const previousSpec = specOf(previous, tableName);
14
+ const recreated = recreatedTables.has(tableName);
15
+ if (nextSpec !== undefined) {
16
+ const unchanged = previousSpec !== undefined &&
17
+ !recreated &&
18
+ isSameTableRowLevelSecurity(previousSpec, nextSpec);
19
+ if (unchanged)
20
+ return undefined;
21
+ return {
22
+ kind: "enable",
23
+ tableName,
24
+ next: nextSpec,
25
+ ...(previousSpec !== undefined && !recreated && { previous: previousSpec }),
26
+ };
27
+ }
28
+ const existedBefore = previous?.tables.some((table) => table.tableName === tableName) === true;
29
+ if (previousSpec !== undefined && existedBefore && !recreated) {
30
+ return { kind: "disable", tableName, previous: previousSpec };
31
+ }
32
+ return undefined;
33
+ }
34
+ export function diffRowLevelSecurity(previous, next, recreatedTables) {
35
+ const changes = [];
36
+ for (const { tableName } of next.tables) {
37
+ const change = changeForTable(tableName, previous, next, recreatedTables);
38
+ if (change !== undefined)
39
+ changes.push(change);
40
+ }
41
+ return changes;
42
+ }
43
+ function renderChange(change) {
44
+ const tableSql = quoteIdent(change.tableName);
45
+ if (change.kind === "enable") {
46
+ return renderEnableRowLevelSecurity(tableSql, change.next, change.previous);
47
+ }
48
+ return [
49
+ "-- WARN: row level security switched off, tenant isolation falls back to the application layer",
50
+ ...renderDisableRowLevelSecurity(tableSql, change.previous),
51
+ ];
52
+ }
53
+ export function renderRowLevelSecurityChanges(changes = []) {
54
+ if (changes.length === 0)
55
+ return [];
56
+ return [
57
+ "-- === Row level security ===",
58
+ ...changes.flatMap((change) => [`-- ${change.tableName}`, ...renderChange(change)]),
59
+ "",
60
+ ];
61
+ }
@@ -17,7 +17,9 @@ import { createHash } from "node:crypto";
17
17
  import { existsSync, readdirSync, readFileSync } from "node:fs";
18
18
  import { join } from "node:path";
19
19
  import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
20
+ import { applyRowLevelSecurityScope } from "./queries/rls-scope.js";
20
21
  import { asRawClient, hasBegin, } from "./query.js";
22
+ import { SYSTEM_ROW_LEVEL_SECURITY_SCOPE } from "./row-level-security-scope.js";
21
23
  // Advisory-lock key (random 32-bit integer, stable). Prevents two Pods
22
24
  // booting at the same time from both running migrate apply (the second
23
25
  // blocks until the first finishes).
@@ -261,6 +263,8 @@ export async function runMigrations(db, migrations) {
261
263
  // apply remains stuck in the books.
262
264
  await conn.unsafe("BEGIN");
263
265
  try {
266
+ // Transaction-local, so the next migration's BEGIN starts clean; migrations rewrite every tenant's rows.
267
+ await applyRowLevelSecurityScope(conn, SYSTEM_ROW_LEVEL_SECURITY_SCOPE);
264
268
  for (const stmt of m.statements) {
265
269
  await conn.unsafe(stmt);
266
270
  }
@@ -1,5 +1,5 @@
1
+ import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
1
2
  import { toMinorUnits } from "../engine/minor-units.ts";
2
- import type { EntityDefinition } from "../engine/types/index.ts";
3
3
  export { toMinorUnits };
4
4
  export declare function moneyPayloadToMinorUnits(raw: unknown): number | undefined;
5
5
  export declare function flattenMoney(payload: Record<string, unknown>, entity: EntityDefinition): Record<string, unknown>;