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,535 @@
1
+ import type { Schema, Infer } from '../../data/schema/types.js'
2
+ import type { DB } from '../../data/db/index.js'
3
+ import { DEFAULT_DB } from './types.js'
4
+ import type { Handler, HandlerMeta, HttpMethod, RouteMeta, AuthRequirement, PermissionMeta, JobRetryConfig, JobTransactionMode, Checkpoint, RouteScreen, UploadConfig, BinaryUploadConfig, MultipartUploadConfig, BinaryUpload, MultipartUpload, FileConfig, RouteRefusedHook } from './types.js'
5
+ import type { ResourceOperations, Resource, PaginationConfig } from '../fixture/types.js'
6
+ import type { HttpRequest, HttpResponse, CorsConfig } from '../http/types.js'
7
+ import { buildResource } from '../fixture/builder.js'
8
+
9
+ interface BuilderState {
10
+ databases: string[]
11
+ requiresAuth: boolean
12
+ authRequirement: AuthRequirement
13
+ inputSchema: Schema | null
14
+ outputSchemas: Map<number, Schema>
15
+ querySchema: Schema | null
16
+ paramsSchema: Schema | null
17
+ route: RouteMeta | null
18
+ cors: CorsConfig | false | null
19
+ rateLimit: string | false | null
20
+ isJob: boolean
21
+ jobType: string | null
22
+ jobRetry: JobRetryConfig | null
23
+ jobTimeout: number | null
24
+ jobTransaction: JobTransactionMode
25
+ permission: PermissionMeta | null
26
+ pagination: PaginationConfig | null
27
+ wantsRequest: boolean
28
+ wantsResponse: boolean
29
+ wantsRawBody: boolean
30
+ ignoresBody: boolean
31
+ upload: UploadConfig | null
32
+ file: FileConfig | null
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ onRefused: RouteRefusedHook<any, any, any> | null
35
+ }
36
+
37
+ /**
38
+ * Deps shape after `.transaction('manual')`: the databases the handler declared
39
+ * with `.use()` move out of the top-level deps (a non-transactional handle there
40
+ * would be a footgun) and into `checkpoint`'s callback, which binds them inside a
41
+ * fresh tenant-scoped transaction. `checkpoint` is added in their place.
42
+ */
43
+ type ManualDeps<TDeps, TDb> = Omit<TDeps, keyof TDb> & { checkpoint: Checkpoint<TDb> }
44
+
45
+ type DepOf<TDeps, K extends string> = TDeps extends Record<K, infer V> ? V : unknown
46
+
47
+ export class Builder<
48
+ TDeps extends Record<string, unknown>,
49
+ TDb extends Record<string, DB> = Record<never, DB>,
50
+ > {
51
+ private readonly state: BuilderState
52
+
53
+ constructor(state?: Partial<BuilderState>) {
54
+ this.state = {
55
+ databases: state?.databases ?? [],
56
+ requiresAuth: state?.requiresAuth ?? false,
57
+ authRequirement: state?.authRequirement ?? 'none',
58
+ inputSchema: state?.inputSchema ?? null,
59
+ outputSchemas: state?.outputSchemas ?? new Map(),
60
+ querySchema: state?.querySchema ?? null,
61
+ paramsSchema: state?.paramsSchema ?? null,
62
+ route: state?.route ?? null,
63
+ cors: state?.cors ?? null,
64
+ rateLimit: state?.rateLimit ?? null,
65
+ isJob: state?.isJob ?? false,
66
+ jobType: state?.jobType ?? null,
67
+ jobRetry: state?.jobRetry ?? null,
68
+ jobTimeout: state?.jobTimeout ?? null,
69
+ jobTransaction: state?.jobTransaction ?? 'auto',
70
+ permission: state?.permission ?? null,
71
+ pagination: state?.pagination ?? null,
72
+ wantsRequest: state?.wantsRequest ?? false,
73
+ wantsResponse: state?.wantsResponse ?? false,
74
+ wantsRawBody: state?.wantsRawBody ?? false,
75
+ ignoresBody: state?.ignoresBody ?? false,
76
+ upload: state?.upload ?? null,
77
+ file: state?.file ?? null,
78
+ onRefused: state?.onRefused ?? null,
79
+ }
80
+ }
81
+
82
+ use(): Builder<TDeps & { db: DB }, TDb & { db: DB }>
83
+ use<N extends string>(name: N): Builder<TDeps & Record<N, DB>, TDb & Record<N, DB>>
84
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
+ use(name?: string): Builder<any, any> {
86
+ const sentinel = name ?? DEFAULT_DB
87
+ return new Builder({
88
+ ...this.state,
89
+ databases: [...this.state.databases, sentinel],
90
+ })
91
+ }
92
+
93
+ auth<TAuth>(): Builder<TDeps & { auth: TAuth }, TDb> {
94
+ return new Builder<TDeps & { auth: TAuth }, TDb>({
95
+ ...this.state,
96
+ requiresAuth: true,
97
+ authRequirement: 'required',
98
+ })
99
+ }
100
+
101
+ authOptional<TAuth>(): Builder<TDeps & { auth: TAuth | null }, TDb> {
102
+ return new Builder<TDeps & { auth: TAuth | null }, TDb>({
103
+ ...this.state,
104
+ requiresAuth: false,
105
+ authRequirement: 'optional',
106
+ })
107
+ }
108
+
109
+ public(): Builder<TDeps, TDb> {
110
+ return new Builder<TDeps, TDb>({
111
+ ...this.state,
112
+ requiresAuth: false,
113
+ authRequirement: 'none',
114
+ })
115
+ }
116
+
117
+ input<T extends Schema>(schema: T): Builder<TDeps & { input: Infer<T> }, TDb> {
118
+ return new Builder<TDeps & { input: Infer<T> }, TDb>({
119
+ ...this.state,
120
+ inputSchema: schema,
121
+ })
122
+ }
123
+
124
+ query<T extends Schema>(schema: T): Builder<TDeps & { query: Infer<T> }, TDb> {
125
+ return new Builder<TDeps & { query: Infer<T> }, TDb>({
126
+ ...this.state,
127
+ querySchema: schema,
128
+ })
129
+ }
130
+
131
+ params<T extends Schema>(schema: T): Builder<TDeps & { params: Infer<T> }, TDb> {
132
+ return new Builder<TDeps & { params: Infer<T> }, TDb>({
133
+ ...this.state,
134
+ paramsSchema: schema,
135
+ })
136
+ }
137
+
138
+ output<T extends Schema>(schema: T): Builder<TDeps, TDb>
139
+ output<T extends Schema>(status: number, schema: T): Builder<TDeps, TDb>
140
+ output(statusOrSchema: number | Schema, maybeSchema?: Schema): Builder<TDeps, TDb> {
141
+ const schemas = new Map(this.state.outputSchemas)
142
+ const status = typeof statusOrSchema === 'number' ? statusOrSchema : 200
143
+ if (schemas.has(status)) {
144
+ const where = this.state.route ? ` on ${this.state.route.method} ${this.state.route.path}` : ''
145
+ throw new Error(
146
+ `[pipework] .output() declares status ${status} twice${where}.\n\n` +
147
+ ` A status keeps one schema; the second would silently replace the first, and a body valid for the first would answer 422.\n` +
148
+ ` Fix: declare ${status} once, with a schema that is a union of the bodies, e.g. .output(${status}, schema.check.union([a, b])).\n`,
149
+ )
150
+ }
151
+ schemas.set(status, typeof statusOrSchema === 'number' ? maybeSchema! : statusOrSchema)
152
+ return new Builder<TDeps, TDb>({
153
+ ...this.state,
154
+ outputSchemas: schemas,
155
+ })
156
+ }
157
+
158
+ route(method: HttpMethod, path: string, options?: { bodyLimit?: number; screen?: RouteScreen }): Builder<TDeps, TDb> {
159
+ return new Builder<TDeps, TDb>({
160
+ ...this.state,
161
+ route: {
162
+ method,
163
+ path,
164
+ ...(options?.bodyLimit !== undefined ? { bodyLimit: options.bodyLimit } : {}),
165
+ ...(options?.screen !== undefined ? { screen: options.screen } : {}),
166
+ },
167
+ })
168
+ }
169
+
170
+ /**
171
+ * This route's own CORS grant. It replaces the server-level `cors` for this route
172
+ * (no merge); `.cors(false)` closes the route under an open server. Preflight
173
+ * requests for the route's path and method are answered from the same grant.
174
+ */
175
+ cors(grant: CorsConfig | false): Builder<TDeps, TDb> {
176
+ return new Builder<TDeps, TDb>({ ...this.state, cors: grant })
177
+ }
178
+
179
+ /**
180
+ * Puts this route in a named class of `rateLimits.classes`; `false` exempts it. Without this, the
181
+ * class follows the auth requirement: `signedIn` for required, `public` for none, and for optional
182
+ * `signedIn` when a user is signed in, else `public`. A name the server config lacks is refused
183
+ * when the server is built.
184
+ */
185
+ rateLimit(name: string | false): Builder<TDeps, TDb> {
186
+ return new Builder<TDeps, TDb>({ ...this.state, rateLimit: name })
187
+ }
188
+
189
+ /**
190
+ * Marks this handler a job. Its deps gain `signal`: aborted when the job is no longer this
191
+ * handler's (returned to pending on shutdown, ...); check it before any outside effect.
192
+ */
193
+ job(type?: string): Builder<TDeps & { signal: AbortSignal }, TDb> {
194
+ return new Builder<TDeps & { signal: AbortSignal }, TDb>({
195
+ ...this.state,
196
+ isJob: true,
197
+ jobType: type ?? null,
198
+ })
199
+ }
200
+
201
+ /**
202
+ * Selects how this handler's database transaction(s) are managed. Applies to
203
+ * a job and to a route alike.
204
+ *
205
+ * `'auto'` (default) keeps the single framework-owned outer transaction.
206
+ * `'manual'` opens no outer transaction; the handler instead receives a
207
+ * `checkpoint(fn)` primitive and owns its own commit boundaries — the
208
+ * databases declared with `.use()` move from the top-level deps into
209
+ * `checkpoint`'s callback.
210
+ *
211
+ * **What manual mode costs, on either surface.** Each checkpoint commits
212
+ * independently and durably. An error after one has committed leaves that
213
+ * state committed: for a job the contract shifts from atomic to
214
+ * at-least-once / idempotent-on-resume, and for a route the response status
215
+ * no longer describes what is in the database — a 500 can follow work that
216
+ * is already durable. The handler owns its own compensation. In exchange it
217
+ * holds no connection between checkpoints, which is what lets a route commit,
218
+ * make a network call, and write again under the request's own tenant.
219
+ *
220
+ * **Against `pipe.system()`, the row state is the same.** `pipe.system()` also
221
+ * runs outside the request transaction and also commits mid-request, so a
222
+ * route already written that way sees no change in what is committed or when.
223
+ * What changes is which mechanism enforces the tenancy: a hand-written `WHERE`
224
+ * on a connection that bypasses row-level security, versus the database under
225
+ * the request's own tenant. That is not observable in the rows, so a test that
226
+ * only reads them cannot tell the two apart — the difference shows up as a
227
+ * policy denial when the filter is wrong, which is the point.
228
+ *
229
+ * So a test that pins this property reads the handler's declaration next to
230
+ * the rows: `handler.meta.jobTransaction === 'manual'` and `handler.meta.databases`
231
+ * holding the databases `.use()` declared. (`jobTransaction` carries the mode
232
+ * for a route too; the name predates the route surface.) Half the property is
233
+ * in the rows and half is in the declaration, and only the pair of them
234
+ * catches a silent move back to `pipe.system()`.
235
+ */
236
+ transaction(mode: 'auto'): Builder<TDeps, TDb>
237
+ transaction(mode: 'manual'): Builder<ManualDeps<TDeps, TDb>, TDb>
238
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
239
+ transaction(mode: JobTransactionMode): Builder<any, TDb> {
240
+ return new Builder({
241
+ ...this.state,
242
+ jobTransaction: mode,
243
+ })
244
+ }
245
+
246
+ retry(config: JobRetryConfig): Builder<TDeps, TDb> {
247
+ return new Builder<TDeps, TDb>({
248
+ ...this.state,
249
+ jobRetry: config,
250
+ })
251
+ }
252
+
253
+ timeout(ms: number): Builder<TDeps, TDb> {
254
+ return new Builder<TDeps, TDb>({
255
+ ...this.state,
256
+ jobTimeout: ms,
257
+ })
258
+ }
259
+
260
+ permission(resource: string, action: string, scope?: string): Builder<TDeps, TDb> {
261
+ const perm: PermissionMeta = scope !== undefined
262
+ ? { resource, action, scope }
263
+ : { resource, action }
264
+ return new Builder<TDeps, TDb>({
265
+ ...this.state,
266
+ permission: perm,
267
+ })
268
+ }
269
+
270
+ paginate(config: { defaultLimit?: number; maxLimit?: number } = {}): Builder<TDeps, TDb> {
271
+ return new Builder<TDeps, TDb>({
272
+ ...this.state,
273
+ pagination: {
274
+ defaultLimit: config.defaultLimit ?? 20,
275
+ maxLimit: config.maxLimit ?? 100,
276
+ },
277
+ })
278
+ }
279
+
280
+ request(): Builder<TDeps & { request: HttpRequest }, TDb> {
281
+ return new Builder<TDeps & { request: HttpRequest }, TDb>({
282
+ ...this.state,
283
+ wantsRequest: true,
284
+ })
285
+ }
286
+
287
+ response(): Builder<TDeps & { response: HttpResponse }, TDb> {
288
+ return new Builder<TDeps & { response: HttpResponse }, TDb>({
289
+ ...this.state,
290
+ wantsResponse: true,
291
+ })
292
+ }
293
+
294
+ rawBody(): Builder<TDeps & { rawBody: Buffer }, TDb> {
295
+ return new Builder<TDeps & { rawBody: Buffer }, TDb>({
296
+ ...this.state,
297
+ wantsRawBody: true,
298
+ })
299
+ }
300
+
301
+ /**
302
+ * Makes this route accept a body of any content type and never read it: the body is drained
303
+ * unparsed (a declared length over 64 KiB is refused with 413) and `input` is undefined.
304
+ * For a POST whose body carries nothing the handler needs, such as an RFC 8058 one-click
305
+ * unsubscribe (`List-Unsubscribe=One-Click` as form-urlencoded or multipart). This route only:
306
+ * no other route's parsing changes. Cannot be combined with `.input()`, `.rawBody()` or `.upload()`.
307
+ */
308
+ ignoreBody(): Builder<TDeps, TDb> {
309
+ return new Builder<TDeps, TDb>({ ...this.state, ignoresBody: true })
310
+ }
311
+
312
+ /**
313
+ * Makes this route accept a file upload and hands the handler the file as a
314
+ * stream in the `upload` dep. The body is never buffered whole.
315
+ *
316
+ * `{ kind: 'binary', mediaTypes, maxBytes }` takes the request body itself as
317
+ * the file: `upload` is `{ stream, length, mediaType, detectedType,
318
+ * declaredType, extension }` (`length` is the declared Content-Length, null
319
+ * when chunked). `{ kind: 'multipart', file, mediaTypes, maxBytes, fields? }`
320
+ * takes the part named `file` of a `multipart/form-data` body: `upload` is
321
+ * `{ stream, filename, fields, mediaType, detectedType, declaredType,
322
+ * extension }`.
323
+ *
324
+ * `mediaTypes` is matched against `mediaType`, the type found in the file's
325
+ * first 1024 bytes (`detectedType`; null when no signature matches). A zip or
326
+ * compound-file container takes the declared type or filename extension when
327
+ * that names an Office, OpenDocument, epub, jar or apk file. With no
328
+ * signature the declared type stands, except a type a signature would show
329
+ * (pdf, png, ...), which the bytes then contradict and is refused. Entries
330
+ * may be `type/*` wildcards, or a star on each side of the slash to take any
331
+ * type and refuse in the handler.
332
+ *
333
+ * A body (binary) or file (multipart) over `maxBytes` gets 413: refused before
334
+ * reading when the declared Content-Length is over, and while streaming
335
+ * otherwise (the handler's read of `upload.stream` rejects with
336
+ * `errors.PayloadTooLarge`). A media type outside `mediaTypes` gets 415. The
337
+ * route's `screen`, when set, still runs first, and auth runs before any body
338
+ * is read.
339
+ *
340
+ * `onRefuse(refusal)` runs once for each such 413 or 415, in the request's
341
+ * context, with the detected and declared types, extension, filename, sizes,
342
+ * accepted list, auth, and the route's `params` and `query` as the handler gets
343
+ * them (typed when `.params()` / `.query()` come before `.upload()`; the raw
344
+ * values on a route with no schema; null when they fail it). A non-empty string it returns becomes the error
345
+ * message; if it throws, the default message is sent. Nothing of the file is
346
+ * kept: only its first 1024 bytes are held, to detect the type.
347
+ *
348
+ * Multipart: text fields must come before the file part, only names listed in
349
+ * `fields` are accepted (another name gets 422), each at most 64 KiB; fields
350
+ * after the file part are not read, and only the first file part is handed
351
+ * over. A missing file part gets 422.
352
+ *
353
+ * The handler must consume or destroy `upload.stream`. If it returns with the
354
+ * stream unfinished the framework destroys it and closes the connection after
355
+ * the response. Errors from the stream reach the handler as rejected reads and
356
+ * become the response when the handler lets them propagate.
357
+ *
358
+ * In `'auto'` transaction mode the request transaction, and its pool
359
+ * connection, is held for the whole upload: for large files use
360
+ * `.transaction('manual')` and write to the database in a `checkpoint` after
361
+ * the bytes are stored.
362
+ *
363
+ * Cannot be combined with `.input()`, `.rawBody()` or `.job()`; each throws.
364
+ */
365
+ upload(config: BinaryUploadConfig<DepOf<TDeps, 'params'>, DepOf<TDeps, 'query'>>): Builder<TDeps & { upload: BinaryUpload }, TDb>
366
+ upload(config: MultipartUploadConfig<DepOf<TDeps, 'params'>, DepOf<TDeps, 'query'>>): Builder<TDeps & { upload: MultipartUpload }, TDb>
367
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
368
+ upload(config: BinaryUploadConfig<any, any> | MultipartUploadConfig<any, any>): Builder<any, TDb> {
369
+ if (config.mediaTypes.length === 0) {
370
+ throw new Error('[pipework] .upload() needs at least one entry in mediaTypes (e.g. ["application/pdf"] or ["image/*"]).')
371
+ }
372
+ if (!Number.isInteger(config.maxBytes) || config.maxBytes <= 0) {
373
+ throw new Error(`[pipework] .upload() maxBytes must be a positive integer number of bytes, got ${String(config.maxBytes)}.`)
374
+ }
375
+ if (config.kind === 'multipart' && config.file === '') {
376
+ throw new Error('[pipework] .upload({ kind: "multipart" }) needs the form field name of the file in `file`.')
377
+ }
378
+ return new Builder({
379
+ ...this.state,
380
+ upload: config,
381
+ })
382
+ }
383
+
384
+ /**
385
+ * Declares that this route answers with a file, returned from the handler as
386
+ * `http.file({ body, mediaType, filename? ... })`. `mediaTypes` lists what the
387
+ * route may send (`type/*` wildcards allowed) and `status` (default 200) is the
388
+ * status of the file response. OpenAPI gets `responses.<status>.content.<type>`
389
+ * as `{ type: 'string', format: 'binary' }` for each media type.
390
+ *
391
+ * At the file's status the route must return `http.file(...)`: anything else,
392
+ * or a file whose `mediaType` is outside `mediaTypes`, is a 500 with the reason
393
+ * in the body. At any other status it answers as on any route: return
394
+ * `{ status, body? }` (declare the body with `.output(status, schema)`); a
395
+ * redirect is `{ status: 302 }` after `response.header('location', url)` on
396
+ * a `.response()` route. A Buffer is sent whole with Content-Length; a Readable is
397
+ * streamed (add `length` for Content-Length, else it is chunked). Content-
398
+ * Disposition carries an ASCII `filename=` fallback and the exact name in
399
+ * `filename*`, and the response sets `X-Content-Type-Options: nosniff`.
400
+ *
401
+ * The request transaction (auto mode) has committed before the body streams,
402
+ * so the stream must not need it. A stream that fails after the first byte
403
+ * destroys the connection and logs the error. Range requests are not supported.
404
+ *
405
+ * Cannot be combined with `.output()` for the same status, or with `.job()`;
406
+ * `fit()` throws.
407
+ */
408
+ file(config: { mediaTypes: readonly string[]; status?: number }): Builder<TDeps, TDb> {
409
+ if (config.mediaTypes.length === 0) {
410
+ throw new Error('[pipework] .file() needs at least one entry in mediaTypes (e.g. ["application/pdf"] or ["image/*"]).')
411
+ }
412
+ const status = config.status ?? 200
413
+ if (!Number.isInteger(status) || status < 200 || status > 599) {
414
+ throw new Error(`[pipework] .file() status must be an HTTP status code, got ${String(config.status)}.`)
415
+ }
416
+ return new Builder<TDeps, TDb>({
417
+ ...this.state,
418
+ file: { mediaTypes: [...config.mediaTypes], status },
419
+ })
420
+ }
421
+
422
+ /**
423
+ * Runs `hook` once for every 4xx this route answers, including those made before
424
+ * the handler: the input/params/query 422, auth 401, permission 403, 429, upload
425
+ * 413/415 and the handler's own thrown 4xx. Never for a 5xx, nor the route's `screen`.
426
+ * It gets `{ status, code, message, fields, auth, params, query, request,
427
+ * requestId }`; `auth` is null where auth itself refused, `params`/`query` are null
428
+ * when they fail their schema. A plain object it returns is merged into the
429
+ * response's `error`; `code`, `message`, `fields` and `details` keep pipework's
430
+ * values (a hook that sets one is warned and dropped). A throw is logged and the
431
+ * refusal is sent as without the hook. Runs in the request's Flow as a trace step
432
+ * after the upload `onRefuse`, once the request transaction has rolled back: it has none.
433
+ */
434
+ onRefused(hook: RouteRefusedHook<DepOf<TDeps, 'auth'>, DepOf<TDeps, 'params'>, DepOf<TDeps, 'query'>>): Builder<TDeps, TDb> {
435
+ return new Builder<TDeps, TDb>({ ...this.state, onRefused: hook })
436
+ }
437
+
438
+ fixture<TAuth>(name: string, operations: ResourceOperations<TAuth>): Resource<TAuth> {
439
+ const dbName = this.state.databases[0]
440
+ if (dbName === undefined) {
441
+ throw new Error(
442
+ `[pipework] .fixture("${name}") requires a database. Call .use("dbName") before .fixture().`,
443
+ )
444
+ }
445
+ return buildResource(name, operations, {
446
+ database: dbName,
447
+ authRequirement: this.state.authRequirement,
448
+ permission: this.state.permission,
449
+ pagination: this.state.pagination,
450
+ })
451
+ }
452
+
453
+ fit<TReturn>(fn: (deps: TDeps) => Promise<TReturn>): Handler<TDeps, TReturn> {
454
+ if (this.state.jobTransaction === 'manual' && this.state.databases.length === 0) {
455
+ throw new Error(
456
+ '[pipework] .transaction("manual") requires at least one database.\n\n' +
457
+ ' A checkpointed handler commits database work incrementally, so it must\n' +
458
+ ' declare which database(s) participate. Call .use("dbName") before\n' +
459
+ ' .transaction("manual").\n'
460
+ )
461
+ }
462
+
463
+ if (this.state.upload !== null) {
464
+ const what = this.state.isJob ? '.job()' : this.state.inputSchema !== null ? '.input()' : this.state.wantsRawBody ? '.rawBody()' : null
465
+ if (what !== null) {
466
+ throw new Error(
467
+ `[pipework] .upload() cannot be combined with ${what}.\n\n` +
468
+ ' An upload route\'s body is the file, delivered as a stream in the `upload` dep.\n' +
469
+ ' Remove ' + what + (what === '.job()' ? ': a job has no request body to stream.' : ', or take the text fields from a multipart form (`fields`).') + '\n',
470
+ )
471
+ }
472
+ }
473
+
474
+ if (this.state.ignoresBody) {
475
+ const what = this.state.upload !== null ? '.upload()' : this.state.inputSchema !== null ? '.input()' : this.state.wantsRawBody ? '.rawBody()' : null
476
+ if (what !== null) {
477
+ throw new Error(`[pipework] .ignoreBody() cannot be combined with ${what}: the body is drained unread, so ${what} would have nothing to read. Remove one.`)
478
+ }
479
+ }
480
+
481
+ if (this.state.file !== null) {
482
+ if (this.state.isJob) {
483
+ throw new Error(
484
+ '[pipework] .file() cannot be combined with .job().\n\n' +
485
+ ' A file response is sent to an HTTP client; a job has no response to send.\n' +
486
+ ' Remove .file(), or remove .job().\n',
487
+ )
488
+ }
489
+ if (this.state.outputSchemas.has(this.state.file.status)) {
490
+ throw new Error(
491
+ `[pipework] .file() and .output(${this.state.file.status}, ...) both declare the ${this.state.file.status} response.\n\n` +
492
+ ' A route answers each status with one body: a file or a JSON schema.\n' +
493
+ ' Remove .output() for that status, or give .file({ status }) another one.\n',
494
+ )
495
+ }
496
+ }
497
+
498
+ const meta: HandlerMeta = {
499
+ databases: this.state.databases,
500
+ requiresAuth: this.state.requiresAuth,
501
+ authRequirement: this.state.authRequirement,
502
+ inputSchema: this.state.inputSchema,
503
+ outputSchemas: this.state.outputSchemas,
504
+ querySchema: this.state.querySchema,
505
+ paramsSchema: this.state.paramsSchema,
506
+ route: this.state.route,
507
+ cors: this.state.cors,
508
+ rateLimit: this.state.rateLimit,
509
+ isJob: this.state.isJob,
510
+ jobType: this.state.jobType,
511
+ jobRetry: this.state.jobRetry,
512
+ jobTimeout: this.state.jobTimeout,
513
+ jobTransaction: this.state.jobTransaction,
514
+ permission: this.state.permission,
515
+ wantsRequest: this.state.wantsRequest,
516
+ wantsResponse: this.state.wantsResponse,
517
+ wantsRawBody: this.state.wantsRawBody,
518
+ ignoresBody: this.state.ignoresBody,
519
+ upload: this.state.upload,
520
+ file: this.state.file,
521
+ onRefused: this.state.onRefused,
522
+ }
523
+
524
+ return {
525
+ async execute(deps: TDeps): Promise<TReturn> {
526
+ return fn(deps)
527
+ },
528
+ meta,
529
+ }
530
+ }
531
+ }
532
+
533
+ export function createBuilder(): Builder<Record<never, never>> {
534
+ return new Builder()
535
+ }
@@ -0,0 +1,8 @@
1
+ import { createBuilder } from './builder.js'
2
+
3
+ export const fitting = createBuilder()
4
+
5
+ export { createBuilder, Builder } from './builder.js'
6
+ export { resolveAndExecute, type ResolveOptions } from './resolve.js'
7
+ export { DEFAULT_DB } from './types.js'
8
+ export type { Handler, HandlerMeta, RouteMeta, HttpMethod, InferDeps, InferReturn, DatabaseDeps, JobTransactionMode, Checkpoint, UploadConfig, BinaryUploadConfig, MultipartUploadConfig, BinaryUpload, MultipartUpload, FileConfig } from './types.js'