@cosmicdrift/kumiko-framework 0.388.0 → 0.390.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (711) hide show
  1. package/AGENTS.md +12 -4
  2. package/README.md +1 -1
  3. package/agents/examples/apex-surface-auth.md +2 -3
  4. package/agents/examples/api-worker-split.md +9 -2
  5. package/agents/examples/auth-claims.md +1 -1
  6. package/agents/examples/cross-feature-events.md +12 -12
  7. package/agents/examples/crypto-shredding-hr.md +2 -2
  8. package/agents/examples/encrypted-tenant-config.md +1 -1
  9. package/agents/examples/error-contract.md +12 -7
  10. package/agents/examples/event-sourcing.md +29 -29
  11. package/agents/examples/files-post-processing.md +10 -8
  12. package/agents/examples/golden-path.md +13 -1
  13. package/agents/examples/inbound-mail-triage.md +1 -0
  14. package/agents/examples/lane-routing.md +2 -1
  15. package/agents/examples/legal-pages.md +2 -2
  16. package/agents/examples/lifecycle-hooks.md +55 -2
  17. package/agents/examples/list-table-options.md +466 -0
  18. package/agents/examples/managed-config.md +4 -4
  19. package/agents/examples/managed-pages.md +1 -1
  20. package/agents/examples/pdf-audit-export.md +4 -2
  21. package/agents/examples/relations.md +19 -4
  22. package/agents/examples/search.md +4 -4
  23. package/agents/examples/secrets-demo.md +9 -6
  24. package/agents/examples/state-machine.md +5 -4
  25. package/agents/examples/tenant-isolation.md +73 -1
  26. package/agents/examples/tenant-settings.md +1 -1
  27. package/agents/examples/user-data-rights.md +3 -6
  28. package/agents/examples/workflow-engine.md +53 -47
  29. package/agents/examples.md +5 -4
  30. package/agents/features.md +1 -1
  31. package/agents/widgets.md +1 -0
  32. package/dist/api/api-constants.d.ts +1 -0
  33. package/dist/api/api-constants.js +2 -0
  34. package/dist/api/auth-middleware.js +1 -1
  35. package/dist/api/auth-routes-invite.js +2 -1
  36. package/dist/api/auth-routes-shared.d.ts +2 -0
  37. package/dist/api/auth-routes-shared.js +5 -0
  38. package/dist/api/client-error-route.js +2 -3
  39. package/dist/api/entity-read-access.d.ts +4 -1
  40. package/dist/api/entity-read-access.js +14 -0
  41. package/dist/api/export/export-cells-reference.d.ts +9 -0
  42. package/dist/api/export/export-cells-reference.js +21 -0
  43. package/dist/api/export/export-cells.d.ts +11 -0
  44. package/dist/api/export/export-cells.js +136 -0
  45. package/dist/api/export/export-ciphertext-guard.d.ts +2 -0
  46. package/dist/api/export/export-ciphertext-guard.js +27 -0
  47. package/dist/api/export/export-columns.d.ts +31 -0
  48. package/dist/api/export/export-columns.js +85 -0
  49. package/dist/api/export/export-errors.d.ts +4 -0
  50. package/dist/api/export/export-errors.js +14 -0
  51. package/dist/api/export/export-route.d.ts +4 -0
  52. package/dist/api/export/export-route.js +75 -0
  53. package/dist/api/export/export-rows.d.ts +13 -0
  54. package/dist/api/export/export-rows.js +62 -0
  55. package/dist/api/export/export-screen.d.ts +13 -0
  56. package/dist/api/export/export-screen.js +47 -0
  57. package/dist/api/export/export-xlsx-writer.d.ts +4 -0
  58. package/dist/api/export/export-xlsx-writer.js +21 -0
  59. package/dist/api/extra-route.d.ts +7 -1
  60. package/dist/api/index.d.ts +23 -27
  61. package/dist/api/index.js +13 -15
  62. package/dist/api/jwt.js +1 -1
  63. package/dist/api/observability-middleware.d.ts +1 -1
  64. package/dist/api/observability-middleware.js +2 -1
  65. package/dist/api/pii-leak-guard.d.ts +3 -0
  66. package/dist/api/pii-leak-guard.js +3 -2
  67. package/dist/api/request-context-internals.d.ts +31 -0
  68. package/dist/api/request-context-internals.js +11 -0
  69. package/dist/api/request-context-scopes.d.ts +14 -0
  70. package/dist/api/request-context-scopes.js +69 -0
  71. package/dist/api/request-context.d.ts +1 -40
  72. package/dist/api/request-context.js +22 -51
  73. package/dist/api/request-id-middleware.d.ts +1 -1
  74. package/dist/api/route-registrars.d.ts +2 -1
  75. package/dist/api/route-registrars.js +1 -1
  76. package/dist/api/routes.d.ts +16 -0
  77. package/dist/api/routes.js +9 -5
  78. package/dist/api/server-boot-checks.d.ts +1 -1
  79. package/dist/api/server-boot-checks.js +2 -2
  80. package/dist/api/server-event-dispatcher.d.ts +6 -1
  81. package/dist/api/server-event-dispatcher.js +3 -4
  82. package/dist/api/server-extra-routes.d.ts +1 -1
  83. package/dist/api/server-extra-routes.js +5 -1
  84. package/dist/api/server-middleware.js +3 -1
  85. package/dist/api/server-routes.d.ts +3 -2
  86. package/dist/api/server-routes.js +8 -2
  87. package/dist/api/server-wiring.js +8 -4
  88. package/dist/api/server.d.ts +2 -1
  89. package/dist/api/sse-route.d.ts +3 -1
  90. package/dist/api/sse-route.js +11 -1
  91. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  92. package/dist/api/tenant-scoped-secrets.js +13 -0
  93. package/dist/api/websocket-route.d.ts +1 -1
  94. package/dist/auth/index.d.ts +0 -1
  95. package/dist/auth/roles.d.ts +0 -5
  96. package/dist/compliance/duration-spec.d.ts +0 -1
  97. package/dist/compliance/duration-spec.js +0 -5
  98. package/dist/compliance/index.d.ts +4 -4
  99. package/dist/compliance/index.js +2 -2
  100. package/dist/compliance/profiles.d.ts +0 -15
  101. package/dist/compliance/profiles.js +0 -23
  102. package/dist/config/index.d.ts +11 -9
  103. package/dist/config/index.js +13 -1
  104. package/dist/config/internals.d.ts +9 -0
  105. package/dist/config/internals.js +1 -0
  106. package/dist/consumer-cli-internals.d.ts +4 -0
  107. package/dist/consumer-cli-internals.js +1 -0
  108. package/dist/consumer-cli.d.ts +1 -4
  109. package/dist/consumer-cli.js +5 -1
  110. package/dist/crypto/event-pii.js +1 -1
  111. package/dist/crypto/index.d.ts +8 -9
  112. package/dist/crypto/index.js +7 -8
  113. package/dist/crypto/pg-kms-adapter.d.ts +1 -0
  114. package/dist/crypto/pg-kms-adapter.js +17 -18
  115. package/dist/db/aggregate-sql.d.ts +2 -0
  116. package/dist/db/aggregate-sql.js +10 -0
  117. package/dist/db/apply-entity-event.d.ts +1 -1
  118. package/dist/db/apply-entity-event.js +15 -47
  119. package/dist/db/blind-index-cleanup.js +91 -77
  120. package/dist/db/closed-connection.js +12 -19
  121. package/dist/db/collect-table-metas.js +1 -1
  122. package/dist/db/compound-types.d.ts +1 -1
  123. package/dist/db/compound-types.js +0 -7
  124. package/dist/db/config-seed.d.ts +2 -1
  125. package/dist/db/config-seed.js +6 -1
  126. package/dist/db/connection.d.ts +7 -6
  127. package/dist/db/connection.js +43 -24
  128. package/dist/db/cross-tenant-reads.d.ts +1 -1
  129. package/dist/db/cross-tenant-reads.js +1 -1
  130. package/dist/db/dialect.d.ts +0 -5
  131. package/dist/db/dialect.js +0 -3
  132. package/dist/db/driver-row-coercion.js +4 -4
  133. package/dist/db/driver-value-preparation.js +6 -4
  134. package/dist/db/eagerload.d.ts +2 -1
  135. package/dist/db/entity-field-encryption.d.ts +1 -1
  136. package/dist/db/entity-table-meta.d.ts +1 -1
  137. package/dist/db/event-store-executor-context.d.ts +3 -1
  138. package/dist/db/event-store-executor-context.js +4 -3
  139. package/dist/db/event-store-executor-read-aggregate-currencies.d.ts +17 -0
  140. package/dist/db/event-store-executor-read-aggregate-currencies.js +40 -0
  141. package/dist/db/event-store-executor-read-aggregate.js +36 -5
  142. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  143. package/dist/db/event-store-executor-read-filter.js +6 -3
  144. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  145. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  146. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  147. package/dist/db/event-store-executor-read.js +2 -2
  148. package/dist/db/event-store-executor-write-atomic.d.ts +4 -0
  149. package/dist/db/event-store-executor-write-atomic.js +42 -0
  150. package/dist/db/event-store-executor-write-steps.d.ts +3 -5
  151. package/dist/db/event-store-executor-write-steps.js +0 -5
  152. package/dist/db/event-store-executor-write.js +22 -19
  153. package/dist/db/event-store-executor.d.ts +1 -1
  154. package/dist/db/event-store-executor.js +2 -1
  155. package/dist/db/executor-managed-tables.d.ts +7 -1
  156. package/dist/db/executor-managed-tables.js +12 -3
  157. package/dist/db/index.d.ts +29 -28
  158. package/dist/db/index.js +22 -20
  159. package/dist/db/known-table-names.d.ts +6 -0
  160. package/dist/db/known-table-names.js +21 -0
  161. package/dist/db/list-aggregate-labels.d.ts +1 -1
  162. package/dist/db/located-timestamp.d.ts +1 -1
  163. package/dist/db/located-timestamp.js +0 -5
  164. package/dist/db/migrate-generator.d.ts +17 -1
  165. package/dist/db/migrate-generator.js +50 -20
  166. package/dist/db/migrate-primary-key.d.ts +12 -0
  167. package/dist/db/migrate-primary-key.js +45 -0
  168. package/dist/db/migrate-rls-diff.d.ts +20 -0
  169. package/dist/db/migrate-rls-diff.js +61 -0
  170. package/dist/db/migrate-runner.js +7 -3
  171. package/dist/db/money.d.ts +1 -1
  172. package/dist/db/money.js +1 -1
  173. package/dist/db/parent-ref-clause.d.ts +2 -1
  174. package/dist/db/pg-error.d.ts +2 -0
  175. package/dist/db/pg-error.js +37 -21
  176. package/dist/db/queries/backfill-pii.js +3 -6
  177. package/dist/db/queries/database-now.js +2 -1
  178. package/dist/db/queries/ddl.d.ts +3 -0
  179. package/dist/db/queries/ddl.js +34 -1
  180. package/dist/db/queries/event-store.js +4 -2
  181. package/dist/db/queries/event-tenants.d.ts +2 -0
  182. package/dist/db/queries/event-tenants.js +17 -0
  183. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  184. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  185. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  186. package/dist/db/queries/rls-boot-catalog.js +39 -0
  187. package/dist/db/queries/rls-catalog.d.ts +6 -0
  188. package/dist/db/queries/rls-catalog.js +82 -0
  189. package/dist/db/queries/rls-scope.d.ts +3 -0
  190. package/dist/db/queries/rls-scope.js +17 -0
  191. package/dist/db/queries/rls-shape.d.ts +10 -0
  192. package/dist/db/queries/rls-shape.js +42 -0
  193. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  194. package/dist/db/queries/session-advisory-lock.js +23 -0
  195. package/dist/db/queries/shadow-swap.d.ts +1 -2
  196. package/dist/db/queries/shadow-swap.js +11 -28
  197. package/dist/db/queries/test-stack.d.ts +4 -1
  198. package/dist/db/queries/test-stack.js +83 -2
  199. package/dist/db/query.d.ts +14 -0
  200. package/dist/db/query.js +77 -48
  201. package/dist/db/reference-data.d.ts +1 -1
  202. package/dist/db/reference-data.js +20 -3
  203. package/dist/db/render-ddl.d.ts +6 -2
  204. package/dist/db/render-ddl.js +7 -7
  205. package/dist/db/render-rls-ddl.d.ts +35 -0
  206. package/dist/db/render-rls-ddl.js +127 -0
  207. package/dist/db/replay-migration-sql.d.ts +3 -1
  208. package/dist/db/replay-migration-sql.js +22 -5
  209. package/dist/db/replay-rls.d.ts +25 -0
  210. package/dist/db/replay-rls.js +156 -0
  211. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  212. package/dist/db/row-level-security-boot-check.js +85 -0
  213. package/dist/db/row-level-security-connection.d.ts +3 -0
  214. package/dist/db/row-level-security-connection.js +213 -0
  215. package/dist/db/row-level-security-scope.d.ts +33 -0
  216. package/dist/db/row-level-security-scope.js +127 -0
  217. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  218. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  219. package/dist/db/sql-identifier.d.ts +1 -0
  220. package/dist/db/sql-identifier.js +3 -0
  221. package/dist/db/statement-timeout.js +2 -1
  222. package/dist/db/table-builder.d.ts +2 -1
  223. package/dist/db/table-builder.js +1 -1
  224. package/dist/db/table-info.js +1 -1
  225. package/dist/db/table-push.d.ts +11 -2
  226. package/dist/db/table-push.js +15 -2
  227. package/dist/db/tenant-db-runner.d.ts +3 -1
  228. package/dist/db/tenant-db-runner.js +4 -3
  229. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  230. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  231. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  232. package/dist/db/tenant-db-statement-runner.js +48 -0
  233. package/dist/db/tenant-db-upsert.d.ts +5 -0
  234. package/dist/db/tenant-db-upsert.js +91 -0
  235. package/dist/db/tenant-db.d.ts +17 -12
  236. package/dist/db/tenant-db.js +60 -121
  237. package/dist/db/tenant-id-filter.d.ts +3 -0
  238. package/dist/db/tenant-id-filter.js +30 -0
  239. package/dist/db/transaction-serialization.d.ts +6 -0
  240. package/dist/db/transaction-serialization.js +60 -0
  241. package/dist/derivatives/delete-stored-file.js +1 -1
  242. package/dist/derivatives/index.d.ts +2 -5
  243. package/dist/derivatives/index.js +2 -3
  244. package/dist/engine/access.d.ts +2 -1
  245. package/dist/engine/access.js +1 -1
  246. package/dist/engine/boot-validator/bundled-lists-table.d.ts +2 -0
  247. package/dist/engine/boot-validator/bundled-lists-table.js +36 -0
  248. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  249. package/dist/engine/boot-validator/entity-handler.js +1 -1
  250. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +3 -0
  251. package/dist/engine/boot-validator/entity-list-aggregate-options.js +23 -0
  252. package/dist/engine/boot-validator/list-bulk-actions.d.ts +3 -0
  253. package/dist/engine/boot-validator/list-bulk-actions.js +49 -0
  254. package/dist/engine/boot-validator/list-column-layout.d.ts +8 -0
  255. package/dist/engine/boot-validator/list-column-layout.js +41 -0
  256. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +24 -0
  257. package/dist/engine/boot-validator/list-table-aggregate-options.js +145 -0
  258. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +11 -0
  259. package/dist/engine/boot-validator/list-table-aggregate-query.js +31 -0
  260. package/dist/engine/boot-validator/list-table-export-options.d.ts +1 -0
  261. package/dist/engine/boot-validator/list-table-export-options.js +27 -0
  262. package/dist/engine/boot-validator/list-table-options.d.ts +3 -0
  263. package/dist/engine/boot-validator/list-table-options.js +77 -0
  264. package/dist/engine/boot-validator/list-table-reject-unknown-keys.d.ts +1 -0
  265. package/dist/engine/boot-validator/list-table-reject-unknown-keys.js +7 -0
  266. package/dist/engine/boot-validator/nav.d.ts +3 -1
  267. package/dist/engine/boot-validator/nav.js +1 -1
  268. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  269. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  270. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  271. package/dist/engine/boot-validator/projection-list-screens.js +3 -13
  272. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  273. package/dist/engine/boot-validator/related-list-table-rules.d.ts +4 -0
  274. package/dist/engine/boot-validator/related-list-table-rules.js +42 -0
  275. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  276. package/dist/engine/boot-validator/screens-kind-entity-list.js +7 -0
  277. package/dist/engine/boot-validator/screens-kind-projection-list.js +4 -0
  278. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  279. package/dist/engine/boot-validator/screens-lists.js +12 -2
  280. package/dist/engine/boot-validator/screens.d.ts +2 -1
  281. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  282. package/dist/engine/bridge-stub.d.ts +5 -2
  283. package/dist/engine/bridge-stub.js +39 -24
  284. package/dist/engine/build-app-schema.d.ts +2 -1
  285. package/dist/engine/build-app-schema.js +9 -1
  286. package/dist/engine/build-config-feature-schema.js +6 -1
  287. package/dist/engine/config-helpers.d.ts +2 -2
  288. package/dist/engine/config-helpers.js +0 -9
  289. package/dist/engine/constants.d.ts +0 -10
  290. package/dist/engine/constants.js +0 -8
  291. package/dist/engine/create-app.js +1 -1
  292. package/dist/engine/define-feature.d.ts +2 -1
  293. package/dist/engine/define-feature.js +5 -2
  294. package/dist/engine/define-handler.d.ts +1 -1
  295. package/dist/engine/define-step.d.ts +0 -1
  296. package/dist/engine/define-step.js +0 -3
  297. package/dist/engine/embedded-derived.d.ts +1 -1
  298. package/dist/engine/entity-handlers.d.ts +2 -1
  299. package/dist/engine/entity-handlers.js +7 -7
  300. package/dist/engine/entity-list-runtime-options.js +3 -1
  301. package/dist/engine/entity-list-searchability.d.ts +2 -1
  302. package/dist/engine/event-def.d.ts +2 -1
  303. package/dist/engine/event-helpers.d.ts +3 -1
  304. package/dist/engine/event-helpers.js +3 -3
  305. package/dist/engine/extension-names.d.ts +2 -8
  306. package/dist/engine/extension-names.js +2 -2
  307. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  308. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  309. package/dist/engine/extensions/user-data.d.ts +0 -8
  310. package/dist/engine/factories.d.ts +2 -1
  311. package/dist/engine/feature-builder-state.d.ts +9 -1
  312. package/dist/engine/feature-builder-state.js +1 -0
  313. package/dist/engine/feature-changelog.d.ts +1 -1
  314. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  315. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  316. package/dist/engine/feature-manifest.d.ts +1 -0
  317. package/dist/engine/feature-manifest.js +2 -1
  318. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  319. package/dist/engine/feature-ui-extensions.js +6 -4
  320. package/dist/engine/field-access.d.ts +3 -1
  321. package/dist/engine/field-access.js +12 -0
  322. package/dist/engine/handler-field-references.d.ts +0 -4
  323. package/dist/engine/index.d.ts +58 -55
  324. package/dist/engine/index.js +23 -28
  325. package/dist/engine/instruction-fields.d.ts +1 -1
  326. package/dist/engine/personal-data-fields.d.ts +1 -1
  327. package/dist/engine/qualified-name.d.ts +0 -1
  328. package/dist/engine/read-claim.d.ts +2 -1
  329. package/dist/engine/registry-facade.js +0 -3
  330. package/dist/engine/registry-ingest.d.ts +2 -1
  331. package/dist/engine/registry-ingest.js +1 -2
  332. package/dist/engine/registry-state.d.ts +12 -2
  333. package/dist/engine/registry-state.js +2 -3
  334. package/dist/engine/registry-validate.d.ts +3 -1
  335. package/dist/engine/registry-validate.js +7 -7
  336. package/dist/engine/run-in.d.ts +1 -1
  337. package/dist/engine/run-in.js +0 -1
  338. package/dist/engine/schema-builder.d.ts +1 -1
  339. package/dist/engine/schema-builder.js +1 -1
  340. package/dist/engine/screen-filter-ops.d.ts +2 -1
  341. package/dist/engine/screen-filter-ops.js +2 -5
  342. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  343. package/dist/engine/soft-delete-cleanup.js +4 -4
  344. package/dist/engine/state-machine.js +2 -1
  345. package/dist/engine/steps/_read-source.js +1 -1
  346. package/dist/engine/steps/aggregate-append-event.js +2 -2
  347. package/dist/engine/steps/call-feature.js +2 -2
  348. package/dist/engine/steps/mail-send.js +1 -1
  349. package/dist/engine/steps/retry.js +1 -1
  350. package/dist/engine/steps/wait-for-event.js +1 -1
  351. package/dist/engine/steps/wait.js +1 -1
  352. package/dist/engine/steps/webhook-send.js +1 -1
  353. package/dist/engine/strip-disabled-features-from-app-schema.js +7 -3
  354. package/dist/engine/template-variables.d.ts +2 -1
  355. package/dist/engine/transfer-adjacency.d.ts +1 -1
  356. package/dist/engine/types/feature.d.ts +1 -0
  357. package/dist/engine/types/index.d.ts +8 -30
  358. package/dist/engine/types/index.js +2 -10
  359. package/dist/engine/types/screen.d.ts +1 -1
  360. package/dist/engine/types/screen.js +1 -1
  361. package/dist/engine/validation.d.ts +2 -1
  362. package/dist/entrypoint/index.d.ts +9 -35
  363. package/dist/entrypoint/index.js +10 -1
  364. package/dist/entrypoint/internals.d.ts +40 -0
  365. package/dist/entrypoint/internals.js +1 -0
  366. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  367. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  368. package/dist/env/dry-run-internals.d.ts +10 -0
  369. package/dist/env/dry-run-internals.js +1 -0
  370. package/dist/env/dry-run.d.ts +1 -10
  371. package/dist/env/dry-run.js +2 -1
  372. package/dist/env/index.d.ts +1 -85
  373. package/dist/env/index.js +6 -50
  374. package/dist/env/internals.d.ts +87 -0
  375. package/dist/env/internals.js +53 -0
  376. package/dist/errors/classes.js +2 -2
  377. package/dist/errors/index.d.ts +5 -14
  378. package/dist/errors/index.js +4 -9
  379. package/dist/errors/member-resolution.js +1 -1
  380. package/dist/errors/reasons.d.ts +0 -1
  381. package/dist/errors/reasons.js +7 -7
  382. package/dist/errors/serialize.d.ts +0 -18
  383. package/dist/errors/serialize.js +0 -27
  384. package/dist/es-ops/index.d.ts +4 -4
  385. package/dist/es-ops/index.js +2 -2
  386. package/dist/es-ops/operations-schema.d.ts +1 -1
  387. package/dist/es-ops/types.d.ts +4 -5
  388. package/dist/event-store/admin-api-internals.d.ts +14 -0
  389. package/dist/event-store/admin-api-internals.js +1 -0
  390. package/dist/event-store/admin-api.d.ts +1 -14
  391. package/dist/event-store/admin-api.js +11 -6
  392. package/dist/event-store/archive.js +4 -2
  393. package/dist/event-store/errors.js +2 -2
  394. package/dist/event-store/event-store.d.ts +1 -0
  395. package/dist/event-store/event-store.js +42 -32
  396. package/dist/event-store/events-schema.js +4 -1
  397. package/dist/event-store/index.d.ts +11 -13
  398. package/dist/event-store/index.js +7 -9
  399. package/dist/event-store/provenance-append.js +1 -1
  400. package/dist/event-store/rebuild-dead-letter.js +4 -2
  401. package/dist/event-store/snapshot.js +4 -3
  402. package/dist/event-store/stream-scope.d.ts +2 -0
  403. package/dist/event-store/stream-scope.js +6 -0
  404. package/dist/event-store/upcaster-dead-letter.js +4 -2
  405. package/dist/event-store/upcaster.d.ts +2 -1
  406. package/dist/files/action-form-upload.d.ts +2 -1
  407. package/dist/files/action-form-upload.js +1 -1
  408. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  409. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  410. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  411. package/dist/files/bind-pending-file-refs.js +2 -1
  412. package/dist/files/bind-referenced-files.write.js +1 -1
  413. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  414. package/dist/files/create-file-ref-from-bytes.js +6 -3
  415. package/dist/files/create-file-ref.d.ts +6 -2
  416. package/dist/files/create-file-ref.js +13 -4
  417. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  418. package/dist/files/dispose-removed-file-refs.js +1 -1
  419. package/dist/files/feature.js +2 -2
  420. package/dist/files/file-handle.js +1 -1
  421. package/dist/files/file-routes.d.ts +3 -1
  422. package/dist/files/file-routes.js +41 -4
  423. package/dist/files/index.d.ts +11 -13
  424. package/dist/files/index.js +5 -7
  425. package/dist/files/load-save-file-refs.d.ts +2 -1
  426. package/dist/files/load-save-file-refs.js +1 -1
  427. package/dist/files/provider-resolver.d.ts +6 -4
  428. package/dist/files/provider-resolver.js +5 -5
  429. package/dist/files/record-write-check.d.ts +6 -0
  430. package/dist/files/record-write-check.js +13 -0
  431. package/dist/files/storage-tracking.js +4 -2
  432. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  433. package/dist/files/sweep-orphaned-uploads.js +1 -1
  434. package/dist/files/upload-ledger.d.ts +2 -2
  435. package/dist/files/upload-ledger.js +4 -4
  436. package/dist/i18n/index.d.ts +2 -8
  437. package/dist/i18n/index.js +1 -1
  438. package/dist/i18n/internals.d.ts +7 -0
  439. package/dist/i18n/internals.js +1 -0
  440. package/dist/i18n/required-surface-keys.d.ts +4 -1
  441. package/dist/i18n/required-surface-keys.js +7 -2
  442. package/dist/internal/row-level-security.d.ts +3 -0
  443. package/dist/internal/row-level-security.js +3 -0
  444. package/dist/internal/stack-support.d.ts +1 -1
  445. package/dist/internal/stack-support.js +1 -1
  446. package/dist/internal/testing.d.ts +1 -0
  447. package/dist/internal/testing.js +10 -6
  448. package/dist/jobs/index.d.ts +1 -1
  449. package/dist/jobs/job-append-event.d.ts +12 -0
  450. package/dist/jobs/job-append-event.js +30 -0
  451. package/dist/jobs/job-runner-context.d.ts +2 -2
  452. package/dist/jobs/job-runner-context.js +46 -16
  453. package/dist/jobs/job-runner-execution.d.ts +1 -1
  454. package/dist/jobs/job-runner-execution.js +6 -4
  455. package/dist/jobs/job-runner-gates.d.ts +1 -1
  456. package/dist/jobs/job-runner-gates.js +0 -1
  457. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  458. package/dist/jobs/job-runner-helpers.js +10 -1
  459. package/dist/jobs/job-runner-scope.d.ts +5 -2
  460. package/dist/jobs/job-runner-scope.js +6 -6
  461. package/dist/jobs/job-runner-types.d.ts +2 -1
  462. package/dist/jobs/job-runner.js +22 -6
  463. package/dist/jobs/max-per-tenant.d.ts +1 -1
  464. package/dist/logging/index.d.ts +1 -2
  465. package/dist/logging/index.js +1 -1
  466. package/dist/logging/pino-logger.js +1 -1
  467. package/dist/logging/utils.d.ts +1 -0
  468. package/dist/logging/utils.js +6 -0
  469. package/dist/migrations/index.d.ts +3 -3
  470. package/dist/migrations/index.js +3 -3
  471. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  472. package/dist/migrations/pending-rebuilds.js +1 -1
  473. package/dist/migrations/pii-event-backfill.js +4 -1
  474. package/dist/observability/escape-hatch-report.d.ts +2 -1
  475. package/dist/observability/escape-hatch-report.js +9 -2
  476. package/dist/observability/index.d.ts +7 -15
  477. package/dist/observability/index.js +4 -12
  478. package/dist/observability/metric-validator.js +1 -1
  479. package/dist/observability/metrics-handle.d.ts +0 -1
  480. package/dist/observability/metrics-handle.js +2 -15
  481. package/dist/observability/recording-tracer.d.ts +1 -2
  482. package/dist/observability/recording-tracer.js +0 -6
  483. package/dist/observability/sensitive-filter.d.ts +0 -2
  484. package/dist/observability/sensitive-filter.js +0 -29
  485. package/dist/pipeline/active-membership.d.ts +2 -1
  486. package/dist/pipeline/active-membership.js +6 -2
  487. package/dist/pipeline/after-rollback-sink.d.ts +6 -0
  488. package/dist/pipeline/after-rollback-sink.js +32 -0
  489. package/dist/pipeline/append-event-core.d.ts +2 -1
  490. package/dist/pipeline/append-event-core.js +2 -2
  491. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  492. package/dist/pipeline/attach-outside-transaction.js +13 -0
  493. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  494. package/dist/pipeline/cascade-handler.d.ts +2 -1
  495. package/dist/pipeline/cascade-handler.js +3 -2
  496. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  497. package/dist/pipeline/config-accessor-factory.js +1 -1
  498. package/dist/pipeline/context-services.d.ts +56 -0
  499. package/dist/pipeline/context-services.js +73 -0
  500. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  501. package/dist/pipeline/dispatch-batch.js +39 -19
  502. package/dist/pipeline/dispatch-query.js +5 -4
  503. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  504. package/dist/pipeline/dispatch-scope.js +27 -0
  505. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  506. package/dist/pipeline/dispatch-shared.js +75 -194
  507. package/dist/pipeline/dispatch-stream.js +8 -4
  508. package/dist/pipeline/dispatch-write.d.ts +2 -1
  509. package/dist/pipeline/dispatch-write.js +10 -8
  510. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  511. package/dist/pipeline/dispatcher-utils.js +8 -2
  512. package/dist/pipeline/dispatcher.d.ts +3 -2
  513. package/dist/pipeline/dispatcher.js +4 -3
  514. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  515. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  516. package/dist/pipeline/event-dispatcher-delivery.js +7 -3
  517. package/dist/pipeline/event-dispatcher.d.ts +3 -2
  518. package/dist/pipeline/event-dispatcher.js +13 -12
  519. package/dist/pipeline/event-retention.js +59 -56
  520. package/dist/pipeline/handler-access-error.js +2 -1
  521. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  522. package/dist/pipeline/handler-context-auth.js +7 -4
  523. package/dist/pipeline/handler-context-config.d.ts +2 -5
  524. package/dist/pipeline/handler-context-config.js +2 -2
  525. package/dist/pipeline/handler-context-db.d.ts +32 -7
  526. package/dist/pipeline/handler-context-db.js +26 -17
  527. package/dist/pipeline/handler-context-dispatch.d.ts +14 -6
  528. package/dist/pipeline/handler-context-dispatch.js +18 -5
  529. package/dist/pipeline/handler-context-events.d.ts +22 -38
  530. package/dist/pipeline/handler-context-events.js +42 -35
  531. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  532. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  533. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  534. package/dist/pipeline/handler-context-notify.js +1 -1
  535. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  536. package/dist/pipeline/handler-context-observability.js +7 -5
  537. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  538. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  539. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  540. package/dist/pipeline/handler-context-scope.js +18 -20
  541. package/dist/pipeline/index.d.ts +9 -21
  542. package/dist/pipeline/index.js +5 -7
  543. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  544. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  545. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  546. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  547. package/dist/pipeline/member-read-only-transaction.js +11 -3
  548. package/dist/pipeline/member-reader.d.ts +1 -1
  549. package/dist/pipeline/member-reader.js +2 -2
  550. package/dist/pipeline/msp-rebuild.js +5 -3
  551. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  552. package/dist/pipeline/notify-scope.d.ts +2 -1
  553. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  554. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  555. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  556. package/dist/pipeline/projection-rebuild.js +12 -5
  557. package/dist/pipeline/projection-state.d.ts +0 -6
  558. package/dist/pipeline/projection-state.js +0 -5
  559. package/dist/pipeline/projections-runner.d.ts +2 -1
  560. package/dist/pipeline/projections-runner.js +10 -6
  561. package/dist/pipeline/system-hooks.d.ts +6 -2
  562. package/dist/pipeline/system-hooks.js +61 -10
  563. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  564. package/dist/pipeline/system-identity-switch.js +51 -36
  565. package/dist/pipeline/typed-append-event.d.ts +2 -0
  566. package/dist/pipeline/typed-append-event.js +4 -0
  567. package/dist/pipeline/write-origin.js +2 -2
  568. package/dist/pipeline/write-result-masking.d.ts +1 -1
  569. package/dist/pipeline/write-result-masking.js +13 -10
  570. package/dist/random/index.d.ts +1 -2
  571. package/dist/random/index.js +1 -2
  572. package/dist/rate-limit/bucket.d.ts +2 -1
  573. package/dist/rate-limit/middleware.js +2 -1
  574. package/dist/redis/index.d.ts +3 -4
  575. package/dist/redis/index.js +2 -2
  576. package/dist/schema-cli/apply-command.js +5 -2
  577. package/dist/schema-cli/baseline-command.js +7 -2
  578. package/dist/schema-cli/generate-command.js +7 -9
  579. package/dist/schema-cli/shared.d.ts +4 -0
  580. package/dist/schema-cli/shared.js +21 -2
  581. package/dist/schema-cli/status-command.js +8 -2
  582. package/dist/schema-cli/validate-command.js +52 -4
  583. package/dist/schema-cli.d.ts +0 -1
  584. package/dist/search/configure-tenant-index.d.ts +1 -3
  585. package/dist/search/configure-tenant-index.js +0 -4
  586. package/dist/search/index.d.ts +1 -4
  587. package/dist/search/index.js +0 -2
  588. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  589. package/dist/search/meilisearch-adapter-internals.js +9 -0
  590. package/dist/search/meilisearch-adapter.d.ts +1 -8
  591. package/dist/search/meilisearch-adapter.js +6 -7
  592. package/dist/search/meilisearch-peer.d.ts +2 -0
  593. package/dist/search/meilisearch-peer.js +5 -0
  594. package/dist/search/reindex-entity.js +107 -91
  595. package/dist/secrets/index.d.ts +3 -4
  596. package/dist/secrets/index.js +2 -3
  597. package/dist/seeding/index.d.ts +2 -2
  598. package/dist/seeding/index.js +1 -2
  599. package/dist/time/index.d.ts +2 -2
  600. package/dist/time/index.js +1 -1
  601. package/dist/time/tz-context.d.ts +0 -5
  602. package/dist/time/tz-context.js +0 -9
  603. package/dist/ui-types/index.d.ts +8 -11
  604. package/dist/ui-types/index.js +3 -3
  605. package/dist/upgrade-changelog.d.ts +3 -0
  606. package/dist/upgrade-changelog.js +18 -0
  607. package/dist/upgrade-cli-internals.d.ts +8 -0
  608. package/dist/upgrade-cli-internals.js +63 -0
  609. package/dist/upgrade-cli.d.ts +1 -18
  610. package/dist/upgrade-cli.js +29 -137
  611. package/dist/upgrade-marker-parse.d.ts +32 -0
  612. package/dist/upgrade-marker-parse.js +73 -0
  613. package/dist/utils/import-optional-peer.d.ts +6 -0
  614. package/dist/utils/import-optional-peer.js +19 -0
  615. package/dist/utils/index.d.ts +1 -4
  616. package/dist/utils/index.js +1 -4
  617. package/package.json +27 -20
  618. package/src/changes.json +451 -0
  619. package/dist/crypto/request-kms-cache.d.ts +0 -8
  620. package/dist/crypto/request-kms-cache.js +0 -21
  621. package/dist/engine/codemod/index.d.ts +0 -2
  622. package/dist/engine/codemod/index.js +0 -1
  623. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  624. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  625. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  626. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  627. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  628. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  629. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  630. package/dist/engine/feature-ast/extractors/events.js +0 -275
  631. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  632. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  633. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  634. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  635. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  636. package/dist/engine/feature-ast/extractors/index.js +0 -13
  637. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  638. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  639. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  640. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  641. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  642. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  643. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -10
  644. package/dist/engine/feature-ast/extractors/round1.js +0 -81
  645. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  646. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  647. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  648. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  649. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  650. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  651. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  652. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  653. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  654. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  655. package/dist/engine/feature-ast/index.d.ts +0 -16
  656. package/dist/engine/feature-ast/index.js +0 -10
  657. package/dist/engine/feature-ast/parse.d.ts +0 -31
  658. package/dist/engine/feature-ast/parse.js +0 -483
  659. package/dist/engine/feature-ast/patch.d.ts +0 -210
  660. package/dist/engine/feature-ast/patch.js +0 -610
  661. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  662. package/dist/engine/feature-ast/patcher.js +0 -281
  663. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1476
  664. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1226
  665. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  666. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -210
  667. package/dist/engine/feature-ast/patterns.d.ts +0 -318
  668. package/dist/engine/feature-ast/patterns.js +0 -106
  669. package/dist/engine/feature-ast/render.d.ts +0 -47
  670. package/dist/engine/feature-ast/render.js +0 -662
  671. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  672. package/dist/engine/feature-ast/source-location.js +0 -27
  673. package/dist/engine/pattern-library/index.d.ts +0 -2
  674. package/dist/engine/pattern-library/index.js +0 -3
  675. package/dist/engine/pattern-library/library.d.ts +0 -14
  676. package/dist/engine/pattern-library/library.js +0 -93
  677. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  678. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  679. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  680. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  681. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  682. package/dist/engine/pattern-library/shared-fields.js +0 -88
  683. package/dist/engine/pattern-library/static-schemas.d.ts +0 -20
  684. package/dist/engine/pattern-library/static-schemas.js +0 -478
  685. package/dist/engine/pattern-library/types.d.ts +0 -158
  686. package/dist/engine/pattern-library/types.js +0 -36
  687. package/dist/engine/provider-plugin-context.d.ts +0 -3
  688. package/dist/engine/provider-plugin-context.js +0 -28
  689. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  690. package/dist/engine/resolve-config-or-param.js +0 -76
  691. package/src/scripts/codemod/README.md +0 -187
  692. package/src/scripts/codemod/codemod-support.ts +0 -334
  693. package/src/scripts/codemod/collect-source-files.ts +0 -48
  694. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  695. package/src/scripts/codemod/db-factory.ts +0 -810
  696. package/src/scripts/codemod/feature-factory.ts +0 -429
  697. package/src/scripts/codemod/feature-layout.ts +0 -424
  698. package/src/scripts/codemod/import-extensions.ts +0 -118
  699. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  700. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  701. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  702. package/src/scripts/codemod/object-form.ts +0 -746
  703. package/src/scripts/codemod/package-merge.ts +0 -299
  704. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  705. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  706. package/src/scripts/codemod/s3-imports.ts +0 -236
  707. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  708. package/src/scripts/codemod/testing-injection.ts +0 -215
  709. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  710. package/src/scripts/codemod/testing-move.ts +0 -542
  711. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -0,0 +1,213 @@
