pipework 0.252.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 (690) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/package.json +4 -3
  3. package/src/async/jobs/abortable-delay.ts +18 -0
  4. package/src/async/jobs/claims.ts +52 -0
  5. package/src/async/jobs/cron.ts +179 -0
  6. package/src/async/jobs/errors.ts +56 -0
  7. package/src/async/jobs/exclusion.ts +117 -0
  8. package/src/async/jobs/execute.ts +219 -0
  9. package/src/async/jobs/index.ts +10 -0
  10. package/src/async/jobs/listener.ts +135 -0
  11. package/src/async/jobs/namespace.ts +20 -0
  12. package/src/async/jobs/queue-door.ts +44 -0
  13. package/src/async/jobs/queue.ts +1012 -0
  14. package/src/async/jobs/run-script.ts +67 -0
  15. package/src/async/jobs/scheduler.ts +218 -0
  16. package/src/async/jobs/schedules-table.ts +37 -0
  17. package/src/async/jobs/serialize-error.ts +48 -0
  18. package/src/async/jobs/table.ts +191 -0
  19. package/src/async/pipeline/define.ts +53 -0
  20. package/src/async/pipeline/errors.ts +35 -0
  21. package/src/async/pipeline/execute.ts +53 -0
  22. package/src/async/pipeline/index.ts +13 -0
  23. package/src/async/pipeline/namespace.ts +12 -0
  24. package/src/async/pipeline/resume.ts +67 -0
  25. package/src/async/pipeline/run-steps.ts +98 -0
  26. package/src/async/pipeline/types.ts +57 -0
  27. package/src/async/state-machine/define.ts +64 -0
  28. package/src/async/state-machine/errors.ts +29 -0
  29. package/src/async/state-machine/index.ts +3 -0
  30. package/src/async/state-machine/namespace.ts +12 -0
  31. package/src/async/state-machine/transition.ts +90 -0
  32. package/src/async/state-machine/types.ts +37 -0
  33. package/src/async/steps/errors.ts +31 -0
  34. package/src/async/steps/graph.ts +1214 -0
  35. package/src/async/steps/hash.ts +40 -0
  36. package/src/async/steps/index.ts +7 -0
  37. package/src/async/steps/namespace.ts +7 -0
  38. package/src/async/steps/table.ts +97 -0
  39. package/src/async/steps/types.ts +318 -0
  40. package/src/audit/chain/index.ts +9 -0
  41. package/src/audit/chain/install.ts +113 -0
  42. package/src/audit/chain/retire.ts +52 -0
  43. package/src/audit/chain/verify.ts +257 -0
  44. package/src/audit/query/cursor.ts +37 -0
  45. package/src/audit/query/index.ts +9 -0
  46. package/src/audit/query/query.ts +223 -0
  47. package/src/audit/schema/audit-record-fields.ts +68 -0
  48. package/src/audit/schema/audit-record.ts +23 -0
  49. package/src/auth/auth/audit.ts +31 -0
  50. package/src/auth/auth/chain.ts +84 -0
  51. package/src/auth/auth/cookie.ts +136 -0
  52. package/src/auth/auth/email-links.ts +311 -0
  53. package/src/auth/auth/guard.ts +128 -0
  54. package/src/auth/auth/index.ts +18 -0
  55. package/src/auth/auth/multi-org.ts +337 -0
  56. package/src/auth/auth/namespace.ts +34 -0
  57. package/src/auth/auth/parse-expiry.ts +13 -0
  58. package/src/auth/auth/passwords.ts +110 -0
  59. package/src/auth/auth/schema.ts +110 -0
  60. package/src/auth/auth/sessions.ts +565 -0
  61. package/src/auth/auth/sign-in.ts +156 -0
  62. package/src/auth/auth/signing-keys.ts +69 -0
  63. package/src/auth/auth/types.ts +26 -0
  64. package/src/auth/auth/uuid.ts +10 -0
  65. package/src/auth/rbac/cache.ts +55 -0
  66. package/src/auth/rbac/check.ts +30 -0
  67. package/src/auth/rbac/create.ts +35 -0
  68. package/src/auth/rbac/index.ts +5 -0
  69. package/src/auth/rbac/middleware.ts +20 -0
  70. package/src/auth/rbac/namespace.ts +15 -0
  71. package/src/auth/rbac/resolve.ts +31 -0
  72. package/src/auth/rbac/schema.sql +31 -0
  73. package/src/auth/rbac/seed.ts +67 -0
  74. package/src/auth/rbac/tables.ts +32 -0
  75. package/src/auth/rbac/types.ts +65 -0
  76. package/src/auth/tenant/extract.ts +33 -0
  77. package/src/auth/tenant/in-tenant.ts +49 -0
  78. package/src/auth/tenant/index.ts +7 -0
  79. package/src/auth/tenant/namespace.ts +23 -0
  80. package/src/auth/tenant/propagate.ts +20 -0
  81. package/src/auth/tenant/rls.ts +120 -0
  82. package/src/auth/tenant/scope.ts +33 -0
  83. package/src/auth/tenant/scoped-db.ts +581 -0
  84. package/src/auth/tenant/types.ts +14 -0
  85. package/src/auth/tenant/validate.ts +27 -0
  86. package/src/cli/commands/add.ts +158 -0
  87. package/src/cli/commands/alerts.ts +98 -0
  88. package/src/cli/commands/check.ts +1418 -0
  89. package/src/cli/commands/codemod.ts +78 -0
  90. package/src/cli/commands/db.ts +356 -0
  91. package/src/cli/commands/dev.ts +101 -0
  92. package/src/cli/commands/generate.ts +75 -0
  93. package/src/cli/commands/init.ts +36 -0
  94. package/src/cli/commands/install.ts +28 -0
  95. package/src/cli/commands/lint.ts +62 -0
  96. package/src/cli/commands/migrate.ts +132 -0
  97. package/src/cli/commands/openapi.ts +63 -0
  98. package/src/cli/commands/remove.ts +72 -0
  99. package/src/cli/commands/run.ts +50 -0
  100. package/src/cli/commands/scope.ts +54 -0
  101. package/src/cli/commands/serve.ts +68 -0
  102. package/src/cli/commands/shard.ts +31 -0
  103. package/src/cli/commands/shared/config-pipework-version.ts +28 -0
  104. package/src/cli/commands/shared/find-config.ts +22 -0
  105. package/src/cli/commands/shared/load-config.ts +35 -0
  106. package/src/cli/commands/shared/pnpm-install.ts +95 -0
  107. package/src/cli/commands/shared/report-removed.ts +8 -0
  108. package/src/cli/commands/sync.ts +32 -0
  109. package/src/cli/commands/test.ts +307 -0
  110. package/src/cli/commands/upgrade.ts +48 -0
  111. package/src/cli/dev-bootstrap.ts +24 -0
  112. package/src/cli/errors.ts +10 -0
  113. package/src/cli/index.ts +303 -0
  114. package/src/cli/output.ts +17 -0
  115. package/src/cli/port.ts +15 -0
  116. package/src/cli/surface-kinds.ts +20 -0
  117. package/src/client/index.ts +4 -0
  118. package/src/client/poll.ts +130 -0
  119. package/src/client/report-fault.ts +119 -0
  120. package/src/core/config/app-pool.ts +19 -0
  121. package/src/core/config/aws-env.ts +29 -0
  122. package/src/core/config/base-dir.ts +24 -0
  123. package/src/core/config/discover.ts +64 -0
  124. package/src/core/config/env-resolve.ts +87 -0
  125. package/src/core/config/env-types.ts +116 -0
  126. package/src/core/config/env.ts +55 -0
  127. package/src/core/config/errors.ts +9 -0
  128. package/src/core/config/import-config.ts +40 -0
  129. package/src/core/config/index.ts +8 -0
  130. package/src/core/config/load.ts +417 -0
  131. package/src/core/config/namespace.ts +14 -0
  132. package/src/core/config/resolve.ts +195 -0
  133. package/src/core/config/schema.ts +488 -0
  134. package/src/core/config/statement-observer.ts +48 -0
  135. package/src/core/config/ts-inline-hooks.ts +75 -0
  136. package/src/core/config/ts-register.ts +4 -0
  137. package/src/core/config/ts-resolve-hooks.ts +101 -0
  138. package/src/core/errors/base.ts +49 -0
  139. package/src/core/errors/http.ts +146 -0
  140. package/src/core/errors/index.ts +2 -0
  141. package/src/core/errors/namespace.ts +31 -0
  142. package/src/core/lifecycle/drain.ts +33 -0
  143. package/src/core/lifecycle/health.ts +72 -0
  144. package/src/core/lifecycle/index.ts +4 -0
  145. package/src/core/lifecycle/namespace.ts +7 -0
  146. package/src/core/lifecycle/startup.ts +102 -0
  147. package/src/core/lifecycle/types.ts +36 -0
  148. package/src/core/logging/context.ts +60 -0
  149. package/src/core/logging/error-chain.ts +68 -0
  150. package/src/core/logging/index.ts +5 -0
  151. package/src/core/logging/logger.ts +65 -0
  152. package/src/core/logging/namespace.ts +16 -0
  153. package/src/core/logging/proxy.ts +22 -0
  154. package/src/core/logging/redact-match.ts +24 -0
  155. package/src/core/logging/types.ts +47 -0
  156. package/src/core/pipework.ts +566 -0
  157. package/src/core/runtime/broker.ts +69 -0
  158. package/src/core/surface/http.ts +133 -0
  159. package/src/core/surface/index.ts +11 -0
  160. package/src/core/surface/job-timeout.ts +40 -0
  161. package/src/core/surface/namespace.ts +13 -0
  162. package/src/core/surface/script.ts +33 -0
  163. package/src/core/surface/start.ts +142 -0
  164. package/src/core/surface/types.ts +225 -0
  165. package/src/core/surface/validate.ts +88 -0
  166. package/src/core/surface/worker.ts +528 -0
  167. package/src/core/validation/connectivity.ts +49 -0
  168. package/src/core/validation/domain.ts +99 -0
  169. package/src/core/validation/index.ts +5 -0
  170. package/src/core/validation/queue-tables.ts +312 -0
  171. package/src/core/validation/rls-role.ts +138 -0
  172. package/src/core/validation/startup.ts +51 -0
  173. package/src/core/validation/surfaces.ts +65 -0
  174. package/src/core/validation/types.ts +25 -0
  175. package/src/data/db/advisory-lock.ts +55 -0
  176. package/src/data/db/aggregates.ts +172 -0
  177. package/src/data/db/array-elements.ts +111 -0
  178. package/src/data/db/bulk-set.ts +53 -0
  179. package/src/data/db/col/index.ts +14 -0
  180. package/src/data/db/composed.ts +53 -0
  181. package/src/data/db/db.ts +276 -0
  182. package/src/data/db/excluded.ts +16 -0
  183. package/src/data/db/expressions.ts +473 -0
  184. package/src/data/db/filter.ts +90 -0
  185. package/src/data/db/function-source.ts +114 -0
  186. package/src/data/db/identifiers.ts +16 -0
  187. package/src/data/db/idx/index.ts +9 -0
  188. package/src/data/db/in-list.ts +49 -0
  189. package/src/data/db/index.ts +9 -0
  190. package/src/data/db/insert-split.ts +137 -0
  191. package/src/data/db/instrumentation.ts +82 -0
  192. package/src/data/db/maintenance.ts +28 -0
  193. package/src/data/db/namespace.ts +107 -0
  194. package/src/data/db/owner-labels.ts +9 -0
  195. package/src/data/db/pool.ts +187 -0
  196. package/src/data/db/query-label.ts +13 -0
  197. package/src/data/db/query-watch.ts +116 -0
  198. package/src/data/db/raw-client-warning.ts +37 -0
  199. package/src/data/db/readonly.ts +23 -0
  200. package/src/data/db/reservation.ts +151 -0
  201. package/src/data/db/schema-features.ts +14 -0
  202. package/src/data/db/serializable.ts +83 -0
  203. package/src/data/db/sql.ts +1 -0
  204. package/src/data/db/timeouts.ts +76 -0
  205. package/src/data/db/types.ts +18 -0
  206. package/src/data/db/unbound.ts +33 -0
  207. package/src/data/db/values.ts +29 -0
  208. package/src/data/domain/brand.ts +15 -0
  209. package/src/data/domain/build-factory.ts +193 -0
  210. package/src/data/domain/build-schema.ts +161 -0
  211. package/src/data/domain/build-table.ts +355 -0
  212. package/src/data/domain/define.ts +239 -0
  213. package/src/data/domain/external-registry.ts +34 -0
  214. package/src/data/domain/external.ts +77 -0
  215. package/src/data/domain/field.ts +279 -0
  216. package/src/data/domain/index.ts +13 -0
  217. package/src/data/domain/naming.ts +6 -0
  218. package/src/data/domain/projections.ts +57 -0
  219. package/src/data/domain/trace-safe-projection.ts +31 -0
  220. package/src/data/domain/traits.ts +108 -0
  221. package/src/data/domain/types.ts +289 -0
  222. package/src/data/jsonb/composed.ts +18 -0
  223. package/src/data/jsonb/index.ts +1 -0
  224. package/src/data/jsonb/namespace.ts +30 -0
  225. package/src/data/jsonb/query.ts +86 -0
  226. package/src/data/migrate/append-only-generate.ts +47 -0
  227. package/src/data/migrate/applied.ts +47 -0
  228. package/src/data/migrate/apply.ts +309 -0
  229. package/src/data/migrate/check.ts +119 -0
  230. package/src/data/migrate/diff.ts +357 -0
  231. package/src/data/migrate/door-generate.ts +130 -0
  232. package/src/data/migrate/framework-rls.ts +58 -0
  233. package/src/data/migrate/generate.ts +201 -0
  234. package/src/data/migrate/history.ts +215 -0
  235. package/src/data/migrate/index.ts +9 -0
  236. package/src/data/migrate/internal-definitions.ts +175 -0
  237. package/src/data/migrate/post-process.ts +73 -0
  238. package/src/data/migrate/pragma.ts +73 -0
  239. package/src/data/migrate/provision-framework.ts +147 -0
  240. package/src/data/migrate/rls-generate.ts +61 -0
  241. package/src/data/migrate/run.ts +124 -0
  242. package/src/data/migrate/safety.ts +167 -0
  243. package/src/data/migrate/snapshot.ts +368 -0
  244. package/src/data/migrate/sql-emit.ts +392 -0
  245. package/src/data/migrate/statements.ts +312 -0
  246. package/src/data/query/alias.ts +126 -0
  247. package/src/data/query/batch.ts +8 -0
  248. package/src/data/query/cache/core/cache.ts +78 -0
  249. package/src/data/query/cache/core/index.ts +1 -0
  250. package/src/data/query/cache/core/types.ts +29 -0
  251. package/src/data/query/cache/readme.md +230 -0
  252. package/src/data/query/casing.ts +76 -0
  253. package/src/data/query/collation.ts +11 -0
  254. package/src/data/query/column-builder.ts +370 -0
  255. package/src/data/query/column.ts +150 -0
  256. package/src/data/query/entity.ts +42 -0
  257. package/src/data/query/errors.ts +33 -0
  258. package/src/data/query/index.ts +14 -0
  259. package/src/data/query/logger.ts +47 -0
  260. package/src/data/query/operations.ts +45 -0
  261. package/src/data/query/pg-core/alias.ts +12 -0
  262. package/src/data/query/pg-core/checks.ts +32 -0
  263. package/src/data/query/pg-core/columns/all.ts +71 -0
  264. package/src/data/query/pg-core/columns/bigint.ts +110 -0
  265. package/src/data/query/pg-core/columns/bigserial.ts +128 -0
  266. package/src/data/query/pg-core/columns/boolean.ts +43 -0
  267. package/src/data/query/pg-core/columns/char.ts +85 -0
  268. package/src/data/query/pg-core/columns/cidr.ts +43 -0
  269. package/src/data/query/pg-core/columns/common.ts +366 -0
  270. package/src/data/query/pg-core/columns/custom.ts +232 -0
  271. package/src/data/query/pg-core/columns/date.common.ts +15 -0
  272. package/src/data/query/pg-core/columns/date.ts +112 -0
  273. package/src/data/query/pg-core/columns/double-precision.ts +55 -0
  274. package/src/data/query/pg-core/columns/enum.ts +201 -0
  275. package/src/data/query/pg-core/columns/index.ts +35 -0
  276. package/src/data/query/pg-core/columns/inet.ts +43 -0
  277. package/src/data/query/pg-core/columns/int.common.ts +57 -0
  278. package/src/data/query/pg-core/columns/integer.ts +53 -0
  279. package/src/data/query/pg-core/columns/interval.ts +83 -0
  280. package/src/data/query/pg-core/columns/json.ts +58 -0
  281. package/src/data/query/pg-core/columns/jsonb.ts +56 -0
  282. package/src/data/query/pg-core/columns/line.ts +117 -0
  283. package/src/data/query/pg-core/columns/macaddr.ts +43 -0
  284. package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
  285. package/src/data/query/pg-core/columns/numeric.ts +227 -0
  286. package/src/data/query/pg-core/columns/point.ts +127 -0
  287. package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
  288. package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
  289. package/src/data/query/pg-core/columns/real.ts +58 -0
  290. package/src/data/query/pg-core/columns/serial.ts +55 -0
  291. package/src/data/query/pg-core/columns/smallint.ts +53 -0
  292. package/src/data/query/pg-core/columns/smallserial.ts +60 -0
  293. package/src/data/query/pg-core/columns/text.ts +67 -0
  294. package/src/data/query/pg-core/columns/time.ts +72 -0
  295. package/src/data/query/pg-core/columns/timestamp.ts +163 -0
  296. package/src/data/query/pg-core/columns/uuid.ts +51 -0
  297. package/src/data/query/pg-core/columns/varchar.ts +89 -0
  298. package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
  299. package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
  300. package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
  301. package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
  302. package/src/data/query/pg-core/db.ts +674 -0
  303. package/src/data/query/pg-core/dialect.ts +1404 -0
  304. package/src/data/query/pg-core/expressions.ts +25 -0
  305. package/src/data/query/pg-core/foreign-keys.ts +130 -0
  306. package/src/data/query/pg-core/index.ts +21 -0
  307. package/src/data/query/pg-core/indexes.ts +276 -0
  308. package/src/data/query/pg-core/policies.ts +56 -0
  309. package/src/data/query/pg-core/primary-keys.ts +62 -0
  310. package/src/data/query/pg-core/query-builders/count.ts +86 -0
  311. package/src/data/query/pg-core/query-builders/delete.ts +293 -0
  312. package/src/data/query/pg-core/query-builders/index.ts +7 -0
  313. package/src/data/query/pg-core/query-builders/insert.ts +452 -0
  314. package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
  315. package/src/data/query/pg-core/query-builders/query.ts +157 -0
  316. package/src/data/query/pg-core/query-builders/raw.ts +49 -0
  317. package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
  318. package/src/data/query/pg-core/query-builders/select.ts +1346 -0
  319. package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
  320. package/src/data/query/pg-core/query-builders/update.ts +626 -0
  321. package/src/data/query/pg-core/roles.ts +41 -0
  322. package/src/data/query/pg-core/schema.ts +72 -0
  323. package/src/data/query/pg-core/sequence.ts +41 -0
  324. package/src/data/query/pg-core/session.ts +292 -0
  325. package/src/data/query/pg-core/subquery.ts +46 -0
  326. package/src/data/query/pg-core/table.ts +252 -0
  327. package/src/data/query/pg-core/unique-constraint.ts +73 -0
  328. package/src/data/query/pg-core/utils/array.ts +95 -0
  329. package/src/data/query/pg-core/utils/index.ts +1 -0
  330. package/src/data/query/pg-core/utils.ts +104 -0
  331. package/src/data/query/pg-core/view-base.ts +14 -0
  332. package/src/data/query/pg-core/view-common.ts +1 -0
  333. package/src/data/query/pg-core/view.ts +435 -0
  334. package/src/data/query/pg-core/with-builder.ts +41 -0
  335. package/src/data/query/postgres-js/README.md +46 -0
  336. package/src/data/query/postgres-js/array-parser.ts +45 -0
  337. package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
  338. package/src/data/query/postgres-js/driver.ts +163 -0
  339. package/src/data/query/postgres-js/index.ts +2 -0
  340. package/src/data/query/postgres-js/session.ts +234 -0
  341. package/src/data/query/primary-key.ts +11 -0
  342. package/src/data/query/query-builders/query-builder.ts +19 -0
  343. package/src/data/query/query-builders/select.types.ts +175 -0
  344. package/src/data/query/query-promise.ts +35 -0
  345. package/src/data/query/relations.ts +725 -0
  346. package/src/data/query/runnable-query.ts +12 -0
  347. package/src/data/query/selection-proxy.ts +121 -0
  348. package/src/data/query/session.ts +8 -0
  349. package/src/data/query/sql/expressions/conditions.ts +741 -0
  350. package/src/data/query/sql/expressions/index.ts +2 -0
  351. package/src/data/query/sql/expressions/select.ts +45 -0
  352. package/src/data/query/sql/functions/aggregate.ts +129 -0
  353. package/src/data/query/sql/functions/index.ts +2 -0
  354. package/src/data/query/sql/functions/vector.ts +178 -0
  355. package/src/data/query/sql/index.ts +3 -0
  356. package/src/data/query/sql/sql.ts +794 -0
  357. package/src/data/query/subquery.ts +53 -0
  358. package/src/data/query/table.ts +208 -0
  359. package/src/data/query/table.utils.ts +2 -0
  360. package/src/data/query/tracing-utils.ts +3 -0
  361. package/src/data/query/tracing.ts +11 -0
  362. package/src/data/query/utils.ts +357 -0
  363. package/src/data/query/version.ts +4 -0
  364. package/src/data/query/view-common.ts +1 -0
  365. package/src/data/schema/branded.ts +13 -0
  366. package/src/data/schema/generated/coerce.ts +5 -0
  367. package/src/data/schema/generated/combinator.ts +6 -0
  368. package/src/data/schema/generated/encoding.ts +5 -0
  369. package/src/data/schema/generated/error.ts +6 -0
  370. package/src/data/schema/generated/format.ts +5 -0
  371. package/src/data/schema/generated/type-constructor.ts +10 -0
  372. package/src/data/schema/generated/type.ts +6 -0
  373. package/src/data/schema/index.ts +6 -0
  374. package/src/data/schema/json-schema.ts +33 -0
  375. package/src/data/schema/namespace.ts +55 -0
  376. package/src/data/schema/parse.ts +39 -0
  377. package/src/data/schema/types.ts +39 -0
  378. package/src/data/temporal/append-only.ts +134 -0
  379. package/src/data/temporal/close.ts +27 -0
  380. package/src/data/temporal/columns.ts +10 -0
  381. package/src/data/temporal/definition-queries.ts +70 -0
  382. package/src/data/temporal/errors.ts +10 -0
  383. package/src/data/temporal/get-current.ts +22 -0
  384. package/src/data/temporal/index.ts +9 -0
  385. package/src/data/temporal/namespace.ts +36 -0
  386. package/src/data/temporal/query.ts +25 -0
  387. package/src/data/temporal/resolve.ts +17 -0
  388. package/src/data/temporal/revise.ts +67 -0
  389. package/src/data/temporal/types.ts +22 -0
  390. package/src/data/valve/artifact.ts +33 -0
  391. package/src/data/valve/contract-diff.ts +21 -0
  392. package/src/data/valve/cross.ts +57 -0
  393. package/src/data/valve/crossing-ledger.ts +50 -0
  394. package/src/data/valve/decision.ts +44 -0
  395. package/src/data/valve/durable-crossing.ts +52 -0
  396. package/src/data/valve/execute-crossing.ts +77 -0
  397. package/src/data/valve/faucet.ts +56 -0
  398. package/src/data/valve/gate.ts +114 -0
  399. package/src/data/valve/graph.ts +77 -0
  400. package/src/data/valve/index.ts +53 -0
  401. package/src/data/valve/namespace.ts +57 -0
  402. package/src/data/valve/registry.ts +50 -0
  403. package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
  404. package/src/data/valve/schema/valve-crossing.ts +9 -0
  405. package/src/data/valve/supply.ts +154 -0
  406. package/src/data/valve/types.ts +143 -0
  407. package/src/data/vector/columns.ts +27 -0
  408. package/src/data/vector/index.ts +4 -0
  409. package/src/data/vector/namespace.ts +33 -0
  410. package/src/data/vector/query.ts +85 -0
  411. package/src/data/vector/validate.ts +16 -0
  412. package/src/data/write/audit/actor.ts +15 -0
  413. package/src/data/write/audit/audit-columns.ts +18 -0
  414. package/src/data/write/audit/audit-select.ts +111 -0
  415. package/src/data/write/audit/bound-transaction.ts +14 -0
  416. package/src/data/write/audit/cte-compile.ts +32 -0
  417. package/src/data/write/audit/decode-returning.ts +47 -0
  418. package/src/data/write/audit/final-select.ts +43 -0
  419. package/src/data/write/audit/infra-audit.ts +36 -0
  420. package/src/data/write/audit/primary-key.ts +65 -0
  421. package/src/data/write/audit/projection.ts +41 -0
  422. package/src/data/write/audit/read-touches.ts +86 -0
  423. package/src/data/write/audit/touch-match.ts +78 -0
  424. package/src/data/write/audit/verb-delete.ts +62 -0
  425. package/src/data/write/audit/verb-insert.ts +36 -0
  426. package/src/data/write/audit/verb-select.ts +47 -0
  427. package/src/data/write/audit/verb-update.ts +60 -0
  428. package/src/data/write/audit/verb-upsert.ts +104 -0
  429. package/src/data/write/conflict.ts +43 -0
  430. package/src/data/write/delete.ts +38 -0
  431. package/src/data/write/execute.ts +243 -0
  432. package/src/data/write/index.ts +11 -0
  433. package/src/data/write/insert.ts +63 -0
  434. package/src/data/write/state.ts +43 -0
  435. package/src/data/write/update.ts +54 -0
  436. package/src/data/write/upsert.ts +58 -0
  437. package/src/data/write/values.ts +19 -0
  438. package/src/index.ts +230 -0
  439. package/src/infra/access-links/code.ts +70 -0
  440. package/src/infra/access-links/handle.ts +892 -0
  441. package/src/infra/access-links/index.ts +9 -0
  442. package/src/infra/access-links/namespace.ts +30 -0
  443. package/src/infra/access-links/person-check.ts +177 -0
  444. package/src/infra/access-links/schema.ts +71 -0
  445. package/src/infra/alerts/async-sources.ts +231 -0
  446. package/src/infra/alerts/audit.ts +36 -0
  447. package/src/infra/alerts/beat.ts +123 -0
  448. package/src/infra/alerts/client-faults.ts +111 -0
  449. package/src/infra/alerts/faults.ts +156 -0
  450. package/src/infra/alerts/handle.ts +778 -0
  451. package/src/infra/alerts/http.ts +192 -0
  452. package/src/infra/alerts/index.ts +12 -0
  453. package/src/infra/alerts/infra-sources.ts +180 -0
  454. package/src/infra/alerts/namespace.ts +81 -0
  455. package/src/infra/alerts/redact.ts +21 -0
  456. package/src/infra/alerts/request-faults.ts +41 -0
  457. package/src/infra/alerts/schema.ts +124 -0
  458. package/src/infra/alerts/sinks.ts +125 -0
  459. package/src/infra/alerts/source-options.ts +26 -0
  460. package/src/infra/alerts/sources.ts +503 -0
  461. package/src/infra/alerts/subsystem-sources.ts +137 -0
  462. package/src/infra/audit/emit.ts +87 -0
  463. package/src/infra/audit/index.ts +2 -0
  464. package/src/infra/audit/namespace.ts +22 -0
  465. package/src/infra/audit/schema.sql +35 -0
  466. package/src/infra/audit/types.ts +18 -0
  467. package/src/infra/aws/credentials.ts +147 -0
  468. package/src/infra/aws/sigv4.ts +140 -0
  469. package/src/infra/cache/create.ts +58 -0
  470. package/src/infra/cache/entry.ts +81 -0
  471. package/src/infra/cache/index.ts +4 -0
  472. package/src/infra/cache/namespace.ts +10 -0
  473. package/src/infra/cache/tenant.ts +93 -0
  474. package/src/infra/cache/types.ts +24 -0
  475. package/src/infra/crawl/audit.ts +35 -0
  476. package/src/infra/crawl/errors.ts +25 -0
  477. package/src/infra/crawl/handle.ts +693 -0
  478. package/src/infra/crawl/index.ts +9 -0
  479. package/src/infra/crawl/links.ts +160 -0
  480. package/src/infra/crawl/namespace.ts +36 -0
  481. package/src/infra/crawl/robots.ts +100 -0
  482. package/src/infra/crawl/schema.ts +89 -0
  483. package/src/infra/credit-line/handle.ts +883 -0
  484. package/src/infra/credit-line/index.ts +6 -0
  485. package/src/infra/credit-line/namespace.ts +7 -0
  486. package/src/infra/credit-line/schema.ts +96 -0
  487. package/src/infra/credits/handle.ts +706 -0
  488. package/src/infra/credits/index.ts +5 -0
  489. package/src/infra/credits/namespace.ts +7 -0
  490. package/src/infra/credits/schema.ts +83 -0
  491. package/src/infra/email/audit.ts +36 -0
  492. package/src/infra/email/inbound.ts +622 -0
  493. package/src/infra/email/index.ts +11 -0
  494. package/src/infra/email/mail.ts +517 -0
  495. package/src/infra/email/mime.ts +447 -0
  496. package/src/infra/email/namespace.ts +22 -0
  497. package/src/infra/email/providers.ts +111 -0
  498. package/src/infra/email/schema.ts +96 -0
  499. package/src/infra/email/sns.ts +200 -0
  500. package/src/infra/email/unsubscribe.ts +44 -0
  501. package/src/infra/fetch/address.ts +88 -0
  502. package/src/infra/fetch/connect-retry.ts +87 -0
  503. package/src/infra/fetch/handle.ts +329 -0
  504. package/src/infra/fetch/index.ts +7 -0
  505. package/src/infra/fetch/namespace.ts +70 -0
  506. package/src/infra/idempotency/index.ts +3 -0
  507. package/src/infra/idempotency/middleware.ts +87 -0
  508. package/src/infra/idempotency/store.ts +92 -0
  509. package/src/infra/idempotency/types.ts +30 -0
  510. package/src/infra/join-requests/handle.ts +312 -0
  511. package/src/infra/join-requests/index.ts +2 -0
  512. package/src/infra/join-requests/namespace.ts +7 -0
  513. package/src/infra/join-requests/schema.ts +33 -0
  514. package/src/infra/outbox/core.ts +165 -0
  515. package/src/infra/quota/errors.ts +32 -0
  516. package/src/infra/quota/handle.ts +215 -0
  517. package/src/infra/quota/index.ts +5 -0
  518. package/src/infra/quota/namespace.ts +7 -0
  519. package/src/infra/quota/schema.ts +15 -0
  520. package/src/infra/storage/backend.ts +34 -0
  521. package/src/infra/storage/handle.ts +513 -0
  522. package/src/infra/storage/index.ts +9 -0
  523. package/src/infra/storage/local.ts +104 -0
  524. package/src/infra/storage/namespace.ts +13 -0
  525. package/src/infra/storage/s3.ts +257 -0
  526. package/src/infra/storage/schema.ts +24 -0
  527. package/src/infra/support/handle.ts +854 -0
  528. package/src/infra/support/http.ts +229 -0
  529. package/src/infra/support/index.ts +7 -0
  530. package/src/infra/support/namespace.ts +12 -0
  531. package/src/infra/support/schema.ts +96 -0
  532. package/src/infra/webhook/inbound.ts +45 -0
  533. package/src/infra/webhook/index.ts +5 -0
  534. package/src/infra/webhook/namespace.ts +24 -0
  535. package/src/infra/webhook/outbound.ts +315 -0
  536. package/src/infra/webhook/sign.ts +32 -0
  537. package/src/infra/webhook/verify.ts +82 -0
  538. package/src/invariants/assert.ts +26 -0
  539. package/src/invariants/index.ts +1 -0
  540. package/src/lint/config.ts +56 -0
  541. package/src/lint/doctrine.ts +163 -0
  542. package/src/lint/include.ts +97 -0
  543. package/src/lint/index.ts +3 -0
  544. package/src/lint/preset.ts +10 -0
  545. package/src/lint/resolver.ts +218 -0
  546. package/src/lint/rules/no-reexports.ts +46 -0
  547. package/src/request/behavior/audited.ts +85 -0
  548. package/src/request/behavior/cached.ts +62 -0
  549. package/src/request/behavior/compose.ts +28 -0
  550. package/src/request/behavior/index.ts +5 -0
  551. package/src/request/behavior/namespace.ts +16 -0
  552. package/src/request/behavior/types.ts +26 -0
  553. package/src/request/behavior/versioned.ts +54 -0
  554. package/src/request/context/create.ts +103 -0
  555. package/src/request/context/guard.ts +49 -0
  556. package/src/request/context/index.ts +4 -0
  557. package/src/request/context/run-in-transaction.ts +200 -0
  558. package/src/request/context/store.ts +28 -0
  559. package/src/request/context/types.ts +50 -0
  560. package/src/request/di/builder.ts +535 -0
  561. package/src/request/di/index.ts +8 -0
  562. package/src/request/di/resolve.ts +271 -0
  563. package/src/request/di/types.ts +262 -0
  564. package/src/request/fitting/namespace.ts +7 -0
  565. package/src/request/fixture/batch.ts +71 -0
  566. package/src/request/fixture/builder.ts +26 -0
  567. package/src/request/fixture/errors.ts +10 -0
  568. package/src/request/fixture/index.ts +8 -0
  569. package/src/request/fixture/namespace.ts +23 -0
  570. package/src/request/fixture/paginate.ts +44 -0
  571. package/src/request/fixture/to-handlers.ts +260 -0
  572. package/src/request/fixture/types.ts +79 -0
  573. package/src/request/flow/act-as.ts +78 -0
  574. package/src/request/flow/namespace.ts +17 -0
  575. package/src/request/http/error-step.ts +42 -0
  576. package/src/request/http/file.ts +141 -0
  577. package/src/request/http/index.ts +4 -0
  578. package/src/request/http/middleware.ts +141 -0
  579. package/src/request/http/namespace.ts +5 -0
  580. package/src/request/http/rate-limit-classes.ts +170 -0
  581. package/src/request/http/response.ts +82 -0
  582. package/src/request/http/server.ts +916 -0
  583. package/src/request/http/sniff.ts +261 -0
  584. package/src/request/http/types.ts +250 -0
  585. package/src/request/http/upload.ts +284 -0
  586. package/src/request/internal/text.ts +6 -0
  587. package/src/request/openapi/generate.ts +205 -0
  588. package/src/request/openapi/index.ts +2 -0
  589. package/src/request/openapi/namespace.ts +7 -0
  590. package/src/test/auth.ts +13 -0
  591. package/src/test/auto-setup.ts +45 -0
  592. package/src/test/context.ts +91 -0
  593. package/src/test/crawl-fixture.ts +157 -0
  594. package/src/test/discover-fork.ts +17 -0
  595. package/src/test/fingerprint.ts +135 -0
  596. package/src/test/globals.d.ts +7 -0
  597. package/src/test/index.ts +19 -0
  598. package/src/test/namespace.ts +87 -0
  599. package/src/test/plugin.ts +189 -0
  600. package/src/test/progress.ts +185 -0
  601. package/src/test/reap-after-run.ts +28 -0
  602. package/src/test/reap.ts +286 -0
  603. package/src/test/reset.ts +253 -0
  604. package/src/test/savepoints.ts +172 -0
  605. package/src/test/setup.ts +1422 -0
  606. package/src/test/system-channel.ts +50 -0
  607. package/src/test/vitest-plugin.ts +142 -0
  608. package/src/test/vitest-workspace.ts +507 -0
  609. package/src/test/vitest.ts +333 -0
  610. package/src/test/watch.ts +105 -0
  611. package/src/trace/capture/bounded-serializer.ts +146 -0
  612. package/src/trace/cardinality/analyze.ts +173 -0
  613. package/src/trace/cardinality/branch-context.ts +214 -0
  614. package/src/trace/cardinality/check.ts +33 -0
  615. package/src/trace/cardinality/classify-edge.ts +64 -0
  616. package/src/trace/cardinality/structural-max.ts +107 -0
  617. package/src/trace/check/coverage-check.ts +188 -0
  618. package/src/trace/check/flow-check.ts +103 -0
  619. package/src/trace/check/flow-step-site.ts +234 -0
  620. package/src/trace/check/io-pattern.ts +116 -0
  621. package/src/trace/codemod/add-cardinality.ts +152 -0
  622. package/src/trace/codemod/run.ts +80 -0
  623. package/src/trace/entry/child-trace.ts +21 -0
  624. package/src/trace/entry/close-trace.ts +87 -0
  625. package/src/trace/entry/finalize-trace.ts +28 -0
  626. package/src/trace/entry/open-trace.ts +138 -0
  627. package/src/trace/entry/parent-trace.ts +20 -0
  628. package/src/trace/entry/parse-traceparent.ts +39 -0
  629. package/src/trace/entry/process-start.ts +38 -0
  630. package/src/trace/entry/trace-context.ts +26 -0
  631. package/src/trace/entry/tracing-enabled.ts +10 -0
  632. package/src/trace/external/record.ts +195 -0
  633. package/src/trace/external/report.ts +66 -0
  634. package/src/trace/namespace.ts +19 -0
  635. package/src/trace/partition/day.ts +47 -0
  636. package/src/trace/partition/index.ts +14 -0
  637. package/src/trace/partition/partition-name.ts +23 -0
  638. package/src/trace/partition/plan.ts +82 -0
  639. package/src/trace/partition/schedule.ts +26 -0
  640. package/src/trace/partition/startup-hook.ts +39 -0
  641. package/src/trace/partition/sync.ts +154 -0
  642. package/src/trace/partition/tables.ts +53 -0
  643. package/src/trace/read/tree.ts +83 -0
  644. package/src/trace/retain/copy-on-error.ts +76 -0
  645. package/src/trace/runtime/expire-stale-traces.ts +54 -0
  646. package/src/trace/runtime/flow-step.ts +147 -0
  647. package/src/trace/runtime/flush-steps.ts +31 -0
  648. package/src/trace/runtime/pending-writes.ts +54 -0
  649. package/src/trace/runtime/step-buffer.ts +298 -0
  650. package/src/trace/runtime/step-error.ts +21 -0
  651. package/src/trace/runtime/step-meta.ts +55 -0
  652. package/src/trace/runtime/thenable.ts +12 -0
  653. package/src/trace/runtime/truncate-trace.ts +62 -0
  654. package/src/trace/schema/trace-fields.ts +52 -0
  655. package/src/trace/schema/trace-retained.ts +22 -0
  656. package/src/trace/schema/trace-step-fields.ts +44 -0
  657. package/src/trace/schema/trace-step-retained.ts +25 -0
  658. package/src/trace/schema/trace-step.ts +18 -0
  659. package/src/trace/schema/trace.ts +12 -0
  660. package/src/trace/transformer/apply.ts +79 -0
  661. package/src/trace/transformer/build-meta-literal.ts +30 -0
  662. package/src/trace/transformer/find-flow-step-sites.ts +85 -0
  663. package/src/trace/transformer/inject-flow-step-import.ts +39 -0
  664. package/src/trace/transformer/transform-error.ts +14 -0
  665. package/src/trace/transformer/transform-flow-steps.ts +123 -0
  666. package/src/trace/transformer/wrap-function-declaration.ts +62 -0
  667. package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
  668. package/src/workspace/affected.ts +110 -0
  669. package/src/workspace/changed-files.ts +163 -0
  670. package/src/workspace/check-deps.ts +213 -0
  671. package/src/workspace/checksum.ts +20 -0
  672. package/src/workspace/dependency-graph.ts +67 -0
  673. package/src/workspace/detect-pipework-copies.ts +93 -0
  674. package/src/workspace/discover.ts +206 -0
  675. package/src/workspace/generate.ts +401 -0
  676. package/src/workspace/index.ts +7 -0
  677. package/src/workspace/module-imports-pipework.ts +39 -0
  678. package/src/workspace/module-package-name.ts +12 -0
  679. package/src/workspace/scrub-git-env.ts +23 -0
  680. package/src/workspace/source-paths.ts +36 -0
  681. package/src/workspace/sync.ts +182 -0
  682. package/dist/REFERENCE.md +0 -1477
  683. package/dist/infra/access-links/rate-limit.d.ts +0 -10
  684. package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
  685. package/dist/infra/access-links/rate-limit.js +0 -28
  686. package/dist/infra/access-links/rate-limit.js.map +0 -1
  687. package/dist/infra/email/sigv4.d.ts +0 -24
  688. package/dist/infra/email/sigv4.d.ts.map +0 -1
  689. package/dist/infra/email/sigv4.js +0 -55
  690. package/dist/infra/email/sigv4.js.map +0 -1
