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,271 @@
1
+ import type { Schema } from '../../data/schema/types.js'
2
+ import { DEFAULT_DB } from './types.js'
3
+ import type { Handler, HandlerMeta, CheckpointFn, BinaryUpload, MultipartUpload } from './types.js'
4
+ import type { DB } from '../../data/db/types.js'
5
+ import type { Flow } from '../context/types.js'
6
+ import type { Manifold } from '../../core/pipework.js'
7
+ import type { TenantConfig } from '../../auth/tenant/types.js'
8
+ import { executeInTransaction } from '../context/run-in-transaction.js'
9
+ import type { HttpRequest, HttpResponse } from '../http/types.js'
10
+ import { requireContext } from '../context/store.js'
11
+ import { verifyTransactionBinding } from '../context/guard.js'
12
+ import { UnauthorizedError, ValidationError } from '../../core/errors/index.js'
13
+ import { parse } from '../../data/schema/parse.js'
14
+ import { unboundDb } from '../../data/db/unbound.js'
15
+ import { createScopedDb, createTenantGuardDb } from '../../auth/tenant/scoped-db.js'
16
+
17
+ export interface ResolveOptions {
18
+ readonly request?: HttpRequest
19
+ readonly response?: HttpResponse
20
+ readonly rawBody?: Buffer
21
+ readonly upload?: BinaryUpload | MultipartUpload
22
+ /**
23
+ * The `checkpoint` primitive for a manual-transaction handler — a job or a
24
+ * route. Injected as the `checkpoint` dep; the top-level database deps are
25
+ * then NOT injected, since a non-transactional handle outside a checkpoint
26
+ * would be a footgun.
27
+ */
28
+ readonly checkpoint?: CheckpointFn
29
+ /** A job's own signal, injected as the `signal` dep. */
30
+ readonly signal?: AbortSignal
31
+ }
32
+
33
+ /**
34
+ * Resolves the database deps a handler declared with `.use()` into the deps
35
+ * record keyed as the handler sees them ('db' for the default database, the
36
+ * name otherwise). Each handle is the context's bound transaction when one is
37
+ * active (request/job/checkpoint), otherwise a pooled connection.
38
+ *
39
+ * `scoped` (default `true`) wraps each handle in the tenant scope/guard proxy —
40
+ * the safe builder surface used for request and auto-mode job deps. The
41
+ * manual-mode `checkpoint` primitive passes `scoped: false` to hand the handler
42
+ * the raw bound transaction: a checkpointed job owns its own boundaries and runs
43
+ * arbitrary SQL, with tenant isolation enforced by the RLS session vars the
44
+ * checkpoint sets (`SET LOCAL pipework.tenant_id`), exactly as `pipe.transaction`
45
+ * already exposes a raw `tx`. Shared by both paths so they cannot drift.
46
+ */
47
+ export function resolveDatabaseDeps(
48
+ databases: readonly string[],
49
+ ctx: Flow,
50
+ options?: { readonly scoped?: boolean },
51
+ ): Record<string, DB> {
52
+ const scoped = options?.scoped ?? true
53
+ const deps: Record<string, DB> = {}
54
+ for (const dbName of databases) {
55
+ const isDefault = dbName === DEFAULT_DB
56
+ const resolvedName = isDefault ? ctx.instance.config.defaultDatabaseName() : dbName
57
+ const depKey = isDefault ? 'db' : dbName
58
+
59
+ const dbConfig = ctx.instance.config.database(resolvedName)
60
+ const bound = ctx.transactions.get(resolvedName)
61
+ let rawDb: DB
62
+ if (bound) {
63
+ verifyTransactionBinding(ctx, bound, resolvedName)
64
+ rawDb = bound.drizzle
65
+ } else {
66
+ rawDb = unboundDb(ctx, resolvedName, dbConfig, 'A handler\'s database dependency')
67
+ }
68
+ if (!scoped) {
69
+ deps[depKey] = rawDb
70
+ } else {
71
+ deps[depKey] = ctx.tenant !== null ? createScopedDb(rawDb, ctx.tenant) : createTenantGuardDb(rawDb)
72
+ }
73
+ }
74
+ return deps
75
+ }
76
+
77
+ /** A route's query as its handler gets it: parsed by its schema, or the raw value when it has none. Throws when it fails the schema. */
78
+ export function parseRouteQuery(meta: { readonly querySchema: Schema | null }, raw: unknown): unknown {
79
+ return meta.querySchema ? parse(meta.querySchema as Schema, raw, 'query') : raw
80
+ }
81
+
82
+ /** A route's params as its handler gets them: parsed by its schema, or the raw value when it has none. Throws when they fail the schema. */
83
+ export function parseRouteParams(meta: { readonly paramsSchema: Schema | null }, raw: unknown): unknown {
84
+ return meta.paramsSchema ? parse(meta.paramsSchema as Schema, raw, 'params') : raw
85
+ }
86
+
87
+ /**
88
+ * A route's params and query as its handler gets them, for a hook that reports on a request:
89
+ * the parsed value, the raw one when the route has no schema, null when it fails its schema
90
+ * or when `meta` is null (no route known).
91
+ */
92
+ export function parseRouteInputs(
93
+ meta: HandlerMeta | null,
94
+ rawQuery: unknown,
95
+ rawParams: unknown,
96
+ ): { readonly params: unknown; readonly query: unknown } {
97
+ if (meta === null) return { params: null, query: null }
98
+ const orNull = (read: () => unknown): unknown => { try { return read() } catch { return null } }
99
+ return { params: orNull(() => parseRouteParams(meta, rawParams)), query: orNull(() => parseRouteQuery(meta, rawQuery)) }
100
+ }
101
+
102
+ export async function resolveAndExecute<TDeps extends Record<string, unknown>, TReturn>(
103
+ handler: Handler<TDeps, TReturn>,
104
+ rawInput?: unknown,
105
+ rawQuery?: unknown,
106
+ rawParams?: unknown,
107
+ options?: ResolveOptions,
108
+ ): Promise<TReturn> {
109
+ const ctx = requireContext()
110
+ const deps: Record<string, unknown> = {}
111
+
112
+ // Manual-transaction handlers take no top-level database handle — they reach
113
+ // the database only inside checkpoint(), which binds a fresh tenant-scoped
114
+ // transaction. Inject that primitive in place of the db deps.
115
+ if (handler.meta.jobTransaction === 'manual') {
116
+ if (options?.checkpoint === undefined) {
117
+ throw new ValidationError(
118
+ 'Handler declares .transaction("manual") but no checkpoint primitive was provided.\n\n' +
119
+ ' checkpoint() is supplied by the surface that runs the handler — jobs.execute\n' +
120
+ ' for a job, the HTTP server for a route. Reaching here without one means the\n' +
121
+ ' handler was executed directly rather than through a surface.\n',
122
+ )
123
+ }
124
+ deps['checkpoint'] = options.checkpoint
125
+ } else {
126
+ Object.assign(deps, resolveDatabaseDeps(handler.meta.databases, ctx))
127
+ }
128
+
129
+ // A job handler's type promises `signal`; one run outside executeJob gets a signal that never aborts.
130
+ if (options?.signal !== undefined) deps['signal'] = options.signal
131
+ else if (handler.meta.isJob) deps['signal'] = new AbortController().signal
132
+
133
+ if (handler.meta.requiresAuth) {
134
+ if (ctx.auth === null) {
135
+ throw new UnauthorizedError()
136
+ }
137
+ deps['auth'] = ctx.auth
138
+ } else if (handler.meta.authRequirement === 'optional') {
139
+ deps['auth'] = ctx.auth
140
+ }
141
+
142
+ if (handler.meta.inputSchema) {
143
+ deps['input'] = parse(handler.meta.inputSchema as Schema, rawInput, 'body')
144
+ }
145
+
146
+ if (handler.meta.querySchema) {
147
+ deps['query'] = parseRouteQuery(handler.meta, rawQuery)
148
+ }
149
+
150
+ if (handler.meta.paramsSchema) {
151
+ deps['params'] = parseRouteParams(handler.meta, rawParams)
152
+ }
153
+
154
+ if (handler.meta.wantsRequest) {
155
+ if (options?.request === undefined) {
156
+ throw new ValidationError(
157
+ 'Handler declared .request() but no HTTP request is available.\n\n' +
158
+ ' This handler requires an HTTP context. It cannot be invoked as a background job\n' +
159
+ ' or via direct resolveAndExecute() without providing a request object.\n',
160
+ )
161
+ }
162
+ deps['request'] = options.request
163
+ }
164
+
165
+ if (handler.meta.wantsResponse) {
166
+ if (options?.response === undefined) {
167
+ throw new ValidationError(
168
+ 'Handler declared .response() but no HTTP response is available.\n\n' +
169
+ ' This handler requires an HTTP context. It cannot be invoked as a background job\n' +
170
+ ' or via direct resolveAndExecute() without providing a response object.\n',
171
+ )
172
+ }
173
+ deps['response'] = options.response
174
+ }
175
+
176
+ if (handler.meta.wantsRawBody) {
177
+ if (options?.rawBody === undefined) {
178
+ throw new ValidationError(
179
+ 'Handler declared .rawBody() but no raw body is available.\n\n' +
180
+ ' Raw body capture requires an HTTP context with body content.\n' +
181
+ ' This handler cannot be invoked as a background job or via GET requests\n' +
182
+ ' without providing a raw body buffer.\n',
183
+ )
184
+ }
185
+ deps['rawBody'] = options.rawBody
186
+ }
187
+
188
+ if (handler.meta.upload) {
189
+ if (options?.upload === undefined) {
190
+ throw new ValidationError(
191
+ 'Handler declared .upload() but no uploaded file is available.\n\n' +
192
+ ' An upload is supplied by the HTTP server for a route. This handler cannot be\n' +
193
+ ' invoked as a background job or via direct resolveAndExecute() without one.\n',
194
+ )
195
+ }
196
+ deps['upload'] = options.upload
197
+ }
198
+
199
+ const result = await handler.execute(deps as TDeps)
200
+
201
+ if (handler.meta.outputSchemas.size > 0) {
202
+ if (isHandlerResponse(result)) {
203
+ const response = result as { status: number; body?: unknown }
204
+ const bodySchema = handler.meta.outputSchemas.get(response.status)
205
+ if (bodySchema) {
206
+ return { status: response.status, body: parse(bodySchema as Schema, response.body, 'response') } as TReturn
207
+ }
208
+ return result
209
+ }
210
+ const defaultSchema = handler.meta.outputSchemas.get(200)
211
+ if (defaultSchema) {
212
+ return parse(defaultSchema as Schema, result, 'response') as TReturn
213
+ }
214
+ }
215
+
216
+ return result
217
+ }
218
+
219
+ function isHandlerResponse(value: unknown): boolean {
220
+ return value !== null && typeof value === 'object' && 'status' in value && typeof (value as Record<string, unknown>)['status'] === 'number'
221
+ }
222
+
223
+
224
+ /**
225
+ * The databases a handler's checkpoints run against: what it declared with
226
+ * `.use()`, with the default-database placeholder resolved to its real name.
227
+ */
228
+ export function resolveHandlerDatabases<TDeps extends Record<string, unknown>, TReturn>(
229
+ handler: Handler<TDeps, TReturn>,
230
+ instance: Manifold,
231
+ ): string[] {
232
+ const names = new Set<string>()
233
+ for (const dbName of handler.meta.databases) {
234
+ names.add(dbName === DEFAULT_DB ? instance.config.defaultDatabaseName() : dbName)
235
+ }
236
+ return [...names]
237
+ }
238
+
239
+ /**
240
+ * Builds the `checkpoint` primitive for one manual-transaction run.
241
+ *
242
+ * Every call opens a fresh top-level transaction on the handler's databases,
243
+ * re-establishing the context's session variables so database-side RLS sees the
244
+ * tenant, and commits it independently of every other checkpoint. The handler
245
+ * gets the raw bound transactions: it owns its own boundaries, and tenant
246
+ * isolation is enforced by the session vars rather than by a scoped wrapper.
247
+ *
248
+ * Shared by the job surface and the HTTP surface so the two cannot drift in
249
+ * what a checkpoint is.
250
+ */
251
+ export function buildCheckpoint<TDeps extends Record<string, unknown>, TReturn>(
252
+ handler: Handler<TDeps, TReturn>,
253
+ ctx: Flow,
254
+ databases: readonly string[],
255
+ tenant: TenantConfig | null,
256
+ timeoutMs: number,
257
+ signal?: AbortSignal,
258
+ refuseWhenAborted?: AbortSignal,
259
+ ): CheckpointFn {
260
+ return (fn) =>
261
+ refuseWhenAborted?.aborted === true
262
+ ? Promise.reject(refuseWhenAborted.reason)
263
+ : executeInTransaction(
264
+ ctx,
265
+ databases,
266
+ tenant,
267
+ timeoutMs,
268
+ () => fn(resolveDatabaseDeps(handler.meta.databases, requireContext(), { scoped: false })),
269
+ signal,
270
+ )
271
+ }
@@ -0,0 +1,262 @@
1
+ import type { CorsConfig } from '../http/types.js'
2
+ import type { Schema } from '../../data/schema/types.js'
3
+ import type { DB } from '../../data/db/index.js'
4
+ import type { Readable } from 'node:stream'
5
+ import type { BackoffConfig } from '../../async/jobs/queue.js'
6
+
7
+ /** The default database name constant ('default') used when pipe() is called without a name argument. */
8
+ export const DEFAULT_DB = '__pipework_default__' as const
9
+
10
+ /** Auth requirement level for a handler — 'required', 'optional', or 'public'. */
11
+ export type AuthRequirement = 'required' | 'optional' | 'none'
12
+
13
+ /** Permission requirement attached to a handler — resource, action, scope. */
14
+ export interface PermissionMeta {
15
+ readonly resource: string
16
+ readonly action: string
17
+ readonly scope?: string
18
+ }
19
+
20
+ /** Retry configuration for job handlers — maxAttempts, backoff strategy, delay. */
21
+ export interface JobRetryConfig {
22
+ readonly attempts: number
23
+ readonly backoff?: BackoffConfig
24
+ }
25
+
26
+ /**
27
+ * How a job's database transaction(s) are managed.
28
+ *
29
+ * - `'auto'` (default): the framework wraps the whole `.fit` run in one outer,
30
+ * tenant-scoped transaction — atomic / all-or-nothing.
31
+ * - `'manual'`: the framework propagates the job context but opens no outer
32
+ * transaction. The handler receives a `checkpoint(fn)` primitive and owns its
33
+ * own transaction boundaries, committing incrementally within a single warm
34
+ * run. The contract shifts from atomic to at-least-once / idempotent-on-resume.
35
+ */
36
+ export type JobTransactionMode = 'auto' | 'manual'
37
+
38
+ /**
39
+ * The `checkpoint` primitive injected into a manual-transaction job's deps.
40
+ * Each call opens a fresh top-level, tenant-scoped transaction (re-establishing
41
+ * the tenant `SET LOCAL` session vars so database-side RLS sees the tenant),
42
+ * runs `fn` with the participating databases bound, and commits durably and
43
+ * independently of any other checkpoint. `TDb` is the record of databases the
44
+ * handler declared with `.use()`.
45
+ */
46
+ export type Checkpoint<TDb> = <R>(fn: (dbs: TDb) => Promise<R>) => Promise<R>
47
+
48
+ /** The erased runtime shape of {@link Checkpoint}, used where the db-deps type is not tracked. */
49
+ export type CheckpointFn = <R>(fn: (dbs: Record<string, DB>) => Promise<R>) => Promise<R>
50
+
51
+ /** Metadata attached to a handler — route info, auth requirements, input/output schemas, database names. */
52
+ export interface HandlerMeta {
53
+ readonly databases: readonly string[]
54
+ readonly requiresAuth: boolean
55
+ readonly authRequirement: AuthRequirement
56
+ readonly inputSchema: Schema | null
57
+ readonly outputSchemas: ReadonlyMap<number, Schema>
58
+ readonly querySchema: Schema | null
59
+ readonly paramsSchema: Schema | null
60
+ readonly route: RouteMeta | null
61
+ /** This route's own CORS grant (replaces the server default); `false` closes it. */
62
+ readonly cors?: CorsConfig | false | null
63
+ /** The named rate limit class this route is in; `false` exempts it; null follows the auth requirement. */
64
+ readonly rateLimit?: string | false | null
65
+ readonly isJob: boolean
66
+ readonly jobType: string | null
67
+ readonly jobRetry: JobRetryConfig | null
68
+ readonly jobTimeout: number | null
69
+ readonly jobTransaction: JobTransactionMode
70
+ readonly permission: PermissionMeta | null
71
+ readonly wantsRequest: boolean
72
+ readonly wantsResponse: boolean
73
+ readonly wantsRawBody: boolean
74
+ readonly ignoresBody?: boolean
75
+ readonly upload?: UploadConfig | null
76
+ readonly file?: FileConfig | null
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ readonly onRefused?: RouteRefusedHook<any, any, any> | null
79
+ }
80
+
81
+ /** A route's file response, declared by `.file()`. */
82
+ export interface FileConfig {
83
+ /** Media types the route may answer with; `type/*` wildcards allowed. */
84
+ readonly mediaTypes: readonly string[]
85
+ /** Status of the file response (default 200). */
86
+ readonly status: number
87
+ }
88
+
89
+ /** What pipework tells an upload route's `onRefuse` hook about a file it refused. */
90
+ export interface UploadRefusal<TParams = unknown, TQuery = unknown> {
91
+ readonly status: 413 | 415
92
+ /** The error code in the response body. */
93
+ readonly code: string
94
+ /** Type found in the file's first bytes; null when none matched or the head was not read. */
95
+ readonly detectedType: string | null
96
+ /** Content-Type the sender declared for the file; '' when none. */
97
+ readonly declaredType: string
98
+ /** Lowercase filename extension; null without a filename or a dot. */
99
+ readonly extension: string | null
100
+ readonly filename: string | null
101
+ /** The request's Content-Length; null when chunked. */
102
+ readonly declaredLength: number | null
103
+ /** File bytes pipework had read when it refused. */
104
+ readonly bytesRead: number
105
+ readonly accepted: readonly string[]
106
+ /** The request's auth (null on a public route). */
107
+ readonly auth: unknown
108
+ readonly requestId: string
109
+ /**
110
+ * The route's params parsed by its schema exactly as the handler receives them
111
+ * (transforms and coercions applied); the raw params when the route declares no
112
+ * schema; null when they fail the schema (the request would be refused too, but
113
+ * a refusal of the file can win the race).
114
+ */
115
+ readonly params: TParams | null
116
+ /** The route's query, on the same terms as `params`. */
117
+ readonly query: TQuery | null
118
+ }
119
+
120
+ /**
121
+ * Runs once for each 413 or 415 pipework answers for a file, inside the
122
+ * request's context. A returned non-empty string replaces the error message;
123
+ * status and code stay. A throw is logged and the default message is sent.
124
+ */
125
+ export type UploadRefuseHook<TParams = unknown, TQuery = unknown> = (refusal: UploadRefusal<TParams, TQuery>) => string | void | Promise<string | void>
126
+
127
+ /** What pipework tells a route's `onRefused` hook about a 4xx it is answering. */
128
+ export interface RouteRefusal<TAuth = unknown, TParams = unknown, TQuery = unknown> {
129
+ /** The response status, 400-499. */
130
+ readonly status: number
131
+ /** The error code in the response body. */
132
+ readonly code: string
133
+ readonly message: string
134
+ /** The body's `fields`; set only for VALIDATION_ERROR. */
135
+ readonly fields: Record<string, readonly string[]> | null
136
+ /** The body's `retryAfterSeconds` on a 429 that has one; else null. */
137
+ readonly retryAfterSeconds: number | null
138
+ /** The request's auth; null when auth itself refused or the request has no context. */
139
+ readonly auth: TAuth | null
140
+ /** The route's params as the handler would get them; null when they fail the schema. */
141
+ readonly params: TParams | null
142
+ /** The route's query, on the same terms as `params`. */
143
+ readonly query: TQuery | null
144
+ readonly request: { readonly headers: Record<string, string | undefined>; readonly ip: string; readonly ips: readonly string[] }
145
+ readonly requestId: string
146
+ }
147
+
148
+ /**
149
+ * Runs once for each 4xx a route answers, inside the request's context. A returned
150
+ * plain object is merged into the response's `error`; `code`, `message`, `fields`
151
+ * and `details` always keep pipework's values.
152
+ */
153
+ export type RouteRefusedHook<TAuth = unknown, TParams = unknown, TQuery = unknown> =
154
+ (refusal: RouteRefusal<TAuth, TParams, TQuery>) => Record<string, unknown> | void | Promise<Record<string, unknown> | void>
155
+
156
+ /** Upload whose whole request body is the file's bytes. */
157
+ export interface BinaryUploadConfig<TParams = unknown, TQuery = unknown> {
158
+ readonly kind: 'binary'
159
+ /** Accepted media types, matched against the type detected from the first bytes; `type/*` wildcards allowed, and a star on each side of the slash for any type. Others get 415. */
160
+ readonly mediaTypes: readonly string[]
161
+ /** Largest accepted body in bytes. Over it gets 413. */
162
+ readonly maxBytes: number
163
+ readonly onRefuse?: UploadRefuseHook<TParams, TQuery>
164
+ }
165
+
166
+ /** Upload whose file is one part of a `multipart/form-data` body. */
167
+ export interface MultipartUploadConfig<TParams = unknown, TQuery = unknown> {
168
+ readonly kind: 'multipart'
169
+ /** Name of the form field carrying the file. */
170
+ readonly file: string
171
+ /** Accepted media types of the file, matched against the type detected from its first bytes; `type/*` wildcards allowed, and a star on each side of the slash for any type. Others get 415. */
172
+ readonly mediaTypes: readonly string[]
173
+ /** Largest accepted file in bytes. Over it gets 413. */
174
+ readonly maxBytes: number
175
+ /** Text field names accepted ahead of the file part; any other field gets 422. */
176
+ readonly fields?: readonly string[]
177
+ readonly onRefuse?: UploadRefuseHook<TParams, TQuery>
178
+ }
179
+
180
+ export type UploadConfig = BinaryUploadConfig | MultipartUploadConfig
181
+
182
+ /** The type fields shared by both upload deps. */
183
+ interface UploadTypes {
184
+ /** The type the file is treated as, and what `mediaTypes` was matched against. */
185
+ readonly mediaType: string
186
+ /** Type found in the first bytes; null when no signature matched. */
187
+ readonly detectedType: string | null
188
+ /** Content-Type the sender declared for the file; '' when none. */
189
+ readonly declaredType: string
190
+ /** Lowercase filename extension; null when there is no filename or no dot. */
191
+ readonly extension: string | null
192
+ }
193
+
194
+ /** The `upload` dep of a binary upload route. */
195
+ export interface BinaryUpload extends UploadTypes {
196
+ readonly stream: Readable
197
+ /** Declared Content-Length, or null for a chunked body. */
198
+ readonly length: number | null
199
+ }
200
+
201
+ /** The `upload` dep of a multipart upload route. */
202
+ export interface MultipartUpload extends UploadTypes {
203
+ readonly stream: Readable
204
+ readonly filename: string | null
205
+ /** Text fields that came before the file part. */
206
+ readonly fields: Readonly<Record<string, string>>
207
+ }
208
+
209
+ /**
210
+ * What a route screen is shown: the request line and headers, plus the declared
211
+ * body size. The body has not been read — nothing here forces it to be buffered.
212
+ */
213
+ export interface ScreenedRequest {
214
+ readonly method: string
215
+ readonly url: string
216
+ readonly headers: Readonly<Record<string, string | undefined>>
217
+ /** Parsed `content-length`, or null when the header is absent or unparseable. */
218
+ readonly contentLength: number | null
219
+ /** The route's params parsed by its schema as the handler gets them; the raw params with no schema; null when they fail it. */
220
+ readonly params: unknown
221
+ }
222
+
223
+ /** A screen's refusal — the status and named reason sent instead of reading the body. */
224
+ export interface ScreenRefusal {
225
+ readonly status: number
226
+ readonly reason: string
227
+ /** Extra fields merged into the response body alongside `reason`. */
228
+ readonly body?: Readonly<Record<string, unknown>>
229
+ }
230
+
231
+ /**
232
+ * Runs before the body is parsed and before the body limit applies. Return a
233
+ * refusal to answer the request there and then; return nothing to let it through.
234
+ */
235
+ export type RouteScreen = (request: ScreenedRequest) => ScreenRefusal | null | undefined | void | Promise<ScreenRefusal | null | undefined | void>
236
+
237
+ /** HTTP route metadata — method, path, and registered middleware. */
238
+ export interface RouteMeta {
239
+ readonly method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
240
+ readonly path: string
241
+ /** Per-route max request body size in bytes — overrides the server-level bodyLimit for this route. */
242
+ readonly bodyLimit?: number
243
+ /** Pre-parse screen — inspects headers before the body is read, and may refuse. */
244
+ readonly screen?: RouteScreen
245
+ }
246
+
247
+ /** HTTP method literal type — 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'. */
248
+ export type HttpMethod = RouteMeta['method']
249
+
250
+ /** A resolved handler produced by fitting().fit() — carries metadata, dependencies, and the handler function. */
251
+ export interface Handler<TDeps extends Record<string, unknown>, TReturn> {
252
+ execute(deps: TDeps): Promise<TReturn>
253
+ readonly meta: HandlerMeta
254
+ }
255
+
256
+ /** Extracts the dependency type from a Handler — InferDeps<typeof myHandler> gives you the deps object shape. */
257
+ export type InferDeps<H> = H extends Handler<infer D, unknown> ? D : never
258
+ /** Extracts the return type from a Handler — InferReturn<typeof myHandler> gives you the resolved return type. */
259
+ export type InferReturn<H> = H extends Handler<Record<string, unknown>, infer R> ? R : never
260
+
261
+ /** Map of database names to their resolved DB instances for a handler. */
262
+ export type DatabaseDeps<N extends string> = Record<N, DB>
@@ -0,0 +1,7 @@
1
+ import { createBuilder } from '../di/builder.js'
2
+
3
+ /** DI handler builder — chain .use(), .auth(), .input(), .route(), .fit() to build type-safe handlers with automatic dependency injection. */
4
+ export const fitting = Object.assign(
5
+ () => createBuilder(),
6
+ {},
7
+ )
@@ -0,0 +1,71 @@
1
+ import type { DB } from '../../data/db/index.js'
2
+ import type { PermissionMeta } from '../di/types.js'
3
+ import { ValidationError } from '../../core/errors/index.js'
4
+
5
+ export interface BatchTargets {
6
+ readonly ids?: string[]
7
+ readonly filters?: Record<string, unknown>
8
+ }
9
+
10
+ export interface BatchAction<TAuth> {
11
+ readonly permission?: PermissionMeta
12
+ readonly preview?: (db: DB, auth: TAuth, tenant: string | null, targets: BatchTargets) => Promise<unknown>
13
+ readonly execute: (db: DB, auth: TAuth, tenant: string | null, targets: BatchTargets) => Promise<unknown>
14
+ }
15
+
16
+ export interface BatchRequest {
17
+ readonly action: string
18
+ readonly targets: BatchTargets
19
+ }
20
+
21
+ export function validateBatchRequest(body: unknown, validActions: readonly string[]): BatchRequest {
22
+ if (body === null || typeof body !== 'object') {
23
+ throw new ValidationError('Batch request body must be an object')
24
+ }
25
+ const obj = body as Record<string, unknown>
26
+
27
+ const action = obj['action']
28
+ if (typeof action !== 'string' || action.length === 0) {
29
+ throw new ValidationError({ action: ['action is required and must be a non-empty string'] })
30
+ }
31
+ if (!validActions.includes(action)) {
32
+ throw new ValidationError({
33
+ action: [`Unknown batch action "${action}". Valid actions: ${validActions.join(', ')}`],
34
+ })
35
+ }
36
+
37
+ const targets = obj['targets']
38
+ if (targets === null || targets === undefined || typeof targets !== 'object') {
39
+ throw new ValidationError({ targets: ['targets is required and must be an object'] })
40
+ }
41
+ const t = targets as Record<string, unknown>
42
+
43
+ const hasIds = Array.isArray(t['ids'])
44
+ const hasFilters = t['filters'] !== undefined && t['filters'] !== null && typeof t['filters'] === 'object'
45
+
46
+ if (!hasIds && !hasFilters) {
47
+ throw new ValidationError({ targets: ['targets must contain exactly one of "ids" or "filters"'] })
48
+ }
49
+ if (hasIds && hasFilters) {
50
+ throw new ValidationError({ targets: ['targets must contain exactly one of "ids" or "filters", not both'] })
51
+ }
52
+
53
+ if (hasIds) {
54
+ const ids = t['ids'] as unknown[]
55
+ if (ids.length === 0) {
56
+ throw new ValidationError({ 'targets.ids': ['ids array must not be empty'] })
57
+ }
58
+ for (const id of ids) {
59
+ if (typeof id !== 'string') {
60
+ throw new ValidationError({ 'targets.ids': ['all ids must be strings'] })
61
+ }
62
+ }
63
+ }
64
+
65
+ return {
66
+ action,
67
+ targets: hasIds
68
+ ? { ids: t['ids'] as string[] }
69
+ : { filters: t['filters'] as Record<string, unknown> },
70
+ }
71
+ }
@@ -0,0 +1,26 @@
1
+ import type { ResourceOperations, Resource, ResourceMeta, PaginationConfig } from './types.js'
2
+ import type { AuthRequirement, PermissionMeta } from '../di/types.js'
3
+
4
+ interface ResourceBuilderState {
5
+ database: string
6
+ authRequirement: AuthRequirement
7
+ permission: PermissionMeta | null
8
+ pagination: PaginationConfig | null
9
+ }
10
+
11
+ export function buildResource<TAuth>(
12
+ name: string,
13
+ operations: ResourceOperations<TAuth>,
14
+ state: ResourceBuilderState,
15
+ ): Resource<TAuth> {
16
+ const meta: ResourceMeta = {
17
+ name,
18
+ database: state.database,
19
+ authRequirement: state.authRequirement,
20
+ permission: state.permission,
21
+ pagination: state.pagination,
22
+ }
23
+ return { meta, operations }
24
+ }
25
+
26
+ export { type ResourceBuilderState }
@@ -0,0 +1,10 @@
1
+ import { PipeworkError } from '../../core/errors/base.js'
2
+
3
+ export class MethodNotAllowedError extends PipeworkError {
4
+ readonly code = 'METHOD_NOT_ALLOWED' as const
5
+ readonly httpStatus = 405 as const
6
+
7
+ constructor(method: string, resource: string) {
8
+ super(`${method} not supported on ${resource}`)
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ export type { Resource, ResourceOperations, ResourceMeta, ResourceId, ResourceListOp, ResourceListPaginatedOp, ResourceListCursorOp, ResourceGetOp, ResourceCreateOp, ResourceUpdateOp, ResourceDeleteOp, PaginationConfig, PaginationParams, PaginatedResponse } from './types.js'
2
+ export { buildResource } from './builder.js'
3
+ export { resourceToHandlers } from './to-handlers.js'
4
+ export { MethodNotAllowedError } from './errors.js'
5
+ export { encodeCursor, decodeCursor, buildPage } from './paginate.js'
6
+ export type { PageResult, CursorPaginationParams } from './paginate.js'
7
+ export { validateBatchRequest } from './batch.js'
8
+ export type { BatchAction, BatchTargets, BatchRequest } from './batch.js'