1
+ import { InternalError } from "../errors/index.js";
2
+ import { applyRowLevelSecurityScope, buildRowLevelSecurityScopeQuery, } from "./queries/rls-scope.js";
3
+ import { activeRowLevelSecurityScope, innerOfScopedRunner, rowLevelSecurityScopeKey, runInCapturedRowLevelSecurityScope, } from "./row-level-security-scope.js";
4
+ import { registerRunnerProxyTarget } from "./transaction-serialization.js";
5
+ const enforcedHandles = new WeakSet();
6
+ // Differs from every scope key, so the next statement always re-applies its scope.
7
+ const UNKNOWN_SCOPE_KEY = "unknown";
8
+ const noop = () => { };
9
+ function isHandle(value) {
10
+ return (typeof value === "object" || typeof value === "function") && value !== null;
11
+ }
12
+ export function rowLevelSecurityModeOf(db) {
13
+ let current = db;
14
+ while (isHandle(current)) {
15
+ if (enforcedHandles.has(current))
16
+ return "on";
17
+ current = innerOfScopedRunner(current);
18
+ }
19
+ return "off";
20
+ }
21
+ function callMethod(target, name, args) {
22
+ return Reflect.apply(Reflect.get(target, name, target), target, args);
23
+ }
24
+ // Tagged-template calls need the real driver object as `this`.
25
+ function applyOnTarget(target, args) {
26
+ if (typeof target !== "function") {
27
+ throw new TypeError("row-level-security proxy applied on a non-callable handle");
28
+ }
29
+ return Reflect.apply(target, target, args);
30
+ }
31
+ function isTaggedTemplateCall(args) {
32
+ const first = args[0];
33
+ return Array.isArray(first) && "raw" in first;
34
+ }
35
+ // Sql methods that send statements on a connection this wrapper cannot align per statement.
36
+ const UNSUPPORTED_ON_ENFORCED_HANDLE = new Set([
37
+ "reserve",
38
+ "beginDistributed",
39
+ "commitDistributed",
40
+ "rollbackDistributed",
41
+ ]);
42
+ function enqueue(state, unit) {
43
+ const result = state.tail.then(unit);
44
+ state.tail = result.then(noop, noop);
45
+ return result;
46
+ }
47
+ // The driver may run the callback outside the caller's async context, so the captured scope is re-entered.
48
+ function withCapturedCallback(args, wrap) {
49
+ const callback = args[args.length - 1];
50
+ if (typeof callback !== "function")
51
+ return [...args];
52
+ const captured = activeRowLevelSecurityScope();
53
+ return [
54
+ ...args.slice(0, -1),
55
+ (handle) => runInCapturedRowLevelSecurityScope(captured, () => callback(wrap(handle))),
56
+ ];
57
+ }
58
+ function alignedStatement(target, state, run) {
59
+ const desired = activeRowLevelSecurityScope();
60
+ return enqueue(state, async () => {
61
+ await alignScope(target, state, desired);
62
+ return run();
63
+ });
64
+ }
65
+ function transactionHandleProxy(handle, state) {
66
+ const proxy = new Proxy(handle, {
67
+ apply(target, _thisArg, args) {
68
+ // Helper calls such as sql(rows) or sql("ident") build fragments and send nothing.
69
+ if (!isTaggedTemplateCall(args))
70
+ return applyOnTarget(target, args);
71
+ return alignedStatement(target, state, () => applyOnTarget(target, args));
72
+ },
73
+ get(target, prop) {
74
+ const value = Reflect.get(target, prop, target);
75
+ if (typeof value !== "function")
76
+ return value;
77
+ if (UNSUPPORTED_ON_ENFORCED_HANDLE.has(prop)) {
78
+ return () => {
79
+ throw new InternalError({
80
+ message: `row-level security: ${String(prop)} is not supported on an enforced transaction handle`,
81
+ });
82
+ };
83
+ }
84
+ if (prop === "unsafe" || prop === "file") {
85
+ return (...args) => alignedStatement(target, state, () => callMethod(target, prop, args));
86
+ }
87
+ if (prop === "savepoint") {
88
+ // A released or rolled-back savepoint reverts the transaction-local settings made inside it.
89
+ return async (...args) => {
90
+ try {
91
+ return await callMethod(target, "savepoint", withCapturedCallback(args, (spHandle) => transactionHandleProxy(spHandle, state)));
92
+ }
93
+ finally {
94
+ state.applied = UNKNOWN_SCOPE_KEY;
95
+ }
96
+ };
97
+ }
98
+ return value.bind(target);
99
+ },
100
+ });
101
+ enforcedHandles.add(proxy);
102
+ registerRunnerProxyTarget(proxy, handle);
103
+ return proxy;
104
+ }
105
+ async function alignScope(handle, state, desired) {
106
+ const key = rowLevelSecurityScopeKey(desired);
107
+ // skip: scope already applied on this connection
108
+ if (key === state.applied)
109
+ return;
110
+ state.applied = UNKNOWN_SCOPE_KEY;
111
+ await applyRowLevelSecurityScope(handle, desired);
112
+ state.applied = key;
113
+ }
114
+ function newTransactionState() {
115
+ return { applied: rowLevelSecurityScopeKey(undefined), tail: Promise.resolve() };
116
+ }
117
+ const templateOf = (strings) => strings;
118
+ // Tagged-template statements pipeline behind each other; unsafe() without parameters is sent as a
119
+ // simple query that waits for its own result first (measured 4.1 vs 2.4 roundtrips).
120
+ const BEGIN_TEMPLATE = templateOf `BEGIN`;
121
+ const COMMIT_TEMPLATE = templateOf `COMMIT`;
122
+ // Bun queries are lazy: they go out when started, so each one is started explicitly, in order,
123
+ // to pipeline BEGIN, the scope and the statement on one connection.
124
+ function startQuery(build) {
125
+ try {
126
+ const query = build();
127
+ if (isHandle(query) && typeof Reflect.get(query, "execute") === "function") {
128
+ callMethod(query, "execute", []);
129
+ }
130
+ return Promise.resolve(query);
131
+ }
132
+ catch (error) {
133
+ // A statement that cannot be built must not stop COMMIT from being queued behind BEGIN.
134
+ return Promise.reject(error);
135
+ }
136
+ }
137
+ // COMMIT is always queued and the connection is released only after all four settled, so it never
138
+ // returns to the pool inside an open transaction; COMMIT after a failed statement rolls back.
139
+ async function pipelinedScopedTransaction(pool, scope, run) {
140
+ const conn = await callMethod(pool, "reserve", []);
141
+ if (!isHandle(conn)) {
142
+ throw new InternalError({
143
+ message: "row-level security: pool.reserve() returned no connection",
144
+ });
145
+ }
146
+ try {
147
+ const begin = startQuery(() => applyOnTarget(conn, [BEGIN_TEMPLATE]));
148
+ const setScope = startQuery(() => buildRowLevelSecurityScopeQuery(conn, scope));
149
+ const statement = startQuery(() => run(conn));
150
+ const commit = startQuery(() => applyOnTarget(conn, [COMMIT_TEMPLATE]));
151
+ const [beginResult, scopeResult, statementResult, commitResult] = await Promise.allSettled([
152
+ begin,
153
+ setScope,
154
+ statement,
155
+ commit,
156
+ ]);
157
+ // Without BEGIN or the scope the statement ran unscoped (fails closed) but is not a success.
158
+ if (beginResult.status === "rejected")
159
+ throw beginResult.reason;
160
+ if (scopeResult.status === "rejected")
161
+ throw scopeResult.reason;
162
+ if (statementResult.status === "rejected")
163
+ throw statementResult.reason;
164
+ if (commitResult.status === "rejected")
165
+ throw commitResult.reason;
166
+ return statementResult.value;
167
+ }
168
+ finally {
169
+ callMethod(conn, "release", []);
170
+ }
171
+ }
172
+ // A pool statement under a scope runs as its own short transaction; without a scope it passes
173
+ // through and the policies see no tenant (fail closed), so DDL like CONCURRENTLY keeps working.
174
+ export function enforceRowLevelSecurity(pool) {
175
+ const inScopedTransaction = (run) => pipelinedScopedTransaction(pool, activeRowLevelSecurityScope(), run);
176
+ const proxy = new Proxy(pool, {
177
+ apply(target, _thisArg, args) {
178
+ if (!isTaggedTemplateCall(args) || activeRowLevelSecurityScope() === undefined) {
179
+ return applyOnTarget(target, args);
180
+ }
181
+ return inScopedTransaction((conn) => applyOnTarget(conn, args));
182
+ },
183
+ get(target, prop) {
184
+ const value = Reflect.get(target, prop, target);
185
+ if (typeof value !== "function")
186
+ return value;
187
+ if (prop === "unsafe" || prop === "file") {
188
+ return (...args) => {
189
+ if (activeRowLevelSecurityScope() === undefined)
190
+ return callMethod(target, prop, args);
191
+ if (prop === "file") {
192
+ // Bun sends file() only after its async file read, i.e. after the pipelined COMMIT.
193
+ const scope = activeRowLevelSecurityScope();
194
+ return callMethod(target, "begin", [
195
+ async (tx) => {
196
+ await applyRowLevelSecurityScope(tx, scope);
197
+ return callMethod(tx, "file", args);
198
+ },
199
+ ]);
200
+ }
201
+ return inScopedTransaction((conn) => callMethod(conn, prop, args));
202
+ };
203
+ }
204
+ if (prop === "begin" || prop === "transaction") {
205
+ return (...args) => callMethod(target, prop, withCapturedCallback(args, (tx) => transactionHandleProxy(tx, newTransactionState())));
206
+ }
207
+ return value.bind(target);
208
+ },
209
+ });
210
+ enforcedHandles.add(proxy);
211
+ registerRunnerProxyTarget(proxy, pool);
212
+ return proxy;
213
+ }
@@ -0,0 +1,33 @@
1
+ import type { TenantId } from "../engine/types/identifiers.ts";
2
+ import type { RowLevelSecurityMode } from "./render-rls-ddl.ts";
3
+ export type RowLevelSecurityScope = {
4
+ readonly kind: "tenant";
5
+ readonly tenantId: TenantId;
6
+ } | {
7
+ readonly kind: "system";
8
+ readonly reason: string;
9
+ };
10
+ export declare const SYSTEM_ROW_LEVEL_SECURITY_SCOPE: RowLevelSecurityScope;
11
+ export declare function tenantRowLevelSecurityScope(tenantId: TenantId): RowLevelSecurityScope;
12
+ export declare function activeRowLevelSecurityScope(): RowLevelSecurityScope | undefined;
13
+ export declare function runInRowLevelSecurityScope<T>(scope: RowLevelSecurityScope, fn: () => T): T;
14
+ export declare function runInSystemRowLevelSecurityScope<T>(reason: string, fn: () => T): T;
15
+ export declare function runInCapturedRowLevelSecurityScope<T>(captured: RowLevelSecurityScope | undefined, fn: () => T): T;
16
+ export declare function outsideRowLevelSecurityScope<T>(fn: () => T): T;
17
+ export declare function rowLevelSecurityScopeKey(scope: RowLevelSecurityScope | undefined): string;
18
+ export type TenantDbModeOptions = {
19
+ readonly mode: "tenant";
20
+ readonly reason?: undefined;
21
+ } | {
22
+ readonly mode: "system";
23
+ readonly reason: string;
24
+ };
25
+ export declare function systemModeOptions(reason: string | undefined): TenantDbModeOptions;
26
+ export declare function tenantDbRowLevelSecurityScope(options: TenantDbModeOptions, tenantId: TenantId, table?: unknown): RowLevelSecurityScope;
27
+ export declare function assertNoActiveRowLevelSecurityScope(startingWhat: string): void;
28
+ export declare function unscopedRunnerOf<T extends object>(runner: T): T;
29
+ export declare function innerOfScopedRunner(runner: unknown): object | undefined;
30
+ export declare function withRowLevelSecurityScope<T extends object>(runner: T, scope: RowLevelSecurityScope): T;
31
+ export declare function systemScopedRunner<T extends object>(runner: T, reason: string): T;
32
+ export declare function appHookScopedRunner<T extends object>(runner: T, mode: RowLevelSecurityMode): T;
33
+ export declare function unsafeRawScopedRunner<T extends object>(runner: T): T;
@@ -0,0 +1,127 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { InternalError } from "../errors/index.js";
3
+ import { asEntityTableMeta } from "./table-introspection.js";
4
+ import { registerRunnerProxyTarget } from "./transaction-serialization.js";
5
+ function systemRowLevelSecurityScope(reason) {
6
+ if (reason.trim() === "") {
7
+ throw new InternalError({
8
+ message: "A system row-level-security scope requires a non-empty reason.",
9
+ });
10
+ }
11
+ return { kind: "system", reason };
12
+ }
13
+ export const SYSTEM_ROW_LEVEL_SECURITY_SCOPE = systemRowLevelSecurityScope("framework-internal cross-tenant access");
14
+ function describeRowLevelSecurityScope(scope) {
15
+ return scope.kind === "system"
16
+ ? `system (reason: ${scope.reason})`
17
+ : rowLevelSecurityScopeKey(scope);
18
+ }
19
+ export function tenantRowLevelSecurityScope(tenantId) {
20
+ return { kind: "tenant", tenantId };
21
+ }
22
+ const storage = new AsyncLocalStorage();
23
+ export function activeRowLevelSecurityScope() {
24
+ return storage.getStore();
25
+ }
26
+ export function runInRowLevelSecurityScope(scope, fn) {
27
+ return storage.run(scope, fn);
28
+ }
29
+ export function runInSystemRowLevelSecurityScope(reason, fn) {
30
+ return storage.run(systemRowLevelSecurityScope(reason), fn);
31
+ }
32
+ // Drivers may invoke callbacks outside the caller's async context; undefined re-enters "no scope".
33
+ export function runInCapturedRowLevelSecurityScope(captured, fn) {
34
+ return captured === undefined ? storage.exit(fn) : storage.run(captured, fn);
35
+ }
36
+ // DDL such as CREATE INDEX CONCURRENTLY cannot run in the per-statement transaction an enforced pool opens under a scope.
37
+ export function outsideRowLevelSecurityScope(fn) {
38
+ return storage.exit(fn);
39
+ }
40
+ export function rowLevelSecurityScopeKey(scope) {
41
+ if (scope === undefined)
42
+ return "none";
43
+ return scope.kind === "system" ? "system" : `tenant:${scope.tenantId}`;
44
+ }
45
+ // Untyped JS callers can still omit the reason; fail at construction, not on the first query.
46
+ export function systemModeOptions(reason) {
47
+ systemRowLevelSecurityScope(reason ?? "");
48
+ return { mode: "system", reason: reason ?? "" };
49
+ }
50
+ // Global tables carry SYSTEM_TENANT_ID rows; the app layer rejects tenant writes and filters reads.
51
+ export function tenantDbRowLevelSecurityScope(options, tenantId, table) {
52
+ if (options.mode === "system")
53
+ return systemRowLevelSecurityScope(options.reason);
54
+ if (asEntityTableMeta(table)?.tenancy === "global")
55
+ return SYSTEM_ROW_LEVEL_SECURITY_SCOPE;
56
+ return tenantRowLevelSecurityScope(tenantId);
57
+ }
58
+ // A server or loop that inherits an ambient scope would run every later request fail-open.
59
+ export function assertNoActiveRowLevelSecurityScope(startingWhat) {
60
+ const active = activeRowLevelSecurityScope();
61
+ // skip: no active scope, nothing leaked
62
+ if (active === undefined)
63
+ return;
64
+ throw new InternalError({
65
+ message: `${startingWhat} was started inside an active row-level-security scope (${describeRowLevelSecurityScope(active)}); long-lived loops must start outside any scope.`,
66
+ });
67
+ }
68
+ const scopedRunnerInners = new WeakMap();
69
+ export function unscopedRunnerOf(runner) {
70
+ return scopedRunnerInners.get(runner) ?? runner;
71
+ }
72
+ export function innerOfScopedRunner(runner) {
73
+ if (typeof runner !== "object" && typeof runner !== "function")
74
+ return undefined;
75
+ return runner === null ? undefined : scopedRunnerInners.get(runner);
76
+ }
77
+ const SCOPED_METHODS = new Set([
78
+ "unsafe",
79
+ "begin",
80
+ "transaction",
81
+ "savepoint",
82
+ ]);
83
+ export function withRowLevelSecurityScope(runner, scope) {
84
+ // Innermost scope wins: re-scoping unwraps instead of stacking proxies.
85
+ const inner = scopedRunnerInners.get(runner) ?? runner;
86
+ const proxy = new Proxy(inner, {
87
+ apply(target, _thisArg, args) {
88
+ if (typeof target !== "function") {
89
+ throw new TypeError("row-level-security scope proxy applied on a non-callable runner");
90
+ }
91
+ return runInRowLevelSecurityScope(scope, () => Reflect.apply(target, target, args));
92
+ },
93
+ get(target, prop) {
94
+ const value = Reflect.get(target, prop, target);
95
+ if (typeof value !== "function")
96
+ return value;
97
+ if (prop === "reserve") {
98
+ return async (...args) => {
99
+ const reserved = await Reflect.apply(value, target, args);
100
+ if (typeof reserved !== "object" || reserved === null)
101
+ return reserved;
102
+ return withRowLevelSecurityScope(reserved, scope);
103
+ };
104
+ }
105
+ if (SCOPED_METHODS.has(prop)) {
106
+ return (...args) => runInRowLevelSecurityScope(scope, () => Reflect.apply(value, target, args));
107
+ }
108
+ return value.bind(target);
109
+ },
110
+ });
111
+ scopedRunnerInners.set(proxy, inner);
112
+ registerRunnerProxyTarget(proxy, inner);
113
+ return proxy;
114
+ }
115
+ export function systemScopedRunner(runner, reason) {
116
+ return withRowLevelSecurityScope(runner, systemRowLevelSecurityScope(reason));
117
+ }
118
+ // Boot and tenant-resolution hooks run before any tenant is established, so the enforcing pool
119
+ // would return zero rows; prod, dev and the test stack all hand them this same system scope.
120
+ export function appHookScopedRunner(runner, mode) {
121
+ return mode === "on"
122
+ ? systemScopedRunner(runner, "app boot and tenant-resolution hooks run before any tenant is established")
123
+ : runner;
124
+ }
125
+ export function unsafeRawScopedRunner(runner) {
126
+ return systemScopedRunner(runner, "granted unsafeRaw bypasses the tenant filter by declaration");
127
+ }
@@ -0,0 +1,3 @@
1
+ import type { TenantDb } from "@cosmicdrift/kumiko-types/tenant-db-types";
2
+ import type { TenantId } from "../engine/types/identifiers.ts";
3
+ export declare function scopeTenantDbToTenant(db: TenantDb, tenantId: TenantId): TenantDb;
@@ -0,0 +1,14 @@
1
+ import { createTenantDb } from "./tenant-db.js";
2
+ import { tenantDbRunner, tenantDbWritesDeniedReason } from "./tenant-db-runner.js";
3
+ // Narrows a (possibly "system"-mode) TenantDb to a "tenant"-mode handle for one tenant on the
4
+ // same connection/transaction. For code that must run caller-supplied callbacks (e.g. config
5
+ // validators) without handing them a cross-tenant view.
6
+ export function scopeTenantDbToTenant(db, tenantId) {
7
+ const writesDeniedReason = tenantDbWritesDeniedReason(db);
8
+ return createTenantDb({
9
+ db: tenantDbRunner(db),
10
+ tenantId,
11
+ mode: "tenant",
12
+ ...(writesDeniedReason !== undefined && { grants: { writesDeniedReason } }),
13
+ });
14
+ }
@@ -0,0 +1 @@
1
+ export declare function quoteIdent(name: string): string;
@@ -0,0 +1,3 @@
1
+ export function quoteIdent(name) {
2
+ return `"${name.replace(/"/g, '""')}"`;
3
+ }
@@ -4,7 +4,8 @@ const UNBOUNDED_POOL_CLOSE_TIMEOUT_SECONDS = 5;
4
4
  // PII backfill and projection rebuilds legitimately run longer. The cap is a connect-time session
