pipework 0.252.0 → 0.253.0

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 (695) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/infra/support/handle.d.ts +8 -1
  3. package/dist/infra/support/handle.d.ts.map +1 -1
  4. package/dist/infra/support/handle.js +9 -2
  5. package/dist/infra/support/handle.js.map +1 -1
  6. package/dist/infra/support/namespace.d.ts.map +1 -1
  7. package/package.json +4 -3
  8. package/src/async/jobs/abortable-delay.ts +18 -0
  9. package/src/async/jobs/claims.ts +52 -0
  10. package/src/async/jobs/cron.ts +179 -0
  11. package/src/async/jobs/errors.ts +56 -0
  12. package/src/async/jobs/exclusion.ts +117 -0
  13. package/src/async/jobs/execute.ts +219 -0
  14. package/src/async/jobs/index.ts +10 -0
  15. package/src/async/jobs/listener.ts +135 -0
  16. package/src/async/jobs/namespace.ts +20 -0
  17. package/src/async/jobs/queue-door.ts +44 -0
  18. package/src/async/jobs/queue.ts +1012 -0
  19. package/src/async/jobs/run-script.ts +67 -0
  20. package/src/async/jobs/scheduler.ts +218 -0
  21. package/src/async/jobs/schedules-table.ts +37 -0
  22. package/src/async/jobs/serialize-error.ts +48 -0
  23. package/src/async/jobs/table.ts +191 -0
  24. package/src/async/pipeline/define.ts +53 -0
  25. package/src/async/pipeline/errors.ts +35 -0
  26. package/src/async/pipeline/execute.ts +53 -0
  27. package/src/async/pipeline/index.ts +13 -0
  28. package/src/async/pipeline/namespace.ts +12 -0
  29. package/src/async/pipeline/resume.ts +67 -0
  30. package/src/async/pipeline/run-steps.ts +98 -0
  31. package/src/async/pipeline/types.ts +57 -0
  32. package/src/async/state-machine/define.ts +64 -0
  33. package/src/async/state-machine/errors.ts +29 -0
  34. package/src/async/state-machine/index.ts +3 -0
  35. package/src/async/state-machine/namespace.ts +12 -0
  36. package/src/async/state-machine/transition.ts +90 -0
  37. package/src/async/state-machine/types.ts +37 -0
  38. package/src/async/steps/errors.ts +31 -0
  39. package/src/async/steps/graph.ts +1214 -0
  40. package/src/async/steps/hash.ts +40 -0
  41. package/src/async/steps/index.ts +7 -0
  42. package/src/async/steps/namespace.ts +7 -0
  43. package/src/async/steps/table.ts +97 -0
  44. package/src/async/steps/types.ts +318 -0
  45. package/src/audit/chain/index.ts +9 -0
  46. package/src/audit/chain/install.ts +113 -0
  47. package/src/audit/chain/retire.ts +52 -0
  48. package/src/audit/chain/verify.ts +257 -0
  49. package/src/audit/query/cursor.ts +37 -0
  50. package/src/audit/query/index.ts +9 -0
  51. package/src/audit/query/query.ts +223 -0
  52. package/src/audit/schema/audit-record-fields.ts +68 -0
  53. package/src/audit/schema/audit-record.ts +23 -0
  54. package/src/auth/auth/audit.ts +31 -0
  55. package/src/auth/auth/chain.ts +84 -0
  56. package/src/auth/auth/cookie.ts +136 -0
  57. package/src/auth/auth/email-links.ts +311 -0
  58. package/src/auth/auth/guard.ts +128 -0
  59. package/src/auth/auth/index.ts +18 -0
  60. package/src/auth/auth/multi-org.ts +337 -0
  61. package/src/auth/auth/namespace.ts +34 -0
  62. package/src/auth/auth/parse-expiry.ts +13 -0
  63. package/src/auth/auth/passwords.ts +110 -0
  64. package/src/auth/auth/schema.ts +110 -0
  65. package/src/auth/auth/sessions.ts +565 -0
  66. package/src/auth/auth/sign-in.ts +156 -0
  67. package/src/auth/auth/signing-keys.ts +69 -0
  68. package/src/auth/auth/types.ts +26 -0
  69. package/src/auth/auth/uuid.ts +10 -0
  70. package/src/auth/rbac/cache.ts +55 -0
  71. package/src/auth/rbac/check.ts +30 -0
  72. package/src/auth/rbac/create.ts +35 -0
  73. package/src/auth/rbac/index.ts +5 -0
  74. package/src/auth/rbac/middleware.ts +20 -0
  75. package/src/auth/rbac/namespace.ts +15 -0
  76. package/src/auth/rbac/resolve.ts +31 -0
  77. package/src/auth/rbac/schema.sql +31 -0
  78. package/src/auth/rbac/seed.ts +67 -0
  79. package/src/auth/rbac/tables.ts +32 -0
  80. package/src/auth/rbac/types.ts +65 -0
  81. package/src/auth/tenant/extract.ts +33 -0
  82. package/src/auth/tenant/in-tenant.ts +49 -0
  83. package/src/auth/tenant/index.ts +7 -0
  84. package/src/auth/tenant/namespace.ts +23 -0
  85. package/src/auth/tenant/propagate.ts +20 -0
  86. package/src/auth/tenant/rls.ts +120 -0
  87. package/src/auth/tenant/scope.ts +33 -0
  88. package/src/auth/tenant/scoped-db.ts +581 -0
  89. package/src/auth/tenant/types.ts +14 -0
  90. package/src/auth/tenant/validate.ts +27 -0
  91. package/src/cli/commands/add.ts +158 -0
  92. package/src/cli/commands/alerts.ts +98 -0
  93. package/src/cli/commands/check.ts +1418 -0
  94. package/src/cli/commands/codemod.ts +78 -0
  95. package/src/cli/commands/db.ts +356 -0
  96. package/src/cli/commands/dev.ts +101 -0
  97. package/src/cli/commands/generate.ts +75 -0
  98. package/src/cli/commands/init.ts +36 -0
  99. package/src/cli/commands/install.ts +28 -0
  100. package/src/cli/commands/lint.ts +62 -0
  101. package/src/cli/commands/migrate.ts +132 -0
  102. package/src/cli/commands/openapi.ts +63 -0
  103. package/src/cli/commands/remove.ts +72 -0
  104. package/src/cli/commands/run.ts +50 -0
  105. package/src/cli/commands/scope.ts +54 -0
  106. package/src/cli/commands/serve.ts +68 -0
  107. package/src/cli/commands/shard.ts +31 -0
  108. package/src/cli/commands/shared/config-pipework-version.ts +28 -0
  109. package/src/cli/commands/shared/find-config.ts +22 -0
  110. package/src/cli/commands/shared/load-config.ts +35 -0
  111. package/src/cli/commands/shared/pnpm-install.ts +95 -0
  112. package/src/cli/commands/shared/report-removed.ts +8 -0
  113. package/src/cli/commands/sync.ts +32 -0
  114. package/src/cli/commands/test.ts +307 -0
  115. package/src/cli/commands/upgrade.ts +48 -0
  116. package/src/cli/dev-bootstrap.ts +24 -0
  117. package/src/cli/errors.ts +10 -0
  118. package/src/cli/index.ts +303 -0
  119. package/src/cli/output.ts +17 -0
  120. package/src/cli/port.ts +15 -0
  121. package/src/cli/surface-kinds.ts +20 -0
  122. package/src/client/index.ts +4 -0
  123. package/src/client/poll.ts +130 -0
  124. package/src/client/report-fault.ts +119 -0
  125. package/src/core/config/app-pool.ts +19 -0
  126. package/src/core/config/aws-env.ts +29 -0
  127. package/src/core/config/base-dir.ts +24 -0
  128. package/src/core/config/discover.ts +64 -0
  129. package/src/core/config/env-resolve.ts +87 -0
  130. package/src/core/config/env-types.ts +116 -0
  131. package/src/core/config/env.ts +55 -0
  132. package/src/core/config/errors.ts +9 -0
  133. package/src/core/config/import-config.ts +40 -0
  134. package/src/core/config/index.ts +8 -0
  135. package/src/core/config/load.ts +417 -0
  136. package/src/core/config/namespace.ts +14 -0
  137. package/src/core/config/resolve.ts +195 -0
  138. package/src/core/config/schema.ts +488 -0
  139. package/src/core/config/statement-observer.ts +48 -0
  140. package/src/core/config/ts-inline-hooks.ts +75 -0
  141. package/src/core/config/ts-register.ts +4 -0
  142. package/src/core/config/ts-resolve-hooks.ts +101 -0
  143. package/src/core/errors/base.ts +49 -0
  144. package/src/core/errors/http.ts +146 -0
  145. package/src/core/errors/index.ts +2 -0
  146. package/src/core/errors/namespace.ts +31 -0
  147. package/src/core/lifecycle/drain.ts +33 -0
  148. package/src/core/lifecycle/health.ts +72 -0
  149. package/src/core/lifecycle/index.ts +4 -0
  150. package/src/core/lifecycle/namespace.ts +7 -0
  151. package/src/core/lifecycle/startup.ts +102 -0
  152. package/src/core/lifecycle/types.ts +36 -0
  153. package/src/core/logging/context.ts +60 -0
  154. package/src/core/logging/error-chain.ts +68 -0
  155. package/src/core/logging/index.ts +5 -0
  156. package/src/core/logging/logger.ts +65 -0
  157. package/src/core/logging/namespace.ts +16 -0
  158. package/src/core/logging/proxy.ts +22 -0
  159. package/src/core/logging/redact-match.ts +24 -0
  160. package/src/core/logging/types.ts +47 -0
  161. package/src/core/pipework.ts +566 -0
  162. package/src/core/runtime/broker.ts +69 -0
  163. package/src/core/surface/http.ts +133 -0
  164. package/src/core/surface/index.ts +11 -0
  165. package/src/core/surface/job-timeout.ts +40 -0
  166. package/src/core/surface/namespace.ts +13 -0
  167. package/src/core/surface/script.ts +33 -0
  168. package/src/core/surface/start.ts +142 -0
  169. package/src/core/surface/types.ts +225 -0
  170. package/src/core/surface/validate.ts +88 -0
  171. package/src/core/surface/worker.ts +528 -0
  172. package/src/core/validation/connectivity.ts +49 -0
  173. package/src/core/validation/domain.ts +99 -0
  174. package/src/core/validation/index.ts +5 -0
  175. package/src/core/validation/queue-tables.ts +312 -0
  176. package/src/core/validation/rls-role.ts +138 -0
  177. package/src/core/validation/startup.ts +51 -0
  178. package/src/core/validation/surfaces.ts +65 -0
  179. package/src/core/validation/types.ts +25 -0
  180. package/src/data/db/advisory-lock.ts +55 -0
  181. package/src/data/db/aggregates.ts +172 -0
  182. package/src/data/db/array-elements.ts +111 -0
  183. package/src/data/db/bulk-set.ts +53 -0
  184. package/src/data/db/col/index.ts +14 -0
  185. package/src/data/db/composed.ts +53 -0
  186. package/src/data/db/db.ts +276 -0
  187. package/src/data/db/excluded.ts +16 -0
  188. package/src/data/db/expressions.ts +473 -0
  189. package/src/data/db/filter.ts +90 -0
  190. package/src/data/db/function-source.ts +114 -0
  191. package/src/data/db/identifiers.ts +16 -0
  192. package/src/data/db/idx/index.ts +9 -0
  193. package/src/data/db/in-list.ts +49 -0
  194. package/src/data/db/index.ts +9 -0
  195. package/src/data/db/insert-split.ts +137 -0
  196. package/src/data/db/instrumentation.ts +82 -0
  197. package/src/data/db/maintenance.ts +28 -0
  198. package/src/data/db/namespace.ts +107 -0
  199. package/src/data/db/owner-labels.ts +9 -0
  200. package/src/data/db/pool.ts +187 -0
  201. package/src/data/db/query-label.ts +13 -0
  202. package/src/data/db/query-watch.ts +116 -0
  203. package/src/data/db/raw-client-warning.ts +37 -0
  204. package/src/data/db/readonly.ts +23 -0
  205. package/src/data/db/reservation.ts +151 -0
  206. package/src/data/db/schema-features.ts +14 -0
  207. package/src/data/db/serializable.ts +83 -0
  208. package/src/data/db/sql.ts +1 -0
  209. package/src/data/db/timeouts.ts +76 -0
  210. package/src/data/db/types.ts +18 -0
  211. package/src/data/db/unbound.ts +33 -0
  212. package/src/data/db/values.ts +29 -0
  213. package/src/data/domain/brand.ts +15 -0
  214. package/src/data/domain/build-factory.ts +193 -0
  215. package/src/data/domain/build-schema.ts +161 -0
  216. package/src/data/domain/build-table.ts +355 -0
  217. package/src/data/domain/define.ts +239 -0
  218. package/src/data/domain/external-registry.ts +34 -0
  219. package/src/data/domain/external.ts +77 -0
  220. package/src/data/domain/field.ts +279 -0
  221. package/src/data/domain/index.ts +13 -0
  222. package/src/data/domain/naming.ts +6 -0
  223. package/src/data/domain/projections.ts +57 -0
  224. package/src/data/domain/trace-safe-projection.ts +31 -0
  225. package/src/data/domain/traits.ts +108 -0
  226. package/src/data/domain/types.ts +289 -0
  227. package/src/data/jsonb/composed.ts +18 -0
  228. package/src/data/jsonb/index.ts +1 -0
  229. package/src/data/jsonb/namespace.ts +30 -0
  230. package/src/data/jsonb/query.ts +86 -0
  231. package/src/data/migrate/append-only-generate.ts +47 -0
  232. package/src/data/migrate/applied.ts +47 -0
  233. package/src/data/migrate/apply.ts +309 -0
  234. package/src/data/migrate/check.ts +119 -0
  235. package/src/data/migrate/diff.ts +357 -0
  236. package/src/data/migrate/door-generate.ts +130 -0
  237. package/src/data/migrate/framework-rls.ts +58 -0
  238. package/src/data/migrate/generate.ts +201 -0
  239. package/src/data/migrate/history.ts +215 -0
  240. package/src/data/migrate/index.ts +9 -0
  241. package/src/data/migrate/internal-definitions.ts +175 -0
  242. package/src/data/migrate/post-process.ts +73 -0
  243. package/src/data/migrate/pragma.ts +73 -0
  244. package/src/data/migrate/provision-framework.ts +147 -0
  245. package/src/data/migrate/rls-generate.ts +61 -0
  246. package/src/data/migrate/run.ts +124 -0
  247. package/src/data/migrate/safety.ts +167 -0
  248. package/src/data/migrate/snapshot.ts +368 -0
  249. package/src/data/migrate/sql-emit.ts +392 -0
  250. package/src/data/migrate/statements.ts +312 -0
  251. package/src/data/query/alias.ts +126 -0
  252. package/src/data/query/batch.ts +8 -0
  253. package/src/data/query/cache/core/cache.ts +78 -0
  254. package/src/data/query/cache/core/index.ts +1 -0
  255. package/src/data/query/cache/core/types.ts +29 -0
  256. package/src/data/query/cache/readme.md +230 -0
  257. package/src/data/query/casing.ts +76 -0
  258. package/src/data/query/collation.ts +11 -0
  259. package/src/data/query/column-builder.ts +370 -0
  260. package/src/data/query/column.ts +150 -0
  261. package/src/data/query/entity.ts +42 -0
  262. package/src/data/query/errors.ts +33 -0
  263. package/src/data/query/index.ts +14 -0
  264. package/src/data/query/logger.ts +47 -0
  265. package/src/data/query/operations.ts +45 -0
  266. package/src/data/query/pg-core/alias.ts +12 -0
  267. package/src/data/query/pg-core/checks.ts +32 -0
  268. package/src/data/query/pg-core/columns/all.ts +71 -0
  269. package/src/data/query/pg-core/columns/bigint.ts +110 -0
  270. package/src/data/query/pg-core/columns/bigserial.ts +128 -0
  271. package/src/data/query/pg-core/columns/boolean.ts +43 -0
  272. package/src/data/query/pg-core/columns/char.ts +85 -0
  273. package/src/data/query/pg-core/columns/cidr.ts +43 -0
  274. package/src/data/query/pg-core/columns/common.ts +366 -0
  275. package/src/data/query/pg-core/columns/custom.ts +232 -0
  276. package/src/data/query/pg-core/columns/date.common.ts +15 -0
  277. package/src/data/query/pg-core/columns/date.ts +112 -0
  278. package/src/data/query/pg-core/columns/double-precision.ts +55 -0
  279. package/src/data/query/pg-core/columns/enum.ts +201 -0
  280. package/src/data/query/pg-core/columns/index.ts +35 -0
  281. package/src/data/query/pg-core/columns/inet.ts +43 -0
  282. package/src/data/query/pg-core/columns/int.common.ts +57 -0
  283. package/src/data/query/pg-core/columns/integer.ts +53 -0
  284. package/src/data/query/pg-core/columns/interval.ts +83 -0
  285. package/src/data/query/pg-core/columns/json.ts +58 -0
  286. package/src/data/query/pg-core/columns/jsonb.ts +56 -0
  287. package/src/data/query/pg-core/columns/line.ts +117 -0
  288. package/src/data/query/pg-core/columns/macaddr.ts +43 -0
  289. package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
  290. package/src/data/query/pg-core/columns/numeric.ts +227 -0
  291. package/src/data/query/pg-core/columns/point.ts +127 -0
  292. package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
  293. package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
  294. package/src/data/query/pg-core/columns/real.ts +58 -0
  295. package/src/data/query/pg-core/columns/serial.ts +55 -0
  296. package/src/data/query/pg-core/columns/smallint.ts +53 -0
  297. package/src/data/query/pg-core/columns/smallserial.ts +60 -0
  298. package/src/data/query/pg-core/columns/text.ts +67 -0
  299. package/src/data/query/pg-core/columns/time.ts +72 -0
  300. package/src/data/query/pg-core/columns/timestamp.ts +163 -0
  301. package/src/data/query/pg-core/columns/uuid.ts +51 -0
  302. package/src/data/query/pg-core/columns/varchar.ts +89 -0
  303. package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
  304. package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
  305. package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
  306. package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
  307. package/src/data/query/pg-core/db.ts +674 -0
  308. package/src/data/query/pg-core/dialect.ts +1404 -0
  309. package/src/data/query/pg-core/expressions.ts +25 -0
  310. package/src/data/query/pg-core/foreign-keys.ts +130 -0
  311. package/src/data/query/pg-core/index.ts +21 -0
  312. package/src/data/query/pg-core/indexes.ts +276 -0
  313. package/src/data/query/pg-core/policies.ts +56 -0
  314. package/src/data/query/pg-core/primary-keys.ts +62 -0
  315. package/src/data/query/pg-core/query-builders/count.ts +86 -0
  316. package/src/data/query/pg-core/query-builders/delete.ts +293 -0
  317. package/src/data/query/pg-core/query-builders/index.ts +7 -0
  318. package/src/data/query/pg-core/query-builders/insert.ts +452 -0
  319. package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
  320. package/src/data/query/pg-core/query-builders/query.ts +157 -0
  321. package/src/data/query/pg-core/query-builders/raw.ts +49 -0
  322. package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
  323. package/src/data/query/pg-core/query-builders/select.ts +1346 -0
  324. package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
  325. package/src/data/query/pg-core/query-builders/update.ts +626 -0
  326. package/src/data/query/pg-core/roles.ts +41 -0
  327. package/src/data/query/pg-core/schema.ts +72 -0
  328. package/src/data/query/pg-core/sequence.ts +41 -0
  329. package/src/data/query/pg-core/session.ts +292 -0
  330. package/src/data/query/pg-core/subquery.ts +46 -0
  331. package/src/data/query/pg-core/table.ts +252 -0
  332. package/src/data/query/pg-core/unique-constraint.ts +73 -0
  333. package/src/data/query/pg-core/utils/array.ts +95 -0
  334. package/src/data/query/pg-core/utils/index.ts +1 -0
  335. package/src/data/query/pg-core/utils.ts +104 -0
  336. package/src/data/query/pg-core/view-base.ts +14 -0
  337. package/src/data/query/pg-core/view-common.ts +1 -0
  338. package/src/data/query/pg-core/view.ts +435 -0
  339. package/src/data/query/pg-core/with-builder.ts +41 -0
  340. package/src/data/query/postgres-js/README.md +46 -0
  341. package/src/data/query/postgres-js/array-parser.ts +45 -0
  342. package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
  343. package/src/data/query/postgres-js/driver.ts +163 -0
  344. package/src/data/query/postgres-js/index.ts +2 -0
  345. package/src/data/query/postgres-js/session.ts +234 -0
  346. package/src/data/query/primary-key.ts +11 -0
  347. package/src/data/query/query-builders/query-builder.ts +19 -0
  348. package/src/data/query/query-builders/select.types.ts +175 -0
  349. package/src/data/query/query-promise.ts +35 -0
  350. package/src/data/query/relations.ts +725 -0
  351. package/src/data/query/runnable-query.ts +12 -0
  352. package/src/data/query/selection-proxy.ts +121 -0
  353. package/src/data/query/session.ts +8 -0
  354. package/src/data/query/sql/expressions/conditions.ts +741 -0
  355. package/src/data/query/sql/expressions/index.ts +2 -0
  356. package/src/data/query/sql/expressions/select.ts +45 -0
  357. package/src/data/query/sql/functions/aggregate.ts +129 -0
  358. package/src/data/query/sql/functions/index.ts +2 -0
  359. package/src/data/query/sql/functions/vector.ts +178 -0
  360. package/src/data/query/sql/index.ts +3 -0
  361. package/src/data/query/sql/sql.ts +794 -0
  362. package/src/data/query/subquery.ts +53 -0
  363. package/src/data/query/table.ts +208 -0
  364. package/src/data/query/table.utils.ts +2 -0
  365. package/src/data/query/tracing-utils.ts +3 -0
  366. package/src/data/query/tracing.ts +11 -0
  367. package/src/data/query/utils.ts +357 -0
  368. package/src/data/query/version.ts +4 -0
  369. package/src/data/query/view-common.ts +1 -0
  370. package/src/data/schema/branded.ts +13 -0
  371. package/src/data/schema/generated/coerce.ts +5 -0
  372. package/src/data/schema/generated/combinator.ts +6 -0
  373. package/src/data/schema/generated/encoding.ts +5 -0
  374. package/src/data/schema/generated/error.ts +6 -0
  375. package/src/data/schema/generated/format.ts +5 -0
  376. package/src/data/schema/generated/type-constructor.ts +10 -0
  377. package/src/data/schema/generated/type.ts +6 -0
  378. package/src/data/schema/index.ts +6 -0
  379. package/src/data/schema/json-schema.ts +33 -0
  380. package/src/data/schema/namespace.ts +55 -0
  381. package/src/data/schema/parse.ts +39 -0
  382. package/src/data/schema/types.ts +39 -0
  383. package/src/data/temporal/append-only.ts +134 -0
  384. package/src/data/temporal/close.ts +27 -0
  385. package/src/data/temporal/columns.ts +10 -0
  386. package/src/data/temporal/definition-queries.ts +70 -0
  387. package/src/data/temporal/errors.ts +10 -0
  388. package/src/data/temporal/get-current.ts +22 -0
  389. package/src/data/temporal/index.ts +9 -0
  390. package/src/data/temporal/namespace.ts +36 -0
  391. package/src/data/temporal/query.ts +25 -0
  392. package/src/data/temporal/resolve.ts +17 -0
  393. package/src/data/temporal/revise.ts +67 -0
  394. package/src/data/temporal/types.ts +22 -0
  395. package/src/data/valve/artifact.ts +33 -0
  396. package/src/data/valve/contract-diff.ts +21 -0
  397. package/src/data/valve/cross.ts +57 -0
  398. package/src/data/valve/crossing-ledger.ts +50 -0
  399. package/src/data/valve/decision.ts +44 -0
  400. package/src/data/valve/durable-crossing.ts +52 -0
  401. package/src/data/valve/execute-crossing.ts +77 -0
  402. package/src/data/valve/faucet.ts +56 -0
  403. package/src/data/valve/gate.ts +114 -0
  404. package/src/data/valve/graph.ts +77 -0
  405. package/src/data/valve/index.ts +53 -0
  406. package/src/data/valve/namespace.ts +57 -0
  407. package/src/data/valve/registry.ts +50 -0
  408. package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
  409. package/src/data/valve/schema/valve-crossing.ts +9 -0
  410. package/src/data/valve/supply.ts +154 -0
  411. package/src/data/valve/types.ts +143 -0
  412. package/src/data/vector/columns.ts +27 -0
  413. package/src/data/vector/index.ts +4 -0
  414. package/src/data/vector/namespace.ts +33 -0
  415. package/src/data/vector/query.ts +85 -0
  416. package/src/data/vector/validate.ts +16 -0
  417. package/src/data/write/audit/actor.ts +15 -0
  418. package/src/data/write/audit/audit-columns.ts +18 -0
  419. package/src/data/write/audit/audit-select.ts +111 -0
  420. package/src/data/write/audit/bound-transaction.ts +14 -0
  421. package/src/data/write/audit/cte-compile.ts +32 -0
  422. package/src/data/write/audit/decode-returning.ts +47 -0
  423. package/src/data/write/audit/final-select.ts +43 -0
  424. package/src/data/write/audit/infra-audit.ts +36 -0
  425. package/src/data/write/audit/primary-key.ts +65 -0
  426. package/src/data/write/audit/projection.ts +41 -0
  427. package/src/data/write/audit/read-touches.ts +86 -0
  428. package/src/data/write/audit/touch-match.ts +78 -0
  429. package/src/data/write/audit/verb-delete.ts +62 -0
  430. package/src/data/write/audit/verb-insert.ts +36 -0
  431. package/src/data/write/audit/verb-select.ts +47 -0
  432. package/src/data/write/audit/verb-update.ts +60 -0
  433. package/src/data/write/audit/verb-upsert.ts +104 -0
  434. package/src/data/write/conflict.ts +43 -0
  435. package/src/data/write/delete.ts +38 -0
  436. package/src/data/write/execute.ts +243 -0
  437. package/src/data/write/index.ts +11 -0
  438. package/src/data/write/insert.ts +63 -0
  439. package/src/data/write/state.ts +43 -0
  440. package/src/data/write/update.ts +54 -0
  441. package/src/data/write/upsert.ts +58 -0
  442. package/src/data/write/values.ts +19 -0
  443. package/src/index.ts +230 -0
  444. package/src/infra/access-links/code.ts +70 -0
  445. package/src/infra/access-links/handle.ts +892 -0
  446. package/src/infra/access-links/index.ts +9 -0
  447. package/src/infra/access-links/namespace.ts +30 -0
  448. package/src/infra/access-links/person-check.ts +177 -0
  449. package/src/infra/access-links/schema.ts +71 -0
  450. package/src/infra/alerts/async-sources.ts +231 -0
  451. package/src/infra/alerts/audit.ts +36 -0
  452. package/src/infra/alerts/beat.ts +123 -0
  453. package/src/infra/alerts/client-faults.ts +111 -0
  454. package/src/infra/alerts/faults.ts +156 -0
  455. package/src/infra/alerts/handle.ts +778 -0
  456. package/src/infra/alerts/http.ts +192 -0
  457. package/src/infra/alerts/index.ts +12 -0
  458. package/src/infra/alerts/infra-sources.ts +180 -0
  459. package/src/infra/alerts/namespace.ts +81 -0
  460. package/src/infra/alerts/redact.ts +21 -0
  461. package/src/infra/alerts/request-faults.ts +41 -0
  462. package/src/infra/alerts/schema.ts +124 -0
  463. package/src/infra/alerts/sinks.ts +125 -0
  464. package/src/infra/alerts/source-options.ts +26 -0
  465. package/src/infra/alerts/sources.ts +503 -0
  466. package/src/infra/alerts/subsystem-sources.ts +137 -0
  467. package/src/infra/audit/emit.ts +87 -0
  468. package/src/infra/audit/index.ts +2 -0
  469. package/src/infra/audit/namespace.ts +22 -0
  470. package/src/infra/audit/schema.sql +35 -0
  471. package/src/infra/audit/types.ts +18 -0
  472. package/src/infra/aws/credentials.ts +147 -0
  473. package/src/infra/aws/sigv4.ts +140 -0
  474. package/src/infra/cache/create.ts +58 -0
  475. package/src/infra/cache/entry.ts +81 -0
  476. package/src/infra/cache/index.ts +4 -0
  477. package/src/infra/cache/namespace.ts +10 -0
  478. package/src/infra/cache/tenant.ts +93 -0
  479. package/src/infra/cache/types.ts +24 -0
  480. package/src/infra/crawl/audit.ts +35 -0
  481. package/src/infra/crawl/errors.ts +25 -0
  482. package/src/infra/crawl/handle.ts +693 -0
  483. package/src/infra/crawl/index.ts +9 -0
  484. package/src/infra/crawl/links.ts +160 -0
  485. package/src/infra/crawl/namespace.ts +36 -0
  486. package/src/infra/crawl/robots.ts +100 -0
  487. package/src/infra/crawl/schema.ts +89 -0
  488. package/src/infra/credit-line/handle.ts +883 -0
  489. package/src/infra/credit-line/index.ts +6 -0
  490. package/src/infra/credit-line/namespace.ts +7 -0
  491. package/src/infra/credit-line/schema.ts +96 -0
  492. package/src/infra/credits/handle.ts +706 -0
  493. package/src/infra/credits/index.ts +5 -0
  494. package/src/infra/credits/namespace.ts +7 -0
  495. package/src/infra/credits/schema.ts +83 -0
  496. package/src/infra/email/audit.ts +36 -0
  497. package/src/infra/email/inbound.ts +622 -0
  498. package/src/infra/email/index.ts +11 -0
  499. package/src/infra/email/mail.ts +517 -0
  500. package/src/infra/email/mime.ts +447 -0
  501. package/src/infra/email/namespace.ts +22 -0
  502. package/src/infra/email/providers.ts +111 -0
  503. package/src/infra/email/schema.ts +96 -0
  504. package/src/infra/email/sns.ts +200 -0
  505. package/src/infra/email/unsubscribe.ts +44 -0
  506. package/src/infra/fetch/address.ts +88 -0
  507. package/src/infra/fetch/connect-retry.ts +87 -0
  508. package/src/infra/fetch/handle.ts +329 -0
  509. package/src/infra/fetch/index.ts +7 -0
  510. package/src/infra/fetch/namespace.ts +70 -0
  511. package/src/infra/idempotency/index.ts +3 -0
  512. package/src/infra/idempotency/middleware.ts +87 -0
  513. package/src/infra/idempotency/store.ts +92 -0
  514. package/src/infra/idempotency/types.ts +30 -0
  515. package/src/infra/join-requests/handle.ts +312 -0
  516. package/src/infra/join-requests/index.ts +2 -0
  517. package/src/infra/join-requests/namespace.ts +7 -0
  518. package/src/infra/join-requests/schema.ts +33 -0
  519. package/src/infra/outbox/core.ts +165 -0
  520. package/src/infra/quota/errors.ts +32 -0
  521. package/src/infra/quota/handle.ts +215 -0
  522. package/src/infra/quota/index.ts +5 -0
  523. package/src/infra/quota/namespace.ts +7 -0
  524. package/src/infra/quota/schema.ts +15 -0
  525. package/src/infra/storage/backend.ts +34 -0
  526. package/src/infra/storage/handle.ts +513 -0
  527. package/src/infra/storage/index.ts +9 -0
  528. package/src/infra/storage/local.ts +104 -0
  529. package/src/infra/storage/namespace.ts +13 -0
  530. package/src/infra/storage/s3.ts +257 -0
  531. package/src/infra/storage/schema.ts +24 -0
  532. package/src/infra/support/handle.ts +869 -0
  533. package/src/infra/support/http.ts +229 -0
  534. package/src/infra/support/index.ts +7 -0
  535. package/src/infra/support/namespace.ts +12 -0
  536. package/src/infra/support/schema.ts +96 -0
  537. package/src/infra/webhook/inbound.ts +45 -0
  538. package/src/infra/webhook/index.ts +5 -0
  539. package/src/infra/webhook/namespace.ts +24 -0
  540. package/src/infra/webhook/outbound.ts +315 -0
  541. package/src/infra/webhook/sign.ts +32 -0
  542. package/src/infra/webhook/verify.ts +82 -0
  543. package/src/invariants/assert.ts +26 -0
  544. package/src/invariants/index.ts +1 -0
  545. package/src/lint/config.ts +56 -0
  546. package/src/lint/doctrine.ts +163 -0
  547. package/src/lint/include.ts +97 -0
  548. package/src/lint/index.ts +3 -0
  549. package/src/lint/preset.ts +10 -0
  550. package/src/lint/resolver.ts +218 -0
  551. package/src/lint/rules/no-reexports.ts +46 -0
  552. package/src/request/behavior/audited.ts +85 -0
  553. package/src/request/behavior/cached.ts +62 -0
  554. package/src/request/behavior/compose.ts +28 -0
  555. package/src/request/behavior/index.ts +5 -0
  556. package/src/request/behavior/namespace.ts +16 -0
  557. package/src/request/behavior/types.ts +26 -0
  558. package/src/request/behavior/versioned.ts +54 -0
  559. package/src/request/context/create.ts +103 -0
  560. package/src/request/context/guard.ts +49 -0
  561. package/src/request/context/index.ts +4 -0
  562. package/src/request/context/run-in-transaction.ts +200 -0
  563. package/src/request/context/store.ts +28 -0
  564. package/src/request/context/types.ts +50 -0
  565. package/src/request/di/builder.ts +535 -0
  566. package/src/request/di/index.ts +8 -0
  567. package/src/request/di/resolve.ts +271 -0
  568. package/src/request/di/types.ts +262 -0
  569. package/src/request/fitting/namespace.ts +7 -0
  570. package/src/request/fixture/batch.ts +71 -0
  571. package/src/request/fixture/builder.ts +26 -0
  572. package/src/request/fixture/errors.ts +10 -0
  573. package/src/request/fixture/index.ts +8 -0
  574. package/src/request/fixture/namespace.ts +23 -0
  575. package/src/request/fixture/paginate.ts +44 -0
  576. package/src/request/fixture/to-handlers.ts +260 -0
  577. package/src/request/fixture/types.ts +79 -0
  578. package/src/request/flow/act-as.ts +78 -0
  579. package/src/request/flow/namespace.ts +17 -0
  580. package/src/request/http/error-step.ts +42 -0
  581. package/src/request/http/file.ts +141 -0
  582. package/src/request/http/index.ts +4 -0
  583. package/src/request/http/middleware.ts +141 -0
  584. package/src/request/http/namespace.ts +5 -0
  585. package/src/request/http/rate-limit-classes.ts +170 -0
  586. package/src/request/http/response.ts +82 -0
  587. package/src/request/http/server.ts +916 -0
  588. package/src/request/http/sniff.ts +261 -0
  589. package/src/request/http/types.ts +250 -0
  590. package/src/request/http/upload.ts +284 -0
  591. package/src/request/internal/text.ts +6 -0
  592. package/src/request/openapi/generate.ts +205 -0
  593. package/src/request/openapi/index.ts +2 -0
  594. package/src/request/openapi/namespace.ts +7 -0
  595. package/src/test/auth.ts +13 -0
  596. package/src/test/auto-setup.ts +45 -0
  597. package/src/test/context.ts +91 -0
  598. package/src/test/crawl-fixture.ts +157 -0
  599. package/src/test/discover-fork.ts +17 -0
  600. package/src/test/fingerprint.ts +135 -0
  601. package/src/test/globals.d.ts +7 -0
  602. package/src/test/index.ts +19 -0
  603. package/src/test/namespace.ts +87 -0
  604. package/src/test/plugin.ts +189 -0
  605. package/src/test/progress.ts +185 -0
  606. package/src/test/reap-after-run.ts +28 -0
  607. package/src/test/reap.ts +286 -0
  608. package/src/test/reset.ts +253 -0
  609. package/src/test/savepoints.ts +172 -0
  610. package/src/test/setup.ts +1422 -0
  611. package/src/test/system-channel.ts +50 -0
  612. package/src/test/vitest-plugin.ts +142 -0
  613. package/src/test/vitest-workspace.ts +507 -0
  614. package/src/test/vitest.ts +333 -0
  615. package/src/test/watch.ts +105 -0
  616. package/src/trace/capture/bounded-serializer.ts +146 -0
  617. package/src/trace/cardinality/analyze.ts +173 -0
  618. package/src/trace/cardinality/branch-context.ts +214 -0
  619. package/src/trace/cardinality/check.ts +33 -0
  620. package/src/trace/cardinality/classify-edge.ts +64 -0
  621. package/src/trace/cardinality/structural-max.ts +107 -0
  622. package/src/trace/check/coverage-check.ts +188 -0
  623. package/src/trace/check/flow-check.ts +103 -0
  624. package/src/trace/check/flow-step-site.ts +234 -0
  625. package/src/trace/check/io-pattern.ts +116 -0
  626. package/src/trace/codemod/add-cardinality.ts +152 -0
  627. package/src/trace/codemod/run.ts +80 -0
  628. package/src/trace/entry/child-trace.ts +21 -0
  629. package/src/trace/entry/close-trace.ts +87 -0
  630. package/src/trace/entry/finalize-trace.ts +28 -0
  631. package/src/trace/entry/open-trace.ts +138 -0
  632. package/src/trace/entry/parent-trace.ts +20 -0
  633. package/src/trace/entry/parse-traceparent.ts +39 -0
  634. package/src/trace/entry/process-start.ts +38 -0
  635. package/src/trace/entry/trace-context.ts +26 -0
  636. package/src/trace/entry/tracing-enabled.ts +10 -0
  637. package/src/trace/external/record.ts +195 -0
  638. package/src/trace/external/report.ts +66 -0
  639. package/src/trace/namespace.ts +19 -0
  640. package/src/trace/partition/day.ts +47 -0
  641. package/src/trace/partition/index.ts +14 -0
  642. package/src/trace/partition/partition-name.ts +23 -0
  643. package/src/trace/partition/plan.ts +82 -0
  644. package/src/trace/partition/schedule.ts +26 -0
  645. package/src/trace/partition/startup-hook.ts +39 -0
  646. package/src/trace/partition/sync.ts +154 -0
  647. package/src/trace/partition/tables.ts +53 -0
  648. package/src/trace/read/tree.ts +83 -0
  649. package/src/trace/retain/copy-on-error.ts +76 -0
  650. package/src/trace/runtime/expire-stale-traces.ts +54 -0
  651. package/src/trace/runtime/flow-step.ts +147 -0
  652. package/src/trace/runtime/flush-steps.ts +31 -0
  653. package/src/trace/runtime/pending-writes.ts +54 -0
  654. package/src/trace/runtime/step-buffer.ts +298 -0
  655. package/src/trace/runtime/step-error.ts +21 -0
  656. package/src/trace/runtime/step-meta.ts +55 -0
  657. package/src/trace/runtime/thenable.ts +12 -0
  658. package/src/trace/runtime/truncate-trace.ts +62 -0
  659. package/src/trace/schema/trace-fields.ts +52 -0
  660. package/src/trace/schema/trace-retained.ts +22 -0
  661. package/src/trace/schema/trace-step-fields.ts +44 -0
  662. package/src/trace/schema/trace-step-retained.ts +25 -0
  663. package/src/trace/schema/trace-step.ts +18 -0
  664. package/src/trace/schema/trace.ts +12 -0
  665. package/src/trace/transformer/apply.ts +79 -0
  666. package/src/trace/transformer/build-meta-literal.ts +30 -0
  667. package/src/trace/transformer/find-flow-step-sites.ts +85 -0
  668. package/src/trace/transformer/inject-flow-step-import.ts +39 -0
  669. package/src/trace/transformer/transform-error.ts +14 -0
  670. package/src/trace/transformer/transform-flow-steps.ts +123 -0
  671. package/src/trace/transformer/wrap-function-declaration.ts +62 -0
  672. package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
  673. package/src/workspace/affected.ts +110 -0
  674. package/src/workspace/changed-files.ts +163 -0
  675. package/src/workspace/check-deps.ts +213 -0
  676. package/src/workspace/checksum.ts +20 -0
  677. package/src/workspace/dependency-graph.ts +67 -0
  678. package/src/workspace/detect-pipework-copies.ts +93 -0
  679. package/src/workspace/discover.ts +206 -0
  680. package/src/workspace/generate.ts +401 -0
  681. package/src/workspace/index.ts +7 -0
  682. package/src/workspace/module-imports-pipework.ts +39 -0
  683. package/src/workspace/module-package-name.ts +12 -0
  684. package/src/workspace/scrub-git-env.ts +23 -0
  685. package/src/workspace/source-paths.ts +36 -0
  686. package/src/workspace/sync.ts +182 -0
  687. package/dist/REFERENCE.md +0 -1477
  688. package/dist/infra/access-links/rate-limit.d.ts +0 -10
  689. package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
  690. package/dist/infra/access-links/rate-limit.js +0 -28
  691. package/dist/infra/access-links/rate-limit.js.map +0 -1
  692. package/dist/infra/email/sigv4.d.ts +0 -24
  693. package/dist/infra/email/sigv4.d.ts.map +0 -1
  694. package/dist/infra/email/sigv4.js +0 -55
  695. package/dist/infra/email/sigv4.js.map +0 -1
