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,23 @@
1
+ import { resourceToHandlers } from './to-handlers.js'
2
+ import { MethodNotAllowedError } from './errors.js'
3
+ import { encodeCursor, decodeCursor, buildPage } from './paginate.js'
4
+ import { validateBatchRequest } from './batch.js'
5
+ import { buildResource } from './builder.js'
6
+
7
+ /** REST resource builder namespace — declarative CRUD with cursor pagination and batch operations. */
8
+ export const fixture = {
9
+ /** Converts a Resource into fitted Handler[] that go through the standard handler pipeline. */
10
+ toHandlers: resourceToHandlers,
11
+ /** Builds a Resource from a name, operations map, and builder state — used internally by fitting().fixture(). */
12
+ build: buildResource,
13
+ /** Encodes pagination cursor values into an opaque base64 string. */
14
+ encodeCursor,
15
+ /** Decodes an opaque pagination cursor back into its values. */
16
+ decodeCursor,
17
+ /** Builds a PageResult from rows, limit, and cursor extractor — handles hasMore detection. */
18
+ buildPage,
19
+ /** Validates a batch request body (preview/execute mode, targets, actions). */
20
+ validateBatch: validateBatchRequest,
21
+ /** Thrown when a resource doesn't support the requested HTTP method. */
22
+ MethodNotAllowedError,
23
+ }
@@ -0,0 +1,44 @@
1
+ import { ValidationError } from '../../core/errors/index.js'
2
+
3
+ export interface PageResult<T> {
4
+ readonly items: T[]
5
+ readonly cursor: string | null
6
+ readonly hasMore: boolean
7
+ }
8
+
9
+ export interface CursorPaginationParams {
10
+ readonly cursor?: string
11
+ readonly limit: number
12
+ }
13
+
14
+ export function encodeCursor(values: readonly unknown[]): string {
15
+ const json = JSON.stringify(values)
16
+ return Buffer.from(json).toString('base64url')
17
+ }
18
+
19
+ export function decodeCursor(cursor: string): unknown[] {
20
+ try {
21
+ const json = Buffer.from(cursor, 'base64url').toString('utf-8')
22
+ const parsed: unknown = JSON.parse(json)
23
+ if (!Array.isArray(parsed)) {
24
+ throw new ValidationError('Invalid cursor: expected encoded array')
25
+ }
26
+ return parsed
27
+ } catch (err) {
28
+ if (err instanceof ValidationError) throw err
29
+ throw new ValidationError('Invalid cursor: malformed or tampered value')
30
+ }
31
+ }
32
+
33
+ export function buildPage<T>(
34
+ rows: readonly T[],
35
+ limit: number,
36
+ getCursor: (item: T) => string,
37
+ ): PageResult<T> {
38
+ const hasMore = rows.length > limit
39
+ const items = hasMore ? rows.slice(0, limit) : [...rows]
40
+ const cursor = hasMore && items.length > 0
41
+ ? encodeCursor([getCursor(items[items.length - 1]!)])
42
+ : null
43
+ return { items, cursor, hasMore }
44
+ }
@@ -0,0 +1,260 @@
1
+ import type { DB } from '../../data/db/index.js'
2
+ import type { Handler, HandlerMeta, HttpMethod } from '../di/types.js'
3
+ import { DEFAULT_DB } from '../di/types.js'
4
+ import type { Resource, PaginationConfig } from './types.js'
5
+ import { unknown as unknownSchema } from '../../data/schema/generated/type-constructor.js'
6
+ import { requireContext } from '../context/store.js'
7
+ import { NotFoundError } from '../../core/errors/index.js'
8
+ import { MethodNotAllowedError } from './errors.js'
9
+ import { validateBatchRequest } from './batch.js'
10
+ import { singularize } from '../internal/text.js'
11
+
12
+ type AnyHandler = Handler<Record<string, unknown>, unknown>
13
+
14
+ const passthroughSchema = unknownSchema().refine((value) => value !== undefined, 'A request body is required')
15
+
16
+ function makeMeta(
17
+ resource: Resource<unknown>,
18
+ method: HttpMethod,
19
+ path: string,
20
+ overrides?: Partial<HandlerMeta>,
21
+ ): HandlerMeta {
22
+ const { database, authRequirement, permission } = resource.meta
23
+ return {
24
+ databases: [database],
25
+ requiresAuth: authRequirement === 'required',
26
+ authRequirement,
27
+ inputSchema: null,
28
+ outputSchemas: new Map(),
29
+ querySchema: null,
30
+ paramsSchema: null,
31
+ route: { method, path },
32
+ isJob: false,
33
+ jobType: null,
34
+ jobRetry: null,
35
+ jobTimeout: null,
36
+ jobTransaction: 'auto',
37
+ permission,
38
+ wantsRequest: false,
39
+ wantsResponse: false,
40
+ wantsRawBody: false,
41
+ ...overrides,
42
+ }
43
+ }
44
+
45
+ function make405(resource: Resource<unknown>, method: HttpMethod, path: string): AnyHandler {
46
+ return {
47
+ meta: makeMeta(resource, method, path, {
48
+ databases: [],
49
+ requiresAuth: false,
50
+ authRequirement: 'none',
51
+ permission: null,
52
+ }),
53
+ execute() {
54
+ return Promise.reject(new MethodNotAllowedError(method, resource.meta.name))
55
+ },
56
+ }
57
+ }
58
+
59
+ function depKey(database: string): string {
60
+ return database === DEFAULT_DB ? 'db' : database
61
+ }
62
+
63
+ function parsePagination(
64
+ query: Record<string, unknown> | undefined,
65
+ config: PaginationConfig,
66
+ ): { limit: number; offset: number } {
67
+ const rawLimit = query?.['limit'] !== undefined ? parseInt(String(query['limit']), 10) : config.defaultLimit
68
+ const limit = Math.min(Math.max(1, Number.isNaN(rawLimit) ? config.defaultLimit : rawLimit), config.maxLimit)
69
+ const rawOffset = query?.['offset'] !== undefined ? parseInt(String(query['offset']), 10) : 0
70
+ const offset = Math.max(0, Number.isNaN(rawOffset) ? 0 : rawOffset)
71
+ return { limit, offset }
72
+ }
73
+
74
+ function capitalize(s: string): string {
75
+ return s.charAt(0).toUpperCase() + s.slice(1)
76
+ }
77
+
78
+
79
+ export function resourceToHandlers(resource: Resource<unknown>): AnyHandler[] {
80
+ const handlers: AnyHandler[] = []
81
+ const { name, database, pagination } = resource.meta
82
+ const ops = resource.operations
83
+ const basePath = `/${name}`
84
+ const itemPath = `/${name}/:id`
85
+ const key = depKey(database)
86
+
87
+ // GET /resource — list
88
+ if (ops.listCursor !== undefined && pagination !== null) {
89
+ handlers.push({
90
+ meta: makeMeta(resource, 'GET', basePath, { querySchema: passthroughSchema }),
91
+ async execute(deps) {
92
+ const db = deps[key] as DB
93
+ const auth = deps['auth'] as unknown
94
+ const tenant = requireContext().tenant
95
+ const query = deps['query'] as Record<string, unknown> | undefined
96
+ const rawLimit = query?.['limit'] !== undefined ? parseInt(String(query['limit']), 10) : pagination.defaultLimit
97
+ const limit = Math.min(Math.max(1, Number.isNaN(rawLimit) ? pagination.defaultLimit : rawLimit), pagination.maxLimit)
98
+ const cursor = query?.['cursor'] !== undefined ? String(query['cursor']) : undefined
99
+ const result = await ops.listCursor!(db, auth, tenant, cursor !== undefined ? { cursor, limit } : { limit })
100
+ return { status: 200, body: result }
101
+ },
102
+ })
103
+ } else if (ops.listPaginated !== undefined && pagination !== null) {
104
+ handlers.push({
105
+ meta: makeMeta(resource, 'GET', basePath, { querySchema: passthroughSchema }),
106
+ async execute(deps) {
107
+ const db = deps[key] as DB
108
+ const auth = deps['auth'] as unknown
109
+ const tenant = requireContext().tenant
110
+ const query = deps['query'] as Record<string, unknown> | undefined
111
+ const { limit, offset } = parsePagination(query, pagination)
112
+ const result = await ops.listPaginated!(db, auth, tenant, { limit, offset })
113
+ return {
114
+ status: 200,
115
+ body: {
116
+ data: result.data,
117
+ pagination: { limit, offset, total: result.total, hasMore: offset + result.data.length < result.total },
118
+ },
119
+ }
120
+ },
121
+ })
122
+ } else if (ops.list !== undefined) {
123
+ handlers.push({
124
+ meta: makeMeta(resource, 'GET', basePath),
125
+ async execute(deps) {
126
+ const db = deps[key] as DB
127
+ const auth = deps['auth'] as unknown
128
+ const tenant = requireContext().tenant
129
+ const result = await ops.list!(db, auth, tenant)
130
+ return { status: 200, body: result }
131
+ },
132
+ })
133
+ } else {
134
+ handlers.push(make405(resource, 'GET', basePath))
135
+ }
136
+
137
+ // GET /resource/:id
138
+ if (ops.get !== undefined) {
139
+ handlers.push({
140
+ meta: makeMeta(resource, 'GET', itemPath, { paramsSchema: passthroughSchema }),
141
+ async execute(deps) {
142
+ const db = deps[key] as DB
143
+ const auth = deps['auth'] as unknown
144
+ const tenant = requireContext().tenant
145
+ const params = deps['params'] as Record<string, unknown>
146
+ const id = String(params['id'])
147
+ const result = await ops.get!(db, auth, tenant, id)
148
+ if (result === null || result === undefined) {
149
+ throw new NotFoundError(`${capitalize(singularize(name))} "${id}"`)
150
+ }
151
+ return { status: 200, body: result }
152
+ },
153
+ })
154
+ } else {
155
+ handlers.push(make405(resource, 'GET', itemPath))
156
+ }
157
+
158
+ // POST /resource
159
+ if (ops.create !== undefined) {
160
+ handlers.push({
161
+ meta: makeMeta(resource, 'POST', basePath, {
162
+ inputSchema: ops.create.input ?? passthroughSchema,
163
+ }),
164
+ async execute(deps) {
165
+ const db = deps[key] as DB
166
+ const auth = deps['auth'] as unknown
167
+ const tenant = requireContext().tenant
168
+ const input = deps['input']
169
+ const result = await ops.create!.handler(db, auth, tenant, input)
170
+ return { status: 201, body: result }
171
+ },
172
+ })
173
+ } else {
174
+ handlers.push(make405(resource, 'POST', basePath))
175
+ }
176
+
177
+ // PUT /resource/:id
178
+ if (ops.update !== undefined) {
179
+ handlers.push({
180
+ meta: makeMeta(resource, 'PUT', itemPath, {
181
+ inputSchema: ops.update.input ?? passthroughSchema,
182
+ paramsSchema: passthroughSchema,
183
+ }),
184
+ async execute(deps) {
185
+ const db = deps[key] as DB
186
+ const auth = deps['auth'] as unknown
187
+ const tenant = requireContext().tenant
188
+ const params = deps['params'] as Record<string, unknown>
189
+ const id = String(params['id'])
190
+ const input = deps['input']
191
+ const result = await ops.update!.handler(db, auth, tenant, id, input)
192
+ if (result === null || result === undefined) {
193
+ throw new NotFoundError(`${capitalize(singularize(name))} "${id}"`)
194
+ }
195
+ return { status: 200, body: result }
196
+ },
197
+ })
198
+ } else {
199
+ handlers.push(make405(resource, 'PUT', itemPath))
200
+ }
201
+
202
+ // DELETE /resource/:id
203
+ if (ops.delete !== undefined) {
204
+ handlers.push({
205
+ meta: makeMeta(resource, 'DELETE', itemPath, { paramsSchema: passthroughSchema }),
206
+ async execute(deps) {
207
+ const db = deps[key] as DB
208
+ const auth = deps['auth'] as unknown
209
+ const tenant = requireContext().tenant
210
+ const params = deps['params'] as Record<string, unknown>
211
+ const id = String(params['id'])
212
+ await ops.delete!(db, auth, tenant, id)
213
+ return { status: 204 }
214
+ },
215
+ })
216
+ } else {
217
+ handlers.push(make405(resource, 'DELETE', itemPath))
218
+ }
219
+
220
+ if (ops.batch !== undefined) {
221
+ const validActions = Object.keys(ops.batch)
222
+
223
+ handlers.push({
224
+ meta: makeMeta(resource, 'POST', `${basePath}/batch/preview`, {
225
+ inputSchema: passthroughSchema,
226
+ }),
227
+ async execute(deps) {
228
+ const db = deps[key] as DB
229
+ const auth = deps['auth'] as unknown
230
+ const tenant = requireContext().tenant
231
+ const input = deps['input']
232
+ const { action, targets } = validateBatchRequest(input, validActions)
233
+ const batchAction = ops.batch![action]!
234
+ if (batchAction.preview === undefined) {
235
+ throw new MethodNotAllowedError('POST', `${name}/batch/preview (action: ${action})`)
236
+ }
237
+ const result = await batchAction.preview(db, auth, tenant, targets)
238
+ return { status: 200, body: result }
239
+ },
240
+ })
241
+
242
+ handlers.push({
243
+ meta: makeMeta(resource, 'POST', `${basePath}/batch`, {
244
+ inputSchema: passthroughSchema,
245
+ }),
246
+ async execute(deps) {
247
+ const db = deps[key] as DB
248
+ const auth = deps['auth'] as unknown
249
+ const tenant = requireContext().tenant
250
+ const input = deps['input']
251
+ const { action, targets } = validateBatchRequest(input, validActions)
252
+ const batchAction = ops.batch![action]!
253
+ const result = await batchAction.execute(db, auth, tenant, targets)
254
+ return { status: 200, body: result }
255
+ },
256
+ })
257
+ }
258
+
259
+ return handlers
260
+ }
@@ -0,0 +1,79 @@
1
+ import type { Schema } from '../../data/schema/types.js'
2
+ import type { DB } from '../../data/db/index.js'
3
+ import type { AuthRequirement, PermissionMeta } from '../di/types.js'
4
+
5
+ export type ResourceId = string
6
+
7
+ export interface PaginationConfig {
8
+ readonly defaultLimit: number
9
+ readonly maxLimit: number
10
+ }
11
+
12
+ export interface PaginationParams {
13
+ readonly limit: number
14
+ readonly offset: number
15
+ }
16
+
17
+ export interface PaginatedResponse<T = unknown> {
18
+ readonly data: T[]
19
+ readonly pagination: {
20
+ readonly limit: number
21
+ readonly offset: number
22
+ readonly total: number
23
+ readonly hasMore: boolean
24
+ }
25
+ }
26
+
27
+ export interface ResourceListOp<TAuth> {
28
+ (db: DB, auth: TAuth, tenant: string | null): Promise<readonly unknown[]>
29
+ }
30
+
31
+ export interface ResourceListPaginatedOp<TAuth> {
32
+ (db: DB, auth: TAuth, tenant: string | null, pagination: PaginationParams): Promise<{ data: readonly unknown[]; total: number }>
33
+ }
34
+
35
+ export interface ResourceListCursorOp<TAuth> {
36
+ (db: DB, auth: TAuth, tenant: string | null, pagination: import('./paginate.js').CursorPaginationParams): Promise<import('./paginate.js').PageResult<unknown>>
37
+ }
38
+
39
+ export interface ResourceGetOp<TAuth> {
40
+ (db: DB, auth: TAuth, tenant: string | null, id: ResourceId): Promise<unknown | null>
41
+ }
42
+
43
+ export interface ResourceCreateOp<TAuth> {
44
+ readonly input?: Schema
45
+ readonly handler: (db: DB, auth: TAuth, tenant: string | null, input: unknown) => Promise<unknown>
46
+ }
47
+
48
+ export interface ResourceUpdateOp<TAuth> {
49
+ readonly input?: Schema
50
+ readonly handler: (db: DB, auth: TAuth, tenant: string | null, id: ResourceId, input: unknown) => Promise<unknown | null>
51
+ }
52
+
53
+ export interface ResourceDeleteOp<TAuth> {
54
+ (db: DB, auth: TAuth, tenant: string | null, id: ResourceId): Promise<void>
55
+ }
56
+
57
+ export interface ResourceOperations<TAuth> {
58
+ readonly list?: ResourceListOp<TAuth>
59
+ readonly listPaginated?: ResourceListPaginatedOp<TAuth>
60
+ readonly listCursor?: ResourceListCursorOp<TAuth>
61
+ readonly get?: ResourceGetOp<TAuth>
62
+ readonly create?: ResourceCreateOp<TAuth>
63
+ readonly update?: ResourceUpdateOp<TAuth>
64
+ readonly delete?: ResourceDeleteOp<TAuth>
65
+ readonly batch?: Record<string, import('./batch.js').BatchAction<TAuth>>
66
+ }
67
+
68
+ export interface ResourceMeta {
69
+ readonly name: string
70
+ readonly database: string
71
+ readonly authRequirement: AuthRequirement
72
+ readonly permission: PermissionMeta | null
73
+ readonly pagination: PaginationConfig | null
74
+ }
75
+
76
+ export interface Resource<TAuth> {
77
+ readonly meta: ResourceMeta
78
+ readonly operations: ResourceOperations<TAuth>
79
+ }
@@ -0,0 +1,78 @@
1
+ import { randomUUID } from 'node:crypto'
2
+ import type { Flow } from '../context/types.js'
3
+ import type { DB } from '../../data/db/index.js'
4
+ import { requireContext, runInContext } from '../context/store.js'
5
+ import { bindTransaction } from '../context/guard.js'
6
+ import { sql } from '../../data/db/sql.js'
7
+ import { propagateLocals } from '../context/run-in-transaction.js'
8
+ import { openChildTrace } from '../../trace/entry/child-trace.js'
9
+ import { finalizeTrace } from '../../trace/entry/finalize-trace.js'
10
+
11
+ /**
12
+ * Runs `fn` as `as.tenant` and `as.userId` from a Flow that has no tenant: a
13
+ * sign-up that has just founded a tenant, a public sign-in recording into its
14
+ * org. Row-level security, audit rows (tenant and actor) and the trace all
15
+ * carry that tenant and user.
16
+ *
17
+ * `fn` runs in a savepoint of the request's own transaction, so it commits or
18
+ * rolls back with the request. If `fn` throws, its writes are undone, the
19
+ * request's transaction stays usable and the error is rethrown. When `actAs`
20
+ * returns the Flow and the transaction are tenantless again. A Flow with no
21
+ * transaction on the default database gets a new app-role transaction instead.
22
+ * Refused when the Flow already has a tenant.
23
+ */
24
+ export async function actAs<T>(
25
+ as: { readonly tenant: string; readonly userId: string },
26
+ fn: () => Promise<T>,
27
+ ): Promise<T> {
28
+ const flow = requireContext()
29
+ if (flow.tenant !== null) {
30
+ throw new Error(
31
+ `[pipework] flow.actAs runs only in a Flow with no tenant; this Flow is tenant "${flow.tenant}", ` +
32
+ `asked for "${as.tenant}".\n\n` +
33
+ ' actAs is for code that has just chosen a tenant (sign-up, a public sign-in). ' +
34
+ 'Code already running as a tenant keeps that tenant.\n',
35
+ )
36
+ }
37
+ const dbName = flow.instance.config.defaultDatabaseName()
38
+ const auth = { userId: as.userId, tenantId: as.tenant }
39
+ const childTrace = openChildTrace(flow, as.tenant, auth)
40
+ const child: Flow = {
41
+ ...flow,
42
+ _nonce: randomUUID(),
43
+ tenant: as.tenant,
44
+ user: null,
45
+ auth,
46
+ transactions: new Map(),
47
+ trace: childTrace,
48
+ }
49
+
50
+ const run = async (tx: DB): Promise<T> => {
51
+ child.transactions.set(dbName, bindTransaction(child, dbName, tx))
52
+ await propagateLocals(tx, child, child.tenantConfig)
53
+ return runInContext(child, fn)
54
+ }
55
+
56
+ const parentBound = flow.transactions.get(dbName)
57
+ if (parentBound === undefined) {
58
+ const conn = flow.instance.pool.getOrCreate(flow.instance.config.database(dbName), 'app')
59
+ return finalizeTrace(flow.instance, childTrace, conn.drizzle.transaction(run))
60
+ }
61
+
62
+ const parentTx = parentBound.drizzle
63
+ const names = [
64
+ 'pipework.request_id', 'pipework.tenant_id', 'pipework.user_id', 'pipework.asof',
65
+ ...Object.keys(flow.tenantConfig?.sessionVars ?? {}),
66
+ ]
67
+ const before = new Map<string, string>()
68
+ for (const name of names) {
69
+ const rows = await parentTx.execute(sql`SELECT current_setting(${name}, true) AS value`)
70
+ before.set(name, (rows[0]?.['value'] as string | null | undefined) ?? '')
71
+ }
72
+ const work = parentTx.transaction(run).then(async (value) => {
73
+ // Releasing the savepoint keeps its SET LOCALs; put the request's own back.
74
+ for (const [name, value] of before) await parentTx.execute(sql`SELECT set_config(${name}, ${value}, true)`)
75
+ return value
76
+ })
77
+ return finalizeTrace(flow.instance, childTrace, work)
78
+ }
@@ -0,0 +1,17 @@
1
+ import { runInContext, requireContext, getContext } from '../context/store.js'
2
+ import { createTestContext } from '../context/create.js'
3
+ import { actAs } from './act-as.js'
4
+
5
+ /** AsyncLocalStorage context namespace — manages request/job/test contexts that carry auth, tenant, transactions. */
6
+ export const flow = {
7
+ /** Executes a function within a Flow context (AsyncLocalStorage). All pipe() calls inside will use this context. */
8
+ run: runInContext,
9
+ /** Returns the current Flow or throws — use in code that must run inside a managed context. */
10
+ require: requireContext,
11
+ /** Returns the current Flow or undefined — use for optional context detection. */
12
+ get: getContext,
13
+ /** Creates a Flow for test isolation with optional auth and tenant overrides. */
14
+ createTest: createTestContext,
15
+ /** Runs `fn` as a tenant and user chosen inside a tenantless Flow (sign-up, a public sign-in): RLS, audit and trace under that tenant, on the request's transaction. */
16
+ actAs,
17
+ }
@@ -0,0 +1,42 @@
1
+ import { randomUUID } from 'node:crypto'
2
+ import type { Flow } from '../context/index.js'
3
+ import { ValidationError } from '../../core/errors/index.js'
4
+ import { serializeForTrace } from '../../trace/capture/bounded-serializer.js'
5
+ import { projectStepError } from '../../trace/runtime/step-error.js'
6
+
7
+ export interface ErrorStepInfo {
8
+ readonly method: string
9
+ /** The route pattern (`/things/:id`), never the URL. */
10
+ readonly route: string
11
+ readonly status: number
12
+ readonly code: string
13
+ readonly error: unknown
14
+ }
15
+
16
+ /**
17
+ * Records one `http.error` step on the request's trace for an error response:
18
+ * method, route pattern, status, code and, for a ValidationError, each issue's
19
+ * source, path and message. Input values are never recorded. A no-op when the
20
+ * request has no trace (the error came before it opened, or tracing is off).
21
+ */
22
+ export function recordErrorStep(ctx: Flow | undefined, info: ErrorStepInfo): void {
23
+ const trace = ctx?.trace
24
+ if (trace === undefined || trace === null) return
25
+ const meta: Record<string, unknown> = { method: info.method, route: info.route, status: info.status, code: info.code }
26
+ if (info.error instanceof ValidationError) {
27
+ meta['issues'] = info.error.issues.map(i => ({ source: i.source, path: [...i.path], message: i.message }))
28
+ }
29
+ const now = new Date()
30
+ const { name, message } = projectStepError(info.error)
31
+ trace.buffer.stageExternal({
32
+ id: randomUUID(),
33
+ parentStepId: trace.buffer.openStepId,
34
+ flowStepRef: 'http.error',
35
+ status: 'error',
36
+ startedAt: now,
37
+ completedAt: now,
38
+ durationMicros: 0n,
39
+ capturedInputs: null,
40
+ error: { name, message: serializeForTrace(message) as string, stack: null, detail: serializeForTrace(meta) },
41
+ })
42
+ }