5
5
  // setting, so the run gets its own short-lived pool with the same options minus the cap: one shared
6
6
  // connection would deadlock code that holds a lock in a tx while its DDL runs on another connection.
7
- // Handles not created by createDbConnection (tx, savepoint, siblings) are passed through.
7
+ // Handles not created by createDbConnection (tx, savepoint, siblings, gated runner proxies) are passed through
8
+ // unchanged and keep the cap; a caller holding such a runner lifts it itself (SET LOCAL in its own transaction).
8
9
  export async function withoutStatementTimeout(db, run) {
9
10
  const unbounded = openUnboundedSiblingPool(db);
10
11
  if (unbounded === undefined)
@@ -1,6 +1,7 @@
1
1
  /// <reference types="temporal-polyfill/global" preserve="true" />
2
+ import type { EntityDefinition, FieldDefinition, FieldsMap } from "@cosmicdrift/kumiko-types/fields";
3
+ import type { EntityRelations } from "@cosmicdrift/kumiko-types/relations";
2
4
  import type { TenancyBrand } from "@cosmicdrift/kumiko-types/tenancy-brand";
3
- import type { EntityDefinition, EntityRelations, FieldDefinition, FieldsMap } from "../engine/types/index.ts";
4
5
  import type { Table } from "./event-store-executor-context.ts";
5
6
  import type { LocatedTimestampRead } from "./located-timestamp.ts";
6
7
  import type { MoneyRead } from "./money.ts";
@@ -368,6 +368,6 @@ export function buildEntityTable(entityName, entity, options) {
368
368
  return indexes;
369
369
  });
