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,25 @@
1
+ /** Which subsystem produced the validation issue. */
2
+ export type ValidationPhase = 'config' | 'workspace' | 'database' | 'domain' | 'surface'
3
+
4
+ /** A single validation problem with its phase and human-readable message. */
5
+ export interface ValidationIssue {
6
+ readonly phase: ValidationPhase
7
+ readonly message: string
8
+ }
9
+
10
+ /** Thrown when startup validation finds issues — lists all problems across all phases. */
11
+ export class StartupValidationError extends Error {
12
+ readonly issues: readonly ValidationIssue[]
13
+
14
+ constructor(issues: readonly ValidationIssue[]) {
15
+ const summary = issues
16
+ .map(i => ` [${i.phase}]${' '.repeat(Math.max(1, 12 - i.phase.length))}${i.message}`)
17
+ .join('\n')
18
+
19
+ super(
20
+ `Startup validation failed (${String(issues.length)} issue${issues.length === 1 ? '' : 's'}):\n\n${summary}\n\nFix these issues and restart.`,
21
+ )
22
+ this.name = 'StartupValidationError'
23
+ this.issues = issues
24
+ }
25
+ }
@@ -0,0 +1,55 @@
1
+ import { sql } from './sql.js'
2
+ import type { DB, SQL } from './types.js'
3
+ import { unscopedExecutor } from '../../auth/tenant/scoped-db.js'
4
+
5
+ /** Validates the key arguments and builds the lock-argument fragment shared by
6
+ * advisoryLock and tryAdvisoryLock, so the two can never disagree about a key. */
7
+ function lockArguments(fn: string, first: string | number | undefined, rest: string[]): SQL {
8
+ if (typeof first === 'number') {
9
+ const key = rest[0]
10
+ if (key === undefined) {
11
+ throw new Error(
12
+ `[pipework] ${fn}(db, namespace, key) requires a key string.\n\n` +
13
+ ` ${fn}(db, 1001, 'my-entity') — numeric namespace + string key\n` +
14
+ ` ${fn}(db, 'key1', 'key2') — two hashed string keys\n`,
15
+ )
16
+ }
17
+ return sql`${first}, hashtext(${key})`
18
+ }
19
+
20
+ if (first === undefined) {
21
+ throw new Error(
22
+ `[pipework] ${fn} requires at least one key.\n\n` +
23
+ ` ${fn}(db, 'my-lock') — single hashed key\n` +
24
+ ` ${fn}(db, 'key1', 'key2') — two hashed keys\n` +
25
+ ` ${fn}(db, 1001, 'my-entity') — numeric namespace + hashed key\n`,
26
+ )
27
+ }
28
+
29
+ if (rest.length === 0) return sql`hashtext(${first})`
30
+ return sql`hashtext(${first}), hashtext(${rest[0]!})`
31
+ }
32
+
33
+ /** Acquires a transaction-scoped advisory lock. Released automatically at commit/rollback.
34
+ *
35
+ * String keys: hashed independently into the int4 arguments of pg_advisory_xact_lock.
36
+ * Numeric namespace: `advisoryLock(db, 1001, 'key')` → `pg_advisory_xact_lock(1001, hashtext('key'))`.
37
+ */
38
+ export async function advisoryLock(db: DB, namespace: number, key: string): Promise<void>
39
+ export async function advisoryLock(db: DB, ...keys: string[]): Promise<void>
40
+ export async function advisoryLock(db: DB, first?: string | number, ...rest: string[]): Promise<void> {
41
+ const args = lockArguments('advisoryLock', first, rest)
42
+ await unscopedExecutor(db).db.execute(sql`SELECT pg_advisory_xact_lock(${args})`)
43
+ }
44
+
45
+ /** Non-blocking advisoryLock: takes the same lock (same key forms, same hashing) if it is free
46
+ * and returns true, or returns false at once when another transaction holds it.
47
+ * A lock won is held until commit/rollback.
48
+ */
49
+ export async function tryAdvisoryLock(db: DB, namespace: number, key: string): Promise<boolean>
50
+ export async function tryAdvisoryLock(db: DB, ...keys: string[]): Promise<boolean>
51
+ export async function tryAdvisoryLock(db: DB, first?: string | number, ...rest: string[]): Promise<boolean> {
52
+ const args = lockArguments('tryAdvisoryLock', first, rest)
53
+ const rows = await unscopedExecutor(db).db.execute(sql`SELECT pg_try_advisory_xact_lock(${args}) AS locked`)
54
+ return rows[0]?.['locked'] === true
55
+ }
@@ -0,0 +1,172 @@
1
+ import { avg, avgDistinct, count, countDistinct, max, min, sum, sumDistinct } from '../query/index.js'
2
+ import type { SQLWrapper } from '../query/sql/sql.js'
3
+ import { noopDecoder } from '../query/sql/sql.js'
4
+ import { parsePgArray } from '../query/pg-core/utils/array.js'
5
+ import { is } from '../query/entity.js'
6
+ import { Column as DrizzleColumn } from '../query/column.js'
7
+ import { sql } from './sql.js'
8
+ import type { SQL, Column } from './types.js'
9
+
10
+ /** An aggregate expression that can be narrowed with `FILTER (WHERE …)`; `undefined` leaves it unfiltered. */
11
+ export type Aggregate<T> = SQL<T> & {
12
+ filterWhere(condition: SQL | undefined): SQL<T>
13
+ }
14
+
15
+ /** An array or jsonb aggregate; `orEmpty()` replaces the no-rows NULL with an empty array. */
16
+ export type EmptyableAggregate<T, E> = SQL<T> & {
17
+ orEmpty(): SQL<E>
18
+ filterWhere(condition: SQL | undefined): SQL<T> & { orEmpty(): SQL<E> }
19
+ }
20
+
21
+ /**
22
+ * The type a value takes after a round trip through jsonb: Date -> string (ISO text),
23
+ * bigint -> number, Buffer/Uint8Array -> string, objects and arrays mapped recursively,
24
+ * null kept. Column decoders are not applied inside jsonb.
25
+ */
26
+ export type JsonOf<T> =
27
+ T extends null | undefined ? T
28
+ : T extends Date ? string
29
+ : T extends bigint ? number
30
+ : T extends Uint8Array ? string
31
+ : T extends readonly (infer U)[] ? JsonOf<U>[]
32
+ : T extends object ? { [K in keyof T]: JsonOf<T[K]> }
33
+ : T
34
+
35
+ type ColumnValue<C extends Column> = C['_']['notNull'] extends true ? C['_']['data'] : C['_']['data'] | null
36
+ type ValueOf<E> = E extends Column ? ColumnValue<E> : E extends SQL<infer T> ? T : unknown
37
+ /** The jsonb-side type of an expression: numeric columns come back as numbers, not strings. */
38
+ type JsonValueOf<E> =
39
+ E extends Column
40
+ ? (E['_']['columnType'] extends 'PgNumeric' ? (E['_']['notNull'] extends true ? number : number | null) : JsonOf<ColumnValue<E>>)
41
+ : E extends SQL<infer T> ? JsonOf<T> : unknown
42
+
43
+ /** `ORDER BY` terms inside an aggregate — `asc(col)` / `desc(col)` or an array of them. */
44
+ export interface AggregateOptions {
45
+ readonly distinct?: boolean
46
+ readonly orderBy?: SQL | ReadonlyArray<SQL>
47
+ }
48
+
49
+ function withFilter<T>(base: SQL<T>): Aggregate<T> {
50
+ const agg = base as Aggregate<T>
51
+ agg.filterWhere = (condition) => {
52
+ if (condition === undefined) return base
53
+ return sql`${base} filter (where ${condition})`.mapWith(base.decoder) as SQL<T>
54
+ }
55
+ return agg
56
+ }
57
+
58
+ /** Parses an array literal the driver left as text, then decodes each non-null element with the argument's decoder. */
59
+ function arrayDecoder(arg: Column | SQL): SQL['decoder'] | undefined {
60
+ const element = is(arg, DrizzleColumn)
61
+ ? (v: unknown) => (arg as Column).mapFromDriverValue(v)
62
+ : (arg as SQL).decoder !== noopDecoder
63
+ ? (v: unknown) => (arg as SQL).decoder.mapFromDriverValue(v)
64
+ : undefined
65
+ return {
66
+ mapFromDriverValue(value: unknown) {
67
+ const list = typeof value === 'string' ? parsePgArray(value) : value
68
+ if (element === undefined || !Array.isArray(list)) return list
69
+ return list.map(v => (v === null || v === undefined ? v : element(v)))
70
+ },
71
+ }
72
+ }
73
+
74
+ function withEmpty<T, E>(base: SQL<T>, empty: SQL, decoder?: SQL['decoder']): EmptyableAggregate<T, E> {
75
+ if (decoder !== undefined) base.mapWith(decoder)
76
+ const orEmpty = (inner: SQL<T>): SQL<E> => {
77
+ const out = sql`coalesce(${inner}, ${empty})`
78
+ if (decoder !== undefined) out.mapWith(decoder)
79
+ return out as SQL<E>
80
+ }
81
+ const agg = base as EmptyableAggregate<T, E>
82
+ agg.orEmpty = () => orEmpty(base)
83
+ agg.filterWhere = (condition) => {
84
+ const filtered = (condition === undefined ? base : sql`${base} filter (where ${condition})`.mapWith(base.decoder)) as SQL<T> & { orEmpty(): SQL<E> }
85
+ filtered.orEmpty = () => orEmpty(filtered)
86
+ return filtered
87
+ }
88
+ return agg
89
+ }
90
+
91
+ function inside(distinct: boolean | undefined, arg: SQL, orderBy: AggregateOptions['orderBy'], tail?: SQL): SQL {
92
+ const parts: SQL[] = []
93
+ if (distinct === true) parts.push(sql`distinct `)
94
+ parts.push(arg)
95
+ if (tail !== undefined) parts.push(sql`, ${tail}`)
96
+ if (orderBy !== undefined) {
97
+ const terms = Array.isArray(orderBy) ? orderBy : [orderBy]
98
+ if (terms.length > 0) parts.push(sql` order by ${sql.join(terms as SQL[], sql`, `)}`)
99
+ }
100
+ return sql.join(parts, sql``)
101
+ }
102
+
103
+ /** `count(expr)` or `count(*)`, with `.filterWhere(cond)`. */
104
+ export function countAgg(expression?: SQLWrapper): Aggregate<number> {
105
+ return withFilter(count(expression))
106
+ }
107
+ /** `count(distinct expr)`, with `.filterWhere(cond)`. */
108
+ export function countDistinctAgg(expression: SQLWrapper): Aggregate<number> {
109
+ return withFilter(countDistinct(expression))
110
+ }
111
+ /** `sum(expr)`, with `.filterWhere(cond)`. */
112
+ export function sumAgg(expression: SQLWrapper): Aggregate<string | null> {
113
+ return withFilter(sum(expression))
114
+ }
115
+ /** `sum(distinct expr)`, with `.filterWhere(cond)`. */
116
+ export function sumDistinctAgg(expression: SQLWrapper): Aggregate<string | null> {
117
+ return withFilter(sumDistinct(expression))
118
+ }
119
+ /** `avg(expr)`, with `.filterWhere(cond)`. */
120
+ export function avgAgg(expression: SQLWrapper): Aggregate<string | null> {
121
+ return withFilter(avg(expression))
122
+ }
123
+ /** `avg(distinct expr)`, with `.filterWhere(cond)`. */
124
+ export function avgDistinctAgg(expression: SQLWrapper): Aggregate<string | null> {
125
+ return withFilter(avgDistinct(expression))
126
+ }
127
+ /** `max(expr)`, with `.filterWhere(cond)`. */
128
+ export function maxAgg<T extends SQLWrapper>(expression: T): Aggregate<ReturnType<typeof max<T>> extends SQL<infer R> ? R : never> {
129
+ return withFilter(max(expression)) as never
130
+ }
131
+ /** `min(expr)`, with `.filterWhere(cond)`. */
132
+ export function minAgg<T extends SQLWrapper>(expression: T): Aggregate<ReturnType<typeof min<T>> extends SQL<infer R> ? R : never> {
133
+ return withFilter(min(expression)) as never
134
+ }
135
+
136
+ /** `bool_and(expr)` — NULL over zero rows. */
137
+ export function boolAnd(expression: Column | SQL): Aggregate<boolean | null> {
138
+ return withFilter(sql<boolean | null>`bool_and(${expression})`)
139
+ }
140
+ /** `bool_or(expr)` — NULL over zero rows. */
141
+ export function boolOr(expression: Column | SQL): Aggregate<boolean | null> {
142
+ return withFilter(sql<boolean | null>`bool_or(${expression})`)
143
+ }
144
+
145
+ /** `array_agg([distinct] expr [order by …])`; NULL over zero rows, `.orEmpty()` gives `{}`. */
146
+ export function arrayAgg<E extends Column | SQL>(expression: E, options: AggregateOptions = {}): EmptyableAggregate<ValueOf<E>[] | null, ValueOf<E>[]> {
147
+ const base = sql<ValueOf<E>[] | null>`array_agg(${inside(options.distinct, sql`${expression}`, options.orderBy)})`
148
+ return withEmpty(base, sql`'{}'`, arrayDecoder(expression))
149
+ }
150
+
151
+ /** `string_agg([distinct] expr, delimiter [order by …])`; the delimiter is bound. */
152
+ export function stringAgg(expression: Column | SQL, delimiter: string, options: AggregateOptions = {}): Aggregate<string | null> {
153
+ return withFilter(sql<string | null>`string_agg(${inside(options.distinct, sql`${expression}`, options.orderBy, sql`${delimiter}::text`)})`)
154
+ }
155
+
156
+ /** `jsonb_agg([distinct] expr [order by …])`; NULL over zero rows, `.orEmpty()` gives `[]`. Elements are typed by {@link JsonOf}. */
157
+ export function jsonbAgg<E extends Column | SQL>(expression: E, options: AggregateOptions = {}): EmptyableAggregate<JsonValueOf<E>[] | null, JsonValueOf<E>[]> {
158
+ const base = sql<JsonValueOf<E>[] | null>`jsonb_agg(${inside(options.distinct, sql`${expression}`, options.orderBy)})`
159
+ return withEmpty(base, sql`'[]'::jsonb`)
160
+ }
161
+
162
+ /** `jsonb_object_agg(key, value)`; NULL over zero rows. */
163
+ export function jsonbObjectAgg<V extends Column | SQL>(key: Column | SQL, value: V): Aggregate<Record<string, JsonValueOf<V>> | null> {
164
+ return withFilter(sql<Record<string, JsonValueOf<V>> | null>`jsonb_object_agg(${key}, ${value})`)
165
+ }
166
+
167
+ /** `jsonb_build_object('key', expr, …)` — keys are bound as text. Values are typed by {@link JsonOf}. */
168
+ export function jsonbBuildObject<F extends Record<string, Column | SQL>>(fields: F): SQL<{ [K in keyof F]: JsonValueOf<F[K]> }> {
169
+ const args: SQL[] = []
170
+ for (const [key, value] of Object.entries(fields)) args.push(sql`${key}::text, ${value}`)
171
+ return sql<{ [K in keyof F]: JsonValueOf<F[K]> }>`jsonb_build_object(${sql.join(args, sql`, `)})`
172
+ }
@@ -0,0 +1,111 @@
1
+ import { sql } from './sql.js'
2
+ import type { SQL, Column } from './types.js'
3
+ import { is } from '../query/entity.js'
4
+ import { Column as DrizzleColumn } from '../query/column.js'
5
+ import { SQL as DrizzleSQL } from '../query/sql/sql.js'
6
+
7
+ const jsonbElementsBrand: unique symbol = Symbol('pipework.jsonbElements')
8
+
9
+ /** A jsonb array read as its elements' text. Produced by {@link jsonbElements}. */
10
+ export interface JsonbElements {
11
+ readonly [jsonbElementsBrand]: SQL
12
+ }
13
+
14
+ /** Something whose elements `arrayAny` / `arrayAll` can test. */
15
+ export type ArraySource =
16
+ | (Column & { _: { data: readonly unknown[] } })
17
+ | SQL<readonly unknown[] | null>
18
+ | JsonbElements
19
+ | readonly string[]
20
+ | readonly number[]
21
+
22
+ /** The element type of an {@link ArraySource}. */
23
+ export type ElementOf<S> =
24
+ S extends readonly (infer E)[] ? E
25
+ : S extends JsonbElements ? string
26
+ : S extends { _: { data: infer D } } ? (D extends readonly (infer E)[] ? E : never)
27
+ : S extends SQL<infer A> ? (A extends readonly (infer E)[] ? E : never)
28
+ : never
29
+
30
+ /** Marks a jsonb array (a column or `SQL`) to be tested element by element, as text: `jsonb_array_elements_text(<jsonb>)`. */
31
+ export function jsonbElements(jsonb: Column | SQL): JsonbElements {
32
+ return { [jsonbElementsBrand]: sql`${jsonb}` }
33
+ }
34
+
35
+ let counter = 0
36
+
37
+ function isJsonbElements(value: unknown): value is JsonbElements {
38
+ return typeof value === 'object' && value !== null && jsonbElementsBrand in value
39
+ }
40
+
41
+ function elementsFrom(source: ArraySource, alias: string): SQL {
42
+ if (Array.isArray(source)) {
43
+ const items = source as readonly (string | number)[]
44
+ const numeric = items.length > 0 && typeof items[0] === 'number'
45
+ if (items.some(v => numeric ? typeof v !== 'number' : typeof v !== 'string')) {
46
+ throw new Error(
47
+ '[pipework] arrayAny/arrayAll: a JS array source must hold only strings or only numbers.\n\n' +
48
+ ' Fix: pass an array of one type, or cast the values before passing them.\n',
49
+ )
50
+ }
51
+ const type = numeric ? 'numeric[]' : 'text[]'
52
+ return sql`unnest(${sql.param(items)}::${sql.raw(type)}) AS ${sql.raw(alias)}(v)`
53
+ }
54
+ if (isJsonbElements(source)) {
55
+ return sql`jsonb_array_elements_text(${source[jsonbElementsBrand]}) AS ${sql.raw(alias)}(v)`
56
+ }
57
+ if (is(source, DrizzleColumn) || is(source, DrizzleSQL)) {
58
+ return sql`unnest(${source}) AS ${sql.raw(alias)}(v)`
59
+ }
60
+ throw new Error(
61
+ '[pipework] arrayAny/arrayAll: the source is not an array column, SQL array expression, JS array or jsonbElements(...).\n\n' +
62
+ ' Fix: pass one of those.\n',
63
+ )
64
+ }
65
+
66
+ function build<S extends ArraySource>(
67
+ negate: boolean,
68
+ source: S,
69
+ predicate: (element: SQL<ElementOf<S>>) => SQL | undefined,
70
+ ): SQL<boolean> {
71
+ const alias = `pw_el_${++counter}`
72
+ const element = sql<ElementOf<S>>`${sql.raw(alias)}.v`
73
+ const test = predicate(element)
74
+ if (test === undefined) {
75
+ throw new Error(
76
+ '[pipework] arrayAny/arrayAll: the test returned nothing (and()/or() of no conditions is undefined).\n\n' +
77
+ ' Fix: return a condition from the test.\n',
78
+ )
79
+ }
80
+ const from = elementsFrom(source, alias)
81
+ return negate
82
+ ? sql<boolean>`NOT EXISTS (SELECT 1 FROM ${from} WHERE NOT (${test}))`
83
+ : sql<boolean>`EXISTS (SELECT 1 FROM ${from} WHERE ${test})`
84
+ }
85
+
86
+ /**
87
+ * True when at least one element of the array satisfies the test:
88
+ * `EXISTS (SELECT 1 FROM unnest(<source>) AS pw_el_<n>(v) WHERE <test>)`.
89
+ * False for an empty array. A JS array is bound as one parameter cast `::text[]` (strings, also when empty)
90
+ * or `::numeric[]` (numbers). Calls nest; each gets its own alias.
91
+ * To test a column's value against an array column so its index can be used, use `filter.arrayHas(arrayCol, col)`.
92
+ */
93
+ export function arrayAny<S extends ArraySource>(
94
+ source: S,
95
+ predicate: (element: SQL<ElementOf<S>>) => SQL | undefined,
96
+ ): SQL<boolean> {
97
+ return build(false, source, predicate)
98
+ }
99
+
100
+ /**
101
+ * True when every element of the array satisfies the test:
102
+ * `NOT EXISTS (SELECT 1 FROM unnest(<source>) AS pw_el_<n>(v) WHERE NOT (<test>))`.
103
+ * True for an empty array. An element for which the test is null counts as not failing it,
104
+ * so a null element passes (SQL three-valued logic: `NOT NULL` is null, and a null WHERE row is dropped).
105
+ */
106
+ export function arrayAll<S extends ArraySource>(
107
+ source: S,
108
+ predicate: (element: SQL<ElementOf<S>>) => SQL | undefined,
109
+ ): SQL<boolean> {
110
+ return build(true, source, predicate)
111
+ }
@@ -0,0 +1,53 @@
1
+ import type { DB, Table } from './types.js'
2
+ import { getTableName, getTableColumns } from '../query/index.js'
3
+ import { values } from './values.js'
4
+ import type { ValueColumnDef } from './values.js'
5
+ import { identifier } from './expressions.js'
6
+ import { sql } from './sql.js'
7
+ import { unscopedExecutor } from '../../auth/tenant/scoped-db.js'
8
+ import { getScopeConfig } from '../../auth/tenant/scope.js'
9
+
10
+ type PgCastType = 'uuid' | 'text' | 'integer' | 'bigint' | 'boolean' | 'jsonb' | 'timestamptz' | 'timestamp' | 'date' | 'numeric' | 'real' | 'double precision' | 'smallint' | 'interval'
11
+
12
+ interface BulkSetOptions<TRow extends Record<string, unknown>> {
13
+ readonly match: keyof TRow & string
14
+ readonly set: ReadonlyArray<keyof TRow & string>
15
+ readonly types: Readonly<Record<keyof TRow & string, PgCastType>>
16
+ }
17
+
18
+ /** Executes UPDATE ... FROM (VALUES ...) for bulk per-row updates in a single statement. */
19
+ export async function bulkSet<TRow extends Record<string, unknown>>(
20
+ handle: DB,
21
+ table: Table,
22
+ rows: readonly TRow[],
23
+ options: BulkSetOptions<TRow>,
24
+ ): Promise<void> {
25
+ if (rows.length === 0) return
26
+
27
+ const { db, tenant } = unscopedExecutor(handle)
28
+ const tableName = getTableName(table)
29
+ const columns = getTableColumns(table)
30
+ const allKeys = [options.match, ...options.set] as string[]
31
+
32
+ const columnDefs: ValueColumnDef[] = allKeys.map(key => ({
33
+ name: columns[key]?.name ?? key,
34
+ type: options.types[key as keyof TRow & string] as PgCastType,
35
+ }))
36
+
37
+ const rowArrays = rows.map(row => allKeys.map(key => row[key as keyof TRow]))
38
+ const valuesClause = values(rowArrays, columnDefs)
39
+
40
+ const colNames = columnDefs.map(c => c.name)
41
+ const matchCol = columns[options.match]?.name ?? options.match
42
+
43
+ const setClauses = (options.set as string[]).map(key => {
44
+ const colName = columns[key]?.name ?? key
45
+ return sql`${identifier(colName)} = ${sql.raw('_vals.' + '"' + colName + '"')}`
46
+ })
47
+
48
+ const scope = tenant === null ? null : getScopeConfig(table as never)
49
+ const tenantFilter = scope == null ? sql`` : sql` AND ${identifier(tableName)}.${identifier(columns[scope.columnKey]?.name ?? scope.columnKey)} = ${tenant}`
50
+ await db.execute(
51
+ sql`UPDATE ${identifier(tableName)} SET ${sql.join(setClauses, sql`, `)} FROM ${valuesClause} AS _vals(${sql.raw(colNames.join(', '))}) WHERE ${identifier(tableName)}.${identifier(matchCol)} = ${sql.raw('_vals.' + '"' + matchCol + '"')}${tenantFilter}`,
52
+ )
53
+ }
@@ -0,0 +1,14 @@
1
+ // Column type builders — manual layer (wrappable)
2
+ // Each re-export can be replaced with a pipework wrapper as needed.
3
+ // e.g., `timestamp` could enforce withTimezone by default.
4
+
5
+ export {
6
+ text, uuid, serial, integer, bigint, boolean,
7
+ timestamp, jsonb, varchar, real, doublePrecision, numeric,
8
+ char, smallint, smallserial, bigserial,
9
+ date, time, interval, json, inet, cidr, macaddr, macaddr8,
10
+ bit, decimal, geometry, point, line,
11
+ vector, halfvec, sparsevec,
12
+ customType,
13
+ pgEnum as enumType,
14
+ } from '../../query/pg-core/index.js'
@@ -0,0 +1,53 @@
1
+ import type { SQL, Column, DB } from './types.js'
2
+ import { now, subtract, interval, cast, scalar, coalesce, increment } from './expressions.js'
3
+ import type { IntervalUnit } from './expressions.js'
4
+ import { max } from '../query/index.js'
5
+ import type { SQLWrapper } from '../query/sql/sql.js'
6
+
7
+ /** `now() - interval '5 minutes'`. Composes `now`, `subtract`, and `interval`. */
8
+ export function ago(amount: number, unit: IntervalUnit): SQL<Date> {
9
+ return subtract<Date>(now(), interval(amount, unit))
10
+ }
11
+
12
+ /** Shorthand for `cast(expr, 'uuid')`. */
13
+ export function castUuid(expression: SQL | Column | SQLWrapper): SQL<string> {
14
+ return cast<string>(expression, 'uuid')
15
+ }
16
+
17
+ /** Shorthand for `cast(expr, 'jsonb')`. */
18
+ export function castJsonb(expression: SQL | Column | SQLWrapper): SQL {
19
+ return cast(expression, 'jsonb')
20
+ }
21
+
22
+ /** Shorthand for `cast(expr, 'timestamptz')`. */
23
+ export function castTimestamp(expression: SQL | Column | SQLWrapper): SQL<Date> {
24
+ return cast<Date>(expression, 'timestamptz')
25
+ }
26
+
27
+ /** Shorthand for `cast(expr, 'boolean')`. */
28
+ export function castBoolean(expression: SQL | Column | SQLWrapper): SQL<boolean> {
29
+ return cast<boolean>(expression, 'boolean')
30
+ }
31
+
32
+ /** Shorthand for `cast(expr, 'numeric')`. */
33
+ export function castNumeric(expression: SQL | Column | SQLWrapper): SQL<number> {
34
+ return cast<number>(expression, 'numeric')
35
+ }
36
+
37
+ /** Shorthand for `cast(expr, 'integer')`. */
38
+ export function castInteger(expression: SQL | Column | SQLWrapper): SQL<number> {
39
+ return cast<number>(expression, 'integer')
40
+ }
41
+
42
+ /** Shorthand for `cast(expr, 'text')`. */
43
+ export function castText(expression: SQL | Column | SQLWrapper): SQL<string> {
44
+ return cast<string>(expression, 'text')
45
+ }
46
+
47
+ /** `COALESCE((SELECT MAX(column) FROM table WHERE condition), 0) + 1`. Composes scalar, coalesce, max, increment. */
48
+ export function nextSequence(db: DB, column: Column, where?: SQL): SQL<number> {
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- drizzle's select/from generics require concrete schema types
50
+ const base = (db as any).select({ v: max(column) }).from(column.table)
51
+ const subquery = where !== undefined ? base.where(where) : base
52
+ return increment(coalesce<number>(scalar<number>(subquery), 0), 1)
53
+ }