@@ -0,0 +1,16 @@
1
+ const VALID_IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_\-]*$/
2
+
3
+ export function assertValidIdentifier(value: string, label: string): void {
4
+ if (!VALID_IDENTIFIER.test(value)) {
5
+ throw new Error(
6
+ `[pipework] Invalid SQL identifier for ${label}: "${value}"\n\n` +
7
+ ` Identifiers must start with a letter or underscore and contain only\n` +
8
+ ` letters, digits, underscores, and hyphens.\n`
9
+ )
10
+ }
11
+ }
12
+
13
+ export function quoteIdentifier(value: string, label: string): string {
14
+ assertValidIdentifier(value, label)
15
+ return `"${value}"`
16
+ }
@@ -0,0 +1,9 @@
1
+ // Index and constraint builders — manual layer (wrappable)
2
+ // Each re-export can be replaced with a pipework wrapper as needed.
3
+ // e.g., `index` could auto-include tenant_id for tenant-scoped tables.
4
+
5
+ export {
6
+ index, uniqueIndex,
7
+ primaryKey, foreignKey,
8
+ unique, check,
9
+ } from '../../query/pg-core/index.js'
@@ -0,0 +1,49 @@
1
+ import { sql } from './sql.js'
2
+ import type { SQL, Column } from './types.js'
3
+
4
+ const CAST = /^[a-z_][a-z0-9_]*(\([0-9, ]+\))?$/i
5
+
6
+ function fail(problem: string, fix: string): never {
7
+ throw new Error(`[pipework] filter.inList: ${problem}\n\n Fix: ${fix}\n`)
8
+ }
9
+
10
+ function elementType(values: readonly (string | number)[], cast: string | undefined): string {
11
+ if (cast !== undefined && !CAST.test(cast)) fail(`cast "${cast}" is not a plain type name.`, "pass a type name such as 'uuid' or 'int'.")
12
+ const numeric = typeof values[0] === 'number'
13
+ for (const v of values as readonly unknown[]) {
14
+ if (v === null || v === undefined) fail('the list holds a null or undefined value.', 'drop nulls before passing the list.')
15
+ if (typeof v !== (numeric ? 'number' : 'string')) {
16
+ fail('the list must hold only strings or only numbers.', 'pass a list of one type, or convert the values first.')
17
+ }
18
+ if (numeric && !Number.isFinite(v as number)) fail('the list holds NaN or a non-finite number.', 'pass finite numbers only.')
19
+ }
20
+ if (cast !== undefined) return cast
21
+ if (!numeric) return 'text'
22
+ return (values as readonly number[]).every(v => Number.isInteger(v)) ? 'bigint' : 'numeric'
23
+ }
24
+
25
+ function bind(values: readonly string[] | readonly number[], cast: string | undefined): SQL {
26
+ if (!Array.isArray(values)) fail('the values are not an array.', 'pass a string[] or number[].')
27
+ return sql`${sql.param(values)}::${sql.raw(elementType(values, cast))}[]`
28
+ }
29
+
30
+ /**
31
+ * Membership of a JS list: `<expr> = ANY($1::text[])`, the list bound as one array parameter
32
+ * whatever its length and hashed by Postgres. An empty list is `false` (no parameter).
33
+ * Strings bind as `text`, integers as `bigint`, other numbers as `numeric`; pass `cast` for
34
+ * other columns, e.g. `inList(t.id, ids, 'uuid')`. Lifts `inArray`'s 65,535-parameter limit.
35
+ */
36
+ export function inList(expr: Column | SQL, values: readonly string[] | readonly number[], cast?: string): SQL<boolean> {
37
+ if (values.length === 0 && cast !== undefined) bind(values, cast)
38
+ return values.length === 0 ? sql<boolean>`false` : sql<boolean>`${expr} = ANY(${bind(values, cast)})`
39
+ }
40
+
41
+ /**
42
+ * Non-membership of a JS list: `<expr> <> ALL($1::text[])`, the list bound as one array
43
+ * parameter. An empty list is `true` (no parameter). Types and `cast` as for `inList`
44
+ * (`notInList(t.id, ids, 'uuid')`); lifts `notInArray`'s 65,535-parameter limit.
45
+ */
46
+ export function notInList(expr: Column | SQL, values: readonly string[] | readonly number[], cast?: string): SQL<boolean> {
47
+ if (values.length === 0 && cast !== undefined) bind(values, cast)
48
+ return values.length === 0 ? sql<boolean>`true` : sql<boolean>`${expr} <> ALL(${bind(values, cast)})`
49
+ }
@@ -0,0 +1,9 @@
1
+ export { pipe } from './db.js'
2
+ export type { DB, SQL, Table, Column, TransactionConfig } from './types.js'
3
+ export { flowStorage as flowContext, runInContext, requireContext, getContext } from '../../request/context/store.js'
4
+ export type { Flow } from '../../request/context/types.js'
5
+ export { createTestContext as createContext } from '../../request/context/create.js'
6
+ export { type ManagedConnection, type ConnectOptions, tap, createManagedConnection } from './pool.js'
7
+ export { assertValidIdentifier, quoteIdentifier } from './identifiers.js'
8
+ export { excluded } from './excluded.js'
9
+ export { isDeadlock, logDeadlock, createDebugFn } from './instrumentation.js'
@@ -0,0 +1,137 @@
1
+ // A drizzle handle's `insert(T).values(rows)` past postgres.js's 65,534-parameter
2
+ // limit runs as several statements on that same handle, inside one transaction
3
+ // (a savepoint when the handle is already a transaction), so a caller never counts binds.
4
+
5
+ import type { PostgresJsDatabase } from '../query/postgres-js/index.js'
6
+ import { getTableColumns } from '../query/index.js'
7
+
8
+ /**
9
+ * Parameters one statement may bind, counting one per column per row (an upper
10
+ * bound; the margin covers `sql` values and an upsert's `set`). Not configurable.
11
+ */
12
+ export const MAX_STATEMENT_PARAMETERS = 30_000
13
+
14
+ /** Rows per statement under the parameter limit. */
15
+ export function rowsPerStatement(table: unknown): number {
16
+ const columns = Object.keys(getTableColumns(table as never)).length
17
+ return Math.max(1, Math.floor(MAX_STATEMENT_PARAMETERS / Math.max(1, columns)))
18
+ }
19
+
20
+ type AnyFn = (...args: never[]) => unknown
21
+ type Handle = PostgresJsDatabase
22
+ interface Originals { insert: AnyFn; transaction: AnyFn }
23
+
24
+ const patched = new WeakSet<object>()
25
+ const originals = new WeakMap<object, Originals>()
26
+
27
+ /**
28
+ * Patches `handle` in place (own `insert` and `transaction`) and returns it.
29
+ * `values(list)` over the budget returns a split insert; any other insert is
30
+ * drizzle's own builder. Transactions opened from the handle are patched too.
31
+ */
32
+ export function splitLargeInserts(handle: Handle): Handle {
33
+ if (patched.has(handle)) return handle
34
+ patched.add(handle)
35
+ const h = handle as unknown as Record<string, AnyFn>
36
+ const insert = h['insert']!
37
+ const transaction = h['transaction']!
38
+ originals.set(handle, { insert, transaction })
39
+
40
+ h['insert'] = ((table: unknown): unknown => {
41
+ const builder = (insert as (this: unknown, t: unknown) => Record<string, AnyFn>).call(handle, table)
42
+ const values = builder['values']!
43
+ builder['values'] = ((rows: unknown): unknown => {
44
+ if (Array.isArray(rows) && rows.length > rowsPerStatement(table)) {
45
+ return new SplitInsert(handle, table, rows)
46
+ }
47
+ return (values as (this: unknown, r: unknown) => unknown).call(builder, rows)
48
+ }) as AnyFn
49
+ return builder
50
+ }) as AnyFn
51
+
52
+ h['transaction'] = ((fn: (tx: Handle) => Promise<unknown>, config?: unknown): unknown =>
53
+ (transaction as (this: unknown, f: unknown, c?: unknown) => unknown).call(
54
+ handle,
55
+ (tx: Handle) => fn(splitLargeInserts(tx)),
56
+ config,
57
+ )) as AnyFn
58
+
59
+ return handle
60
+ }
61
+
62
+ type Call = readonly [method: 'onConflictDoNothing' | 'onConflictDoUpdate' | 'returning', args: unknown[]]
63
+
64
+ /** The insert `values(list)` returns for a list over the budget; awaiting it runs the slices. */
65
+ class SplitInsert implements PromiseLike<unknown> {
66
+ private readonly calls: Call[] = []
67
+
68
+ constructor(
69
+ private readonly handle: Handle,
70
+ private readonly table: unknown,
71
+ private readonly rows: readonly unknown[],
72
+ ) {}
73
+
74
+ onConflictDoNothing(config?: unknown): this {
75
+ this.calls.push(['onConflictDoNothing', config === undefined ? [] : [config]])
76
+ return this
77
+ }
78
+
79
+ onConflictDoUpdate(config: unknown): this {
80
+ this.calls.push(['onConflictDoUpdate', [config]])
81
+ return this
82
+ }
83
+
84
+ returning(fields?: unknown): this {
85
+ this.calls.push(['returning', fields === undefined ? [] : [fields]])
86
+ return this
87
+ }
88
+
89
+ execute(): Promise<unknown> {
90
+ const size = rowsPerStatement(this.table)
91
+ const returns = this.calls.some(([method]) => method === 'returning')
92
+ return (this.handle.transaction as unknown as (fn: (tx: Handle) => Promise<unknown>) => Promise<unknown>)(async (tx) => {
93
+ const insert = originals.get(tx)!.insert as (this: unknown, t: unknown) => Record<string, AnyFn>
94
+ const rows: unknown[] = []
95
+ let count = 0
96
+ for (let i = 0; i < this.rows.length; i += size) {
97
+ let statement: unknown = insert.call(tx, this.table)['values']!(this.rows.slice(i, i + size) as never)
98
+ for (const [method, args] of this.calls) {
99
+ statement = (statement as Record<string, (...a: unknown[]) => unknown>)[method]!(...args)
100
+ }
101
+ const out = await (statement as PromiseLike<unknown>)
102
+ if (Array.isArray(out)) rows.push(...out)
103
+ const written = (out as { count?: unknown } | null)?.count
104
+ if (typeof written === 'number') count += written
105
+ }
106
+ return returns ? rows : Object.assign([], { count })
107
+ })
108
+ }
109
+
110
+ then<R1 = unknown, R2 = never>(
111
+ onfulfilled?: ((value: unknown) => R1 | PromiseLike<R1>) | null,
112
+ onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null,
113
+ ): Promise<R1 | R2> {
114
+ return this.execute().then(onfulfilled, onrejected)
115
+ }
116
+
117
+ catch<R = never>(onrejected?: ((reason: unknown) => R | PromiseLike<R>) | null): Promise<unknown> {
118
+ return this.execute().catch(onrejected)
119
+ }
120
+
121
+ finally(onfinally?: (() => void) | null): Promise<unknown> {
122
+ return this.execute().finally(onfinally)
123
+ }
124
+
125
+ private refuse(method: string): never {
126
+ throw new Error(
127
+ `[pipework] ${method}() is not available: this insert has ${String(this.rows.length)} rows, over Postgres's ` +
128
+ `parameter limit, so it is split into several statements of at most ${String(rowsPerStatement(this.table))} rows. ` +
129
+ 'Await it to run them in one transaction, or pass a shorter list.',
130
+ )
131
+ }
132
+
133
+ toSQL(): never { return this.refuse('toSQL') }
134
+ getSQL(): never { return this.refuse('getSQL') }
135
+ prepare(): never { return this.refuse('prepare') }
136
+ $dynamic(): never { return this.refuse('$dynamic') }
137
+ }
@@ -0,0 +1,82 @@
1
+ import { getBaseLogger } from '../../core/logging/logger.js'
2
+ import { getContext } from '../../request/context/store.js'
3
+ import type { ResolvedObservability } from '../../core/config/load.js'
4
+
5
+ const DEADLOCK_CODE = '40P01'
6
+ const QUERY_TRUNCATE_LENGTH = 500
7
+
8
+ /** postgres.js's `debug` hook signature. */
9
+ type DebugFn = (connection: number, query: string, parameters: unknown[]) => void
10
+
11
+ /**
12
+ * True when the driver's `debug` hook exists ONLY to feed a statement observer.
13
+ * Such a connection's errors are put back to their unobserved shape by the
14
+ * driver error boundary; `logAllQueries` connections are left exactly as they
15
+ * are today, that mode having already opted into verbose errors.
16
+ */
17
+ export function isObserverOnly(config: ResolvedObservability): boolean {
18
+ return config.onStatement !== undefined && !config.logAllQueries
19
+ }
20
+
21
+ /**
22
+ * The driver's `debug` hook for a connection, or undefined when nothing is
23
+ * observing. Query logging and the caller-supplied `onStatement` observer are
24
+ * independent: either alone installs the hook, and with both configured both
25
+ * fire for every statement.
26
+ */
27
+ export function createDebugFn(config: ResolvedObservability): DebugFn | undefined {
28
+ const logQuery = config.logAllQueries ? createQueryLogFn() : undefined
29
+ const observer = config.onStatement
30
+
31
+ if (!logQuery && !observer) return undefined
32
+ if (!observer) return logQuery
33
+ if (!logQuery) {
34
+ return (connection, query, parameters) => {
35
+ observer({ connectionId: connection, query, parameters })
36
+ }
37
+ }
38
+
39
+ return (connection, query, parameters) => {
40
+ logQuery(connection, query, parameters)
41
+ observer({ connectionId: connection, query, parameters })
42
+ }
43
+ }
44
+
45
+ function createQueryLogFn(): DebugFn {
46
+ return (connection: number, query: string) => {
47
+ const logger = getBaseLogger()
48
+ const ctx = getContext()
49
+ const fields: Record<string, unknown> = {
50
+ query: query.length > QUERY_TRUNCATE_LENGTH ? query.slice(0, QUERY_TRUNCATE_LENGTH) + '...' : query,
51
+ connection,
52
+ }
53
+
54
+ if (ctx) {
55
+ if (ctx.tenant !== null) fields['tenant'] = ctx.tenant
56
+ if (ctx.requestId !== '') fields['requestId'] = ctx.requestId
57
+ }
58
+
59
+ logger.debug(fields, 'query:execute')
60
+ }
61
+ }
62
+
63
+ export function isDeadlock(err: unknown): boolean {
64
+ if (!(err instanceof Error)) return false
65
+ return 'code' in err && (err as { code: unknown }).code === DEADLOCK_CODE
66
+ }
67
+
68
+ export function logDeadlock(err: unknown, dbName: string): void {
69
+ const logger = getBaseLogger()
70
+ const ctx = getContext()
71
+ const fields: Record<string, unknown> = {
72
+ err,
73
+ database: dbName,
74
+ }
75
+
76
+ if (ctx) {
77
+ if (ctx.tenant !== null) fields['tenant'] = ctx.tenant
78
+ if (ctx.requestId !== '') fields['requestId'] = ctx.requestId
79
+ }
80
+
81
+ logger.error(fields, 'deadlock detected')
82
+ }
@@ -0,0 +1,28 @@
1
+ // The maintenance setting: lets framework passes that must read or update the
2
+ // built-in trace and audit tables across tenants (closing a trace, expiring
3
+ // stale ones, retiring an audit partition, verifying the tenantless chain)
4
+ // satisfy those tables' row-level security policies. Set transaction-locally,
5
+ // by the framework only; application code must never set it.
6
+
7
+ import { sql } from './sql.js'
8
+ import type { DB } from './index.js'
9
+
10
+ export const MAINTENANCE_SETTING = 'pipework.maintenance'
11
+
12
+ /** The policy predicate that admits a maintenance transaction. */
13
+ export const MAINTENANCE_CLAUSE = `current_setting('${MAINTENANCE_SETTING}', true) = 'on'`
14
+
15
+ /**
16
+ * Runs `fn` in a transaction (a savepoint when `db` is already one) with the
17
+ * maintenance setting on, and puts the previous value back when `fn` returns.
18
+ */
19
+ export async function withMaintenance<T>(db: DB, fn: (tx: DB) => Promise<T>): Promise<T> {
20
+ return db.transaction(async raw => {
21
+ const tx = raw as unknown as DB
22
+ const before = await tx.execute(sql`SELECT current_setting(${MAINTENANCE_SETTING}, true) AS v`)
23
+ await tx.execute(sql`SELECT set_config(${MAINTENANCE_SETTING}, 'on', true)`)
24
+ const result = await fn(tx)
25
+ await tx.execute(sql`SELECT set_config(${MAINTENANCE_SETTING}, ${(before[0]?.['v'] as string | null) ?? ''}, true)`)
26
+ return result
27
+ })
28
+ }
@@ -0,0 +1,107 @@
1
+ import { pipe as getDb, pipeSystem, pipeDoor } from './db.js'
2
+ import { sql } from './sql.js'
3
+ import { labelled } from './query-label.js'
4
+ import { migrateAll, migrateOne } from '../migrate/index.js'
5
+ import { filter } from './filter.js'
6
+ import { excluded } from './excluded.js'
7
+ import { advisoryLock, tryAdvisoryLock } from './advisory-lock.js'
8
+ import { serializable } from './serializable.js'
9
+ import { withTimeouts } from './timeouts.js'
10
+ import { bulkSet } from './bulk-set.js'
11
+ import { values } from './values.js'
12
+ import { fn } from './function-source.js'
13
+ import { update, insert, remove, upsert } from '../write/index.js'
14
+
15
+ import { aliasedRelation, aliasedTable, aliasedTableColumn, getTableColumns, getTableName, getViewName, getViewSelectedFields, isTable, createMany, createOne, relations } from '../query/index.js'
16
+
17
+ // Domain definitions
18
+ import { field, define, definitions, external } from '../domain/index.js'
19
+
20
+ // Pipework-owned type aliases
21
+ export type { DB, SQL, Table, Column, TransactionConfig } from './types.js'
22
+
23
+ /** Query operators and aggregates — eq, gt, lt, and, or, count, sum, etc. */
24
+ export { filter } from './filter.js'
25
+
26
+ /** Returns excluded-column references for onConflictDoUpdate set clauses. */
27
+ export { excluded } from './excluded.js'
28
+
29
+ /** Database accessor — returns a Drizzle DB instance scoped to the current request/job/test context. Requires active AsyncLocalStorage context. */
30
+ export const pipe = Object.assign(getDb, {
31
+ /** The system channel — deliberate cross-tenant access for pre-tenant surfaces (auth membership resolution, public webhook ingress, admin tooling). Never tenant-scoped or tenant-guarded; runs on the owner-role connection outside the request transaction. */
32
+ system: pipeSystem,
33
+
34
+ /** A named cross-tenant read: `pipe.door(name, db => ...)`. The door is declared under `doors` in config; the callback runs in one transaction on the platform-role connection and may SELECT from the door's table and from non-tenant tables. Needs `rls.platformRole`. */
35
+ door: pipeDoor,
36
+
37
+ /** Query operators and aggregates — eq, gt, lt, and, or, count, sum, etc. */
38
+ filter,
39
+
40
+ /** Names every statement `fn` starts, in `query:slow` and `query:in-flight` log lines: `pipe.labelled('servable-footprints', async () => await ...)`. A query builder is lazy: `fn` must await it, not return it, or it runs outside the scope. */
41
+ labelled,
42
+
43
+ /** Raw statement tag — for a statement pipework does not model. Interpolated values are parameters; `sql.raw` is not. Runs on the caller's connection, so inside a request it is the request transaction. Writes still go through pipe.update / insert / delete, which is what audit hooks. */
44
+ sql,
45
+
46
+ // Introspection — aliasedTable, aliasedRelation, getTableColumns, getTableName, getViewName, etc.
47
+ aliasedRelation,
48
+ aliasedTable,
49
+ aliasedTableColumn,
50
+ getTableColumns,
51
+ getTableName,
52
+ getViewName,
53
+ getViewSelectedFields,
54
+ isTable,
55
+
56
+ // Relations — relations(), createOne(), createMany()
57
+ createMany,
58
+ createOne,
59
+ relations,
60
+
61
+ /** Runs migrations for all configured databases. */
62
+ migrate: migrateAll,
63
+ /** Runs migrations for a single named database. */
64
+ migrateOne,
65
+
66
+ /** Returns excluded-column references for onConflictDoUpdate set clauses. */
67
+ excluded,
68
+
69
+ /** Acquires a transaction-scoped advisory lock. Released at commit/rollback. */
70
+ advisoryLock,
71
+
72
+ /** Non-blocking advisoryLock: true if the transaction-scoped lock was won, false if another transaction holds it. */
73
+ tryAdvisoryLock,
74
+
75
+ /** Runs a function in a SERIALIZABLE transaction with automatic retry on serialization failures and deadlocks. */
76
+ serializable,
77
+
78
+ /** Sets statement_timeout and/or lock_timeout for the current transaction in one statement, then runs fn; a statement cancelled for them rejects with StatementTimeoutError or LockTimeoutError. */
79
+ withTimeouts,
80
+
81
+ /** Bulk UPDATE ... FROM (VALUES ...) — updates multiple rows with per-row values in a single statement. */
82
+ bulkSet,
83
+
84
+ /** Produces a typed VALUES clause for bulk operations — the base primitive for bulkSet and bulkUpsert. */
85
+ values,
86
+
87
+ /** A set-returning SQL function as a typed source for `.from()` and joins — `pipe.fn('schema.f', { args: [field.uuid()], columns: { path: field.text() } })`. Arguments are bound and cast to their declared types. */
88
+ fn,
89
+
90
+ /** Field builders for domain definitions — uuid(), text(), integer(), etc. */
91
+ field,
92
+ /** Registers a domain definition with table, validators, and factory projections. The `auditEntity` option names the `@touches` entity writes to this table are audited under (see `__flowStep`). */
93
+ define,
94
+ /** Returns the global registry of all domain definitions. */
95
+ definitions,
96
+ /** Declares a table or view another service owns (`pipe.external(name, fields, { schema, table? })`): typed columns and every query operator, read-only, never migrated, not tenant-scoped. */
97
+ external,
98
+
99
+ /** Pipework-owned UPDATE builder — the only consumer-facing way to update pipework-managed tables (Q8). */
100
+ update,
101
+ /** Pipework-owned INSERT builder — the only consumer-facing way to insert into pipework-managed tables (Q8). A list of any size is split into statements under Postgres's parameter limit, in one transaction. */
102
+ insert,
103
+ /** Pipework-owned DELETE builder — the only consumer-facing way to delete from pipework-managed tables (Q8). */
104
+ delete: remove,
105
+ /** Pipework-owned UPSERT builder — insert with conflict resolution (Q8). A list of any size is split into statements under Postgres's parameter limit, in one transaction; rows repeating a conflict key across statements do not fail as one statement would. */
106
+ upsert,
107
+ })
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Callers that legitimately open the owner-role connection of a platform-mode
3
+ * database: they run DDL. Everything else runs on the platform role.
4
+ */
5
+ export const OWNER_LABEL_MIGRATE = 'migrate'
6
+ /** Trace and audit partition maintenance (`createTracePartitionStartupHook`, `scheduleTracePartitionMaintenance`): the app passes it `getOrCreate(config, 'owner', label)`. */
7
+ export const OWNER_LABEL_TRACE_PARTITIONS = 'trace-partition-maintenance'
8
+
9
+ export const OWNER_DDL_LABELS: readonly string[] = [OWNER_LABEL_MIGRATE, OWNER_LABEL_TRACE_PARTITIONS]
@@ -0,0 +1,187 @@
1
+ import postgres from 'postgres'
2
+ import { drizzle, type PostgresJsDatabase } from '../query/postgres-js/index.js'
3
+ import type { ResolvedDatabase } from '../../core/config/load.js'
4
+ import type { ResolvedObservability } from '../../core/config/load.js'
5
+ import { createDebugFn, isObserverOnly } from './instrumentation.js'
6
+ import { markObservedConnection } from '../query/postgres-js/driver-error-boundary.js'
7
+ import { warnRawClientIsUnsanitized } from './raw-client-warning.js'
8
+ import { splitLargeInserts } from './insert-split.js'
9
+ import { createStatementWatch } from './query-watch.js'
10
+
11
+ /** Which database role a pooled connection authenticates as. `owner` runs migrations/bootstrap and owns tables (bypasses RLS); `app` is the non-owner, non-BYPASSRLS runtime role that RLS policies enforce against; `system` is the platform role (`rls.platformRole`, via `systemUrl`), which reaches a tenant table only through a declared door. */
12
+ export type ConnectionRole = 'owner' | 'app' | 'system'
13
+
14
+ /** A standalone pooled connection: the raw postgres.js client, its drizzle handle, and a `close()` that ends the pool. */
15
+ export interface ManagedConnection {
16
+ readonly name: string
17
+ /**
18
+ * The raw postgres.js client — deliberately unmediated. With
19
+ * `observability.onStatement` configured, queries issued through it fall
20
+ * outside pipework's driver error boundary, so their errors serialize bind
21
+ * parameters; `connection.drizzle` does not. Reading this on an observed
22
+ * connection logs a warning once per database.
23
+ */
24
+ readonly client: postgres.Sql
25
+ readonly drizzle: PostgresJsDatabase
26
+ /** Test override only: this connection's handle for `pipe.system()`, reading across tenants under row-level security. */
27
+ readonly system?: PostgresJsDatabase
28
+ /** Test override only: a handle for `pipe.door(name)` on the test connection, with that door's setting open for each statement. */
29
+ readonly door?: (name: string) => PostgresJsDatabase
30
+ /**
31
+ * The ids of every pooled connection (opening up to `max`), ascending by
32
+ * `connectionId`. `connectionId` is the driver ordinal that
33
+ * `observability.onStatement` events carry as `StatementEvent.connectionId`;
34
+ * `backendPid` is the server's `pg_backend_pid()`, matching `pg_stat_activity`.
35
+ *
36
+ * Holds all `max` connections at once, runs one `SELECT pg_backend_pid()` on
37
+ * each, then releases them. The probes are real statements, so they reach
38
+ * `onStatement` like any other: one `SELECT pg_backend_pid()` per connection,
39
+ * plus the driver's own type lookup on a connection not yet used. Waits for
40
+ * connections in use elsewhere to be free.
41
+ *
42
+ * Needs the driver's `debug` hook (configure `observability.onStatement`);
43
+ * without it, throws.
44
+ */
45
+ connectionIds(): Promise<ReadonlyArray<{ connectionId: number; backendPid: number }>>
46
+ close(options?: { timeoutSeconds?: number }): Promise<void>
47
+ }
48
+
49
+ /** Options for `tap()` — pool size (default 1), idle timeout in seconds, and session settings (GUCs) sent in every connection's startup packet. */
50
+ export interface ConnectOptions {
51
+ readonly max?: number
52
+ readonly idleTimeout?: number
53
+ readonly settings?: Readonly<Record<string, string | number | boolean>>
54
+ }
55
+
56
+ function startupSettings(settings: Readonly<Record<string, string | number | boolean>>): Record<string, string> {
57
+ const out: Record<string, string> = {}
58
+ for (const [k, v] of Object.entries(settings)) out[k] = typeof v === 'boolean' ? (v ? 'on' : 'off') : String(v)
59
+ return out
60
+ }
61
+
62
+ const PROBE_QUERY = 'SELECT pg_backend_pid() AS pid'
63
+
64
+ /** Slot the wrapped debug hook fills with the ordinal of the connection a probe runs on. */
65
+ interface ProbeSlot { current: ((connectionId: number) => void) | null }
66
+
67
+ async function probeConnectionIds(
68
+ client: postgres.Sql,
69
+ slot: ProbeSlot | undefined,
70
+ ): Promise<ReadonlyArray<{ connectionId: number; backendPid: number }>> {
71
+ if (!slot) {
72
+ throw new Error(
73
+ '[pipework] connectionIds() cannot read the driver\'s connection ordinals: this connection has no statement hook.\n' +
74
+ ' Fix: connectionIds() exists to correlate with observability.onStatement events; configure observability.onStatement on the manifold.',
75
+ )
76
+ }
77
+ const max = client.options.max
78
+ const settled = await Promise.allSettled(Array.from({ length: max }, () => client.reserve()))
79
+ const reserved = settled.flatMap(r => (r.status === 'fulfilled' ? [r.value] : []))
80
+ try {
81
+ const failed = settled.find((r): r is PromiseRejectedResult => r.status === 'rejected')
82
+ if (failed) throw failed.reason
83
+ const out: Array<{ connectionId: number; backendPid: number }> = []
84
+ for (const conn of reserved) {
85
+ let connectionId: number | undefined
86
+ slot.current = (id: number) => { connectionId ??= id }
87
+ let rows: Array<{ pid: number }>
88
+ try {
89
+ rows = await conn.unsafe<Array<{ pid: number }>>(PROBE_QUERY)
90
+ } finally {
91
+ slot.current = null
92
+ }
93
+ const pid = rows[0]?.pid
94
+ if (connectionId === undefined || pid === undefined) {
95
+ throw new Error('[pipework] connectionIds() could not read a connection\'s ordinal and backend pid.\n Fix: report this as a bug; the probe statement was not seen by the driver hook.')
96
+ }
97
+ out.push({ connectionId, backendPid: pid })
98
+ }
99
+ out.sort((a, b) => a.connectionId - b.connectionId)
100
+ if (new Set(out.map(o => o.connectionId)).size !== out.length) {
101
+ throw new Error('[pipework] connectionIds() saw the same connection twice.\n Fix: report this as a bug; reserved connections must be distinct.')
102
+ }
103
+ return out
104
+ } finally {
105
+ for (const conn of reserved) conn.release()
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Opens a standalone managed connection outside the manifold's pools — the
111
+ * sanctioned door for contexts where `pipe()` structurally cannot resolve:
112
+ * `worker_threads`, detached monitors, one-off scripts. Callers own the
113
+ * lifecycle: always `await conn.close()`.
114
+ */
115
+ export function tap(url: string, options?: ConnectOptions): ManagedConnection {
116
+ const client = postgres(url, {
117
+ max: options?.max ?? 1,
118
+ onnotice: () => {},
119
+ ...(options?.idleTimeout !== undefined ? { idle_timeout: options.idleTimeout } : {}),
120
+ ...(options?.settings !== undefined ? { connection: startupSettings(options.settings) } : {}),
121
+ })
122
+
123
+ const db = splitLargeInserts(drizzle(client))
124
+
125
+ return {
126
+ name: 'manual',
127
+ client,
128
+ drizzle: db,
129
+ connectionIds: () => probeConnectionIds(client, undefined),
130
+ async close(options) {
131
+ await client.end(endOptions(options))
132
+ },
133
+ }
134
+ }
135
+
136
+ /** Builds the pooled connection for one resolved database — used by the manifold's pool manager; consumers outside a managed context use `tap()` or `pool.getOrCreate()`. */
137
+ export function createManagedConnection(
138
+ config: ResolvedDatabase,
139
+ onClose: () => void,
140
+ observability?: ResolvedObservability,
141
+ applicationName?: string,
142
+ ): ManagedConnection {
143
+ const baseDebug = observability ? createDebugFn(observability) : undefined
144
+ const slot: ProbeSlot | undefined = baseDebug ? { current: null } : undefined
145
+ const debug = baseDebug && slot
146
+ ? ((connection, query, parameters) => {
147
+ if (slot.current && query === PROBE_QUERY) slot.current(connection)
148
+ baseDebug(connection, query, parameters)
149
+ }) as typeof baseDebug
150
+ : undefined
151
+ const client = postgres(config.url, {
152
+ max: config.pool.max,
153
+ idle_timeout: config.pool.idleTimeout,
154
+ onnotice: () => {},
155
+ ...(config.pool.settings !== undefined || applicationName !== undefined
156
+ ? { connection: { ...(applicationName !== undefined ? { application_name: applicationName } : {}), ...config.pool.settings } }
157
+ : {}),
158
+ ...(debug ? { debug } : {}),
159
+ })
160
+
161
+ const observerOnly = observability !== undefined && isObserverOnly(observability)
162
+ if (observerOnly) markObservedConnection(client)
163
+
164
+ const statementWatch = observability
165
+ ? createStatementWatch({ database: config.name, url: config.url, slowQueryMs: observability.slowQueryMs, inFlightQueryMs: observability.inFlightQueryMs })
166
+ : undefined
167
+ const db = splitLargeInserts(drizzle(client, statementWatch ? { statementWatch: statementWatch.watch } : {}))
168
+
169
+ return {
170
+ name: config.name,
171
+ get client() {
172
+ if (observerOnly) warnRawClientIsUnsanitized(config.name)
173
+ return client
174
+ },
175
+ drizzle: db,
176
+ connectionIds: () => probeConnectionIds(client, slot),
177
+ async close(options) {
178
+ onClose()
179
+ await statementWatch?.close()
180
+ await client.end(endOptions(options))
181
+ },
182
+ }
183
+ }
184
+
185
+ function endOptions(options: { timeoutSeconds?: number } | undefined): { timeout?: number } {
186
+ return options?.timeoutSeconds === undefined ? {} : { timeout: options.timeoutSeconds }
187
+ }
@@ -0,0 +1,13 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks'
2
+
3
+ const scope = new AsyncLocalStorage<string>()
4
+
5
+ /** Runs `fn` with `label` naming every statement it starts, in slow-query and in-flight-query log lines. */
6
+ export function labelled<T>(label: string, fn: () => T): T {
7
+ return scope.run(label, fn)
8
+ }
9
+
10
+ /** The label of the enclosing `labelled` scope, if any. */
11
+ export function currentQueryLabel(): string | undefined {
12
+ return scope.getStore()
13
+ }