370
370
  stampEntityTableMeta(built, entity);
371
- markExecutorManagedTable(built);
371
+ markExecutorManagedTable(built, { entityName, entity });
372
372
  return built;
373
373
  }
@@ -1,4 +1,4 @@
1
- import { camelCase as envCamelCase } from "../env/index.js";
1
+ import { camelCase as envCamelCase } from "../env/internals.js";
2
2
  import { toSnakeCase } from "./table-builder.js";
3
3
  import { asEntityTableMeta } from "./table-introspection.js";
4
4
  // Idempotent snake_case → camelCase. `env.camelCase` always lowercases first
@@ -1,6 +1,7 @@
1
- import type { EntityDefinition } from "../engine/types/index.ts";
1
+ import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
2
2
  import type { DbConnection } from "./connection.ts";
3
3
  import type { ColumnMeta, EntityTableMeta, IndexMeta } from "./entity-table-meta.ts";
4
+ import type { RowLevelSecurityMode } from "./render-rls-ddl.ts";
4
5
  /**
5
6
  * Bypass: creates an entity-table directly without going through the
6
7
  * full registry. Reserved for framework-internal meta-tables and
@@ -13,6 +14,12 @@ export declare function tableToMeta(table: unknown): EntityTableMeta;
13
14
  export declare function addMissingColumns(db: DbConnection, tableName: string, columns: readonly ColumnMeta[]): Promise<void>;
14
15
  /** CREATE [UNIQUE] INDEX IF NOT EXISTS for exactly the given indexes. */