@@ -0,0 +1,163 @@
1
+ import { execSync } from 'node:child_process'
2
+ import { relative, resolve, sep } from 'node:path'
3
+ import { scrubGitEnv } from './scrub-git-env.js'
4
+
5
+ export type DiffMode = 'uncommitted' | 'staged' | 'branch'
6
+
7
+ // Base branches a `branch`-mode diff is taken against when the blueprint does
8
+ // not configure `fastPath.baseBranches`, in priority order — the working
9
+ // branch first.
10
+ const DEFAULT_BASE_BRANCHES: readonly string[] = ['integration', 'main']
11
+
12
+ // Base refs are interpolated into git commands, so only plain ref characters
13
+ // are admitted — anything else is treated as not-a-base rather than executed.
14
+ const SAFE_REF = /^[A-Za-z0-9._/-]+$/
15
+
16
+ type GitEnv = ReturnType<typeof scrubGitEnv>
17
+
18
+ /**
19
+ * Files changed under `mode`, as paths relative to `anchor` (the directory
20
+ * holding pipework.config.ts — the same base module paths are relative to).
21
+ *
22
+ * Three path coordinate systems meet here, and they only coincide when the
23
+ * anchor IS the git toplevel: `git diff --name-only` prints toplevel-relative
24
+ * paths regardless of cwd, `git ls-files --others` prints cwd-relative paths,
25
+ * and module paths are anchor-relative. Every git command therefore runs from
26
+ * the toplevel and every returned path is rebased onto the anchor before it is
27
+ * handed to `filesToModules` — otherwise a config dir below the toplevel
28
+ * (monorepo layout, e.g. <repo>/packages/backend) makes every diff path miss
29
+ * the module prefix match and `rootChanged` widens every scoped run to all
30
+ * modules. A change outside the anchor subtree comes back as a `../` path,
31
+ * which deliberately matches no module and keeps the fail-wide behavior.
32
+ *
33
+ * `branch` mode (the `--fast` path) returns `null` — never an empty array —
34
+ * when the set cannot be computed (no base branch, unrelated history, no git):
35
+ * the caller must fail open on `null`, widening to everything, never silently
36
+ * scoping to nothing. Issue #325.
37
+ *
38
+ * `uncommitted` / `staged` modes return `[]` on a non-git or empty tree — a
39
+ * clean tree genuinely has nothing to do, and the caller exits 0 (#266). An
40
+ * empty array always means "computed cleanly, nothing changed".
41
+ */
42
+ export function changedFiles(
43
+ anchor: string,
44
+ mode: DiffMode,
45
+ baseBranches?: readonly string[],
46
+ ): string[] | null {
47
+ const env = scrubGitEnv()
48
+
49
+ let toplevel: string
50
+ try {
51
+ toplevel = git(anchor, env, 'git rev-parse --show-toplevel').trim()
52
+ if (toplevel === '') throw new Error('no toplevel')
53
+ } catch {
54
+ // Not a git repository: branch mode must fail open (null), the tree modes
55
+ // report a genuinely empty diff (#266).
56
+ return mode === 'branch' ? null : []
57
+ }
58
+
59
+ if (mode === 'branch') {
60
+ try {
61
+ const base = baseBranch(toplevel, env, baseBranches)
62
+ if (base === null) return null
63
+ const mergeBase = git(toplevel, env, `git merge-base ${base} HEAD`).trim()
64
+ if (mergeBase === '') return null
65
+ const committed = parseLines(git(toplevel, env, `git diff --name-only ${mergeBase}`))
66
+ const untracked = parseLines(git(toplevel, env, 'git ls-files --others --exclude-standard'))
67
+ return rebase([...new Set([...committed, ...untracked])], toplevel, anchor)
68
+ } catch {
69
+ return null
70
+ }
71
+ }
72
+
73
+ try {
74
+ if (mode === 'staged') {
75
+ return rebase(parseLines(git(toplevel, env, 'git diff --name-only --cached')), toplevel, anchor)
76
+ }
77
+ const diffRaw = git(toplevel, env, 'git diff --name-only HEAD')
78
+ const untrackedRaw = git(toplevel, env, 'git ls-files --others --exclude-standard')
79
+ return rebase([...new Set([...parseLines(diffRaw), ...parseLines(untrackedRaw)])], toplevel, anchor)
80
+ } catch {
81
+ return []
82
+ }
83
+ }
84
+
85
+ /** Toplevel-relative git paths → anchor-relative POSIX paths. */
86
+ function rebase(files: readonly string[], toplevel: string, anchor: string): string[] {
87
+ return files.map(f => relative(resolve(anchor), resolve(toplevel, f)).split(sep).join('/'))
88
+ }
89
+
90
+ function git(cwd: string, env: GitEnv, cmd: string): string {
91
+ return execSync(cmd, { cwd, env, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] })
92
+ }
93
+
94
+ /**
95
+ * The base branch a `branch`-mode diff would be taken against, for scope
96
+ * reporting (the population line). `null` when none exists or git is absent.
97
+ */
98
+ export function resolveBaseBranch(anchor: string, baseBranches?: readonly string[]): string | null {
99
+ try {
100
+ return baseBranch(anchor, scrubGitEnv(), baseBranches)
101
+ } catch {
102
+ return null
103
+ }
104
+ }
105
+
106
+ /**
107
+ * The first configured base ref that resolves to a commit, or `null` when none
108
+ * does. A configured entry may be any committish — a local branch, a
109
+ * remote-tracking ref like 'origin/main', a tag — so a stale or absent local
110
+ * ref can be routed around instead of failing every fast run wide.
111
+ */
112
+ function baseBranch(cwd: string, env: GitEnv, baseBranches?: readonly string[]): string | null {
113
+ for (const ref of baseBranches ?? DEFAULT_BASE_BRANCHES) {
114
+ if (!SAFE_REF.test(ref)) continue
115
+ try {
116
+ git(cwd, env, `git rev-parse --verify --quiet ${ref}^{commit}`)
117
+ return ref
118
+ } catch {
119
+ // Not this one — try the next.
120
+ }
121
+ }
122
+ return null
123
+ }
124
+
125
+ export function filesToModules(
126
+ files: readonly string[],
127
+ modulePaths: readonly string[],
128
+ ): { modules: Set<string>; rootChanged: boolean } {
129
+ const sorted = [...modulePaths].sort((a, b) => b.length - a.length)
130
+ const modules = new Set<string>()
131
+ let rootChanged = false
132
+
133
+ for (const file of files) {
134
+ // A `../` path is a change outside the config dir's subtree. It can affect
135
+ // every module (root lockfile, shared tsconfig) but can never BE a module
136
+ // file — not even of the synthesized '.' module — so it always fails wide.
137
+ if (file.startsWith('../')) {
138
+ rootChanged = true
139
+ continue
140
+ }
141
+ let matched = false
142
+ for (const modPath of sorted) {
143
+ // '.' is the synthesized implicit module for a single-package repo — it
144
+ // is the config dir itself, so it contains every anchor-relative file.
145
+ // Rebased paths never carry a leading './', so the prefix check below
146
+ // can never match '.' on its own.
147
+ if (modPath === '.' || file === modPath || file.startsWith(modPath + '/')) {
148
+ modules.add(modPath)
149
+ matched = true
150
+ break
151
+ }
152
+ }
153
+ if (!matched) {
154
+ rootChanged = true
155
+ }
156
+ }
157
+
158
+ return { modules, rootChanged }
159
+ }
160
+
161
+ function parseLines(raw: string): string[] {
162
+ return raw.split('\n').filter(line => line.length > 0)
163
+ }
@@ -0,0 +1,213 @@
1
+ import { readFileSync, existsSync, readdirSync } from 'node:fs'
2
+ import { join, dirname } from 'node:path'
3
+
4
+ const WRAPPED_PACKAGES = [
5
+ 'postgres',
6
+ 'pg',
7
+ '@neondatabase/serverless',
8
+ 'drizzle-orm',
9
+ 'fastify',
10
+ 'zod',
11
+ 'pino',
12
+ 'jose',
13
+ ] as const
14
+
15
+ const WRAPPED_SCOPES = [
16
+ '@fastify/',
17
+ 'drizzle-orm/',
18
+ 'pino/',
19
+ 'zod/',
20
+ ] as const
21
+
22
+ export interface DepViolation {
23
+ readonly package: string
24
+ readonly dependency: string
25
+ readonly field: 'dependencies' | 'devDependencies'
26
+ readonly message: string
27
+ }
28
+
29
+ export interface DepCheckResult {
30
+ readonly violations: readonly DepViolation[]
31
+ readonly packagesChecked: number
32
+ }
33
+
34
+ interface WorkspacePackage {
35
+ readonly name: string
36
+ readonly root: string
37
+ readonly exempt: boolean
38
+ readonly exemptDeps: readonly string[]
39
+ }
40
+
41
+ export function checkDependencies(cwd: string): DepCheckResult {
42
+ const packages = discoverPackages(cwd)
43
+ const violations: DepViolation[] = []
44
+
45
+ for (const pkg of packages) {
46
+ if (pkg.exempt) continue
47
+ checkPackageDeps(pkg, violations)
48
+ }
49
+
50
+ return {
51
+ violations,
52
+ packagesChecked: packages.filter(p => !p.exempt).length,
53
+ }
54
+ }
55
+
56
+ function isBanned(dep: string, exemptDeps: readonly string[]): boolean {
57
+ if (exemptDeps.includes(dep)) return false
58
+
59
+ if ((WRAPPED_PACKAGES as readonly string[]).includes(dep)) return true
60
+
61
+ for (const scope of WRAPPED_SCOPES) {
62
+ if (dep.startsWith(scope)) {
63
+ if (!exemptDeps.some(e => dep.startsWith(e) || dep === e)) return true
64
+ }
65
+ }
66
+
67
+ return false
68
+ }
69
+
70
+ function checkPackageDeps(pkg: WorkspacePackage, violations: DepViolation[]): void {
71
+ const pkgPath = join(pkg.root, 'package.json')
72
+ if (!existsSync(pkgPath)) return
73
+
74
+ let pkgJson: Record<string, unknown>
75
+ try {
76
+ pkgJson = JSON.parse(readFileSync(pkgPath, 'utf-8')) as Record<string, unknown>
77
+ } catch {
78
+ return
79
+ }
80
+
81
+ const fields = ['dependencies', 'devDependencies'] as const
82
+
83
+ for (const field of fields) {
84
+ const deps = pkgJson[field]
85
+ if (typeof deps !== 'object' || deps === null) continue
86
+
87
+ for (const dep of Object.keys(deps as Record<string, unknown>)) {
88
+ if (dep === 'pipework') continue
89
+ if (!isBanned(dep, pkg.exemptDeps)) continue
90
+
91
+ const wrapped = matchWrappedPackage(dep)
92
+ violations.push({
93
+ package: pkg.name,
94
+ dependency: dep,
95
+ field,
96
+ message: `Direct dependency on "${dep}" — this is wrapped by pipework.${wrapped !== null ? `\n Import from pipework instead of "${dep}".` : ''}`,
97
+ })
98
+ }
99
+ }
100
+ }
101
+
102
+ function matchWrappedPackage(dep: string): string | null {
103
+ if (dep === 'postgres' || dep === 'pg' || dep === '@neondatabase/serverless') return 'pipe()'
104
+ if (dep === 'drizzle-orm' || dep.startsWith('drizzle-orm/')) return 'pipe.define(), schema.*'
105
+ if (dep === 'fastify' || dep.startsWith('@fastify/')) return 'surface.http(), fitting()'
106
+ if (dep === 'zod' || dep.startsWith('zod/')) return 'pipe.define() shapes'
107
+ if (dep === 'pino' || dep.startsWith('pino/')) return 'pipework logging'
108
+ if (dep === 'jose') return 'pipework auth'
109
+ return null
110
+ }
111
+
112
+ function discoverPackages(cwd: string): WorkspacePackage[] {
113
+ const workspaceFile = join(cwd, 'pnpm-workspace.yaml')
114
+ if (existsSync(workspaceFile)) {
115
+ return discoverFromPnpmWorkspace(cwd, workspaceFile)
116
+ }
117
+
118
+ const rootPkg = readPackageJson(cwd)
119
+ if (rootPkg !== null) {
120
+ const workspaces = rootPkg['workspaces']
121
+ if (Array.isArray(workspaces)) {
122
+ return expandGlobs(cwd, workspaces as string[])
123
+ }
124
+ if (typeof workspaces === 'object' && workspaces !== null) {
125
+ const packages = (workspaces as Record<string, unknown>)['packages']
126
+ if (Array.isArray(packages)) {
127
+ return expandGlobs(cwd, packages as string[])
128
+ }
129
+ }
130
+ }
131
+
132
+ return []
133
+ }
134
+
135
+ function discoverFromPnpmWorkspace(cwd: string, file: string): WorkspacePackage[] {
136
+ const content = readFileSync(file, 'utf-8')
137
+ const patterns: string[] = []
138
+ for (const line of content.split('\n')) {
139
+ const match = line.match(/^\s*-\s+['"]?([^'"]+)['"]?\s*$/)
140
+ if (match?.[1] !== undefined && match[1] !== '.') {
141
+ patterns.push(match[1])
142
+ }
143
+ }
144
+ return expandGlobs(cwd, patterns)
145
+ }
146
+
147
+ function expandGlobs(cwd: string, patterns: string[]): WorkspacePackage[] {
148
+ const packages: WorkspacePackage[] = []
149
+
150
+ for (const pattern of patterns) {
151
+ if (pattern === '.') continue
152
+
153
+ if (pattern.includes('*')) {
154
+ const base = pattern.replace(/\/?\*.*$/, '')
155
+ const baseDir = join(cwd, base)
156
+ if (!existsSync(baseDir)) continue
157
+
158
+ for (const entry of readdirSync(baseDir, { withFileTypes: true })) {
159
+ if (!entry.isDirectory() || entry.name === 'node_modules') continue
160
+ const pkgDir = join(baseDir, entry.name)
161
+ const pkg = tryLoadPackage(pkgDir)
162
+ if (pkg !== null) packages.push(pkg)
163
+ }
164
+ } else {
165
+ const pkgDir = join(cwd, pattern)
166
+ const pkg = tryLoadPackage(pkgDir)
167
+ if (pkg !== null) packages.push(pkg)
168
+ }
169
+ }
170
+
171
+ return packages
172
+ }
173
+
174
+ function tryLoadPackage(dir: string): WorkspacePackage | null {
175
+ const pkgJson = readPackageJson(dir)
176
+ if (pkgJson === null) return null
177
+
178
+ const name = typeof pkgJson['name'] === 'string' ? pkgJson['name'] : dirname(dir)
179
+ const boundaries = getBoundaryConfig(pkgJson)
180
+
181
+ return {
182
+ name,
183
+ root: dir,
184
+ exempt: boundaries?.exempt === true || boundaries?.dependencies?.exempt === true,
185
+ exemptDeps: boundaries?.dependencies?.allow ?? [],
186
+ }
187
+ }
188
+
189
+ function readPackageJson(dir: string): Record<string, unknown> | null {
190
+ const file = join(dir, 'package.json')
191
+ if (!existsSync(file)) return null
192
+ try {
193
+ return JSON.parse(readFileSync(file, 'utf-8')) as Record<string, unknown>
194
+ } catch {
195
+ return null
196
+ }
197
+ }
198
+
199
+ interface BoundaryConfig {
200
+ readonly exempt?: boolean
201
+ readonly dependencies?: {
202
+ readonly exempt?: boolean
203
+ readonly allow?: readonly string[]
204
+ }
205
+ }
206
+
207
+ function getBoundaryConfig(pkgJson: Record<string, unknown>): BoundaryConfig | null {
208
+ const pw = pkgJson['pipework']
209
+ if (typeof pw !== 'object' || pw === null) return null
210
+ const boundaries = (pw as Record<string, unknown>)['boundaries']
211
+ if (typeof boundaries !== 'object' || boundaries === null) return null
212
+ return boundaries as BoundaryConfig
213
+ }
@@ -0,0 +1,20 @@
1
+ import { createHash } from 'node:crypto'
2
+
3
+ export function computeChecksum(input: string): string {
4
+ const hash = createHash('sha256').update(input).digest('hex').slice(0, 16)
5
+ return `sha256:${hash}`
6
+ }
7
+
8
+ export function checksumFromPackageJson(content: string): string | undefined {
9
+ try {
10
+ const parsed = JSON.parse(content) as Record<string, unknown>
11
+ if (typeof parsed['_checksum'] === 'string') return parsed['_checksum']
12
+ return undefined
13
+ } catch {
14
+ return undefined
15
+ }
16
+ }
17
+
18
+ export function isStale(expected: string, actual: string | undefined): boolean {
19
+ return actual !== expected
20
+ }
@@ -0,0 +1,67 @@
1
+ import type { ResolvedModule } from './discover.js'
2
+ import { modulePackageName } from './module-package-name.js'
3
+
4
+ export interface ModuleGraph {
5
+ affected(changed: ReadonlySet<string>): ReadonlySet<string>
6
+ dependentsOf(modulePath: string): ReadonlySet<string>
7
+ allModules(): ReadonlySet<string>
8
+ }
9
+
10
+ export function buildModuleGraph(
11
+ modules: readonly ResolvedModule[],
12
+ projectName: string,
13
+ ): ModuleGraph {
14
+ const packageToPath = new Map<string, string>()
15
+ for (const mod of modules) {
16
+ packageToPath.set(modulePackageName(mod, projectName), mod.relativePath)
17
+ }
18
+
19
+ const allPaths = new Set(modules.map(m => m.relativePath))
20
+
21
+ const dependents = new Map<string, Set<string>>()
22
+ for (const path of allPaths) {
23
+ dependents.set(path, new Set())
24
+ }
25
+
26
+ for (const mod of modules) {
27
+ const deps = { ...mod.config.dependencies, ...mod.config.devDependencies }
28
+ for (const [pkgName, version] of Object.entries(deps)) {
29
+ if (version === null || !version.startsWith('workspace:')) continue
30
+ const depPath = packageToPath.get(pkgName)
31
+ if (depPath === undefined) continue
32
+ dependents.get(depPath)!.add(mod.relativePath)
33
+ }
34
+ }
35
+
36
+ return {
37
+ affected(changed: ReadonlySet<string>): ReadonlySet<string> {
38
+ const result = new Set<string>()
39
+ const queue = [...changed]
40
+
41
+ while (queue.length > 0) {
42
+ const current = queue.pop()!
43
+ if (result.has(current)) continue
44
+ if (!allPaths.has(current)) continue
45
+ result.add(current)
46
+ const deps = dependents.get(current)
47
+ if (deps !== undefined) {
48
+ for (const dep of deps) {
49
+ if (!result.has(dep)) {
50
+ queue.push(dep)
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ return result
57
+ },
58
+
59
+ dependentsOf(modulePath: string): ReadonlySet<string> {
60
+ return dependents.get(modulePath) ?? new Set()
61
+ },
62
+
63
+ allModules(): ReadonlySet<string> {
64
+ return allPaths
65
+ },
66
+ }
67
+ }
@@ -0,0 +1,93 @@
1
+ import { readdirSync, readFileSync } from 'node:fs'
2
+ import { join } from 'node:path'
3
+
4
+ export interface PipeworkCopy {
5
+ readonly version: string
6
+ readonly path: string
7
+ }
8
+
9
+ export interface PipeworkInstall {
10
+ /** Copies the install resolves: the hoisted copy plus every store copy the virtual-store lockfile names. */
11
+ readonly copies: PipeworkCopy[]
12
+ /** Store copies the lockfile does not name: stale directories pnpm left behind. */
13
+ readonly orphans: PipeworkCopy[]
14
+ }
15
+
16
+ // Pipework versions named by the keys of `node_modules/.pnpm/lock.yaml`, or undefined when the
17
+ // file is absent, unreadable, or names none (a key format this scan does not know). Keys seen across pnpm versions: `pipework@0.211.0(peers):`,
18
+ // `/pipework@0.211.0(peers):`, `/pipework/0.11.0_peerhash:`, any of them quoted. Scanned by
19
+ // line so no YAML parser is needed; `pipework-flow-parser@…` never matches (`@` or `/` must follow).
20
+ function readLockedVersions(storeDir: string): Set<string> | undefined {
21
+ let raw: string
22
+ try {
23
+ raw = readFileSync(join(storeDir, 'lock.yaml'), 'utf8')
24
+ } catch {
25
+ return undefined
26
+ }
27
+ const versions = new Set<string>()
28
+ for (const line of raw.split('\n')) {
29
+ const m = /^\s*['"]?\/?pipework[@/]([^()_:'"\s]+)/.exec(line)
30
+ if (m !== null) versions.add(m[1]!)
31
+ }
32
+ return versions.size === 0 ? undefined : versions
33
+ }
34
+
35
+ // Detects every physical copy of pipework resolvable from a workspace's install tree.
36
+ // Two copies of the SAME version are harmless (the runtime broker shares one ALS across
37
+ // them); copies of DIFFERENT versions are the multi-instance hazard — a shared library
38
+ // resolving a different pipework than its workspace forks the ALS and error classes
39
+ // (no active context; 403->500), and on 0.12.0+ the broker throws at first use. Catching
40
+ // the skew here, at check/CI time, surfaces it before first request.
41
+ //
42
+ // A virtual-store directory the install does not resolve (its version is not in the store's
43
+ // lock.yaml) is an orphan: pnpm leaves the previous version's directory behind after a move.
44
+ // It is reported apart and never counted as a loaded copy. With no readable lock.yaml, or one
45
+ // naming no pipework, every store directory counts.
46
+ export function detectPipeworkInstall(cwd: string): PipeworkInstall {
47
+ const copies = new Map<string, PipeworkCopy>()
48
+ const orphans = new Map<string, PipeworkCopy>()
49
+
50
+ const read = (pkgJsonPath: string): PipeworkCopy | undefined => {
51
+ try {
52
+ const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8')) as { name?: string; version?: string }
53
+ if (pkg.name === 'pipework' && typeof pkg.version === 'string') {
54
+ return { version: pkg.version, path: pkgJsonPath }
55
+ }
56
+ } catch {
57
+ // not a readable/parseable package.json — skip
58
+ }
59
+ return undefined
60
+ }
61
+
62
+ // Hoisted copy: always resolved.
63
+ const hoisted = read(join(cwd, 'node_modules', 'pipework', 'package.json'))
64
+ if (hoisted !== undefined) copies.set(hoisted.path, hoisted)
65
+
66
+ // pnpm virtual store: node_modules/.pnpm/pipework@<version>[_<peerhash>]/node_modules/pipework.
67
+ // `pipework@` (not `pipework-`) excludes pipework-flow-parser and other prefixed packages.
68
+ const pnpmDir = join(cwd, 'node_modules', '.pnpm')
69
+ try {
70
+ const locked = readLockedVersions(pnpmDir)
71
+ for (const entry of readdirSync(pnpmDir)) {
72
+ if (!entry.startsWith('pipework@')) continue
73
+ const c = read(join(pnpmDir, entry, 'node_modules', 'pipework', 'package.json'))
74
+ if (c === undefined) continue
75
+ if (locked === undefined || locked.has(c.version)) copies.set(c.path, c)
76
+ else orphans.set(c.path, c)
77
+ }
78
+ } catch {
79
+ // no .pnpm store (npm/yarn, or not installed) — the hoisted check above still applies
80
+ }
81
+
82
+ return { copies: [...copies.values()], orphans: [...orphans.values()] }
83
+ }
84
+
85
+ /** The copies the install resolves; see detectPipeworkInstall for the orphans. */
86
+ export function detectPipeworkCopies(cwd: string): PipeworkCopy[] {
87
+ return detectPipeworkInstall(cwd).copies
88
+ }
89
+
90
+ /** Distinct pipework versions across the resolved copies, sorted. More than one means skew. */
91
+ export function distinctPipeworkVersions(copies: readonly PipeworkCopy[]): string[] {
92
+ return [...new Set(copies.map((c) => c.version))].sort()
93
+ }