pipework 0.252.0 → 0.252.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (690) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/package.json +4 -3
  3. package/src/async/jobs/abortable-delay.ts +18 -0
  4. package/src/async/jobs/claims.ts +52 -0
  5. package/src/async/jobs/cron.ts +179 -0
  6. package/src/async/jobs/errors.ts +56 -0
  7. package/src/async/jobs/exclusion.ts +117 -0
  8. package/src/async/jobs/execute.ts +219 -0
  9. package/src/async/jobs/index.ts +10 -0
  10. package/src/async/jobs/listener.ts +135 -0
  11. package/src/async/jobs/namespace.ts +20 -0
  12. package/src/async/jobs/queue-door.ts +44 -0
  13. package/src/async/jobs/queue.ts +1012 -0
  14. package/src/async/jobs/run-script.ts +67 -0
  15. package/src/async/jobs/scheduler.ts +218 -0
  16. package/src/async/jobs/schedules-table.ts +37 -0
  17. package/src/async/jobs/serialize-error.ts +48 -0
  18. package/src/async/jobs/table.ts +191 -0
  19. package/src/async/pipeline/define.ts +53 -0
  20. package/src/async/pipeline/errors.ts +35 -0
  21. package/src/async/pipeline/execute.ts +53 -0
  22. package/src/async/pipeline/index.ts +13 -0
  23. package/src/async/pipeline/namespace.ts +12 -0
  24. package/src/async/pipeline/resume.ts +67 -0
  25. package/src/async/pipeline/run-steps.ts +98 -0
  26. package/src/async/pipeline/types.ts +57 -0
  27. package/src/async/state-machine/define.ts +64 -0
  28. package/src/async/state-machine/errors.ts +29 -0
  29. package/src/async/state-machine/index.ts +3 -0
  30. package/src/async/state-machine/namespace.ts +12 -0
  31. package/src/async/state-machine/transition.ts +90 -0
  32. package/src/async/state-machine/types.ts +37 -0
  33. package/src/async/steps/errors.ts +31 -0
  34. package/src/async/steps/graph.ts +1214 -0
  35. package/src/async/steps/hash.ts +40 -0
  36. package/src/async/steps/index.ts +7 -0
  37. package/src/async/steps/namespace.ts +7 -0
  38. package/src/async/steps/table.ts +97 -0
  39. package/src/async/steps/types.ts +318 -0
  40. package/src/audit/chain/index.ts +9 -0
  41. package/src/audit/chain/install.ts +113 -0
  42. package/src/audit/chain/retire.ts +52 -0
  43. package/src/audit/chain/verify.ts +257 -0
  44. package/src/audit/query/cursor.ts +37 -0
  45. package/src/audit/query/index.ts +9 -0
  46. package/src/audit/query/query.ts +223 -0
  47. package/src/audit/schema/audit-record-fields.ts +68 -0
  48. package/src/audit/schema/audit-record.ts +23 -0
  49. package/src/auth/auth/audit.ts +31 -0
  50. package/src/auth/auth/chain.ts +84 -0
  51. package/src/auth/auth/cookie.ts +136 -0
  52. package/src/auth/auth/email-links.ts +311 -0
  53. package/src/auth/auth/guard.ts +128 -0
  54. package/src/auth/auth/index.ts +18 -0
  55. package/src/auth/auth/multi-org.ts +337 -0
  56. package/src/auth/auth/namespace.ts +34 -0
  57. package/src/auth/auth/parse-expiry.ts +13 -0
  58. package/src/auth/auth/passwords.ts +110 -0
  59. package/src/auth/auth/schema.ts +110 -0
  60. package/src/auth/auth/sessions.ts +565 -0
  61. package/src/auth/auth/sign-in.ts +156 -0
  62. package/src/auth/auth/signing-keys.ts +69 -0
  63. package/src/auth/auth/types.ts +26 -0
  64. package/src/auth/auth/uuid.ts +10 -0
  65. package/src/auth/rbac/cache.ts +55 -0
  66. package/src/auth/rbac/check.ts +30 -0
  67. package/src/auth/rbac/create.ts +35 -0
  68. package/src/auth/rbac/index.ts +5 -0
  69. package/src/auth/rbac/middleware.ts +20 -0
  70. package/src/auth/rbac/namespace.ts +15 -0
  71. package/src/auth/rbac/resolve.ts +31 -0
  72. package/src/auth/rbac/schema.sql +31 -0
  73. package/src/auth/rbac/seed.ts +67 -0
  74. package/src/auth/rbac/tables.ts +32 -0
  75. package/src/auth/rbac/types.ts +65 -0
  76. package/src/auth/tenant/extract.ts +33 -0
  77. package/src/auth/tenant/in-tenant.ts +49 -0
  78. package/src/auth/tenant/index.ts +7 -0
  79. package/src/auth/tenant/namespace.ts +23 -0
  80. package/src/auth/tenant/propagate.ts +20 -0
  81. package/src/auth/tenant/rls.ts +120 -0
  82. package/src/auth/tenant/scope.ts +33 -0
  83. package/src/auth/tenant/scoped-db.ts +581 -0
  84. package/src/auth/tenant/types.ts +14 -0
  85. package/src/auth/tenant/validate.ts +27 -0
  86. package/src/cli/commands/add.ts +158 -0
  87. package/src/cli/commands/alerts.ts +98 -0
  88. package/src/cli/commands/check.ts +1418 -0
  89. package/src/cli/commands/codemod.ts +78 -0
  90. package/src/cli/commands/db.ts +356 -0
  91. package/src/cli/commands/dev.ts +101 -0
  92. package/src/cli/commands/generate.ts +75 -0
  93. package/src/cli/commands/init.ts +36 -0
  94. package/src/cli/commands/install.ts +28 -0
  95. package/src/cli/commands/lint.ts +62 -0
  96. package/src/cli/commands/migrate.ts +132 -0
  97. package/src/cli/commands/openapi.ts +63 -0
  98. package/src/cli/commands/remove.ts +72 -0
  99. package/src/cli/commands/run.ts +50 -0
  100. package/src/cli/commands/scope.ts +54 -0
  101. package/src/cli/commands/serve.ts +68 -0
  102. package/src/cli/commands/shard.ts +31 -0
  103. package/src/cli/commands/shared/config-pipework-version.ts +28 -0
  104. package/src/cli/commands/shared/find-config.ts +22 -0
  105. package/src/cli/commands/shared/load-config.ts +35 -0
  106. package/src/cli/commands/shared/pnpm-install.ts +95 -0
  107. package/src/cli/commands/shared/report-removed.ts +8 -0
  108. package/src/cli/commands/sync.ts +32 -0
  109. package/src/cli/commands/test.ts +307 -0
  110. package/src/cli/commands/upgrade.ts +48 -0
  111. package/src/cli/dev-bootstrap.ts +24 -0
  112. package/src/cli/errors.ts +10 -0
  113. package/src/cli/index.ts +303 -0
  114. package/src/cli/output.ts +17 -0
  115. package/src/cli/port.ts +15 -0
  116. package/src/cli/surface-kinds.ts +20 -0
  117. package/src/client/index.ts +4 -0
  118. package/src/client/poll.ts +130 -0
  119. package/src/client/report-fault.ts +119 -0
  120. package/src/core/config/app-pool.ts +19 -0
  121. package/src/core/config/aws-env.ts +29 -0
  122. package/src/core/config/base-dir.ts +24 -0
  123. package/src/core/config/discover.ts +64 -0
  124. package/src/core/config/env-resolve.ts +87 -0
  125. package/src/core/config/env-types.ts +116 -0
  126. package/src/core/config/env.ts +55 -0
  127. package/src/core/config/errors.ts +9 -0
  128. package/src/core/config/import-config.ts +40 -0
  129. package/src/core/config/index.ts +8 -0
  130. package/src/core/config/load.ts +417 -0
  131. package/src/core/config/namespace.ts +14 -0
  132. package/src/core/config/resolve.ts +195 -0
  133. package/src/core/config/schema.ts +488 -0
  134. package/src/core/config/statement-observer.ts +48 -0
  135. package/src/core/config/ts-inline-hooks.ts +75 -0
  136. package/src/core/config/ts-register.ts +4 -0
  137. package/src/core/config/ts-resolve-hooks.ts +101 -0
  138. package/src/core/errors/base.ts +49 -0
  139. package/src/core/errors/http.ts +146 -0
  140. package/src/core/errors/index.ts +2 -0
  141. package/src/core/errors/namespace.ts +31 -0
  142. package/src/core/lifecycle/drain.ts +33 -0
  143. package/src/core/lifecycle/health.ts +72 -0
  144. package/src/core/lifecycle/index.ts +4 -0
  145. package/src/core/lifecycle/namespace.ts +7 -0
  146. package/src/core/lifecycle/startup.ts +102 -0
  147. package/src/core/lifecycle/types.ts +36 -0
  148. package/src/core/logging/context.ts +60 -0
  149. package/src/core/logging/error-chain.ts +68 -0
  150. package/src/core/logging/index.ts +5 -0
  151. package/src/core/logging/logger.ts +65 -0
  152. package/src/core/logging/namespace.ts +16 -0
  153. package/src/core/logging/proxy.ts +22 -0
  154. package/src/core/logging/redact-match.ts +24 -0
  155. package/src/core/logging/types.ts +47 -0
  156. package/src/core/pipework.ts +566 -0
  157. package/src/core/runtime/broker.ts +69 -0
  158. package/src/core/surface/http.ts +133 -0
  159. package/src/core/surface/index.ts +11 -0
  160. package/src/core/surface/job-timeout.ts +40 -0
  161. package/src/core/surface/namespace.ts +13 -0
  162. package/src/core/surface/script.ts +33 -0
  163. package/src/core/surface/start.ts +142 -0
  164. package/src/core/surface/types.ts +225 -0
  165. package/src/core/surface/validate.ts +88 -0
  166. package/src/core/surface/worker.ts +528 -0
  167. package/src/core/validation/connectivity.ts +49 -0
  168. package/src/core/validation/domain.ts +99 -0
  169. package/src/core/validation/index.ts +5 -0
  170. package/src/core/validation/queue-tables.ts +312 -0
  171. package/src/core/validation/rls-role.ts +138 -0
  172. package/src/core/validation/startup.ts +51 -0
  173. package/src/core/validation/surfaces.ts +65 -0
  174. package/src/core/validation/types.ts +25 -0
  175. package/src/data/db/advisory-lock.ts +55 -0
  176. package/src/data/db/aggregates.ts +172 -0
  177. package/src/data/db/array-elements.ts +111 -0
  178. package/src/data/db/bulk-set.ts +53 -0
  179. package/src/data/db/col/index.ts +14 -0
  180. package/src/data/db/composed.ts +53 -0
  181. package/src/data/db/db.ts +276 -0
  182. package/src/data/db/excluded.ts +16 -0
  183. package/src/data/db/expressions.ts +473 -0
  184. package/src/data/db/filter.ts +90 -0
  185. package/src/data/db/function-source.ts +114 -0
  186. package/src/data/db/identifiers.ts +16 -0
  187. package/src/data/db/idx/index.ts +9 -0
  188. package/src/data/db/in-list.ts +49 -0
  189. package/src/data/db/index.ts +9 -0
  190. package/src/data/db/insert-split.ts +137 -0
  191. package/src/data/db/instrumentation.ts +82 -0
  192. package/src/data/db/maintenance.ts +28 -0
  193. package/src/data/db/namespace.ts +107 -0
  194. package/src/data/db/owner-labels.ts +9 -0
  195. package/src/data/db/pool.ts +187 -0
  196. package/src/data/db/query-label.ts +13 -0
  197. package/src/data/db/query-watch.ts +116 -0
  198. package/src/data/db/raw-client-warning.ts +37 -0
  199. package/src/data/db/readonly.ts +23 -0
  200. package/src/data/db/reservation.ts +151 -0
  201. package/src/data/db/schema-features.ts +14 -0
  202. package/src/data/db/serializable.ts +83 -0
  203. package/src/data/db/sql.ts +1 -0
  204. package/src/data/db/timeouts.ts +76 -0
  205. package/src/data/db/types.ts +18 -0
  206. package/src/data/db/unbound.ts +33 -0
  207. package/src/data/db/values.ts +29 -0
  208. package/src/data/domain/brand.ts +15 -0
  209. package/src/data/domain/build-factory.ts +193 -0
  210. package/src/data/domain/build-schema.ts +161 -0
  211. package/src/data/domain/build-table.ts +355 -0
  212. package/src/data/domain/define.ts +239 -0
  213. package/src/data/domain/external-registry.ts +34 -0
  214. package/src/data/domain/external.ts +77 -0
  215. package/src/data/domain/field.ts +279 -0
  216. package/src/data/domain/index.ts +13 -0
  217. package/src/data/domain/naming.ts +6 -0
  218. package/src/data/domain/projections.ts +57 -0
  219. package/src/data/domain/trace-safe-projection.ts +31 -0
  220. package/src/data/domain/traits.ts +108 -0
  221. package/src/data/domain/types.ts +289 -0
  222. package/src/data/jsonb/composed.ts +18 -0
  223. package/src/data/jsonb/index.ts +1 -0
  224. package/src/data/jsonb/namespace.ts +30 -0
  225. package/src/data/jsonb/query.ts +86 -0
  226. package/src/data/migrate/append-only-generate.ts +47 -0
  227. package/src/data/migrate/applied.ts +47 -0
  228. package/src/data/migrate/apply.ts +309 -0
  229. package/src/data/migrate/check.ts +119 -0
  230. package/src/data/migrate/diff.ts +357 -0
  231. package/src/data/migrate/door-generate.ts +130 -0
  232. package/src/data/migrate/framework-rls.ts +58 -0
  233. package/src/data/migrate/generate.ts +201 -0
  234. package/src/data/migrate/history.ts +215 -0
  235. package/src/data/migrate/index.ts +9 -0
  236. package/src/data/migrate/internal-definitions.ts +175 -0
  237. package/src/data/migrate/post-process.ts +73 -0
  238. package/src/data/migrate/pragma.ts +73 -0
  239. package/src/data/migrate/provision-framework.ts +147 -0
  240. package/src/data/migrate/rls-generate.ts +61 -0
  241. package/src/data/migrate/run.ts +124 -0
  242. package/src/data/migrate/safety.ts +167 -0
  243. package/src/data/migrate/snapshot.ts +368 -0
  244. package/src/data/migrate/sql-emit.ts +392 -0
  245. package/src/data/migrate/statements.ts +312 -0
  246. package/src/data/query/alias.ts +126 -0
  247. package/src/data/query/batch.ts +8 -0
  248. package/src/data/query/cache/core/cache.ts +78 -0
  249. package/src/data/query/cache/core/index.ts +1 -0
  250. package/src/data/query/cache/core/types.ts +29 -0
  251. package/src/data/query/cache/readme.md +230 -0
  252. package/src/data/query/casing.ts +76 -0
  253. package/src/data/query/collation.ts +11 -0
  254. package/src/data/query/column-builder.ts +370 -0
  255. package/src/data/query/column.ts +150 -0
  256. package/src/data/query/entity.ts +42 -0
  257. package/src/data/query/errors.ts +33 -0
  258. package/src/data/query/index.ts +14 -0
  259. package/src/data/query/logger.ts +47 -0
  260. package/src/data/query/operations.ts +45 -0
  261. package/src/data/query/pg-core/alias.ts +12 -0
  262. package/src/data/query/pg-core/checks.ts +32 -0
  263. package/src/data/query/pg-core/columns/all.ts +71 -0
  264. package/src/data/query/pg-core/columns/bigint.ts +110 -0
  265. package/src/data/query/pg-core/columns/bigserial.ts +128 -0
  266. package/src/data/query/pg-core/columns/boolean.ts +43 -0
  267. package/src/data/query/pg-core/columns/char.ts +85 -0
  268. package/src/data/query/pg-core/columns/cidr.ts +43 -0
  269. package/src/data/query/pg-core/columns/common.ts +366 -0
  270. package/src/data/query/pg-core/columns/custom.ts +232 -0
  271. package/src/data/query/pg-core/columns/date.common.ts +15 -0
  272. package/src/data/query/pg-core/columns/date.ts +112 -0
  273. package/src/data/query/pg-core/columns/double-precision.ts +55 -0
  274. package/src/data/query/pg-core/columns/enum.ts +201 -0
  275. package/src/data/query/pg-core/columns/index.ts +35 -0
  276. package/src/data/query/pg-core/columns/inet.ts +43 -0
  277. package/src/data/query/pg-core/columns/int.common.ts +57 -0
  278. package/src/data/query/pg-core/columns/integer.ts +53 -0
  279. package/src/data/query/pg-core/columns/interval.ts +83 -0
  280. package/src/data/query/pg-core/columns/json.ts +58 -0
  281. package/src/data/query/pg-core/columns/jsonb.ts +56 -0
  282. package/src/data/query/pg-core/columns/line.ts +117 -0
  283. package/src/data/query/pg-core/columns/macaddr.ts +43 -0
  284. package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
  285. package/src/data/query/pg-core/columns/numeric.ts +227 -0
  286. package/src/data/query/pg-core/columns/point.ts +127 -0
  287. package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
  288. package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
  289. package/src/data/query/pg-core/columns/real.ts +58 -0
  290. package/src/data/query/pg-core/columns/serial.ts +55 -0
  291. package/src/data/query/pg-core/columns/smallint.ts +53 -0
  292. package/src/data/query/pg-core/columns/smallserial.ts +60 -0
  293. package/src/data/query/pg-core/columns/text.ts +67 -0
  294. package/src/data/query/pg-core/columns/time.ts +72 -0
  295. package/src/data/query/pg-core/columns/timestamp.ts +163 -0
  296. package/src/data/query/pg-core/columns/uuid.ts +51 -0
  297. package/src/data/query/pg-core/columns/varchar.ts +89 -0
  298. package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
  299. package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
  300. package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
  301. package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
  302. package/src/data/query/pg-core/db.ts +674 -0
  303. package/src/data/query/pg-core/dialect.ts +1404 -0
  304. package/src/data/query/pg-core/expressions.ts +25 -0
  305. package/src/data/query/pg-core/foreign-keys.ts +130 -0
  306. package/src/data/query/pg-core/index.ts +21 -0
  307. package/src/data/query/pg-core/indexes.ts +276 -0
  308. package/src/data/query/pg-core/policies.ts +56 -0
  309. package/src/data/query/pg-core/primary-keys.ts +62 -0
  310. package/src/data/query/pg-core/query-builders/count.ts +86 -0
  311. package/src/data/query/pg-core/query-builders/delete.ts +293 -0
  312. package/src/data/query/pg-core/query-builders/index.ts +7 -0
  313. package/src/data/query/pg-core/query-builders/insert.ts +452 -0
  314. package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
  315. package/src/data/query/pg-core/query-builders/query.ts +157 -0
  316. package/src/data/query/pg-core/query-builders/raw.ts +49 -0
  317. package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
  318. package/src/data/query/pg-core/query-builders/select.ts +1346 -0
  319. package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
  320. package/src/data/query/pg-core/query-builders/update.ts +626 -0
  321. package/src/data/query/pg-core/roles.ts +41 -0
  322. package/src/data/query/pg-core/schema.ts +72 -0
  323. package/src/data/query/pg-core/sequence.ts +41 -0
  324. package/src/data/query/pg-core/session.ts +292 -0
  325. package/src/data/query/pg-core/subquery.ts +46 -0
  326. package/src/data/query/pg-core/table.ts +252 -0
  327. package/src/data/query/pg-core/unique-constraint.ts +73 -0
  328. package/src/data/query/pg-core/utils/array.ts +95 -0
  329. package/src/data/query/pg-core/utils/index.ts +1 -0
  330. package/src/data/query/pg-core/utils.ts +104 -0
  331. package/src/data/query/pg-core/view-base.ts +14 -0
  332. package/src/data/query/pg-core/view-common.ts +1 -0
  333. package/src/data/query/pg-core/view.ts +435 -0
  334. package/src/data/query/pg-core/with-builder.ts +41 -0
  335. package/src/data/query/postgres-js/README.md +46 -0
  336. package/src/data/query/postgres-js/array-parser.ts +45 -0
  337. package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
  338. package/src/data/query/postgres-js/driver.ts +163 -0
  339. package/src/data/query/postgres-js/index.ts +2 -0
  340. package/src/data/query/postgres-js/session.ts +234 -0
  341. package/src/data/query/primary-key.ts +11 -0
  342. package/src/data/query/query-builders/query-builder.ts +19 -0
  343. package/src/data/query/query-builders/select.types.ts +175 -0
  344. package/src/data/query/query-promise.ts +35 -0
  345. package/src/data/query/relations.ts +725 -0
  346. package/src/data/query/runnable-query.ts +12 -0
  347. package/src/data/query/selection-proxy.ts +121 -0
  348. package/src/data/query/session.ts +8 -0
  349. package/src/data/query/sql/expressions/conditions.ts +741 -0
  350. package/src/data/query/sql/expressions/index.ts +2 -0
  351. package/src/data/query/sql/expressions/select.ts +45 -0
  352. package/src/data/query/sql/functions/aggregate.ts +129 -0
  353. package/src/data/query/sql/functions/index.ts +2 -0
  354. package/src/data/query/sql/functions/vector.ts +178 -0
  355. package/src/data/query/sql/index.ts +3 -0
  356. package/src/data/query/sql/sql.ts +794 -0
  357. package/src/data/query/subquery.ts +53 -0
  358. package/src/data/query/table.ts +208 -0
  359. package/src/data/query/table.utils.ts +2 -0
  360. package/src/data/query/tracing-utils.ts +3 -0
  361. package/src/data/query/tracing.ts +11 -0
  362. package/src/data/query/utils.ts +357 -0
  363. package/src/data/query/version.ts +4 -0
  364. package/src/data/query/view-common.ts +1 -0
  365. package/src/data/schema/branded.ts +13 -0
  366. package/src/data/schema/generated/coerce.ts +5 -0
  367. package/src/data/schema/generated/combinator.ts +6 -0
  368. package/src/data/schema/generated/encoding.ts +5 -0
  369. package/src/data/schema/generated/error.ts +6 -0
  370. package/src/data/schema/generated/format.ts +5 -0
  371. package/src/data/schema/generated/type-constructor.ts +10 -0
  372. package/src/data/schema/generated/type.ts +6 -0
  373. package/src/data/schema/index.ts +6 -0
  374. package/src/data/schema/json-schema.ts +33 -0
  375. package/src/data/schema/namespace.ts +55 -0
  376. package/src/data/schema/parse.ts +39 -0
  377. package/src/data/schema/types.ts +39 -0
  378. package/src/data/temporal/append-only.ts +134 -0
  379. package/src/data/temporal/close.ts +27 -0
  380. package/src/data/temporal/columns.ts +10 -0
  381. package/src/data/temporal/definition-queries.ts +70 -0
  382. package/src/data/temporal/errors.ts +10 -0
  383. package/src/data/temporal/get-current.ts +22 -0
  384. package/src/data/temporal/index.ts +9 -0
  385. package/src/data/temporal/namespace.ts +36 -0
  386. package/src/data/temporal/query.ts +25 -0
  387. package/src/data/temporal/resolve.ts +17 -0
  388. package/src/data/temporal/revise.ts +67 -0
  389. package/src/data/temporal/types.ts +22 -0
  390. package/src/data/valve/artifact.ts +33 -0
  391. package/src/data/valve/contract-diff.ts +21 -0
  392. package/src/data/valve/cross.ts +57 -0
  393. package/src/data/valve/crossing-ledger.ts +50 -0
  394. package/src/data/valve/decision.ts +44 -0
  395. package/src/data/valve/durable-crossing.ts +52 -0
  396. package/src/data/valve/execute-crossing.ts +77 -0
  397. package/src/data/valve/faucet.ts +56 -0
  398. package/src/data/valve/gate.ts +114 -0
  399. package/src/data/valve/graph.ts +77 -0
  400. package/src/data/valve/index.ts +53 -0
  401. package/src/data/valve/namespace.ts +57 -0
  402. package/src/data/valve/registry.ts +50 -0
  403. package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
  404. package/src/data/valve/schema/valve-crossing.ts +9 -0
  405. package/src/data/valve/supply.ts +154 -0
  406. package/src/data/valve/types.ts +143 -0
  407. package/src/data/vector/columns.ts +27 -0
  408. package/src/data/vector/index.ts +4 -0
  409. package/src/data/vector/namespace.ts +33 -0
  410. package/src/data/vector/query.ts +85 -0
  411. package/src/data/vector/validate.ts +16 -0
  412. package/src/data/write/audit/actor.ts +15 -0
  413. package/src/data/write/audit/audit-columns.ts +18 -0
  414. package/src/data/write/audit/audit-select.ts +111 -0
  415. package/src/data/write/audit/bound-transaction.ts +14 -0
  416. package/src/data/write/audit/cte-compile.ts +32 -0
  417. package/src/data/write/audit/decode-returning.ts +47 -0
  418. package/src/data/write/audit/final-select.ts +43 -0
  419. package/src/data/write/audit/infra-audit.ts +36 -0
  420. package/src/data/write/audit/primary-key.ts +65 -0
  421. package/src/data/write/audit/projection.ts +41 -0
  422. package/src/data/write/audit/read-touches.ts +86 -0
  423. package/src/data/write/audit/touch-match.ts +78 -0
  424. package/src/data/write/audit/verb-delete.ts +62 -0
  425. package/src/data/write/audit/verb-insert.ts +36 -0
  426. package/src/data/write/audit/verb-select.ts +47 -0
  427. package/src/data/write/audit/verb-update.ts +60 -0
  428. package/src/data/write/audit/verb-upsert.ts +104 -0
  429. package/src/data/write/conflict.ts +43 -0
  430. package/src/data/write/delete.ts +38 -0
  431. package/src/data/write/execute.ts +243 -0
  432. package/src/data/write/index.ts +11 -0
  433. package/src/data/write/insert.ts +63 -0
  434. package/src/data/write/state.ts +43 -0
  435. package/src/data/write/update.ts +54 -0
  436. package/src/data/write/upsert.ts +58 -0
  437. package/src/data/write/values.ts +19 -0
  438. package/src/index.ts +230 -0
  439. package/src/infra/access-links/code.ts +70 -0
  440. package/src/infra/access-links/handle.ts +892 -0
  441. package/src/infra/access-links/index.ts +9 -0
  442. package/src/infra/access-links/namespace.ts +30 -0
  443. package/src/infra/access-links/person-check.ts +177 -0
  444. package/src/infra/access-links/schema.ts +71 -0
  445. package/src/infra/alerts/async-sources.ts +231 -0
  446. package/src/infra/alerts/audit.ts +36 -0
  447. package/src/infra/alerts/beat.ts +123 -0
  448. package/src/infra/alerts/client-faults.ts +111 -0
  449. package/src/infra/alerts/faults.ts +156 -0
  450. package/src/infra/alerts/handle.ts +778 -0
  451. package/src/infra/alerts/http.ts +192 -0
  452. package/src/infra/alerts/index.ts +12 -0
  453. package/src/infra/alerts/infra-sources.ts +180 -0
  454. package/src/infra/alerts/namespace.ts +81 -0
  455. package/src/infra/alerts/redact.ts +21 -0
  456. package/src/infra/alerts/request-faults.ts +41 -0
  457. package/src/infra/alerts/schema.ts +124 -0
  458. package/src/infra/alerts/sinks.ts +125 -0
  459. package/src/infra/alerts/source-options.ts +26 -0
  460. package/src/infra/alerts/sources.ts +503 -0
  461. package/src/infra/alerts/subsystem-sources.ts +137 -0
  462. package/src/infra/audit/emit.ts +87 -0
  463. package/src/infra/audit/index.ts +2 -0
  464. package/src/infra/audit/namespace.ts +22 -0
  465. package/src/infra/audit/schema.sql +35 -0
  466. package/src/infra/audit/types.ts +18 -0
  467. package/src/infra/aws/credentials.ts +147 -0
  468. package/src/infra/aws/sigv4.ts +140 -0
  469. package/src/infra/cache/create.ts +58 -0
  470. package/src/infra/cache/entry.ts +81 -0
  471. package/src/infra/cache/index.ts +4 -0
  472. package/src/infra/cache/namespace.ts +10 -0
  473. package/src/infra/cache/tenant.ts +93 -0
  474. package/src/infra/cache/types.ts +24 -0
  475. package/src/infra/crawl/audit.ts +35 -0
  476. package/src/infra/crawl/errors.ts +25 -0
  477. package/src/infra/crawl/handle.ts +693 -0
  478. package/src/infra/crawl/index.ts +9 -0
  479. package/src/infra/crawl/links.ts +160 -0
  480. package/src/infra/crawl/namespace.ts +36 -0
  481. package/src/infra/crawl/robots.ts +100 -0
  482. package/src/infra/crawl/schema.ts +89 -0
  483. package/src/infra/credit-line/handle.ts +883 -0
  484. package/src/infra/credit-line/index.ts +6 -0
  485. package/src/infra/credit-line/namespace.ts +7 -0
  486. package/src/infra/credit-line/schema.ts +96 -0
  487. package/src/infra/credits/handle.ts +706 -0
  488. package/src/infra/credits/index.ts +5 -0
  489. package/src/infra/credits/namespace.ts +7 -0
  490. package/src/infra/credits/schema.ts +83 -0
  491. package/src/infra/email/audit.ts +36 -0
  492. package/src/infra/email/inbound.ts +622 -0
  493. package/src/infra/email/index.ts +11 -0
  494. package/src/infra/email/mail.ts +517 -0
  495. package/src/infra/email/mime.ts +447 -0
  496. package/src/infra/email/namespace.ts +22 -0
  497. package/src/infra/email/providers.ts +111 -0
  498. package/src/infra/email/schema.ts +96 -0
  499. package/src/infra/email/sns.ts +200 -0
  500. package/src/infra/email/unsubscribe.ts +44 -0
  501. package/src/infra/fetch/address.ts +88 -0
  502. package/src/infra/fetch/connect-retry.ts +87 -0
  503. package/src/infra/fetch/handle.ts +329 -0
  504. package/src/infra/fetch/index.ts +7 -0
  505. package/src/infra/fetch/namespace.ts +70 -0
  506. package/src/infra/idempotency/index.ts +3 -0
  507. package/src/infra/idempotency/middleware.ts +87 -0
  508. package/src/infra/idempotency/store.ts +92 -0
  509. package/src/infra/idempotency/types.ts +30 -0
  510. package/src/infra/join-requests/handle.ts +312 -0
  511. package/src/infra/join-requests/index.ts +2 -0
  512. package/src/infra/join-requests/namespace.ts +7 -0
  513. package/src/infra/join-requests/schema.ts +33 -0
  514. package/src/infra/outbox/core.ts +165 -0
  515. package/src/infra/quota/errors.ts +32 -0
  516. package/src/infra/quota/handle.ts +215 -0
  517. package/src/infra/quota/index.ts +5 -0
  518. package/src/infra/quota/namespace.ts +7 -0
  519. package/src/infra/quota/schema.ts +15 -0
  520. package/src/infra/storage/backend.ts +34 -0
  521. package/src/infra/storage/handle.ts +513 -0
  522. package/src/infra/storage/index.ts +9 -0
  523. package/src/infra/storage/local.ts +104 -0
  524. package/src/infra/storage/namespace.ts +13 -0
  525. package/src/infra/storage/s3.ts +257 -0
  526. package/src/infra/storage/schema.ts +24 -0
  527. package/src/infra/support/handle.ts +854 -0
  528. package/src/infra/support/http.ts +229 -0
  529. package/src/infra/support/index.ts +7 -0
  530. package/src/infra/support/namespace.ts +12 -0
  531. package/src/infra/support/schema.ts +96 -0
  532. package/src/infra/webhook/inbound.ts +45 -0
  533. package/src/infra/webhook/index.ts +5 -0
  534. package/src/infra/webhook/namespace.ts +24 -0
  535. package/src/infra/webhook/outbound.ts +315 -0
  536. package/src/infra/webhook/sign.ts +32 -0
  537. package/src/infra/webhook/verify.ts +82 -0
  538. package/src/invariants/assert.ts +26 -0
  539. package/src/invariants/index.ts +1 -0
  540. package/src/lint/config.ts +56 -0
  541. package/src/lint/doctrine.ts +163 -0
  542. package/src/lint/include.ts +97 -0
  543. package/src/lint/index.ts +3 -0
  544. package/src/lint/preset.ts +10 -0
  545. package/src/lint/resolver.ts +218 -0
  546. package/src/lint/rules/no-reexports.ts +46 -0
  547. package/src/request/behavior/audited.ts +85 -0
  548. package/src/request/behavior/cached.ts +62 -0
  549. package/src/request/behavior/compose.ts +28 -0
  550. package/src/request/behavior/index.ts +5 -0
  551. package/src/request/behavior/namespace.ts +16 -0
  552. package/src/request/behavior/types.ts +26 -0
  553. package/src/request/behavior/versioned.ts +54 -0
  554. package/src/request/context/create.ts +103 -0
  555. package/src/request/context/guard.ts +49 -0
  556. package/src/request/context/index.ts +4 -0
  557. package/src/request/context/run-in-transaction.ts +200 -0
  558. package/src/request/context/store.ts +28 -0
  559. package/src/request/context/types.ts +50 -0
  560. package/src/request/di/builder.ts +535 -0
  561. package/src/request/di/index.ts +8 -0
  562. package/src/request/di/resolve.ts +271 -0
  563. package/src/request/di/types.ts +262 -0
  564. package/src/request/fitting/namespace.ts +7 -0
  565. package/src/request/fixture/batch.ts +71 -0
  566. package/src/request/fixture/builder.ts +26 -0
  567. package/src/request/fixture/errors.ts +10 -0
  568. package/src/request/fixture/index.ts +8 -0
  569. package/src/request/fixture/namespace.ts +23 -0
  570. package/src/request/fixture/paginate.ts +44 -0
  571. package/src/request/fixture/to-handlers.ts +260 -0
  572. package/src/request/fixture/types.ts +79 -0
  573. package/src/request/flow/act-as.ts +78 -0
  574. package/src/request/flow/namespace.ts +17 -0
  575. package/src/request/http/error-step.ts +42 -0
  576. package/src/request/http/file.ts +141 -0
  577. package/src/request/http/index.ts +4 -0
  578. package/src/request/http/middleware.ts +141 -0
  579. package/src/request/http/namespace.ts +5 -0
  580. package/src/request/http/rate-limit-classes.ts +170 -0
  581. package/src/request/http/response.ts +82 -0
  582. package/src/request/http/server.ts +916 -0
  583. package/src/request/http/sniff.ts +261 -0
  584. package/src/request/http/types.ts +250 -0
  585. package/src/request/http/upload.ts +284 -0
  586. package/src/request/internal/text.ts +6 -0
  587. package/src/request/openapi/generate.ts +205 -0
  588. package/src/request/openapi/index.ts +2 -0
  589. package/src/request/openapi/namespace.ts +7 -0
  590. package/src/test/auth.ts +13 -0
  591. package/src/test/auto-setup.ts +45 -0
  592. package/src/test/context.ts +91 -0
  593. package/src/test/crawl-fixture.ts +157 -0
  594. package/src/test/discover-fork.ts +17 -0
  595. package/src/test/fingerprint.ts +135 -0
  596. package/src/test/globals.d.ts +7 -0
  597. package/src/test/index.ts +19 -0
  598. package/src/test/namespace.ts +87 -0
  599. package/src/test/plugin.ts +189 -0
  600. package/src/test/progress.ts +185 -0
  601. package/src/test/reap-after-run.ts +28 -0
  602. package/src/test/reap.ts +286 -0
  603. package/src/test/reset.ts +253 -0
  604. package/src/test/savepoints.ts +172 -0
  605. package/src/test/setup.ts +1422 -0
  606. package/src/test/system-channel.ts +50 -0
  607. package/src/test/vitest-plugin.ts +142 -0
  608. package/src/test/vitest-workspace.ts +507 -0
  609. package/src/test/vitest.ts +333 -0
  610. package/src/test/watch.ts +105 -0
  611. package/src/trace/capture/bounded-serializer.ts +146 -0
  612. package/src/trace/cardinality/analyze.ts +173 -0
  613. package/src/trace/cardinality/branch-context.ts +214 -0
  614. package/src/trace/cardinality/check.ts +33 -0
  615. package/src/trace/cardinality/classify-edge.ts +64 -0
  616. package/src/trace/cardinality/structural-max.ts +107 -0
  617. package/src/trace/check/coverage-check.ts +188 -0
  618. package/src/trace/check/flow-check.ts +103 -0
  619. package/src/trace/check/flow-step-site.ts +234 -0
  620. package/src/trace/check/io-pattern.ts +116 -0
  621. package/src/trace/codemod/add-cardinality.ts +152 -0
  622. package/src/trace/codemod/run.ts +80 -0
  623. package/src/trace/entry/child-trace.ts +21 -0
  624. package/src/trace/entry/close-trace.ts +87 -0
  625. package/src/trace/entry/finalize-trace.ts +28 -0
  626. package/src/trace/entry/open-trace.ts +138 -0
  627. package/src/trace/entry/parent-trace.ts +20 -0
  628. package/src/trace/entry/parse-traceparent.ts +39 -0
  629. package/src/trace/entry/process-start.ts +38 -0
  630. package/src/trace/entry/trace-context.ts +26 -0
  631. package/src/trace/entry/tracing-enabled.ts +10 -0
  632. package/src/trace/external/record.ts +195 -0
  633. package/src/trace/external/report.ts +66 -0
  634. package/src/trace/namespace.ts +19 -0
  635. package/src/trace/partition/day.ts +47 -0
  636. package/src/trace/partition/index.ts +14 -0
  637. package/src/trace/partition/partition-name.ts +23 -0
  638. package/src/trace/partition/plan.ts +82 -0
  639. package/src/trace/partition/schedule.ts +26 -0
  640. package/src/trace/partition/startup-hook.ts +39 -0
  641. package/src/trace/partition/sync.ts +154 -0
  642. package/src/trace/partition/tables.ts +53 -0
  643. package/src/trace/read/tree.ts +83 -0
  644. package/src/trace/retain/copy-on-error.ts +76 -0
  645. package/src/trace/runtime/expire-stale-traces.ts +54 -0
  646. package/src/trace/runtime/flow-step.ts +147 -0
  647. package/src/trace/runtime/flush-steps.ts +31 -0
  648. package/src/trace/runtime/pending-writes.ts +54 -0
  649. package/src/trace/runtime/step-buffer.ts +298 -0
  650. package/src/trace/runtime/step-error.ts +21 -0
  651. package/src/trace/runtime/step-meta.ts +55 -0
  652. package/src/trace/runtime/thenable.ts +12 -0
  653. package/src/trace/runtime/truncate-trace.ts +62 -0
  654. package/src/trace/schema/trace-fields.ts +52 -0
  655. package/src/trace/schema/trace-retained.ts +22 -0
  656. package/src/trace/schema/trace-step-fields.ts +44 -0
  657. package/src/trace/schema/trace-step-retained.ts +25 -0
  658. package/src/trace/schema/trace-step.ts +18 -0
  659. package/src/trace/schema/trace.ts +12 -0
  660. package/src/trace/transformer/apply.ts +79 -0
  661. package/src/trace/transformer/build-meta-literal.ts +30 -0
  662. package/src/trace/transformer/find-flow-step-sites.ts +85 -0
  663. package/src/trace/transformer/inject-flow-step-import.ts +39 -0
  664. package/src/trace/transformer/transform-error.ts +14 -0
  665. package/src/trace/transformer/transform-flow-steps.ts +123 -0
  666. package/src/trace/transformer/wrap-function-declaration.ts +62 -0
  667. package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
  668. package/src/workspace/affected.ts +110 -0
  669. package/src/workspace/changed-files.ts +163 -0
  670. package/src/workspace/check-deps.ts +213 -0
  671. package/src/workspace/checksum.ts +20 -0
  672. package/src/workspace/dependency-graph.ts +67 -0
  673. package/src/workspace/detect-pipework-copies.ts +93 -0
  674. package/src/workspace/discover.ts +206 -0
  675. package/src/workspace/generate.ts +401 -0
  676. package/src/workspace/index.ts +7 -0
  677. package/src/workspace/module-imports-pipework.ts +39 -0
  678. package/src/workspace/module-package-name.ts +12 -0
  679. package/src/workspace/scrub-git-env.ts +23 -0
  680. package/src/workspace/source-paths.ts +36 -0
  681. package/src/workspace/sync.ts +182 -0
  682. package/dist/REFERENCE.md +0 -1477
  683. package/dist/infra/access-links/rate-limit.d.ts +0 -10
  684. package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
  685. package/dist/infra/access-links/rate-limit.js +0 -28
  686. package/dist/infra/access-links/rate-limit.js.map +0 -1
  687. package/dist/infra/email/sigv4.d.ts +0 -24
  688. package/dist/infra/email/sigv4.d.ts.map +0 -1
  689. package/dist/infra/email/sigv4.js +0 -55
  690. package/dist/infra/email/sigv4.js.map +0 -1