15
16
  export declare function addMissingIndexes(db: DbConnection, tableName: string, indexes: readonly IndexMeta[]): Promise<void>;
17
+ /**
18
+ * Re-applies the row-level security DDL on a table that already exists. The create functions of
19
+ * framework tables skip the push for existing tables, so databases created before row-level
20
+ * security was switched on would never get the policies. Idempotent; no-op unless the mode is "on".
21
+ */
22
+ export declare function ensureTableRowLevelSecurity(db: DbConnection, table: unknown): Promise<void>;
16
23
  /**
17
24
  * Bypass: pushes table definitions to the database directly. Produces
18
25
  * CREATE TABLE IF NOT EXISTS + CREATE INDEX statements via renderTableDdl
@@ -21,4 +28,6 @@ export declare function addMissingIndexes(db: DbConnection, tableName: string, i
21
28
  * Reserved for framework-internal meta-tables + test setup. App-defined
22
29
  * entities go through `kumiko schema apply` (committed SQL files).
23
30
  */
24
- export declare function unsafePushTables(db: DbConnection, tables: Record<string, unknown>, prevTables?: Record<string, unknown>): Promise<void>;
31
+ export declare function unsafePushTables(db: DbConnection, tables: Record<string, unknown>, prevTables?: Record<string, unknown>, options?: {
32
+ readonly rowLevelSecurity?: RowLevelSecurityMode;
33
+ }): Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import { pgTypeToSqlType } from "./dialect.js";
2
- import { alterTableAddColumn, createIndexIfNotExists, executeDdlStatement } from "./queries/ddl.js";
2
+ import { alterTableAddColumn, applyTableRowLevelSecurity, createIndexIfNotExists, executeDdlStatement, } from "./queries/ddl.js";
3
3
  import { renderTableDdl } from "./render-ddl.js";
