pipework 0.251.0 → 0.252.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (730) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/core/config/load.d.ts +2 -0
  3. package/dist/core/config/load.d.ts.map +1 -1
  4. package/dist/core/config/load.js +1 -0
  5. package/dist/core/config/load.js.map +1 -1
  6. package/dist/core/config/namespace.d.ts +1 -0
  7. package/dist/core/config/namespace.d.ts.map +1 -1
  8. package/dist/core/config/schema.d.ts +2 -0
  9. package/dist/core/config/schema.d.ts.map +1 -1
  10. package/dist/core/config/schema.js +1 -0
  11. package/dist/core/config/schema.js.map +1 -1
  12. package/dist/core/surface/types.d.ts +1 -0
  13. package/dist/core/surface/types.d.ts.map +1 -1
  14. package/dist/data/db/namespace.d.ts +3 -0
  15. package/dist/data/db/namespace.d.ts.map +1 -1
  16. package/dist/data/db/namespace.js +3 -0
  17. package/dist/data/db/namespace.js.map +1 -1
  18. package/dist/data/db/pool.d.ts.map +1 -1
  19. package/dist/data/db/pool.js +6 -1
  20. package/dist/data/db/pool.js.map +1 -1
  21. package/dist/data/db/query-label.d.ts +5 -0
  22. package/dist/data/db/query-label.d.ts.map +1 -0
  23. package/dist/data/db/query-label.js +11 -0
  24. package/dist/data/db/query-label.js.map +1 -0
  25. package/dist/data/db/query-watch.d.ts +21 -0
  26. package/dist/data/db/query-watch.d.ts.map +1 -0
  27. package/dist/data/db/query-watch.js +90 -0
  28. package/dist/data/db/query-watch.js.map +1 -0
  29. package/dist/data/query/postgres-js/driver.js +1 -1
  30. package/dist/data/query/postgres-js/driver.js.map +1 -1
  31. package/dist/data/query/postgres-js/session.d.ts +5 -1
  32. package/dist/data/query/postgres-js/session.d.ts.map +1 -1
  33. package/dist/data/query/postgres-js/session.js +16 -11
  34. package/dist/data/query/postgres-js/session.js.map +1 -1
  35. package/dist/data/query/utils.d.ts +2 -0
  36. package/dist/data/query/utils.d.ts.map +1 -1
  37. package/dist/data/query/utils.js.map +1 -1
  38. package/dist/infra/credits/schema.d.ts +1 -1
  39. package/dist/test/plugin.d.ts.map +1 -1
  40. package/dist/test/plugin.js +10 -4
  41. package/dist/test/plugin.js.map +1 -1
  42. package/package.json +4 -3
  43. package/src/async/jobs/abortable-delay.ts +18 -0
  44. package/src/async/jobs/claims.ts +52 -0
  45. package/src/async/jobs/cron.ts +179 -0
  46. package/src/async/jobs/errors.ts +56 -0
  47. package/src/async/jobs/exclusion.ts +117 -0
  48. package/src/async/jobs/execute.ts +219 -0
  49. package/src/async/jobs/index.ts +10 -0
  50. package/src/async/jobs/listener.ts +135 -0
  51. package/src/async/jobs/namespace.ts +20 -0
  52. package/src/async/jobs/queue-door.ts +44 -0
  53. package/src/async/jobs/queue.ts +1012 -0
  54. package/src/async/jobs/run-script.ts +67 -0
  55. package/src/async/jobs/scheduler.ts +218 -0
  56. package/src/async/jobs/schedules-table.ts +37 -0
  57. package/src/async/jobs/serialize-error.ts +48 -0
  58. package/src/async/jobs/table.ts +191 -0
  59. package/src/async/pipeline/define.ts +53 -0
  60. package/src/async/pipeline/errors.ts +35 -0
  61. package/src/async/pipeline/execute.ts +53 -0
  62. package/src/async/pipeline/index.ts +13 -0
  63. package/src/async/pipeline/namespace.ts +12 -0
  64. package/src/async/pipeline/resume.ts +67 -0
  65. package/src/async/pipeline/run-steps.ts +98 -0
  66. package/src/async/pipeline/types.ts +57 -0
  67. package/src/async/state-machine/define.ts +64 -0
  68. package/src/async/state-machine/errors.ts +29 -0
  69. package/src/async/state-machine/index.ts +3 -0
  70. package/src/async/state-machine/namespace.ts +12 -0
  71. package/src/async/state-machine/transition.ts +90 -0
  72. package/src/async/state-machine/types.ts +37 -0
  73. package/src/async/steps/errors.ts +31 -0
  74. package/src/async/steps/graph.ts +1214 -0
  75. package/src/async/steps/hash.ts +40 -0
  76. package/src/async/steps/index.ts +7 -0
  77. package/src/async/steps/namespace.ts +7 -0
  78. package/src/async/steps/table.ts +97 -0
  79. package/src/async/steps/types.ts +318 -0
  80. package/src/audit/chain/index.ts +9 -0
  81. package/src/audit/chain/install.ts +113 -0
  82. package/src/audit/chain/retire.ts +52 -0
  83. package/src/audit/chain/verify.ts +257 -0
  84. package/src/audit/query/cursor.ts +37 -0
  85. package/src/audit/query/index.ts +9 -0
  86. package/src/audit/query/query.ts +223 -0
  87. package/src/audit/schema/audit-record-fields.ts +68 -0
  88. package/src/audit/schema/audit-record.ts +23 -0
  89. package/src/auth/auth/audit.ts +31 -0
  90. package/src/auth/auth/chain.ts +84 -0
  91. package/src/auth/auth/cookie.ts +136 -0
  92. package/src/auth/auth/email-links.ts +311 -0
  93. package/src/auth/auth/guard.ts +128 -0
  94. package/src/auth/auth/index.ts +18 -0
  95. package/src/auth/auth/multi-org.ts +337 -0
  96. package/src/auth/auth/namespace.ts +34 -0
  97. package/src/auth/auth/parse-expiry.ts +13 -0
  98. package/src/auth/auth/passwords.ts +110 -0
  99. package/src/auth/auth/schema.ts +110 -0
  100. package/src/auth/auth/sessions.ts +565 -0
  101. package/src/auth/auth/sign-in.ts +156 -0
  102. package/src/auth/auth/signing-keys.ts +69 -0
  103. package/src/auth/auth/types.ts +26 -0
  104. package/src/auth/auth/uuid.ts +10 -0
  105. package/src/auth/rbac/cache.ts +55 -0
  106. package/src/auth/rbac/check.ts +30 -0
  107. package/src/auth/rbac/create.ts +35 -0
  108. package/src/auth/rbac/index.ts +5 -0
  109. package/src/auth/rbac/middleware.ts +20 -0
  110. package/src/auth/rbac/namespace.ts +15 -0
  111. package/src/auth/rbac/resolve.ts +31 -0
  112. package/src/auth/rbac/schema.sql +31 -0
  113. package/src/auth/rbac/seed.ts +67 -0
  114. package/src/auth/rbac/tables.ts +32 -0
  115. package/src/auth/rbac/types.ts +65 -0
  116. package/src/auth/tenant/extract.ts +33 -0
  117. package/src/auth/tenant/in-tenant.ts +49 -0
  118. package/src/auth/tenant/index.ts +7 -0
  119. package/src/auth/tenant/namespace.ts +23 -0
  120. package/src/auth/tenant/propagate.ts +20 -0
  121. package/src/auth/tenant/rls.ts +120 -0
  122. package/src/auth/tenant/scope.ts +33 -0
  123. package/src/auth/tenant/scoped-db.ts +581 -0
  124. package/src/auth/tenant/types.ts +14 -0
  125. package/src/auth/tenant/validate.ts +27 -0
  126. package/src/cli/commands/add.ts +158 -0
  127. package/src/cli/commands/alerts.ts +98 -0
  128. package/src/cli/commands/check.ts +1418 -0
  129. package/src/cli/commands/codemod.ts +78 -0
  130. package/src/cli/commands/db.ts +356 -0
  131. package/src/cli/commands/dev.ts +101 -0
  132. package/src/cli/commands/generate.ts +75 -0
  133. package/src/cli/commands/init.ts +36 -0
  134. package/src/cli/commands/install.ts +28 -0
  135. package/src/cli/commands/lint.ts +62 -0
  136. package/src/cli/commands/migrate.ts +132 -0
  137. package/src/cli/commands/openapi.ts +63 -0
  138. package/src/cli/commands/remove.ts +72 -0
  139. package/src/cli/commands/run.ts +50 -0
  140. package/src/cli/commands/scope.ts +54 -0
  141. package/src/cli/commands/serve.ts +68 -0
  142. package/src/cli/commands/shard.ts +31 -0
  143. package/src/cli/commands/shared/config-pipework-version.ts +28 -0
  144. package/src/cli/commands/shared/find-config.ts +22 -0
  145. package/src/cli/commands/shared/load-config.ts +35 -0
  146. package/src/cli/commands/shared/pnpm-install.ts +95 -0
  147. package/src/cli/commands/shared/report-removed.ts +8 -0
  148. package/src/cli/commands/sync.ts +32 -0
  149. package/src/cli/commands/test.ts +307 -0
  150. package/src/cli/commands/upgrade.ts +48 -0
  151. package/src/cli/dev-bootstrap.ts +24 -0
  152. package/src/cli/errors.ts +10 -0
  153. package/src/cli/index.ts +303 -0
  154. package/src/cli/output.ts +17 -0
  155. package/src/cli/port.ts +15 -0
  156. package/src/cli/surface-kinds.ts +20 -0
  157. package/src/client/index.ts +4 -0
  158. package/src/client/poll.ts +130 -0
  159. package/src/client/report-fault.ts +119 -0
  160. package/src/core/config/app-pool.ts +19 -0
  161. package/src/core/config/aws-env.ts +29 -0
  162. package/src/core/config/base-dir.ts +24 -0
  163. package/src/core/config/discover.ts +64 -0
  164. package/src/core/config/env-resolve.ts +87 -0
  165. package/src/core/config/env-types.ts +116 -0
  166. package/src/core/config/env.ts +55 -0
  167. package/src/core/config/errors.ts +9 -0
  168. package/src/core/config/import-config.ts +40 -0
  169. package/src/core/config/index.ts +8 -0
  170. package/src/core/config/load.ts +417 -0
  171. package/src/core/config/namespace.ts +14 -0
  172. package/src/core/config/resolve.ts +195 -0
  173. package/src/core/config/schema.ts +488 -0
  174. package/src/core/config/statement-observer.ts +48 -0
  175. package/src/core/config/ts-inline-hooks.ts +75 -0
  176. package/src/core/config/ts-register.ts +4 -0
  177. package/src/core/config/ts-resolve-hooks.ts +101 -0
  178. package/src/core/errors/base.ts +49 -0
  179. package/src/core/errors/http.ts +146 -0
  180. package/src/core/errors/index.ts +2 -0
  181. package/src/core/errors/namespace.ts +31 -0
  182. package/src/core/lifecycle/drain.ts +33 -0
  183. package/src/core/lifecycle/health.ts +72 -0
  184. package/src/core/lifecycle/index.ts +4 -0
  185. package/src/core/lifecycle/namespace.ts +7 -0
  186. package/src/core/lifecycle/startup.ts +102 -0
  187. package/src/core/lifecycle/types.ts +36 -0
  188. package/src/core/logging/context.ts +60 -0
  189. package/src/core/logging/error-chain.ts +68 -0
  190. package/src/core/logging/index.ts +5 -0
  191. package/src/core/logging/logger.ts +65 -0
  192. package/src/core/logging/namespace.ts +16 -0
  193. package/src/core/logging/proxy.ts +22 -0
  194. package/src/core/logging/redact-match.ts +24 -0
  195. package/src/core/logging/types.ts +47 -0
  196. package/src/core/pipework.ts +566 -0
  197. package/src/core/runtime/broker.ts +69 -0
  198. package/src/core/surface/http.ts +133 -0
  199. package/src/core/surface/index.ts +11 -0
  200. package/src/core/surface/job-timeout.ts +40 -0
  201. package/src/core/surface/namespace.ts +13 -0
  202. package/src/core/surface/script.ts +33 -0
  203. package/src/core/surface/start.ts +142 -0
  204. package/src/core/surface/types.ts +225 -0
  205. package/src/core/surface/validate.ts +88 -0
  206. package/src/core/surface/worker.ts +528 -0
  207. package/src/core/validation/connectivity.ts +49 -0
  208. package/src/core/validation/domain.ts +99 -0
  209. package/src/core/validation/index.ts +5 -0
  210. package/src/core/validation/queue-tables.ts +312 -0
  211. package/src/core/validation/rls-role.ts +138 -0
  212. package/src/core/validation/startup.ts +51 -0
  213. package/src/core/validation/surfaces.ts +65 -0
  214. package/src/core/validation/types.ts +25 -0
  215. package/src/data/db/advisory-lock.ts +55 -0
  216. package/src/data/db/aggregates.ts +172 -0
  217. package/src/data/db/array-elements.ts +111 -0
  218. package/src/data/db/bulk-set.ts +53 -0
  219. package/src/data/db/col/index.ts +14 -0
  220. package/src/data/db/composed.ts +53 -0
  221. package/src/data/db/db.ts +276 -0
  222. package/src/data/db/excluded.ts +16 -0
  223. package/src/data/db/expressions.ts +473 -0
  224. package/src/data/db/filter.ts +90 -0
  225. package/src/data/db/function-source.ts +114 -0
  226. package/src/data/db/identifiers.ts +16 -0
  227. package/src/data/db/idx/index.ts +9 -0
  228. package/src/data/db/in-list.ts +49 -0
  229. package/src/data/db/index.ts +9 -0
  230. package/src/data/db/insert-split.ts +137 -0
  231. package/src/data/db/instrumentation.ts +82 -0
  232. package/src/data/db/maintenance.ts +28 -0
  233. package/src/data/db/namespace.ts +107 -0
  234. package/src/data/db/owner-labels.ts +9 -0
  235. package/src/data/db/pool.ts +187 -0
  236. package/src/data/db/query-label.ts +13 -0
  237. package/src/data/db/query-watch.ts +116 -0
  238. package/src/data/db/raw-client-warning.ts +37 -0
  239. package/src/data/db/readonly.ts +23 -0
  240. package/src/data/db/reservation.ts +151 -0
  241. package/src/data/db/schema-features.ts +14 -0
  242. package/src/data/db/serializable.ts +83 -0
  243. package/src/data/db/sql.ts +1 -0
  244. package/src/data/db/timeouts.ts +76 -0
  245. package/src/data/db/types.ts +18 -0
  246. package/src/data/db/unbound.ts +33 -0
  247. package/src/data/db/values.ts +29 -0
  248. package/src/data/domain/brand.ts +15 -0
  249. package/src/data/domain/build-factory.ts +193 -0
  250. package/src/data/domain/build-schema.ts +161 -0
  251. package/src/data/domain/build-table.ts +355 -0
  252. package/src/data/domain/define.ts +239 -0
  253. package/src/data/domain/external-registry.ts +34 -0
  254. package/src/data/domain/external.ts +77 -0
  255. package/src/data/domain/field.ts +279 -0
  256. package/src/data/domain/index.ts +13 -0
  257. package/src/data/domain/naming.ts +6 -0
  258. package/src/data/domain/projections.ts +57 -0
  259. package/src/data/domain/trace-safe-projection.ts +31 -0
  260. package/src/data/domain/traits.ts +108 -0
  261. package/src/data/domain/types.ts +289 -0
  262. package/src/data/jsonb/composed.ts +18 -0
  263. package/src/data/jsonb/index.ts +1 -0
  264. package/src/data/jsonb/namespace.ts +30 -0
  265. package/src/data/jsonb/query.ts +86 -0
  266. package/src/data/migrate/append-only-generate.ts +47 -0
  267. package/src/data/migrate/applied.ts +47 -0
  268. package/src/data/migrate/apply.ts +309 -0
  269. package/src/data/migrate/check.ts +119 -0
  270. package/src/data/migrate/diff.ts +357 -0
  271. package/src/data/migrate/door-generate.ts +130 -0
  272. package/src/data/migrate/framework-rls.ts +58 -0
  273. package/src/data/migrate/generate.ts +201 -0
  274. package/src/data/migrate/history.ts +215 -0
  275. package/src/data/migrate/index.ts +9 -0
  276. package/src/data/migrate/internal-definitions.ts +175 -0
  277. package/src/data/migrate/post-process.ts +73 -0
  278. package/src/data/migrate/pragma.ts +73 -0
  279. package/src/data/migrate/provision-framework.ts +147 -0
  280. package/src/data/migrate/rls-generate.ts +61 -0
  281. package/src/data/migrate/run.ts +124 -0
  282. package/src/data/migrate/safety.ts +167 -0
  283. package/src/data/migrate/snapshot.ts +368 -0
  284. package/src/data/migrate/sql-emit.ts +392 -0
  285. package/src/data/migrate/statements.ts +312 -0
  286. package/src/data/query/alias.ts +126 -0
  287. package/src/data/query/batch.ts +8 -0
  288. package/src/data/query/cache/core/cache.ts +78 -0
  289. package/src/data/query/cache/core/index.ts +1 -0
  290. package/src/data/query/cache/core/types.ts +29 -0
  291. package/src/data/query/cache/readme.md +230 -0
  292. package/src/data/query/casing.ts +76 -0
  293. package/src/data/query/collation.ts +11 -0
  294. package/src/data/query/column-builder.ts +370 -0
  295. package/src/data/query/column.ts +150 -0
  296. package/src/data/query/entity.ts +42 -0
  297. package/src/data/query/errors.ts +33 -0
  298. package/src/data/query/index.ts +14 -0
  299. package/src/data/query/logger.ts +47 -0
  300. package/src/data/query/operations.ts +45 -0
  301. package/src/data/query/pg-core/alias.ts +12 -0
  302. package/src/data/query/pg-core/checks.ts +32 -0
  303. package/src/data/query/pg-core/columns/all.ts +71 -0
  304. package/src/data/query/pg-core/columns/bigint.ts +110 -0
  305. package/src/data/query/pg-core/columns/bigserial.ts +128 -0
  306. package/src/data/query/pg-core/columns/boolean.ts +43 -0
  307. package/src/data/query/pg-core/columns/char.ts +85 -0
  308. package/src/data/query/pg-core/columns/cidr.ts +43 -0
  309. package/src/data/query/pg-core/columns/common.ts +366 -0
  310. package/src/data/query/pg-core/columns/custom.ts +232 -0
  311. package/src/data/query/pg-core/columns/date.common.ts +15 -0
  312. package/src/data/query/pg-core/columns/date.ts +112 -0
  313. package/src/data/query/pg-core/columns/double-precision.ts +55 -0
  314. package/src/data/query/pg-core/columns/enum.ts +201 -0
  315. package/src/data/query/pg-core/columns/index.ts +35 -0
  316. package/src/data/query/pg-core/columns/inet.ts +43 -0
  317. package/src/data/query/pg-core/columns/int.common.ts +57 -0
  318. package/src/data/query/pg-core/columns/integer.ts +53 -0
  319. package/src/data/query/pg-core/columns/interval.ts +83 -0
  320. package/src/data/query/pg-core/columns/json.ts +58 -0
  321. package/src/data/query/pg-core/columns/jsonb.ts +56 -0
  322. package/src/data/query/pg-core/columns/line.ts +117 -0
  323. package/src/data/query/pg-core/columns/macaddr.ts +43 -0
  324. package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
  325. package/src/data/query/pg-core/columns/numeric.ts +227 -0
  326. package/src/data/query/pg-core/columns/point.ts +127 -0
  327. package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
  328. package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
  329. package/src/data/query/pg-core/columns/real.ts +58 -0
  330. package/src/data/query/pg-core/columns/serial.ts +55 -0
  331. package/src/data/query/pg-core/columns/smallint.ts +53 -0
  332. package/src/data/query/pg-core/columns/smallserial.ts +60 -0
  333. package/src/data/query/pg-core/columns/text.ts +67 -0
  334. package/src/data/query/pg-core/columns/time.ts +72 -0
  335. package/src/data/query/pg-core/columns/timestamp.ts +163 -0
  336. package/src/data/query/pg-core/columns/uuid.ts +51 -0
  337. package/src/data/query/pg-core/columns/varchar.ts +89 -0
  338. package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
  339. package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
  340. package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
  341. package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
  342. package/src/data/query/pg-core/db.ts +674 -0
  343. package/src/data/query/pg-core/dialect.ts +1404 -0
  344. package/src/data/query/pg-core/expressions.ts +25 -0
  345. package/src/data/query/pg-core/foreign-keys.ts +130 -0
  346. package/src/data/query/pg-core/index.ts +21 -0
  347. package/src/data/query/pg-core/indexes.ts +276 -0
  348. package/src/data/query/pg-core/policies.ts +56 -0
  349. package/src/data/query/pg-core/primary-keys.ts +62 -0
  350. package/src/data/query/pg-core/query-builders/count.ts +86 -0
  351. package/src/data/query/pg-core/query-builders/delete.ts +293 -0
  352. package/src/data/query/pg-core/query-builders/index.ts +7 -0
  353. package/src/data/query/pg-core/query-builders/insert.ts +452 -0
  354. package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
  355. package/src/data/query/pg-core/query-builders/query.ts +157 -0
  356. package/src/data/query/pg-core/query-builders/raw.ts +49 -0
  357. package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
  358. package/src/data/query/pg-core/query-builders/select.ts +1346 -0
  359. package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
  360. package/src/data/query/pg-core/query-builders/update.ts +626 -0
  361. package/src/data/query/pg-core/roles.ts +41 -0
  362. package/src/data/query/pg-core/schema.ts +72 -0
  363. package/src/data/query/pg-core/sequence.ts +41 -0
  364. package/src/data/query/pg-core/session.ts +292 -0
  365. package/src/data/query/pg-core/subquery.ts +46 -0
  366. package/src/data/query/pg-core/table.ts +252 -0
  367. package/src/data/query/pg-core/unique-constraint.ts +73 -0
  368. package/src/data/query/pg-core/utils/array.ts +95 -0
  369. package/src/data/query/pg-core/utils/index.ts +1 -0
  370. package/src/data/query/pg-core/utils.ts +104 -0
  371. package/src/data/query/pg-core/view-base.ts +14 -0
  372. package/src/data/query/pg-core/view-common.ts +1 -0
  373. package/src/data/query/pg-core/view.ts +435 -0
  374. package/src/data/query/pg-core/with-builder.ts +41 -0
  375. package/src/data/query/postgres-js/README.md +46 -0
  376. package/src/data/query/postgres-js/array-parser.ts +45 -0
  377. package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
  378. package/src/data/query/postgres-js/driver.ts +163 -0
  379. package/src/data/query/postgres-js/index.ts +2 -0
  380. package/src/data/query/postgres-js/session.ts +234 -0
  381. package/src/data/query/primary-key.ts +11 -0
  382. package/src/data/query/query-builders/query-builder.ts +19 -0
  383. package/src/data/query/query-builders/select.types.ts +175 -0
  384. package/src/data/query/query-promise.ts +35 -0
  385. package/src/data/query/relations.ts +725 -0
  386. package/src/data/query/runnable-query.ts +12 -0
  387. package/src/data/query/selection-proxy.ts +121 -0
  388. package/src/data/query/session.ts +8 -0
  389. package/src/data/query/sql/expressions/conditions.ts +741 -0
  390. package/src/data/query/sql/expressions/index.ts +2 -0
  391. package/src/data/query/sql/expressions/select.ts +45 -0
  392. package/src/data/query/sql/functions/aggregate.ts +129 -0
  393. package/src/data/query/sql/functions/index.ts +2 -0
  394. package/src/data/query/sql/functions/vector.ts +178 -0
  395. package/src/data/query/sql/index.ts +3 -0
  396. package/src/data/query/sql/sql.ts +794 -0
  397. package/src/data/query/subquery.ts +53 -0
  398. package/src/data/query/table.ts +208 -0
  399. package/src/data/query/table.utils.ts +2 -0
  400. package/src/data/query/tracing-utils.ts +3 -0
  401. package/src/data/query/tracing.ts +11 -0
  402. package/src/data/query/utils.ts +357 -0
  403. package/src/data/query/version.ts +4 -0
  404. package/src/data/query/view-common.ts +1 -0
  405. package/src/data/schema/branded.ts +13 -0
  406. package/src/data/schema/generated/coerce.ts +5 -0
  407. package/src/data/schema/generated/combinator.ts +6 -0
  408. package/src/data/schema/generated/encoding.ts +5 -0
  409. package/src/data/schema/generated/error.ts +6 -0
  410. package/src/data/schema/generated/format.ts +5 -0
  411. package/src/data/schema/generated/type-constructor.ts +10 -0
  412. package/src/data/schema/generated/type.ts +6 -0
  413. package/src/data/schema/index.ts +6 -0
  414. package/src/data/schema/json-schema.ts +33 -0
  415. package/src/data/schema/namespace.ts +55 -0
  416. package/src/data/schema/parse.ts +39 -0
  417. package/src/data/schema/types.ts +39 -0
  418. package/src/data/temporal/append-only.ts +134 -0
  419. package/src/data/temporal/close.ts +27 -0
  420. package/src/data/temporal/columns.ts +10 -0
  421. package/src/data/temporal/definition-queries.ts +70 -0
  422. package/src/data/temporal/errors.ts +10 -0
  423. package/src/data/temporal/get-current.ts +22 -0
  424. package/src/data/temporal/index.ts +9 -0
  425. package/src/data/temporal/namespace.ts +36 -0
  426. package/src/data/temporal/query.ts +25 -0
  427. package/src/data/temporal/resolve.ts +17 -0
  428. package/src/data/temporal/revise.ts +67 -0
  429. package/src/data/temporal/types.ts +22 -0
  430. package/src/data/valve/artifact.ts +33 -0
  431. package/src/data/valve/contract-diff.ts +21 -0
  432. package/src/data/valve/cross.ts +57 -0
  433. package/src/data/valve/crossing-ledger.ts +50 -0
  434. package/src/data/valve/decision.ts +44 -0
  435. package/src/data/valve/durable-crossing.ts +52 -0
  436. package/src/data/valve/execute-crossing.ts +77 -0
  437. package/src/data/valve/faucet.ts +56 -0
  438. package/src/data/valve/gate.ts +114 -0
  439. package/src/data/valve/graph.ts +77 -0
  440. package/src/data/valve/index.ts +53 -0
  441. package/src/data/valve/namespace.ts +57 -0
  442. package/src/data/valve/registry.ts +50 -0
  443. package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
  444. package/src/data/valve/schema/valve-crossing.ts +9 -0
  445. package/src/data/valve/supply.ts +154 -0
  446. package/src/data/valve/types.ts +143 -0
  447. package/src/data/vector/columns.ts +27 -0
  448. package/src/data/vector/index.ts +4 -0
  449. package/src/data/vector/namespace.ts +33 -0
  450. package/src/data/vector/query.ts +85 -0
  451. package/src/data/vector/validate.ts +16 -0
  452. package/src/data/write/audit/actor.ts +15 -0
  453. package/src/data/write/audit/audit-columns.ts +18 -0
  454. package/src/data/write/audit/audit-select.ts +111 -0
  455. package/src/data/write/audit/bound-transaction.ts +14 -0
  456. package/src/data/write/audit/cte-compile.ts +32 -0
  457. package/src/data/write/audit/decode-returning.ts +47 -0
  458. package/src/data/write/audit/final-select.ts +43 -0
  459. package/src/data/write/audit/infra-audit.ts +36 -0
  460. package/src/data/write/audit/primary-key.ts +65 -0
  461. package/src/data/write/audit/projection.ts +41 -0
  462. package/src/data/write/audit/read-touches.ts +86 -0
  463. package/src/data/write/audit/touch-match.ts +78 -0
  464. package/src/data/write/audit/verb-delete.ts +62 -0
  465. package/src/data/write/audit/verb-insert.ts +36 -0
  466. package/src/data/write/audit/verb-select.ts +47 -0
  467. package/src/data/write/audit/verb-update.ts +60 -0
  468. package/src/data/write/audit/verb-upsert.ts +104 -0
  469. package/src/data/write/conflict.ts +43 -0
  470. package/src/data/write/delete.ts +38 -0
  471. package/src/data/write/execute.ts +243 -0
  472. package/src/data/write/index.ts +11 -0
  473. package/src/data/write/insert.ts +63 -0
  474. package/src/data/write/state.ts +43 -0
  475. package/src/data/write/update.ts +54 -0
  476. package/src/data/write/upsert.ts +58 -0
  477. package/src/data/write/values.ts +19 -0
  478. package/src/index.ts +230 -0
  479. package/src/infra/access-links/code.ts +70 -0
  480. package/src/infra/access-links/handle.ts +892 -0
  481. package/src/infra/access-links/index.ts +9 -0
  482. package/src/infra/access-links/namespace.ts +30 -0
  483. package/src/infra/access-links/person-check.ts +177 -0
  484. package/src/infra/access-links/schema.ts +71 -0
  485. package/src/infra/alerts/async-sources.ts +231 -0
  486. package/src/infra/alerts/audit.ts +36 -0
  487. package/src/infra/alerts/beat.ts +123 -0
  488. package/src/infra/alerts/client-faults.ts +111 -0
  489. package/src/infra/alerts/faults.ts +156 -0
  490. package/src/infra/alerts/handle.ts +778 -0
  491. package/src/infra/alerts/http.ts +192 -0
  492. package/src/infra/alerts/index.ts +12 -0
  493. package/src/infra/alerts/infra-sources.ts +180 -0
  494. package/src/infra/alerts/namespace.ts +81 -0
  495. package/src/infra/alerts/redact.ts +21 -0
  496. package/src/infra/alerts/request-faults.ts +41 -0
  497. package/src/infra/alerts/schema.ts +124 -0
  498. package/src/infra/alerts/sinks.ts +125 -0
  499. package/src/infra/alerts/source-options.ts +26 -0
  500. package/src/infra/alerts/sources.ts +503 -0
  501. package/src/infra/alerts/subsystem-sources.ts +137 -0
  502. package/src/infra/audit/emit.ts +87 -0
  503. package/src/infra/audit/index.ts +2 -0
  504. package/src/infra/audit/namespace.ts +22 -0
  505. package/src/infra/audit/schema.sql +35 -0
  506. package/src/infra/audit/types.ts +18 -0
  507. package/src/infra/aws/credentials.ts +147 -0
  508. package/src/infra/aws/sigv4.ts +140 -0
  509. package/src/infra/cache/create.ts +58 -0
  510. package/src/infra/cache/entry.ts +81 -0
  511. package/src/infra/cache/index.ts +4 -0
  512. package/src/infra/cache/namespace.ts +10 -0
  513. package/src/infra/cache/tenant.ts +93 -0
  514. package/src/infra/cache/types.ts +24 -0
  515. package/src/infra/crawl/audit.ts +35 -0
  516. package/src/infra/crawl/errors.ts +25 -0
  517. package/src/infra/crawl/handle.ts +693 -0
  518. package/src/infra/crawl/index.ts +9 -0
  519. package/src/infra/crawl/links.ts +160 -0
  520. package/src/infra/crawl/namespace.ts +36 -0
  521. package/src/infra/crawl/robots.ts +100 -0
  522. package/src/infra/crawl/schema.ts +89 -0
  523. package/src/infra/credit-line/handle.ts +883 -0
  524. package/src/infra/credit-line/index.ts +6 -0
  525. package/src/infra/credit-line/namespace.ts +7 -0
  526. package/src/infra/credit-line/schema.ts +96 -0
  527. package/src/infra/credits/handle.ts +706 -0
  528. package/src/infra/credits/index.ts +5 -0
  529. package/src/infra/credits/namespace.ts +7 -0
  530. package/src/infra/credits/schema.ts +83 -0
  531. package/src/infra/email/audit.ts +36 -0
  532. package/src/infra/email/inbound.ts +622 -0
  533. package/src/infra/email/index.ts +11 -0
  534. package/src/infra/email/mail.ts +517 -0
  535. package/src/infra/email/mime.ts +447 -0
  536. package/src/infra/email/namespace.ts +22 -0
  537. package/src/infra/email/providers.ts +111 -0
  538. package/src/infra/email/schema.ts +96 -0
  539. package/src/infra/email/sns.ts +200 -0
  540. package/src/infra/email/unsubscribe.ts +44 -0
  541. package/src/infra/fetch/address.ts +88 -0
  542. package/src/infra/fetch/connect-retry.ts +87 -0
  543. package/src/infra/fetch/handle.ts +329 -0
  544. package/src/infra/fetch/index.ts +7 -0
  545. package/src/infra/fetch/namespace.ts +70 -0
  546. package/src/infra/idempotency/index.ts +3 -0
  547. package/src/infra/idempotency/middleware.ts +87 -0
  548. package/src/infra/idempotency/store.ts +92 -0
  549. package/src/infra/idempotency/types.ts +30 -0
  550. package/src/infra/join-requests/handle.ts +312 -0
  551. package/src/infra/join-requests/index.ts +2 -0
  552. package/src/infra/join-requests/namespace.ts +7 -0
  553. package/src/infra/join-requests/schema.ts +33 -0
  554. package/src/infra/outbox/core.ts +165 -0
  555. package/src/infra/quota/errors.ts +32 -0
  556. package/src/infra/quota/handle.ts +215 -0
  557. package/src/infra/quota/index.ts +5 -0
  558. package/src/infra/quota/namespace.ts +7 -0
  559. package/src/infra/quota/schema.ts +15 -0
  560. package/src/infra/storage/backend.ts +34 -0
  561. package/src/infra/storage/handle.ts +513 -0
  562. package/src/infra/storage/index.ts +9 -0
  563. package/src/infra/storage/local.ts +104 -0
  564. package/src/infra/storage/namespace.ts +13 -0
  565. package/src/infra/storage/s3.ts +257 -0
  566. package/src/infra/storage/schema.ts +24 -0
  567. package/src/infra/support/handle.ts +854 -0
  568. package/src/infra/support/http.ts +229 -0
  569. package/src/infra/support/index.ts +7 -0
  570. package/src/infra/support/namespace.ts +12 -0
  571. package/src/infra/support/schema.ts +96 -0
  572. package/src/infra/webhook/inbound.ts +45 -0
  573. package/src/infra/webhook/index.ts +5 -0
  574. package/src/infra/webhook/namespace.ts +24 -0
  575. package/src/infra/webhook/outbound.ts +315 -0
  576. package/src/infra/webhook/sign.ts +32 -0
  577. package/src/infra/webhook/verify.ts +82 -0
  578. package/src/invariants/assert.ts +26 -0
  579. package/src/invariants/index.ts +1 -0
  580. package/src/lint/config.ts +56 -0
  581. package/src/lint/doctrine.ts +163 -0
  582. package/src/lint/include.ts +97 -0
  583. package/src/lint/index.ts +3 -0
  584. package/src/lint/preset.ts +10 -0
  585. package/src/lint/resolver.ts +218 -0
  586. package/src/lint/rules/no-reexports.ts +46 -0
  587. package/src/request/behavior/audited.ts +85 -0
  588. package/src/request/behavior/cached.ts +62 -0
  589. package/src/request/behavior/compose.ts +28 -0
  590. package/src/request/behavior/index.ts +5 -0
  591. package/src/request/behavior/namespace.ts +16 -0
  592. package/src/request/behavior/types.ts +26 -0
  593. package/src/request/behavior/versioned.ts +54 -0
  594. package/src/request/context/create.ts +103 -0
  595. package/src/request/context/guard.ts +49 -0
  596. package/src/request/context/index.ts +4 -0
  597. package/src/request/context/run-in-transaction.ts +200 -0
  598. package/src/request/context/store.ts +28 -0
  599. package/src/request/context/types.ts +50 -0
  600. package/src/request/di/builder.ts +535 -0
  601. package/src/request/di/index.ts +8 -0
  602. package/src/request/di/resolve.ts +271 -0
  603. package/src/request/di/types.ts +262 -0
  604. package/src/request/fitting/namespace.ts +7 -0
  605. package/src/request/fixture/batch.ts +71 -0
  606. package/src/request/fixture/builder.ts +26 -0
  607. package/src/request/fixture/errors.ts +10 -0
  608. package/src/request/fixture/index.ts +8 -0
  609. package/src/request/fixture/namespace.ts +23 -0
  610. package/src/request/fixture/paginate.ts +44 -0
  611. package/src/request/fixture/to-handlers.ts +260 -0
  612. package/src/request/fixture/types.ts +79 -0
  613. package/src/request/flow/act-as.ts +78 -0
  614. package/src/request/flow/namespace.ts +17 -0
  615. package/src/request/http/error-step.ts +42 -0
  616. package/src/request/http/file.ts +141 -0
  617. package/src/request/http/index.ts +4 -0
  618. package/src/request/http/middleware.ts +141 -0
  619. package/src/request/http/namespace.ts +5 -0
  620. package/src/request/http/rate-limit-classes.ts +170 -0
  621. package/src/request/http/response.ts +82 -0
  622. package/src/request/http/server.ts +916 -0
  623. package/src/request/http/sniff.ts +261 -0
  624. package/src/request/http/types.ts +250 -0
  625. package/src/request/http/upload.ts +284 -0
  626. package/src/request/internal/text.ts +6 -0
  627. package/src/request/openapi/generate.ts +205 -0
  628. package/src/request/openapi/index.ts +2 -0
  629. package/src/request/openapi/namespace.ts +7 -0
  630. package/src/test/auth.ts +13 -0
  631. package/src/test/auto-setup.ts +45 -0
  632. package/src/test/context.ts +91 -0
  633. package/src/test/crawl-fixture.ts +157 -0
  634. package/src/test/discover-fork.ts +17 -0
  635. package/src/test/fingerprint.ts +135 -0
  636. package/src/test/globals.d.ts +7 -0
  637. package/src/test/index.ts +19 -0
  638. package/src/test/namespace.ts +87 -0
  639. package/src/test/plugin.ts +189 -0
  640. package/src/test/progress.ts +185 -0
  641. package/src/test/reap-after-run.ts +28 -0
  642. package/src/test/reap.ts +286 -0
  643. package/src/test/reset.ts +253 -0
  644. package/src/test/savepoints.ts +172 -0
  645. package/src/test/setup.ts +1422 -0
  646. package/src/test/system-channel.ts +50 -0
  647. package/src/test/vitest-plugin.ts +142 -0
  648. package/src/test/vitest-workspace.ts +507 -0
  649. package/src/test/vitest.ts +333 -0
  650. package/src/test/watch.ts +105 -0
  651. package/src/trace/capture/bounded-serializer.ts +146 -0
  652. package/src/trace/cardinality/analyze.ts +173 -0
  653. package/src/trace/cardinality/branch-context.ts +214 -0
  654. package/src/trace/cardinality/check.ts +33 -0
  655. package/src/trace/cardinality/classify-edge.ts +64 -0
  656. package/src/trace/cardinality/structural-max.ts +107 -0
  657. package/src/trace/check/coverage-check.ts +188 -0
  658. package/src/trace/check/flow-check.ts +103 -0
  659. package/src/trace/check/flow-step-site.ts +234 -0
  660. package/src/trace/check/io-pattern.ts +116 -0
  661. package/src/trace/codemod/add-cardinality.ts +152 -0
  662. package/src/trace/codemod/run.ts +80 -0
  663. package/src/trace/entry/child-trace.ts +21 -0
  664. package/src/trace/entry/close-trace.ts +87 -0
  665. package/src/trace/entry/finalize-trace.ts +28 -0
  666. package/src/trace/entry/open-trace.ts +138 -0
  667. package/src/trace/entry/parent-trace.ts +20 -0
  668. package/src/trace/entry/parse-traceparent.ts +39 -0
  669. package/src/trace/entry/process-start.ts +38 -0
  670. package/src/trace/entry/trace-context.ts +26 -0
  671. package/src/trace/entry/tracing-enabled.ts +10 -0
  672. package/src/trace/external/record.ts +195 -0
  673. package/src/trace/external/report.ts +66 -0
  674. package/src/trace/namespace.ts +19 -0
  675. package/src/trace/partition/day.ts +47 -0
  676. package/src/trace/partition/index.ts +14 -0
  677. package/src/trace/partition/partition-name.ts +23 -0
  678. package/src/trace/partition/plan.ts +82 -0
  679. package/src/trace/partition/schedule.ts +26 -0
  680. package/src/trace/partition/startup-hook.ts +39 -0
  681. package/src/trace/partition/sync.ts +154 -0
  682. package/src/trace/partition/tables.ts +53 -0
  683. package/src/trace/read/tree.ts +83 -0
  684. package/src/trace/retain/copy-on-error.ts +76 -0
  685. package/src/trace/runtime/expire-stale-traces.ts +54 -0
  686. package/src/trace/runtime/flow-step.ts +147 -0
  687. package/src/trace/runtime/flush-steps.ts +31 -0
  688. package/src/trace/runtime/pending-writes.ts +54 -0
  689. package/src/trace/runtime/step-buffer.ts +298 -0
  690. package/src/trace/runtime/step-error.ts +21 -0
  691. package/src/trace/runtime/step-meta.ts +55 -0
  692. package/src/trace/runtime/thenable.ts +12 -0
  693. package/src/trace/runtime/truncate-trace.ts +62 -0
  694. package/src/trace/schema/trace-fields.ts +52 -0
  695. package/src/trace/schema/trace-retained.ts +22 -0
  696. package/src/trace/schema/trace-step-fields.ts +44 -0
  697. package/src/trace/schema/trace-step-retained.ts +25 -0
  698. package/src/trace/schema/trace-step.ts +18 -0
  699. package/src/trace/schema/trace.ts +12 -0
  700. package/src/trace/transformer/apply.ts +79 -0
  701. package/src/trace/transformer/build-meta-literal.ts +30 -0
  702. package/src/trace/transformer/find-flow-step-sites.ts +85 -0
  703. package/src/trace/transformer/inject-flow-step-import.ts +39 -0
  704. package/src/trace/transformer/transform-error.ts +14 -0
  705. package/src/trace/transformer/transform-flow-steps.ts +123 -0
  706. package/src/trace/transformer/wrap-function-declaration.ts +62 -0
  707. package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
  708. package/src/workspace/affected.ts +110 -0
  709. package/src/workspace/changed-files.ts +163 -0
  710. package/src/workspace/check-deps.ts +213 -0
  711. package/src/workspace/checksum.ts +20 -0
  712. package/src/workspace/dependency-graph.ts +67 -0
  713. package/src/workspace/detect-pipework-copies.ts +93 -0
  714. package/src/workspace/discover.ts +206 -0
  715. package/src/workspace/generate.ts +401 -0
  716. package/src/workspace/index.ts +7 -0
  717. package/src/workspace/module-imports-pipework.ts +39 -0
  718. package/src/workspace/module-package-name.ts +12 -0
  719. package/src/workspace/scrub-git-env.ts +23 -0
  720. package/src/workspace/source-paths.ts +36 -0
  721. package/src/workspace/sync.ts +182 -0
  722. package/dist/REFERENCE.md +0 -1477
  723. package/dist/infra/access-links/rate-limit.d.ts +0 -10
  724. package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
  725. package/dist/infra/access-links/rate-limit.js +0 -28
  726. package/dist/infra/access-links/rate-limit.js.map +0 -1
  727. package/dist/infra/email/sigv4.d.ts +0 -24
  728. package/dist/infra/email/sigv4.d.ts.map +0 -1
  729. package/dist/infra/email/sigv4.js +0 -55
  730. package/dist/infra/email/sigv4.js.map +0 -1