@@ -0,0 +1,101 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { readFile } from 'node:fs/promises'
3
+ import { fileURLToPath } from 'node:url'
4
+ import { stripTypeScriptTypes } from 'node:module'
5
+
6
+ // ESM loader hooks — run on a separate thread, so this file must be
7
+ // self-contained: no static imports from the rest of pipework. The one
8
+ // exception is `load`, which dynamically imports the flow-step transformer
9
+ // (`../../trace/transformer/apply.js`) only for a file that mentions `@flow_step`.
10
+ //
11
+ // `resolve` rewrites a relative specifier to the TS file that actually backs
12
+ // it (.js→.ts, and extensionless bundler-style imports); `load` fully transpiles
13
+ // that TS — parameter properties, enums, namespaces and all — which
14
+ // `--experimental-strip-types` cannot do. Together they let `pipework dev` and
15
+ // config discovery run a consumer's real TypeScript source unbuilt.
16
+ //
17
+ // Mirrors the inline hook in `registerTsResolveHooks()` (discover.ts) for
18
+ // `resolve` and for TS stripping. They stay separate on purpose: that one
19
+ // registers a self-contained `data:` URL so it works during pipework's own
20
+ // source-mode runs where this compiled `.js` file does not exist yet, and it
21
+ // skips the `@flow_step` transform because config discovery has no steps; this
22
+ // one is a real file loaded via `--import` into child processes (`pipework
23
+ // dev`/`serve`), so it can reach the compiled transformer by relative URL.
24
+ // Keep the `resolve` and strip logic of BOTH hooks in sync.
25
+ //
26
+ // The `.ts` candidate must exist on disk before we rewrite. `nextResolve` does
27
+ // not touch the filesystem for file: URLs, so a missing file is not caught by a
28
+ // try/catch — it surfaces later as a misleading "Cannot find module foo.ts" at
29
+ // load time, even when foo.js sits right there (issue #292).
30
+ export function resolve(
31
+ specifier: string,
32
+ context: { parentURL?: string },
33
+ nextResolve: (specifier: string, context: { parentURL?: string }) => { url: string },
34
+ ): { url: string } {
35
+ const parent = context.parentURL ?? ''
36
+ const isLocal = (specifier.startsWith('./') || specifier.startsWith('../'))
37
+ && !parent.includes('/node_modules/') && !parent.includes('/dist/')
38
+ if (isLocal) {
39
+ for (const candidate of tsCandidates(specifier)) {
40
+ let candidatePath: string | null = null
41
+ try {
42
+ const url = new URL(candidate, parent)
43
+ if (url.protocol === 'file:') candidatePath = fileURLToPath(url)
44
+ } catch {
45
+ // candidate did not form a valid URL — try the next one.
46
+ }
47
+ if (candidatePath !== null && existsSync(candidatePath)) {
48
+ return nextResolve(candidate, context)
49
+ }
50
+ }
51
+ }
52
+ return nextResolve(specifier, context)
53
+ }
54
+
55
+ // Ordered resolution candidates for a relative specifier authored in TS source.
56
+ // - `./foo.js` → `./foo.ts` (NodeNext style: import the emit name)
57
+ // - `./foo` → .ts, .js, /index.ts, /index.js (bundler-style extensionless)
58
+ // - `./foo.ts` → [] (already explicit — let the host resolve)
59
+ // The caller probes each in order and rewrites to the first that exists on disk.
60
+ function tsCandidates(specifier: string): string[] {
61
+ const jsMatch = specifier.match(/\.([cm]?)js$/)
62
+ if (jsMatch !== null) {
63
+ return [specifier.slice(0, -jsMatch[0].length) + '.' + (jsMatch[1] ?? '') + 'ts']
64
+ }
65
+ if (/\.[cm]?tsx?$/.test(specifier)) return []
66
+ return [specifier + '.ts', specifier + '.js', specifier + '/index.ts', specifier + '/index.js']
67
+ }
68
+
69
+ interface LoadResult {
70
+ format: string
71
+ source?: string | ArrayBuffer | NodeJS.TypedArray
72
+ shortCircuit?: boolean
73
+ }
74
+
75
+ // Installed by ts-register.js, which marks globalThis[Symbol.for('pipework.tsHooks')]
76
+ // so discovery's inline hook (ts-inline-hooks.ts) is not registered over it.
77
+ // `--experimental-strip-types` only erases annotations — it cannot emit the
78
+ // runtime code that parameter properties, enums, or namespaces require, and it
79
+ // rejects them outright (ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX). This `load` hook
80
+ // does the full transform via Node's bundled `stripTypeScriptTypes` (amaro)
81
+ // instead, so consumer TS using any of those features loads cleanly. Only
82
+ // consumer source is transformed — pipework's own published code is compiled
83
+ // `.js` and node_modules is left to the host loader.
84
+ export async function load(
85
+ url: string,
86
+ context: { format?: string | null | undefined },
87
+ nextLoad: (url: string, context: { format?: string | null | undefined }) => LoadResult | Promise<LoadResult>,
88
+ ): Promise<LoadResult> {
89
+ if (url.endsWith('.ts') && !url.includes('/node_modules/')) {
90
+ let source = await readFile(fileURLToPath(url), 'utf8')
91
+ if (source.includes('@flow_step')) {
92
+ const { applyFlowStepTransform } = await import('../../trace/transformer/apply.js')
93
+ const applied = applyFlowStepTransform(source, fileURLToPath(url))
94
+ if (applied !== null) source = applied.code
95
+ }
96
+ const code = stripTypeScriptTypes(source, { mode: 'transform', sourceMap: true, sourceUrl: url })
97
+ return { format: 'module', source: code, shortCircuit: true }
98
+ }
99
+ return nextLoad(url, context)
100
+ }
101
+
@@ -0,0 +1,49 @@
1
+ // Cross-realm brand. The HTTP error mapper must recognize a PipeworkError thrown by a
2
+ // shared leaf library that resolved a DIFFERENT physical copy of pipework — where the
3
+ // two PipeworkError class objects are distinct and `instanceof` is false. A global
4
+ // Symbol survives the realm boundary (the same pattern drizzle uses for entityKind),
5
+ // so identity is keyed on the brand, never on the constructor.
6
+ // Stryker disable next-line StringLiteral: static module-init constant; ignoreStatic makes the mutant
7
+ // unreachable. Behavior is covered by tests/errors/brand.test.ts (cross-realm brand identity).
8
+ const PIPEWORK_ERROR = Symbol.for('pipework.error')
9
+
10
+ export abstract class PipeworkError extends Error {
11
+ abstract readonly code: string
12
+ abstract readonly httpStatus: number
13
+ readonly details: Record<string, unknown>
14
+
15
+ constructor(message: string, details: Record<string, unknown> = {}) {
16
+ super(message)
17
+ this.name = this.constructor.name
18
+ this.details = details
19
+ Object.defineProperty(this, PIPEWORK_ERROR, { value: true, enumerable: false })
20
+ }
21
+
22
+ // The brand is the identity across physical copies of pipework: a branded error is an
23
+ // instance of the class its prototype chain names, whichever copy constructed it.
24
+ static override [Symbol.hasInstance](value: unknown): boolean {
25
+ if (Function.prototype[Symbol.hasInstance].call(this, value)) return true
26
+ if (!isPipeworkError(value)) return false
27
+ if (this === PipeworkError) return true
28
+ for (let proto: unknown = Object.getPrototypeOf(value); proto !== null; proto = Object.getPrototypeOf(proto)) {
29
+ if ((proto as { constructor?: { name?: unknown } }).constructor?.name === this.name) return true
30
+ }
31
+ return false
32
+ }
33
+ }
34
+
35
+ /**
36
+ * True for any PipeworkError, including one thrown across a module-realm boundary
37
+ * (a shared library that resolved its own copy of pipework). Use this instead of
38
+ * `instanceof PipeworkError` anywhere an error may cross such a boundary — `instanceof`
39
+ * silently fails there, mapping a 403/401 to a generic 500.
40
+ */
41
+ export function isPipeworkError(error: unknown): error is PipeworkError {
42
+ return (
43
+ typeof error === 'object' &&
44
+ error !== null &&
45
+ (error as Record<symbol, unknown>)[PIPEWORK_ERROR] === true &&
46
+ typeof (error as { httpStatus?: unknown }).httpStatus === 'number' &&
47
+ typeof (error as { code?: unknown }).code === 'string'
48
+ )
49
+ }
@@ -0,0 +1,146 @@
1
+ import { PipeworkError } from './base.js'
2
+
3
+ export class NotFoundError extends PipeworkError {
4
+ readonly code = 'NOT_FOUND' as const
5
+ readonly httpStatus = 404 as const
6
+
7
+ constructor(resource: string, details: Record<string, unknown> = {}) {
8
+ super(`${resource} not found`, details)
9
+ }
10
+ }
11
+
12
+ export class UnauthorizedError extends PipeworkError {
13
+ readonly code = 'UNAUTHORIZED' as const
14
+ readonly httpStatus = 401 as const
15
+
16
+ constructor(message: string = 'Authentication required', details: Record<string, unknown> = {}) {
17
+ super(message, details)
18
+ }
19
+ }
20
+
21
+ export class ForbiddenError extends PipeworkError {
22
+ readonly code = 'FORBIDDEN' as const
23
+ readonly httpStatus = 403 as const
24
+
25
+ constructor(message: string = 'Insufficient permissions', details: Record<string, unknown> = {}) {
26
+ super(message, details)
27
+ }
28
+ }
29
+
30
+ export class CrossSiteRequestError extends PipeworkError {
31
+ readonly code = 'CROSS_SITE_REQUEST' as const
32
+ readonly httpStatus = 403 as const
33
+
34
+ constructor(
35
+ message: string = 'A request authenticated by a cookie must come from the app\'s own site.',
36
+ details: Record<string, unknown> = {},
37
+ ) {
38
+ super(message, details)
39
+ }
40
+ }
41
+
42
+ /** Where the failing input came from: the request parts a route validates, or the handler's own response. */
43
+ export type ValidationSource = 'body' | 'query' | 'params' | 'headers' | 'response'
44
+
45
+ /** One failed check: the path to the field (empty for the root) and the schema's message. Never the input value. */
46
+ export interface ValidationFieldIssue {
47
+ readonly source: ValidationSource | null
48
+ readonly path: readonly string[]
49
+ readonly message: string
50
+ }
51
+
52
+ export class ValidationError extends PipeworkError {
53
+ readonly code = 'VALIDATION_ERROR' as const
54
+ readonly httpStatus = 422 as const
55
+ readonly fieldErrors: Readonly<Record<string, readonly string[]>>
56
+ /** The part of the request that failed, when a schema check threw this; null for an error raised by hand. */
57
+ readonly source: ValidationSource | null
58
+ readonly issues: readonly ValidationFieldIssue[]
59
+
60
+ constructor(message: string)
61
+ constructor(fieldErrors: Record<string, readonly string[]>, message?: string, detail?: { source: ValidationSource; paths: ReadonlyArray<{ path: readonly string[]; message: string }> })
62
+ constructor(fieldErrorsOrMessage: Record<string, readonly string[]> | string, message?: string, detail?: { source: ValidationSource; paths: ReadonlyArray<{ path: readonly string[]; message: string }> }) {
63
+ if (typeof fieldErrorsOrMessage === 'string') {
64
+ super(fieldErrorsOrMessage, { fieldErrors: {} })
65
+ this.fieldErrors = {}
66
+ this.source = null
67
+ this.issues = []
68
+ } else {
69
+ const msg = message ?? 'Invalid input'
70
+ super(msg, { fieldErrors: fieldErrorsOrMessage })
71
+ this.fieldErrors = fieldErrorsOrMessage
72
+ this.source = detail?.source ?? null
73
+ this.issues = detail !== undefined
74
+ ? detail.paths.map(p => ({ source: detail.source, path: p.path, message: p.message }))
75
+ : Object.entries(fieldErrorsOrMessage).flatMap(([key, messages]) =>
76
+ messages.map(m => ({ source: null, path: key === '_root' ? [] : key.split('.'), message: m })))
77
+ }
78
+ }
79
+ }
80
+
81
+ export class TooManyRequestsError extends PipeworkError {
82
+ readonly code = 'TOO_MANY_REQUESTS' as const
83
+ readonly httpStatus = 429 as const
84
+ readonly retryAfterSeconds: number
85
+
86
+ constructor(retryAfterSeconds: number, message: string = 'Too many attempts. Try again later.') {
87
+ super(message, { retryAfterSeconds })
88
+ this.retryAfterSeconds = retryAfterSeconds
89
+ }
90
+ }
91
+
92
+ export class ConflictError extends PipeworkError {
93
+ readonly code = 'CONFLICT' as const
94
+ readonly httpStatus = 409 as const
95
+
96
+ constructor(message: string, details: Record<string, unknown> = {}) {
97
+ super(message, details)
98
+ }
99
+ }
100
+
101
+
102
+ export class PayloadTooLargeError extends PipeworkError {
103
+ readonly code = 'PAYLOAD_TOO_LARGE' as const
104
+ readonly httpStatus = 413 as const
105
+
106
+ constructor(message: string = 'Request body too large', details: Record<string, unknown> = {}) {
107
+ super(message, details)
108
+ }
109
+ }
110
+
111
+ export class UnsupportedMediaTypeError extends PipeworkError {
112
+ readonly code = 'UNSUPPORTED_MEDIA_TYPE' as const
113
+ readonly httpStatus = 415 as const
114
+
115
+ constructor(message: string = 'Unsupported media type', details: Record<string, unknown> = {}) {
116
+ super(message, details)
117
+ }
118
+ }
119
+
120
+ export class MalformedMultipartError extends PipeworkError {
121
+ readonly code = 'MALFORMED_MULTIPART' as const
122
+ readonly httpStatus = 400 as const
123
+
124
+ constructor(message: string = 'The multipart body is malformed or ends before its closing boundary', details: Record<string, unknown> = {}) {
125
+ super(message, details)
126
+ }
127
+ }
128
+
129
+ export class AuthConfigurationError extends PipeworkError {
130
+ readonly code = 'AUTH_CONFIGURATION' as const
131
+ readonly httpStatus = 500 as const
132
+
133
+ constructor(message: string, details: Record<string, unknown> = {}) {
134
+ super(message, details)
135
+ }
136
+ }
137
+
138
+ export class AuthUnavailableError extends PipeworkError {
139
+ readonly code = 'AUTH_UNAVAILABLE' as const
140
+ readonly httpStatus = 503 as const
141
+
142
+ constructor(message: string, options: { cause?: unknown; details?: Record<string, unknown> } = {}) {
143
+ super(message, options.details ?? {})
144
+ if (options.cause !== undefined) this.cause = options.cause
145
+ }
146
+ }
@@ -0,0 +1,2 @@
1
+ export { PipeworkError, isPipeworkError } from './base.js'
2
+ export { NotFoundError, UnauthorizedError, ForbiddenError, CrossSiteRequestError, AuthConfigurationError, AuthUnavailableError, ValidationError, type ValidationSource, type ValidationFieldIssue, ConflictError, TooManyRequestsError, PayloadTooLargeError, UnsupportedMediaTypeError, MalformedMultipartError } from './http.js'
@@ -0,0 +1,31 @@
1
+ import { PipeworkError, NotFoundError, UnauthorizedError, ForbiddenError, CrossSiteRequestError, AuthConfigurationError, AuthUnavailableError, ValidationError, ConflictError, TooManyRequestsError, PayloadTooLargeError, UnsupportedMediaTypeError, MalformedMultipartError } from './index.js'
2
+
3
+ /** Standard error classes — all extend PipeworkError with structured error codes and actionable messages. */
4
+ export const errors = {
5
+ /** Base error class with code, statusCode, and suggestion fields. */
6
+ Base: PipeworkError,
7
+ /** 404 — resource not found. */
8
+ NotFound: NotFoundError,
9
+ /** 401 — missing or invalid authentication. */
10
+ Unauthorized: UnauthorizedError,
11
+ /** 403 — authenticated but insufficient permissions. */
12
+ Forbidden: ForbiddenError,
13
+ /** 403 `CROSS_SITE_REQUEST` — a cookie-authenticated request that did not come from the app's own site. */
14
+ CrossSiteRequest: CrossSiteRequestError,
15
+ /** 500 `AUTH_CONFIGURATION` — the auth setup itself is faulty (a signing key that will not load); never a refusal of the caller. */
16
+ AuthConfiguration: AuthConfigurationError,
17
+ /** 503 `AUTH_UNAVAILABLE` — authentication could not be decided (its database failed); never read as signed out. */
18
+ AuthUnavailable: AuthUnavailableError,
19
+ /** 422 — input validation failed, carries field-level details. */
20
+ Validation: ValidationError,
21
+ /** 409 — resource state conflict (duplicate, version mismatch). */
22
+ Conflict: ConflictError,
23
+ /** 429 — too many attempts; carries `retryAfterSeconds`, sent in both the `Retry-After` header and the body's `error.retryAfterSeconds`. */
24
+ TooManyRequests: TooManyRequestsError,
25
+ /** 413 — request body over the route's size limit. */
26
+ PayloadTooLarge: PayloadTooLargeError,
27
+ /** 415 — request body media type not accepted by the route. */
28
+ UnsupportedMediaType: UnsupportedMediaTypeError,
29
+ /** 400 `MALFORMED_MULTIPART` — a multipart body that cannot be parsed or ends before its closing boundary. */
30
+ MalformedMultipart: MalformedMultipartError,
31
+ }
@@ -0,0 +1,33 @@
1
+ import type { FastifyInstance } from 'fastify'
2
+
3
+ export interface DrainState {
4
+ readonly inFlight: () => number
5
+ readonly waitForDrain: (timeoutMs: number) => Promise<void>
6
+ }
7
+
8
+ export function setupDrain(app: FastifyInstance): DrainState {
9
+ let count = 0
10
+
11
+ app.addHook('onRequest', () => { count++; return Promise.resolve() })
12
+ app.addHook('onResponse', () => { count--; return Promise.resolve() })
13
+
14
+ return {
15
+ inFlight: () => count,
16
+ waitForDrain: (timeoutMs: number) => new Promise<void>((resolve, reject) => {
17
+ if (count === 0) return resolve()
18
+
19
+ const deadline = setTimeout(() => {
20
+ clearInterval(poll)
21
+ reject(new Error(`[pipework] Drain timeout: ${count} requests still in-flight after ${timeoutMs}ms`))
22
+ }, timeoutMs)
23
+
24
+ const poll = setInterval(() => {
25
+ if (count === 0) {
26
+ clearTimeout(deadline)
27
+ clearInterval(poll)
28
+ resolve()
29
+ }
30
+ }, 50)
31
+ }),
32
+ }
33
+ }
@@ -0,0 +1,72 @@
1
+ import type { FastifyInstance } from 'fastify'
2
+ import type { Manifold } from '../pipework.js'
3
+ import type { HealthCheck, HealthCheckResult, HealthStatus } from './types.js'
4
+ import { sql } from '../../data/db/sql.js'
5
+
6
+ const startedAt = Date.now()
7
+
8
+ export function registerHealthRoutes(
9
+ app: FastifyInstance,
10
+ instance: Manifold,
11
+ checks: readonly HealthCheck[],
12
+ paths: { health: string; ready: string },
13
+ ): void {
14
+ app.get(paths.health, async (_req, reply) => {
15
+ return reply.status(200).send({ status: 'healthy', release: instance.release, uptime: Date.now() - startedAt })
16
+ })
17
+
18
+ app.get(paths.ready, async (_req, reply) => {
19
+ const results: Record<string, HealthCheckResult> = {}
20
+ let overall: HealthStatus['status'] = 'healthy'
21
+
22
+ const dbChecks = await checkDatabases(instance)
23
+ for (const [name, result] of Object.entries(dbChecks)) {
24
+ results[name] = result
25
+ if (result.status === 'unhealthy') overall = 'unhealthy'
26
+ else if (result.status === 'degraded' && overall !== 'unhealthy') overall = 'degraded'
27
+ }
28
+
29
+ for (const check of checks) {
30
+ const start = Date.now()
31
+ try {
32
+ const result = await check.check()
33
+ results[check.name] = { ...result, latencyMs: result.latencyMs ?? (Date.now() - start) }
34
+ if (result.status === 'unhealthy') overall = 'unhealthy'
35
+ else if (result.status === 'degraded' && overall !== 'unhealthy') overall = 'degraded'
36
+ } catch (err) {
37
+ results[check.name] = {
38
+ status: 'unhealthy',
39
+ message: err instanceof Error ? err.message : 'check failed',
40
+ latencyMs: Date.now() - start,
41
+ }
42
+ overall = 'unhealthy'
43
+ }
44
+ }
45
+
46
+ const status: HealthStatus = { status: overall, release: instance.release, uptime: Date.now() - startedAt, checks: results }
47
+ return reply.status(overall === 'unhealthy' ? 503 : 200).send(status)
48
+ })
49
+ }
50
+
51
+ async function checkDatabases(instance: Manifold): Promise<Record<string, HealthCheckResult>> {
52
+ const results: Record<string, HealthCheckResult> = {}
53
+ const dbNames = instance.config.databaseNames()
54
+
55
+ for (const name of dbNames) {
56
+ const start = Date.now()
57
+ try {
58
+ const dbConfig = instance.config.database(name)
59
+ const conn = instance.pool.getOrCreate(dbConfig)
60
+ await conn.drizzle.execute(sql`SELECT 1`)
61
+ results[`db:${name}`] = { status: 'healthy', latencyMs: Date.now() - start }
62
+ } catch (err) {
63
+ results[`db:${name}`] = {
64
+ status: 'unhealthy',
65
+ message: err instanceof Error ? err.message : 'connection failed',
66
+ latencyMs: Date.now() - start,
67
+ }
68
+ }
69
+ }
70
+
71
+ return results
72
+ }
@@ -0,0 +1,4 @@
1
+ export { orchestrateStartup, type StartupOptions } from './startup.js'
2
+ export { registerHealthRoutes } from './health.js'
3
+ export { setupDrain, type DrainState } from './drain.js'
4
+ export type { LifecycleConfig, StartupHook, ShutdownHook, HealthCheck, HealthCheckResult, HealthStatus } from './types.js'
@@ -0,0 +1,7 @@
1
+ import { orchestrateStartup } from './startup.js'
2
+
3
+ /** Application lifecycle namespace — startup orchestration with hooks and timeouts. */
4
+ export const lifecycle = {
5
+ /** Runs pre-start hooks (DB readiness checks, migrations, etc.) with a configurable timeout. The hooks run in one trace that names the process; the trace-partition hook runs first, outside it. */
6
+ orchestrate: orchestrateStartup,
7
+ }
@@ -0,0 +1,102 @@
1
+ import { randomUUID } from 'node:crypto'
2
+ import { sql } from '../../data/db/sql.js'
3
+ import type { Manifold } from '../pipework.js'
4
+ import type { StartupHook } from './types.js'
5
+ import { getBaseLogger } from '../logging/index.js'
6
+ import { runScript } from '../../async/jobs/run-script.js'
7
+ import { getContext } from '../../request/context/store.js'
8
+ import { TRACE_PARTITION_HOOK_NAME } from '../../trace/partition/startup-hook.js'
9
+ import { projectStepError } from '../../trace/runtime/step-error.js'
10
+ import { serializeForTrace } from '../../trace/capture/bounded-serializer.js'
11
+
12
+ export interface StartupOptions {
13
+ readonly hooks?: readonly StartupHook[]
14
+ readonly timeoutMs?: number
15
+ }
16
+
17
+ export async function orchestrateStartup(instance: Manifold, options: StartupOptions = {}): Promise<void> {
18
+ const logger = getBaseLogger()
19
+ const timeoutMs = options.timeoutMs ?? 30000
20
+
21
+ const doStartupWork = async () => {
22
+ await verifyDatabases(instance, logger)
23
+
24
+ if (options.hooks) {
25
+ // The partition hook creates today's trace partition, so it runs first and outside the trace.
26
+ const partition = options.hooks.filter(h => h.name === TRACE_PARTITION_HOOK_NAME)
27
+ const rest = options.hooks.filter(h => h.name !== TRACE_PARTITION_HOOK_NAME)
28
+ for (const hook of partition) await runHook(hook)
29
+ if (rest.length > 0) {
30
+ await runScript(instance, async () => {
31
+ for (const hook of rest) await runTracedHook(hook)
32
+ }, { jobType: 'start', process: { phase: 'preStart', surfaces: instance.surfaceNames() } })
33
+ }
34
+ }
35
+ }
36
+
37
+ const runHook = async (hook: StartupHook) => {
38
+ logger.info({ hook: hook.name }, 'Running pre-start hook')
39
+ await hook.execute()
40
+ }
41
+
42
+ const runTracedHook = async (hook: StartupHook) => {
43
+ const startedAt = new Date()
44
+ const t0 = process.hrtime.bigint()
45
+ const stage = (error: unknown): void => {
46
+ const trace = getContext()?.trace
47
+ if (trace === undefined || trace === null) return
48
+ trace.buffer.stageExternal({
49
+ id: randomUUID(),
50
+ parentStepId: null,
51
+ flowStepRef: 'external:pipework.start.hook',
52
+ status: error === undefined ? 'ok' : 'error',
53
+ startedAt,
54
+ completedAt: new Date(),
55
+ durationMicros: (process.hrtime.bigint() - t0) / 1000n,
56
+ capturedInputs: [serializeForTrace({ hook: hook.name })],
57
+ error: error === undefined ? null : projectStepError(error),
58
+ })
59
+ }
60
+ try {
61
+ await runHook(hook)
62
+ } catch (err) {
63
+ stage(err)
64
+ throw err
65
+ }
66
+ stage(undefined)
67
+ }
68
+
69
+ const timeoutPromise = new Promise<never>((_, reject) => {
70
+ const timer = setTimeout(() => {
71
+ reject(new Error(
72
+ `[pipework] Startup timed out after ${timeoutMs}ms.\n\n` +
73
+ ' This usually means a database is unreachable or a pre-start hook is hanging.\n' +
74
+ ' Check your DATABASE_URL values and network connectivity.\n'
75
+ ))
76
+ }, timeoutMs)
77
+ timer.unref()
78
+ })
79
+
80
+ await Promise.race([doStartupWork(), timeoutPromise])
81
+ }
82
+
83
+ async function verifyDatabases(instance: Manifold, logger: { info(obj: Record<string, unknown>, msg?: string): void }): Promise<void> {
84
+ const dbNames = instance.config.databaseNames()
85
+
86
+ for (const name of dbNames) {
87
+ const dbConfig = instance.config.database(name)
88
+ const conn = instance.pool.getOrCreate(dbConfig)
89
+ try {
90
+ await conn.drizzle.execute(sql`SELECT 1`)
91
+ logger.info({ database: name }, 'Database connectivity verified')
92
+ } catch (err) {
93
+ const message = err instanceof Error ? err.message : String(err)
94
+ throw new Error(
95
+ `[pipework] Cannot connect to database "${name}".\n\n` +
96
+ ` URL: ${dbConfig.url.replace(/\/\/[^@]+@/, '//***@')}\n` +
97
+ ` Error: ${message}\n\n` +
98
+ ' Check that the database is running and the URL is correct.\n'
99
+ )
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,36 @@
1
+ export interface LifecycleConfig {
2
+ readonly preStart?: readonly StartupHook[]
3
+ readonly preShutdown?: readonly ShutdownHook[]
4
+ readonly healthChecks?: readonly HealthCheck[]
5
+ readonly drainTimeoutMs?: number
6
+ readonly startupTimeoutMs?: number
7
+ }
8
+
9
+ export interface StartupHook {
10
+ readonly name: string
11
+ execute(): Promise<void>
12
+ }
13
+
14
+ export interface ShutdownHook {
15
+ readonly name: string
16
+ execute(): Promise<void>
17
+ }
18
+
19
+ export interface HealthCheck {
20
+ readonly name: string
21
+ check(): Promise<HealthCheckResult>
22
+ }
23
+
24
+ export interface HealthCheckResult {
25
+ readonly status: 'healthy' | 'degraded' | 'unhealthy'
26
+ readonly message?: string
27
+ readonly latencyMs?: number
28
+ }
29
+
30
+ export interface HealthStatus {
31
+ readonly status: 'healthy' | 'degraded' | 'unhealthy'
32
+ /** The release this process runs (`manifold.release`); null when none is configured or set. */
33
+ readonly release: string | null
34
+ readonly uptime: number
35
+ readonly checks: Record<string, HealthCheckResult>
36
+ }
@@ -0,0 +1,60 @@
1
+ import { getContext } from '../../request/context/store.js'
2
+ import { getLoggingConfig } from './logger.js'
3
+ import type { ContextField } from './types.js'
4
+
5
+ export interface CorrelationFields {
6
+ requestId?: string
7
+ tenantId?: string
8
+ userId?: string
9
+ sessionId?: string
10
+ traceId?: string
11
+ jobType?: string
12
+ [key: string]: string | undefined
13
+ }
14
+
15
+ export function getCorrelationFields(): CorrelationFields {
16
+ const ctx = getContext()
17
+ if (!ctx) return {}
18
+
19
+ const config = getLoggingConfig()
20
+ const enabled = config?.contextFields
21
+
22
+ const fields: CorrelationFields = {}
23
+
24
+ if (isEnabled('requestId', enabled) && ctx.requestId !== '') {
25
+ fields.requestId = ctx.requestId
26
+ }
27
+ if (isEnabled('tenantId', enabled) && ctx.tenant !== null) {
28
+ fields.tenantId = ctx.tenant
29
+ }
30
+ if (isEnabled('userId', enabled) && ctx.auth !== null && typeof ctx.auth === 'object' && 'userId' in ctx.auth) {
31
+ const userId = (ctx.auth as { userId: unknown }).userId
32
+ if (typeof userId === 'string') fields.userId = userId
33
+ }
34
+ if (isEnabled('sessionId', enabled) && ctx.metadata?.sessionId != null) {
35
+ fields.sessionId = ctx.metadata.sessionId
36
+ }
37
+ if (isEnabled('traceId', enabled) && ctx.metadata?.traceId != null) {
38
+ fields.traceId = ctx.metadata.traceId
39
+ }
40
+ if (ctx.jobType !== null) {
41
+ fields.jobType = ctx.jobType
42
+ }
43
+
44
+ if (config?.authFields != null && ctx.auth !== null && typeof ctx.auth === 'object') {
45
+ const auth = ctx.auth as Record<string, unknown>
46
+ for (const field of config.authFields) {
47
+ const value = auth[field]
48
+ if (typeof value === 'string') {
49
+ fields[field] = value
50
+ }
51
+ }
52
+ }
53
+
54
+ return fields
55
+ }
56
+
57
+ function isEnabled(field: ContextField, enabled: readonly ContextField[] | undefined): boolean {
58
+ if (enabled === undefined) return true
59
+ return enabled.includes(field)
60
+ }