4
+ import { rowLevelSecurityModeOf } from "./row-level-security-connection.js";
4
5
  import { tableExists } from "./schema-inspection.js";
5
6
  import { buildEntityTable, toTableName } from "./table-builder.js";
6
7
  import { asEntityTableMeta } from "./table-introspection.js";
@@ -46,6 +47,15 @@ export async function addMissingIndexes(db, tableName, indexes) {
46
47
  await createIndexIfNotExists(db, kind, idx.name, tableName, colList, idx.whereSql);
47
48
  }
48
49
  }
50
+ /**
51
+ * Re-applies the row-level security DDL on a table that already exists. The create functions of
52
+ * framework tables skip the push for existing tables, so databases created before row-level
53
+ * security was switched on would never get the policies. Idempotent; no-op unless the mode is "on".
54
+ */
55
+ export async function ensureTableRowLevelSecurity(db, table) {
56
+ if (rowLevelSecurityModeOf(db) === "on")
57
+ await applyTableRowLevelSecurity(db, tableToMeta(table));
58
+ }
49
59
  /**
50
60
  * Bypass: pushes table definitions to the database directly. Produces
51
61
  * CREATE TABLE IF NOT EXISTS + CREATE INDEX statements via renderTableDdl
@@ -54,7 +64,8 @@ export async function addMissingIndexes(db, tableName, indexes) {
54
64
  * Reserved for framework-internal meta-tables + test setup. App-defined
55
65
  * entities go through `kumiko schema apply` (committed SQL files).
56
66
  */