@@ -0,0 +1,357 @@
1
+ import type {
2
+ PwSnapshot,
3
+ PwTableSnapshot,
4
+ PwColumnSnapshot,
5
+ PwIndexSnapshot,
6
+ PwForeignKeySnapshot,
7
+ PwCheckSnapshot,
8
+ PwUniqueSnapshot,
9
+ PwCompositePKSnapshot,
10
+ } from './snapshot.js'
11
+
12
+ export type DiffOp =
13
+ | { type: 'create_table'; table: PwTableSnapshot }
14
+ | { type: 'drop_table'; table: PwTableSnapshot }
15
+ | { type: 'add_column'; tableName: string; tableSchema: string; column: PwColumnSnapshot }
16
+ | { type: 'drop_column'; tableName: string; tableSchema: string; column: PwColumnSnapshot }
17
+ | { type: 'alter_column_type'; tableName: string; tableSchema: string; column: string; from: string; to: string; collation?: string | undefined }
18
+ | { type: 'alter_column_set_not_null'; tableName: string; tableSchema: string; column: string }
19
+ | { type: 'alter_column_drop_not_null'; tableName: string; tableSchema: string; column: string }
20
+ | { type: 'alter_column_set_default'; tableName: string; tableSchema: string; column: string; value: string }
21
+ | { type: 'alter_column_drop_default'; tableName: string; tableSchema: string; column: string }
22
+ | { type: 'alter_column_set_generated'; tableName: string; tableSchema: string; column: PwColumnSnapshot }
23
+ | { type: 'alter_column_drop_generated'; tableName: string; tableSchema: string; column: string }
24
+ | { type: 'alter_column_set_identity'; tableName: string; tableSchema: string; column: PwColumnSnapshot }
25
+ | { type: 'alter_column_drop_identity'; tableName: string; tableSchema: string; column: string }
26
+ | { type: 'create_index'; tableName: string; tableSchema: string; index: PwIndexSnapshot }
27
+ | { type: 'drop_index'; tableName: string; tableSchema: string; index: PwIndexSnapshot }
28
+ | { type: 'replace_index'; tableName: string; tableSchema: string; from: PwIndexSnapshot; to: PwIndexSnapshot }
29
+ | { type: 'add_foreign_key'; tableName: string; tableSchema: string; fk: PwForeignKeySnapshot; tablePartitioned: boolean }
30
+ | { type: 'drop_foreign_key'; tableName: string; tableSchema: string; fk: PwForeignKeySnapshot }
31
+ | { type: 'add_check'; tableName: string; tableSchema: string; check: PwCheckSnapshot }
32
+ | { type: 'drop_check'; tableName: string; tableSchema: string; check: PwCheckSnapshot }
33
+ | { type: 'add_unique'; tableName: string; tableSchema: string; unique: PwUniqueSnapshot; tablePartitioned: boolean }
34
+ | { type: 'replace_unique'; tableName: string; tableSchema: string; from: PwUniqueSnapshot; to: PwUniqueSnapshot; tablePartitioned: boolean }
35
+ | { type: 'drop_unique'; tableName: string; tableSchema: string; unique: PwUniqueSnapshot }
36
+ | { type: 'add_composite_pk'; tableName: string; tableSchema: string; pk: PwCompositePKSnapshot; tablePartitioned: boolean }
37
+ | { type: 'replace_composite_pk'; tableName: string; tableSchema: string; from: PwCompositePKSnapshot; to: PwCompositePKSnapshot; tablePartitioned: boolean }
38
+ | { type: 'drop_composite_pk'; tableName: string; tableSchema: string; pk: PwCompositePKSnapshot }
39
+
40
+ /** The wire name of the table an op acts on, across all `DiffOp` shapes. */
41
+ export function diffOpTableName(op: DiffOp): string {
42
+ return op.type === 'create_table' || op.type === 'drop_table' ? op.table.name : op.tableName
43
+ }
44
+
45
+ export function diffSnapshots(prev: PwSnapshot, cur: PwSnapshot): DiffOp[] {
46
+ const ops: DiffOp[] = []
47
+
48
+ const prevKeys = new Set(Object.keys(prev.tables))
49
+ const curKeys = new Set(Object.keys(cur.tables))
50
+
51
+ // Phase 0: A table's partitioning is fixed at creation — Postgres has no
52
+ // ALTER TABLE ... PARTITION BY. A changed strategy is a manual migration.
53
+ for (const key of prevKeys) {
54
+ if (!curKeys.has(key)) continue
55
+ assertPartitioningUnchanged(prev.tables[key]!, cur.tables[key]!)
56
+ }
57
+
58
+ // Phase 1: Drop constraints and indexes from tables that will be modified or dropped
59
+ for (const key of prevKeys) {
60
+ if (!curKeys.has(key)) continue
61
+ const prevTable = prev.tables[key]!
62
+ const curTable = cur.tables[key]!
63
+ diffDropConstraints(prevTable, curTable, ops)
64
+ }
65
+
66
+ // Phase 2: Drop tables
67
+ for (const key of prevKeys) {
68
+ if (!curKeys.has(key)) {
69
+ ops.push({ type: 'drop_table', table: prev.tables[key]! })
70
+ }
71
+ }
72
+
73
+ // Phase 3: Create tables
74
+ for (const key of curKeys) {
75
+ if (!prevKeys.has(key)) {
76
+ ops.push({ type: 'create_table', table: cur.tables[key]! })
77
+ }
78
+ }
79
+
80
+ // Phase 4: Alter columns on shared tables
81
+ for (const key of prevKeys) {
82
+ if (!curKeys.has(key)) continue
83
+ const prevTable = prev.tables[key]!
84
+ const curTable = cur.tables[key]!
85
+ diffColumns(prevTable, curTable, ops)
86
+ }
87
+
88
+ // Phase 5: Add constraints and indexes to modified or new tables
89
+ for (const key of prevKeys) {
90
+ if (!curKeys.has(key)) continue
91
+ const prevTable = prev.tables[key]!
92
+ const curTable = cur.tables[key]!
93
+ diffAddConstraints(prevTable, curTable, ops)
94
+ }
95
+
96
+ return ops
97
+ }
98
+
99
+ function diffDropConstraints(prev: PwTableSnapshot, cur: PwTableSnapshot, ops: DiffOp[]): void {
100
+ const tn = prev.name
101
+ const ts = prev.schema
102
+
103
+ for (const name of Object.keys(prev.foreignKeys)) {
104
+ const prevFk = prev.foreignKeys[name]!
105
+ const curFk = cur.foreignKeys[name]
106
+ if (curFk === undefined || !fkEqual(prevFk, curFk)) {
107
+ ops.push({ type: 'drop_foreign_key', tableName: tn, tableSchema: ts, fk: prevFk })
108
+ }
109
+ }
110
+
111
+ for (const name of Object.keys(prev.indexes)) {
112
+ const prevIdx = prev.indexes[name]!
113
+ const curIdx = cur.indexes[name]
114
+ if (curIdx === undefined) {
115
+ ops.push({ type: 'drop_index', tableName: tn, tableSchema: ts, index: prevIdx })
116
+ }
117
+ }
118
+
119
+ for (const name of Object.keys(prev.checks)) {
120
+ const prevChk = prev.checks[name]!
121
+ const curChk = cur.checks[name]
122
+ if (curChk === undefined || prevChk.value !== curChk.value) {
123
+ ops.push({ type: 'drop_check', tableName: tn, tableSchema: ts, check: prevChk })
124
+ }
125
+ }
126
+
127
+ for (const name of Object.keys(prev.uniqueConstraints)) {
128
+ const prevUc = prev.uniqueConstraints[name]!
129
+ const curUc = cur.uniqueConstraints[name]
130
+ if (curUc === undefined || (!uniqueEqual(prevUc, curUc) && !canSwapOnline(prev, cur, prevUc.columns))) {
131
+ ops.push({ type: 'drop_unique', tableName: tn, tableSchema: ts, unique: prevUc })
132
+ }
133
+ }
134
+
135
+ for (const name of Object.keys(prev.compositePrimaryKeys)) {
136
+ const prevPk = prev.compositePrimaryKeys[name]!
137
+ const curPk = cur.compositePrimaryKeys[name]
138
+ if (curPk === undefined || (!arraysEqual(prevPk.columns, curPk.columns) && !canSwapOnline(prev, cur, prevPk.columns))) {
139
+ ops.push({ type: 'drop_composite_pk', tableName: tn, tableSchema: ts, pk: prevPk })
140
+ }
141
+ }
142
+ }
143
+
144
+ function diffColumns(prev: PwTableSnapshot, cur: PwTableSnapshot, ops: DiffOp[]): void {
145
+ const tn = prev.name
146
+ const ts = prev.schema
147
+
148
+ const prevCols = new Set(Object.keys(prev.columns))
149
+ const curCols = new Set(Object.keys(cur.columns))
150
+
151
+ for (const name of prevCols) {
152
+ if (!curCols.has(name)) {
153
+ ops.push({ type: 'drop_column', tableName: tn, tableSchema: ts, column: prev.columns[name]! })
154
+ }
155
+ }
156
+
157
+ for (const name of curCols) {
158
+ if (!prevCols.has(name)) {
159
+ ops.push({ type: 'add_column', tableName: tn, tableSchema: ts, column: cur.columns[name]! })
160
+ }
161
+ }
162
+
163
+ for (const name of prevCols) {
164
+ if (!curCols.has(name)) continue
165
+ const prevCol = prev.columns[name]!
166
+ const curCol = cur.columns[name]!
167
+
168
+ if (prevCol.type !== curCol.type || prevCol.collation !== curCol.collation) {
169
+ ops.push({ type: 'alter_column_type', tableName: tn, tableSchema: ts, column: name, from: prevCol.type, to: curCol.type, collation: curCol.collation ?? (prevCol.collation !== undefined ? '"default"' : undefined) })
170
+ }
171
+
172
+ if (!prevCol.notNull && curCol.notNull) {
173
+ ops.push({ type: 'alter_column_set_not_null', tableName: tn, tableSchema: ts, column: name })
174
+ }
175
+ if (prevCol.notNull && !curCol.notNull) {
176
+ ops.push({ type: 'alter_column_drop_not_null', tableName: tn, tableSchema: ts, column: name })
177
+ }
178
+
179
+ if (prevCol.default !== curCol.default) {
180
+ if (curCol.default !== undefined) {
181
+ ops.push({ type: 'alter_column_set_default', tableName: tn, tableSchema: ts, column: name, value: curCol.default })
182
+ } else {
183
+ ops.push({ type: 'alter_column_drop_default', tableName: tn, tableSchema: ts, column: name })
184
+ }
185
+ }
186
+
187
+ if (prevCol.generated === undefined && curCol.generated !== undefined) {
188
+ ops.push({ type: 'alter_column_set_generated', tableName: tn, tableSchema: ts, column: curCol })
189
+ }
190
+ if (prevCol.generated !== undefined && curCol.generated === undefined) {
191
+ ops.push({ type: 'alter_column_drop_generated', tableName: tn, tableSchema: ts, column: name })
192
+ }
193
+ if (prevCol.generated !== undefined && curCol.generated !== undefined && prevCol.generated.as !== curCol.generated.as) {
194
+ ops.push({ type: 'alter_column_drop_generated', tableName: tn, tableSchema: ts, column: name })
195
+ ops.push({ type: 'alter_column_set_generated', tableName: tn, tableSchema: ts, column: curCol })
196
+ }
197
+
198
+ if (prevCol.identity === undefined && curCol.identity !== undefined) {
199
+ ops.push({ type: 'alter_column_set_identity', tableName: tn, tableSchema: ts, column: curCol })
200
+ }
201
+ if (prevCol.identity !== undefined && curCol.identity === undefined) {
202
+ ops.push({ type: 'alter_column_drop_identity', tableName: tn, tableSchema: ts, column: name })
203
+ }
204
+ if (prevCol.identity !== undefined && curCol.identity !== undefined && prevCol.identity.type !== curCol.identity.type) {
205
+ ops.push({ type: 'alter_column_drop_identity', tableName: tn, tableSchema: ts, column: name })
206
+ ops.push({ type: 'alter_column_set_identity', tableName: tn, tableSchema: ts, column: curCol })
207
+ }
208
+ }
209
+ }
210
+
211
+ function diffAddConstraints(prev: PwTableSnapshot, cur: PwTableSnapshot, ops: DiffOp[]): void {
212
+ const tn = cur.name
213
+ const ts = cur.schema
214
+ const partitioned = cur.partitionBy !== undefined
215
+
216
+ for (const name of Object.keys(cur.compositePrimaryKeys)) {
217
+ const prevPk = prev.compositePrimaryKeys[name]
218
+ const curPk = cur.compositePrimaryKeys[name]!
219
+ if (prevPk === undefined || !arraysEqual(prevPk.columns, curPk.columns)) {
220
+ if (prevPk !== undefined && canSwapOnline(prev, cur, prevPk.columns)) {
221
+ ops.push({ type: 'replace_composite_pk', tableName: tn, tableSchema: ts, from: prevPk, to: curPk, tablePartitioned: partitioned })
222
+ } else {
223
+ assertNoIndexNamed(cur, name, 'primary key')
224
+ ops.push({ type: 'add_composite_pk', tableName: tn, tableSchema: ts, pk: curPk, tablePartitioned: partitioned })
225
+ }
226
+ }
227
+ }
228
+
229
+ for (const name of Object.keys(cur.uniqueConstraints)) {
230
+ const prevUc = prev.uniqueConstraints[name]
231
+ const curUc = cur.uniqueConstraints[name]!
232
+ if (prevUc === undefined || !uniqueEqual(prevUc, curUc)) {
233
+ if (prevUc !== undefined && canSwapOnline(prev, cur, prevUc.columns)) {
234
+ ops.push({ type: 'replace_unique', tableName: tn, tableSchema: ts, from: prevUc, to: curUc, tablePartitioned: partitioned })
235
+ } else {
236
+ assertNoIndexNamed(cur, name, 'unique constraint')
237
+ ops.push({ type: 'add_unique', tableName: tn, tableSchema: ts, unique: curUc, tablePartitioned: partitioned })
238
+ }
239
+ }
240
+ }
241
+
242
+ for (const name of Object.keys(cur.checks)) {
243
+ const prevChk = prev.checks[name]
244
+ const curChk = cur.checks[name]!
245
+ if (prevChk === undefined || prevChk.value !== curChk.value) {
246
+ ops.push({ type: 'add_check', tableName: tn, tableSchema: ts, check: curChk })
247
+ }
248
+ }
249
+
250
+ for (const name of Object.keys(cur.indexes)) {
251
+ const prevIdx = prev.indexes[name]
252
+ const curIdx = cur.indexes[name]!
253
+ if (prevIdx === undefined) {
254
+ ops.push({ type: 'create_index', tableName: tn, tableSchema: ts, index: curIdx })
255
+ } else if (!indexEqual(prevIdx, curIdx)) {
256
+ ops.push({ type: 'replace_index', tableName: tn, tableSchema: ts, from: prevIdx, to: curIdx })
257
+ }
258
+ }
259
+
260
+ for (const name of Object.keys(cur.foreignKeys)) {
261
+ const prevFk = prev.foreignKeys[name]
262
+ const curFk = cur.foreignKeys[name]!
263
+ if (prevFk === undefined || !fkEqual(prevFk, curFk)) {
264
+ ops.push({ type: 'add_foreign_key', tableName: tn, tableSchema: ts, fk: curFk, tablePartitioned: cur.partitionBy !== undefined })
265
+ }
266
+ }
267
+ }
268
+
269
+ /**
270
+ * A changed key constraint is swapped in one statement (new index built
271
+ * beside it first) only while the old key's columns survive the migration
272
+ * unchanged; otherwise the old constraint is dropped up front, as before.
273
+ */
274
+ function canSwapOnline(prev: PwTableSnapshot, cur: PwTableSnapshot, oldColumns: string[]): boolean {
275
+ return oldColumns.every(c => {
276
+ const p = prev.columns[c]
277
+ const n = cur.columns[c]
278
+ return p !== undefined && n !== undefined && p.type === n.type && p.collation === n.collation
279
+ })
280
+ }
281
+
282
+ /**
283
+ * An added key constraint builds its index under the constraint's name after
284
+ * clearing any leftover of that name, so a declared index may not share it.
285
+ */
286
+ function assertNoIndexNamed(cur: PwTableSnapshot, name: string, what: string): void {
287
+ if (cur.indexes[name] === undefined) return
288
+ throw new Error(
289
+ `[pipework] The ${what} "${name}" on "${cur.name}" has the same name as an index on that table. ` +
290
+ 'Give one of them another name.',
291
+ )
292
+ }
293
+
294
+ function fkEqual(a: PwForeignKeySnapshot, b: PwForeignKeySnapshot): boolean {
295
+ return a.foreignTable === b.foreignTable
296
+ && a.foreignSchema === b.foreignSchema
297
+ && a.onUpdate === b.onUpdate
298
+ && a.onDelete === b.onDelete
299
+ && (a.onDeleteColumns === undefined || b.onDeleteColumns === undefined
300
+ ? a.onDeleteColumns === b.onDeleteColumns
301
+ : arraysEqual(a.onDeleteColumns, b.onDeleteColumns))
302
+ && arraysEqual(a.columns, b.columns)
303
+ && arraysEqual(a.foreignColumns, b.foreignColumns)
304
+ }
305
+
306
+ function withEqual(a: Record<string, unknown> | undefined, b: Record<string, unknown> | undefined): boolean {
307
+ const ae = Object.entries(a ?? {}).sort(([x], [y]) => x.localeCompare(y))
308
+ const be = Object.entries(b ?? {}).sort(([x], [y]) => x.localeCompare(y))
309
+ return ae.length === be.length && ae.every(([k, v], i) => be[i]![0] === k && be[i]![1] === v)
310
+ }
311
+
312
+ function indexEqual(a: PwIndexSnapshot, b: PwIndexSnapshot): boolean {
313
+ if (a.unique !== b.unique || a.method !== b.method || a.where !== b.where) return false
314
+ if ((a.nullsNotDistinct ?? false) !== (b.nullsNotDistinct ?? false)) return false
315
+ if (!withEqual(a.with, b.with)) return false
316
+ const ai = a.include ?? []
317
+ const bi = b.include ?? []
318
+ if (ai.length !== bi.length || ai.some((c, i) => c !== bi[i])) return false
319
+ if (a.columns.length !== b.columns.length) return false
320
+ for (let i = 0; i < a.columns.length; i++) {
321
+ const ac = a.columns[i]!
322
+ const bc = b.columns[i]!
323
+ if (ac.expression !== bc.expression || ac.isExpression !== bc.isExpression
324
+ || ac.order !== bc.order || ac.nulls !== bc.nulls || ac.opClass !== bc.opClass || ac.collation !== bc.collation) {
325
+ return false
326
+ }
327
+ }
328
+ return true
329
+ }
330
+
331
+ function uniqueEqual(a: PwUniqueSnapshot, b: PwUniqueSnapshot): boolean {
332
+ return a.nullsNotDistinct === b.nullsNotDistinct && arraysEqual(a.columns, b.columns)
333
+ }
334
+
335
+ function assertPartitioningUnchanged(prev: PwTableSnapshot, cur: PwTableSnapshot): void {
336
+ const p = prev.partitionBy
337
+ const c = cur.partitionBy
338
+ if (p === undefined && c === undefined) return
339
+ if (p !== undefined && c !== undefined && p.column === c.column) return
340
+
341
+ const describe = (s: typeof p): string =>
342
+ s === undefined ? 'not partitioned' : `${s.strategy} (${s.column})`
343
+
344
+ throw new Error(
345
+ `[pipework] Cannot change the partitioning of "${cur.name}" — ${describe(p)} → ${describe(c)}.\n\n` +
346
+ ' Postgres has no ALTER TABLE ... PARTITION BY; partitioning is fixed at table creation.\n' +
347
+ ' Changing it requires a manual migration that recreates the table and moves its rows.\n',
348
+ )
349
+ }
350
+
351
+ function arraysEqual(a: string[], b: string[]): boolean {
352
+ if (a.length !== b.length) return false
353
+ for (let i = 0; i < a.length; i++) {
354
+ if (a[i] !== b[i]) return false
355
+ }
356
+ return true
357
+ }
@@ -0,0 +1,130 @@
1
+ import type { DefinedTable } from '../domain/types.js'
2
+ import type { ResolvedDoor } from '../../core/config/load.js'
3
+ import { ConfigError } from '../../core/config/errors.js'
4
+ import { quoteIdentifier } from '../db/identifiers.js'
5
+
6
+ /** The setting a door's policy reads; `pipe.door()` sets it for one transaction. */
7
+ export const DOOR_SETTING = 'pipework.door'
8
+
9
+ /** What a snapshot remembers of a door, so the next generate can tell an added, removed or moved one. */
10
+ export interface DoorSnapshot {
11
+ readonly table: string
12
+ readonly role: string
13
+ /** Present only for a door that also writes (pipework's own); an app door is SELECT-only. */
14
+ readonly ops?: readonly DoorOp[]
15
+ }
16
+
17
+ export type DoorOp = 'select' | 'update' | 'delete'
18
+
19
+ /** The operations a door opens beyond SELECT, which every door has. */
20
+ const writes = (snapshot: DoorSnapshot): DoorOp[] =>
21
+ (['update', 'delete'] as const).filter(op => snapshot.ops?.includes(op) === true)
22
+ const sameDoor = (a: DoorSnapshot, b: DoorSnapshot): boolean =>
23
+ a.table === b.table && a.role === b.role && writes(a).join() === writes(b).join()
24
+
25
+ export function doorOpPolicyName(door: string, op: 'update' | 'delete'): string {
26
+ return `${doorPolicyName(door)}__${op}`
27
+ }
28
+
29
+ export function doorDeletePolicyName(door: string): string {
30
+ return doorOpPolicyName(door, 'delete')
31
+ }
32
+
33
+ export function doorPolicyName(door: string): string {
34
+ return `pipework_door_${door.replace(/\./g, '__')}`
35
+ }
36
+
37
+ function sqlString(value: string): string {
38
+ return `'${value.replace(/'/g, "''")}'`
39
+ }
40
+
41
+ export function createDoorPolicy(door: string, snapshot: DoorSnapshot): string {
42
+ return `CREATE POLICY ${quoteIdentifier(doorPolicyName(door), 'policy')} ON ${quoteIdentifier(snapshot.table, 'table')} ` +
43
+ `AS PERMISSIVE FOR SELECT TO ${quoteIdentifier(snapshot.role, 'role')} ` +
44
+ `USING (current_setting('${DOOR_SETTING}', true) = ${sqlString(door)})`
45
+ }
46
+
47
+ export function createDoorOpPolicy(door: string, snapshot: DoorSnapshot, op: 'update' | 'delete'): string {
48
+ return `CREATE POLICY ${quoteIdentifier(doorOpPolicyName(door, op), 'policy')} ON ${quoteIdentifier(snapshot.table, 'table')} ` +
49
+ `AS PERMISSIVE FOR ${op.toUpperCase()} TO ${quoteIdentifier(snapshot.role, 'role')} ` +
50
+ `USING (current_setting('${DOOR_SETTING}', true) = ${sqlString(door)})`
51
+ }
52
+
53
+ export function createDoorDeletePolicy(door: string, snapshot: DoorSnapshot): string {
54
+ return createDoorOpPolicy(door, snapshot, 'delete')
55
+ }
56
+
57
+ export function dropDoorOpPolicy(door: string, snapshot: DoorSnapshot, op: 'update' | 'delete'): string {
58
+ return `DROP POLICY IF EXISTS ${quoteIdentifier(doorOpPolicyName(door, op), 'policy')} ON ${quoteIdentifier(snapshot.table, 'table')}`
59
+ }
60
+
61
+ export function dropDoorDeletePolicy(door: string, snapshot: DoorSnapshot): string {
62
+ return dropDoorOpPolicy(door, snapshot, 'delete')
63
+ }
64
+
65
+ export function dropDoorPolicy(door: string, snapshot: DoorSnapshot): string {
66
+ return `DROP POLICY IF EXISTS ${quoteIdentifier(doorPolicyName(door), 'policy')} ON ${quoteIdentifier(snapshot.table, 'table')}`
67
+ }
68
+
69
+ /**
70
+ * The doors a database's migrations must carry: its declared doors when it is
71
+ * in platform mode, none otherwise. Each door's table must be tenant-scoped in
72
+ * a definition — any other table needs no door, and the platform role reads it
73
+ * on its ordinary grants.
74
+ */
75
+ export function doorSnapshots(
76
+ doors: readonly ResolvedDoor[],
77
+ platformRole: string | undefined,
78
+ definitions: ReadonlyMap<string, DefinedTable>,
79
+ ): Record<string, DoorSnapshot> {
80
+ if (platformRole === undefined) return {}
81
+ const out: Record<string, DoorSnapshot> = {}
82
+ for (const door of doors) {
83
+ if (door.framework === true) {
84
+ const ops = door.ops?.filter(op => op !== 'select') ?? []
85
+ out[door.name] = { table: door.table, role: platformRole, ...(ops.length > 0 ? { ops: ['select', ...ops] as const } : {}) }
86
+ continue
87
+ }
88
+ const definition = definitions.get(door.table)
89
+ const tenanted = definition !== undefined
90
+ && Object.values(definition.$fields).some(field => field._meta.tenant === true)
91
+ if (!tenanted) {
92
+ throw new ConfigError(
93
+ `Door "${door.name}" names table "${door.table}", which is not tenant-scoped in any definition.`,
94
+ definition === undefined
95
+ ? `No definition produces a table named "${door.table}". Door tables are SQL names of tables defined with a .tenant() field.`
96
+ : `"${door.table}" has no .tenant() field, so row-level security does not hide it from the platform role and it needs no door. Remove the door.`,
97
+ )
98
+ }
99
+ out[door.name] = { table: door.table, role: platformRole }
100
+ }
101
+ return out
102
+ }
103
+
104
+ /** Statements that move a database from the doors `prev` recorded to the doors `cur` declares. A door whose table, role or operations changed is dropped from the old table and created on the new. */
105
+ export function diffDoors(
106
+ prev: Readonly<Record<string, DoorSnapshot>> | undefined,
107
+ cur: Readonly<Record<string, DoorSnapshot>>,
108
+ ): string[] {
109
+ const before = prev ?? {}
110
+ const statements: string[] = []
111
+ for (const [name, old] of Object.entries(before)) {
112
+ const now = cur[name]
113
+ if (now !== undefined && sameDoor(old, now)) continue
114
+ statements.push(dropDoorPolicy(name, old))
115
+ for (const op of writes(old) as Array<'update' | 'delete'>) statements.push(dropDoorOpPolicy(name, old, op))
116
+ }
117
+ for (const [name, now] of Object.entries(cur)) {
118
+ const old = before[name]
119
+ if (old !== undefined && sameDoor(old, now)) continue
120
+ statements.push(createDoorPolicy(name, now))
121
+ for (const op of writes(now) as Array<'update' | 'delete'>) statements.push(createDoorOpPolicy(name, now, op))
122
+ }
123
+ return statements
124
+ }
125
+
126
+ /** The name prefix reserved for doors pipework declares itself. */
127
+ export const FRAMEWORK_DOOR_PREFIX = 'pipework.'
128
+
129
+ /** The storage sweep's door: it reads and deletes `storage_file` across tenants. */
130
+ export const STORAGE_SWEEP_DOOR = 'pipework.storage_sweep'
@@ -0,0 +1,58 @@
1
+ // Row-level security for the built-in tenant tables. They are provisioned by
2
+ // `provisionFrameworkTables`, not through generated migrations, so
3
+ // `rls-generate` never sees them. When the default database configures `rls`,
4
+ // each gets the same tenant rule as an application table, split by command:
5
+ //
6
+ // pipework_tenant_read SELECT tenant matches the session setting, or a maintenance transaction
7
+ // pipework_tenant_update UPDATE same
8
+ // pipework_tenant_insert INSERT anything: the framework writes traces and audit rows
9
+ // for any tenant, and for none, from connections that
10
+ // carry no tenant setting
11
+ //
12
+ // No DELETE policy except on audit_record: retention drops partitions, and audit_record is
13
+ // append-only. Its one DELETE policy admits a maintenance pass that has named the tenant being
14
+ // erased (`audit.removeTenant`), and only that tenant's rows.
15
+
16
+ import { sql } from '../db/sql.js'
17
+ import type { DB } from '../db/index.js'
18
+ import { quoteIdentifier } from '../db/identifiers.js'
19
+ import { tenantUsingClause } from '../../auth/tenant/rls.js'
20
+ import { validateSessionVarName } from '../../auth/tenant/validate.js'
21
+ import { MAINTENANCE_CLAUSE } from '../db/maintenance.js'
22
+ import { AUDIT_ERASE_SETTING } from '../../audit/chain/install.js'
23
+
24
+ export const AUDIT_ERASE_POLICY = 'pipework_audit_erase'
25
+
26
+ export const FRAMEWORK_POLICY_NAMES = ['pipework_tenant_read', 'pipework_tenant_update', 'pipework_tenant_insert'] as const
27
+
28
+ export interface FrameworkRls {
29
+ readonly sessionVar: string
30
+ readonly force: boolean
31
+ }
32
+
33
+ /** Statements that (re)install the policies on `table`. Safe to run again. */
34
+ export function frameworkTablePolicies(table: string, rls: FrameworkRls): string[] {
35
+ validateSessionVarName(rls.sessionVar)
36
+ const t = quoteIdentifier(table, 'table')
37
+ const visible = `(${tenantUsingClause('tenant_id', 'uuid', rls.sessionVar)} OR ${MAINTENANCE_CLAUSE})`
38
+ const policy = (name: string) => quoteIdentifier(name, 'policy')
39
+ return [
40
+ `ALTER TABLE ${t} ENABLE ROW LEVEL SECURITY`,
41
+ `ALTER TABLE ${t} ${rls.force ? 'FORCE' : 'NO FORCE'} ROW LEVEL SECURITY`,
42
+ ...FRAMEWORK_POLICY_NAMES.map(name => `DROP POLICY IF EXISTS ${policy(name)} ON ${t}`),
43
+ `CREATE POLICY ${policy('pipework_tenant_read')} ON ${t} FOR SELECT USING ${visible}`,
44
+ `CREATE POLICY ${policy('pipework_tenant_update')} ON ${t} FOR UPDATE USING ${visible}`,
45
+ `CREATE POLICY ${policy('pipework_tenant_insert')} ON ${t} FOR INSERT WITH CHECK (true)`,
46
+ `DROP POLICY IF EXISTS ${policy(AUDIT_ERASE_POLICY)} ON ${t}`,
47
+ ...(table === 'audit_record'
48
+ ? [`CREATE POLICY ${policy(AUDIT_ERASE_POLICY)} ON ${t} FOR DELETE USING ` +
49
+ `(${MAINTENANCE_CLAUSE} AND tenant_id::text = current_setting('${AUDIT_ERASE_SETTING}', true))`]
50
+ : []),
51
+ ]
52
+ }
53
+
54
+ export async function installFrameworkPolicies(db: DB, tables: readonly string[], rls: FrameworkRls): Promise<void> {
55
+ for (const table of tables) {
56
+ for (const statement of frameworkTablePolicies(table, rls)) await db.execute(sql.raw(statement))
57
+ }
58
+ }