57
- export async function unsafePushTables(db, tables, prevTables) {
67
+ export async function unsafePushTables(db, tables, prevTables, options = {}) {
68
+ const rowLevelSecurity = options.rowLevelSecurity ?? rowLevelSecurityModeOf(db);
58
69
  const prevMetas = new Map();
59
70
  if (prevTables) {
60
71
  for (const [key, table] of Object.entries(prevTables)) {
@@ -78,6 +89,8 @@ export async function unsafePushTables(db, tables, prevTables) {
78
89
  await executeDdlStatement(db, stmt);
79
90
  }
80
91
  }
92
+ if (rowLevelSecurity === "on")
93
+ await applyTableRowLevelSecurity(db, meta);
81
94
  }
82
95
  }
83
96
  // @wrapper-known semantic-alias
@@ -1,9 +1,11 @@
1
1
  import type { TenantDb } from "@cosmicdrift/kumiko-types/tenant-db-types";
2
+ import type { TenantId } from "../engine/types/identifiers.ts";
2
3
  import { InternalError } from "../errors/index.ts";
3
4
  import type { DbRunner } from "./connection.ts";
5
+ import { type TenantDbModeOptions } from "./row-level-security-scope.ts";
4
6
  export declare function isBoundTenantDb(value: unknown): value is TenantDb;
5
7
  export declare function isDbRunner(value: unknown): value is DbRunner;
6
- export declare function bindTenantDbRunner(tenantDb: TenantDb, runner: DbRunner): void;
8
+ export declare function bindTenantDbRunner(tenantDb: TenantDb, runner: DbRunner, modeOptions: TenantDbModeOptions, tenantId: TenantId): void;
7
9
  export declare function tenantDbRunner(tenantDb: TenantDb): DbRunner;
8
10
  export declare function denyTenantDbWrites(tenantDb: TenantDb, reason: string): void;
9
11
  export declare function tenantDbWritesDeniedReason(tenantDb: TenantDb): string | undefined;
@@ -1,5 +1,6 @@
1
1
  import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
2
2
  import { InternalError } from "../errors/index.js";
3
+ import { tenantDbRowLevelSecurityScope, withRowLevelSecurityScope, } from "./row-level-security-scope.js";
3
4
  const tenantDbRunners = new WeakMap();
4
5
  export function isBoundTenantDb(value) {
5
6
  return typeof value === "object" && value !== null && tenantDbRunners.has(value);
@@ -7,8 +8,8 @@ export function isBoundTenantDb(value) {
7
8
  export function isDbRunner(value) {
8
9
  return typeof propertyOf(value, "unsafe") === "function";
9
10
  }
10
- export function bindTenantDbRunner(tenantDb, runner) {
11
- tenantDbRunners.set(tenantDb, runner);
11
+ export function bindTenantDbRunner(tenantDb, runner, modeOptions, tenantId) {
12
+ tenantDbRunners.set(tenantDb, withRowLevelSecurityScope(runner, tenantDbRowLevelSecurityScope(modeOptions, tenantId)));
12
13
  }
13
14
  // WeakMap.get never reads a property off tenantDb — safe even when tenantDb is a
14
15
  // throwing systemScope guard Proxy that rejects every property access.
@@ -31,7 +32,7 @@ export function tenantDbWritesDeniedReason(tenantDb) {
31
32
  }
32
33
  export function tenantDbWritesDeniedError(operation, reason) {
33
34
  return new InternalError({
34
- message: `${operation}: writes are not available ${reason}; run the write through ctx.write so it gets its own transaction`,
35
+ message: `${operation}: writes are not available ${reason}; run the write through ctx.dispatch.write so it gets its own transaction`,
35
36
  });
36
37
  }
37
38
  // For framework code that writes through the raw runner (executor verbs, event appends, projection steps):
@@ -0,0 +1,10 @@
1
+ import type { TenantDb } from "@cosmicdrift/kumiko-types/tenant-db-types";
2
+ import type { DbRunner } from "./connection.ts";
3
+ type ScopedRebinder = {
4
+ readonly memberReadOnly: boolean;
5
+ readonly rebind: (runner: DbRunner) => TenantDb;
6
+ };
7
+ export declare function registerScopedRebinder(tenantDb: TenantDb, scoped: ScopedRebinder): void;
8
+ export declare function runInOwnTransaction<T>(tenantDb: TenantDb, fn: (txDb: TenantDb) => Promise<T>): Promise<T>;
9
+ export declare function runInOwnSavepoint<T>(tenantDb: TenantDb, fn: (savepointDb: TenantDb) => Promise<T>): Promise<T>;
10
+ export {};
@@ -0,0 +1,33 @@
1
+ import { InternalError } from "../errors/index.js";
2
+ import { runInNewTransaction, runInSavepointIfSupported } from "./query.js";
3
+ import { tenantDbRunner } from "./tenant-db-runner.js";
4
+ const scopedRebinders = new WeakMap();
5
+ export function registerScopedRebinder(tenantDb, scoped) {
6
+ scopedRebinders.set(tenantDb, scoped);
7
+ }
8
+ function requireScopedRebinder(tenantDb, caller) {
9
+ const scoped = scopedRebinders.get(tenantDb);
10
+ if (!scoped) {
11
+ throw new InternalError({
12
+ message: `${caller} received a TenantDb without a transaction rebinder: either it was not ` +
13
+ "built by createTenantDb, or it is the fail-closed ctx.db/ctx.db.outsideTransaction of an " +
14
+ "r.systemScope() handler (use ctx.systemDb.outsideTransaction there).",
15
+ });
16
+ }
17
+ return scoped;
18
+ }
19
+ export async function runInOwnTransaction(tenantDb, fn) {
20
+ const scoped = requireScopedRebinder(tenantDb, "runInOwnTransaction");
21
+ if (scoped.memberReadOnly) {
22
+ throw new InternalError({
23
+ message: "runInOwnTransaction: memberReadOnly TenantDb — a fresh transaction would escape " +
24
+ "the enforced read-only scope.",
25
+ });
26
+ }
27
+ return runInNewTransaction(tenantDbRunner(tenantDb), (tx) => fn(scoped.rebind(tx)));
28
+ }
29
+ // A throw inside fn rolls back only fn's statements; the caller's transaction stays usable.
30
+ export async function runInOwnSavepoint(tenantDb, fn) {
31
+ const scoped = requireScopedRebinder(tenantDb, "runInOwnSavepoint");
32
+ return runInSavepointIfSupported(tenantDbRunner(tenantDb), (sp) => fn(scoped.rebind(sp)));
33
+ }
@@ -0,0 +1,13 @@
1
+ import type { EntityTableMeta } from "@cosmicdrift/kumiko-types/entity-table-meta-types";
2
+ import type { Meter, Tracer } from "@cosmicdrift/kumiko-types/observability";
3
+ import type { SchemaTable } from "@cosmicdrift/kumiko-types/schema-table-types";
4
+ import type { TenantId } from "../engine/types/identifiers.ts";
5
+ import { type TenantDbModeOptions } from "./row-level-security-scope.ts";
6
+ export type TenantDbStatementRunnerOptions = {
7
+ readonly tracer?: Tracer | undefined;
8
+ readonly meter?: Meter | undefined;
9
+ readonly signal?: AbortSignal | undefined;
10
+ readonly tenantId: TenantId;
11
+ } & TenantDbModeOptions;
12
+ export type TenantDbOperation = "select" | "insert" | "update" | "delete";
13
+ export declare function createTenantDbStatementRunner({ tracer, meter, signal, mode, reason, tenantId, }: TenantDbStatementRunnerOptions): <T>(operation: TenantDbOperation, table: SchemaTable | EntityTableMeta, runner: () => Promise<T>) => Promise<T>;