pipework 0.211.1 → 0.242.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 (324) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/REFERENCE.md +95 -2
  3. package/dist/async/jobs/claims.d.ts +1 -1
  4. package/dist/async/jobs/claims.d.ts.map +1 -1
  5. package/dist/async/jobs/claims.js +2 -1
  6. package/dist/async/jobs/claims.js.map +1 -1
  7. package/dist/async/jobs/queue.d.ts +11 -2
  8. package/dist/async/jobs/queue.d.ts.map +1 -1
  9. package/dist/async/jobs/queue.js +93 -25
  10. package/dist/async/jobs/queue.js.map +1 -1
  11. package/dist/async/jobs/table.d.ts +4 -0
  12. package/dist/async/jobs/table.d.ts.map +1 -1
  13. package/dist/async/jobs/table.js +12 -1
  14. package/dist/async/jobs/table.js.map +1 -1
  15. package/dist/cli/commands/openapi.d.ts +8 -0
  16. package/dist/cli/commands/openapi.d.ts.map +1 -0
  17. package/dist/cli/commands/openapi.js +49 -0
  18. package/dist/cli/commands/openapi.js.map +1 -0
  19. package/dist/cli/commands/serve.d.ts +8 -0
  20. package/dist/cli/commands/serve.d.ts.map +1 -1
  21. package/dist/cli/commands/serve.js +22 -3
  22. package/dist/cli/commands/serve.js.map +1 -1
  23. package/dist/cli/dev-bootstrap.js +6 -1
  24. package/dist/cli/dev-bootstrap.js.map +1 -1
  25. package/dist/cli/index.d.ts.map +1 -1
  26. package/dist/cli/index.js +15 -1
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/cli/surface-kinds.d.ts +5 -0
  29. package/dist/cli/surface-kinds.d.ts.map +1 -0
  30. package/dist/cli/surface-kinds.js +15 -0
  31. package/dist/cli/surface-kinds.js.map +1 -0
  32. package/dist/core/config/load.d.ts +1 -0
  33. package/dist/core/config/load.d.ts.map +1 -1
  34. package/dist/core/config/load.js +1 -0
  35. package/dist/core/config/load.js.map +1 -1
  36. package/dist/core/config/namespace.d.ts +6 -0
  37. package/dist/core/config/namespace.d.ts.map +1 -1
  38. package/dist/core/config/schema.d.ts +15 -0
  39. package/dist/core/config/schema.d.ts.map +1 -1
  40. package/dist/core/config/schema.js +11 -2
  41. package/dist/core/config/schema.js.map +1 -1
  42. package/dist/core/lifecycle/health.js +2 -2
  43. package/dist/core/lifecycle/health.js.map +1 -1
  44. package/dist/core/lifecycle/types.d.ts +2 -0
  45. package/dist/core/lifecycle/types.d.ts.map +1 -1
  46. package/dist/core/pipework.d.ts +14 -1
  47. package/dist/core/pipework.d.ts.map +1 -1
  48. package/dist/core/pipework.js +18 -2
  49. package/dist/core/pipework.js.map +1 -1
  50. package/dist/core/surface/http.d.ts +3 -0
  51. package/dist/core/surface/http.d.ts.map +1 -1
  52. package/dist/core/surface/http.js +27 -8
  53. package/dist/core/surface/http.js.map +1 -1
  54. package/dist/core/surface/start.d.ts.map +1 -1
  55. package/dist/core/surface/start.js +19 -3
  56. package/dist/core/surface/start.js.map +1 -1
  57. package/dist/core/surface/types.d.ts +9 -1
  58. package/dist/core/surface/types.d.ts.map +1 -1
  59. package/dist/data/db/filter.d.ts +3 -0
  60. package/dist/data/db/filter.d.ts.map +1 -1
  61. package/dist/data/db/filter.js +3 -0
  62. package/dist/data/db/filter.js.map +1 -1
  63. package/dist/data/db/in-list.d.ts +15 -0
  64. package/dist/data/db/in-list.d.ts.map +1 -0
  65. package/dist/data/db/in-list.js +51 -0
  66. package/dist/data/db/in-list.js.map +1 -0
  67. package/dist/data/db/namespace.d.ts +2 -0
  68. package/dist/data/db/namespace.d.ts.map +1 -1
  69. package/dist/data/db/pool.d.ts +1 -1
  70. package/dist/data/db/pool.d.ts.map +1 -1
  71. package/dist/data/db/pool.js +4 -2
  72. package/dist/data/db/pool.js.map +1 -1
  73. package/dist/data/db/reservation.d.ts +40 -0
  74. package/dist/data/db/reservation.d.ts.map +1 -0
  75. package/dist/data/db/reservation.js +108 -0
  76. package/dist/data/db/reservation.js.map +1 -0
  77. package/dist/data/domain/build-table.js +32 -1
  78. package/dist/data/domain/build-table.js.map +1 -1
  79. package/dist/data/domain/index.d.ts +2 -1
  80. package/dist/data/domain/index.d.ts.map +1 -1
  81. package/dist/data/domain/types.d.ts +9 -1
  82. package/dist/data/domain/types.d.ts.map +1 -1
  83. package/dist/data/domain/types.js.map +1 -1
  84. package/dist/data/migrate/apply.d.ts.map +1 -1
  85. package/dist/data/migrate/apply.js +3 -11
  86. package/dist/data/migrate/apply.js.map +1 -1
  87. package/dist/data/migrate/check.d.ts.map +1 -1
  88. package/dist/data/migrate/check.js +3 -6
  89. package/dist/data/migrate/check.js.map +1 -1
  90. package/dist/data/migrate/diff.d.ts +16 -0
  91. package/dist/data/migrate/diff.d.ts.map +1 -1
  92. package/dist/data/migrate/diff.js +44 -4
  93. package/dist/data/migrate/diff.js.map +1 -1
  94. package/dist/data/migrate/generate.d.ts +1 -1
  95. package/dist/data/migrate/generate.d.ts.map +1 -1
  96. package/dist/data/migrate/generate.js +19 -51
  97. package/dist/data/migrate/generate.js.map +1 -1
  98. package/dist/data/migrate/history.d.ts +36 -0
  99. package/dist/data/migrate/history.d.ts.map +1 -0
  100. package/dist/data/migrate/history.js +185 -0
  101. package/dist/data/migrate/history.js.map +1 -0
  102. package/dist/data/migrate/internal-definitions.d.ts.map +1 -1
  103. package/dist/data/migrate/internal-definitions.js +22 -1
  104. package/dist/data/migrate/internal-definitions.js.map +1 -1
  105. package/dist/data/migrate/provision-framework.d.ts +2 -0
  106. package/dist/data/migrate/provision-framework.d.ts.map +1 -1
  107. package/dist/data/migrate/provision-framework.js +11 -3
  108. package/dist/data/migrate/provision-framework.js.map +1 -1
  109. package/dist/data/migrate/snapshot.d.ts +4 -0
  110. package/dist/data/migrate/snapshot.d.ts.map +1 -1
  111. package/dist/data/migrate/snapshot.js +2 -0
  112. package/dist/data/migrate/snapshot.js.map +1 -1
  113. package/dist/data/migrate/sql-emit.js +66 -12
  114. package/dist/data/migrate/sql-emit.js.map +1 -1
  115. package/dist/data/query/pg-core/foreign-keys.d.ts +5 -0
  116. package/dist/data/query/pg-core/foreign-keys.d.ts.map +1 -1
  117. package/dist/data/query/pg-core/foreign-keys.js +9 -0
  118. package/dist/data/query/pg-core/foreign-keys.js.map +1 -1
  119. package/dist/data/query/pg-core/indexes.d.ts +5 -0
  120. package/dist/data/query/pg-core/indexes.d.ts.map +1 -1
  121. package/dist/data/query/pg-core/indexes.js +7 -0
  122. package/dist/data/query/pg-core/indexes.js.map +1 -1
  123. package/dist/data/schema/json-schema.js +29 -1
  124. package/dist/data/schema/json-schema.js.map +1 -1
  125. package/dist/data/schema/types.d.ts +2 -2
  126. package/dist/data/schema/types.d.ts.map +1 -1
  127. package/dist/index.d.ts +18 -9
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +5 -1
  130. package/dist/index.js.map +1 -1
  131. package/dist/infra/alerts/handle.d.ts +33 -5
  132. package/dist/infra/alerts/handle.d.ts.map +1 -1
  133. package/dist/infra/alerts/handle.js +56 -12
  134. package/dist/infra/alerts/handle.js.map +1 -1
  135. package/dist/infra/alerts/http.d.ts +2 -2
  136. package/dist/infra/alerts/http.d.ts.map +1 -1
  137. package/dist/infra/alerts/http.js +21 -3
  138. package/dist/infra/alerts/http.js.map +1 -1
  139. package/dist/infra/alerts/index.d.ts +1 -1
  140. package/dist/infra/alerts/index.d.ts.map +1 -1
  141. package/dist/infra/alerts/schema.d.ts +5 -0
  142. package/dist/infra/alerts/schema.d.ts.map +1 -1
  143. package/dist/infra/alerts/schema.js +1 -0
  144. package/dist/infra/alerts/schema.js.map +1 -1
  145. package/dist/infra/crawl/audit.d.ts +6 -0
  146. package/dist/infra/crawl/audit.d.ts.map +1 -0
  147. package/dist/infra/crawl/audit.js +38 -0
  148. package/dist/infra/crawl/audit.js.map +1 -0
  149. package/dist/infra/crawl/errors.d.ts +14 -0
  150. package/dist/infra/crawl/errors.d.ts.map +1 -0
  151. package/dist/infra/crawl/errors.js +22 -0
  152. package/dist/infra/crawl/errors.js.map +1 -0
  153. package/dist/infra/crawl/handle.d.ts +149 -0
  154. package/dist/infra/crawl/handle.d.ts.map +1 -0
  155. package/dist/infra/crawl/handle.js +550 -0
  156. package/dist/infra/crawl/handle.js.map +1 -0
  157. package/dist/infra/crawl/index.d.ts +7 -0
  158. package/dist/infra/crawl/index.d.ts.map +1 -0
  159. package/dist/infra/crawl/index.js +5 -0
  160. package/dist/infra/crawl/index.js.map +1 -0
  161. package/dist/infra/crawl/links.d.ts +9 -0
  162. package/dist/infra/crawl/links.d.ts.map +1 -0
  163. package/dist/infra/crawl/links.js +194 -0
  164. package/dist/infra/crawl/links.js.map +1 -0
  165. package/dist/infra/crawl/namespace.d.ts +36 -0
  166. package/dist/infra/crawl/namespace.d.ts.map +1 -0
  167. package/dist/infra/crawl/namespace.js +36 -0
  168. package/dist/infra/crawl/namespace.js.map +1 -0
  169. package/dist/infra/crawl/robots.d.ts +16 -0
  170. package/dist/infra/crawl/robots.d.ts.map +1 -0
  171. package/dist/infra/crawl/robots.js +98 -0
  172. package/dist/infra/crawl/robots.js.map +1 -0
  173. package/dist/infra/crawl/schema.d.ts +222 -0
  174. package/dist/infra/crawl/schema.d.ts.map +1 -0
  175. package/dist/infra/crawl/schema.js +84 -0
  176. package/dist/infra/crawl/schema.js.map +1 -0
  177. package/dist/infra/credit-line/handle.d.ts +250 -0
  178. package/dist/infra/credit-line/handle.d.ts.map +1 -0
  179. package/dist/infra/credit-line/handle.js +618 -0
  180. package/dist/infra/credit-line/handle.js.map +1 -0
  181. package/dist/infra/credit-line/index.d.ts +3 -0
  182. package/dist/infra/credit-line/index.d.ts.map +1 -0
  183. package/dist/infra/credit-line/index.js +2 -0
  184. package/dist/infra/credit-line/index.js.map +1 -0
  185. package/dist/infra/credit-line/namespace.d.ts +7 -0
  186. package/dist/infra/credit-line/namespace.d.ts.map +1 -0
  187. package/dist/infra/credit-line/namespace.js +7 -0
  188. package/dist/infra/credit-line/namespace.js.map +1 -0
  189. package/dist/infra/credit-line/schema.d.ts +194 -0
  190. package/dist/infra/credit-line/schema.d.ts.map +1 -0
  191. package/dist/infra/credit-line/schema.js +89 -0
  192. package/dist/infra/credit-line/schema.js.map +1 -0
  193. package/dist/infra/email/inbound.d.ts +14 -2
  194. package/dist/infra/email/inbound.d.ts.map +1 -1
  195. package/dist/infra/email/inbound.js +5 -1
  196. package/dist/infra/email/inbound.js.map +1 -1
  197. package/dist/infra/email/index.d.ts +2 -2
  198. package/dist/infra/email/index.d.ts.map +1 -1
  199. package/dist/infra/email/index.js.map +1 -1
  200. package/dist/infra/email/mail.d.ts +43 -5
  201. package/dist/infra/email/mail.d.ts.map +1 -1
  202. package/dist/infra/email/mail.js +124 -9
  203. package/dist/infra/email/mail.js.map +1 -1
  204. package/dist/infra/email/mime.d.ts +6 -0
  205. package/dist/infra/email/mime.d.ts.map +1 -1
  206. package/dist/infra/email/mime.js +10 -2
  207. package/dist/infra/email/mime.js.map +1 -1
  208. package/dist/infra/email/schema.d.ts +17 -3
  209. package/dist/infra/email/schema.d.ts.map +1 -1
  210. package/dist/infra/email/schema.js +15 -4
  211. package/dist/infra/email/schema.js.map +1 -1
  212. package/dist/infra/email/sns.js +2 -2
  213. package/dist/infra/email/sns.js.map +1 -1
  214. package/dist/infra/email/unsubscribe.d.ts +13 -0
  215. package/dist/infra/email/unsubscribe.d.ts.map +1 -0
  216. package/dist/infra/email/unsubscribe.js +43 -0
  217. package/dist/infra/email/unsubscribe.js.map +1 -0
  218. package/dist/infra/fetch/handle.d.ts +20 -1
  219. package/dist/infra/fetch/handle.d.ts.map +1 -1
  220. package/dist/infra/fetch/handle.js +60 -28
  221. package/dist/infra/fetch/handle.js.map +1 -1
  222. package/dist/infra/fetch/index.d.ts +2 -2
  223. package/dist/infra/fetch/index.d.ts.map +1 -1
  224. package/dist/infra/fetch/index.js +1 -1
  225. package/dist/infra/fetch/index.js.map +1 -1
  226. package/dist/infra/fetch/namespace.d.ts +20 -2
  227. package/dist/infra/fetch/namespace.d.ts.map +1 -1
  228. package/dist/infra/fetch/namespace.js +20 -2
  229. package/dist/infra/fetch/namespace.js.map +1 -1
  230. package/dist/infra/join-requests/handle.d.ts +86 -0
  231. package/dist/infra/join-requests/handle.d.ts.map +1 -0
  232. package/dist/infra/join-requests/handle.js +233 -0
  233. package/dist/infra/join-requests/handle.js.map +1 -0
  234. package/dist/infra/join-requests/index.d.ts +3 -0
  235. package/dist/infra/join-requests/index.d.ts.map +1 -0
  236. package/dist/infra/join-requests/index.js +2 -0
  237. package/dist/infra/join-requests/index.js.map +1 -0
  238. package/dist/infra/join-requests/namespace.d.ts +7 -0
  239. package/dist/infra/join-requests/namespace.d.ts.map +1 -0
  240. package/dist/infra/join-requests/namespace.js +7 -0
  241. package/dist/infra/join-requests/namespace.js.map +1 -0
  242. package/dist/infra/join-requests/schema.d.ts +58 -0
  243. package/dist/infra/join-requests/schema.d.ts.map +1 -0
  244. package/dist/infra/join-requests/schema.js +31 -0
  245. package/dist/infra/join-requests/schema.js.map +1 -0
  246. package/dist/infra/outbox/core.d.ts +9 -0
  247. package/dist/infra/outbox/core.d.ts.map +1 -1
  248. package/dist/infra/outbox/core.js +14 -0
  249. package/dist/infra/outbox/core.js.map +1 -1
  250. package/dist/infra/support/handle.d.ts +43 -0
  251. package/dist/infra/support/handle.d.ts.map +1 -1
  252. package/dist/infra/support/handle.js +35 -7
  253. package/dist/infra/support/handle.js.map +1 -1
  254. package/dist/infra/support/http.d.ts +28 -0
  255. package/dist/infra/support/http.d.ts.map +1 -0
  256. package/dist/infra/support/http.js +217 -0
  257. package/dist/infra/support/http.js.map +1 -0
  258. package/dist/infra/support/index.d.ts +2 -0
  259. package/dist/infra/support/index.d.ts.map +1 -1
  260. package/dist/infra/support/index.js +1 -0
  261. package/dist/infra/support/index.js.map +1 -1
  262. package/dist/infra/support/namespace.d.ts +3 -0
  263. package/dist/infra/support/namespace.d.ts.map +1 -1
  264. package/dist/infra/support/namespace.js +3 -0
  265. package/dist/infra/support/namespace.js.map +1 -1
  266. package/dist/infra/support/schema.d.ts +4 -4
  267. package/dist/infra/webhook/outbound.d.ts +16 -0
  268. package/dist/infra/webhook/outbound.d.ts.map +1 -1
  269. package/dist/infra/webhook/outbound.js +78 -27
  270. package/dist/infra/webhook/outbound.js.map +1 -1
  271. package/dist/request/di/builder.d.ts +24 -1
  272. package/dist/request/di/builder.d.ts.map +1 -1
  273. package/dist/request/di/builder.js +35 -0
  274. package/dist/request/di/builder.js.map +1 -1
  275. package/dist/request/di/types.d.ts +30 -0
  276. package/dist/request/di/types.d.ts.map +1 -1
  277. package/dist/request/http/server.d.ts.map +1 -1
  278. package/dist/request/http/server.js +111 -20
  279. package/dist/request/http/server.js.map +1 -1
  280. package/dist/test/auto-setup.js +2 -2
  281. package/dist/test/auto-setup.js.map +1 -1
  282. package/dist/test/crawl-fixture.d.ts +53 -0
  283. package/dist/test/crawl-fixture.d.ts.map +1 -0
  284. package/dist/test/crawl-fixture.js +130 -0
  285. package/dist/test/crawl-fixture.js.map +1 -0
  286. package/dist/test/index.d.ts +2 -1
  287. package/dist/test/index.d.ts.map +1 -1
  288. package/dist/test/index.js +2 -1
  289. package/dist/test/index.js.map +1 -1
  290. package/dist/test/progress.d.ts +7 -1
  291. package/dist/test/progress.d.ts.map +1 -1
  292. package/dist/test/progress.js +6 -0
  293. package/dist/test/progress.js.map +1 -1
  294. package/dist/test/reap-after-run.d.ts +3 -0
  295. package/dist/test/reap-after-run.d.ts.map +1 -0
  296. package/dist/test/reap-after-run.js +29 -0
  297. package/dist/test/reap-after-run.js.map +1 -0
  298. package/dist/test/reap.d.ts +11 -2
  299. package/dist/test/reap.d.ts.map +1 -1
  300. package/dist/test/reap.js +19 -12
  301. package/dist/test/reap.js.map +1 -1
  302. package/dist/test/setup.d.ts +2 -0
  303. package/dist/test/setup.d.ts.map +1 -1
  304. package/dist/test/setup.js +87 -30
  305. package/dist/test/setup.js.map +1 -1
  306. package/dist/test/vitest-plugin.d.ts.map +1 -1
  307. package/dist/test/vitest-plugin.js +8 -1
  308. package/dist/test/vitest-plugin.js.map +1 -1
  309. package/dist/test/vitest-workspace.d.ts +1 -0
  310. package/dist/test/vitest-workspace.d.ts.map +1 -1
  311. package/dist/test/vitest-workspace.js +1 -1
  312. package/dist/test/vitest-workspace.js.map +1 -1
  313. package/dist/test/vitest.d.ts +20 -0
  314. package/dist/test/vitest.d.ts.map +1 -1
  315. package/dist/test/vitest.js +41 -1
  316. package/dist/test/vitest.js.map +1 -1
  317. package/dist/trace/partition/sync.d.ts +8 -2
  318. package/dist/trace/partition/sync.d.ts.map +1 -1
  319. package/dist/trace/partition/sync.js +6 -3
  320. package/dist/trace/partition/sync.js.map +1 -1
  321. package/dist/workspace/generate.d.ts.map +1 -1
  322. package/dist/workspace/generate.js +1 -0
  323. package/dist/workspace/generate.js.map +1 -1
  324. package/package.json +1 -1
@@ -0,0 +1,217 @@
1
+ import { createHash, timingSafeEqual } from 'node:crypto';
2
+ import { Builder } from '../../request/di/builder.js';
3
+ import { schema } from '../../data/schema/namespace.js';
4
+ import { NotFoundError, UnauthorizedError, ForbiddenError } from '../../core/errors/index.js';
5
+ import { requireContext, runInContext } from '../../request/context/store.js';
6
+ import { __flowStep } from '../../trace/runtime/flow-step.js';
7
+ import { pipeSystem } from '../../data/db/db.js';
8
+ import { sql } from '../../data/db/sql.js';
9
+ import { BadRequestError } from '../alerts/http.js';
10
+ import { TICKET_STATES } from './schema.js';
11
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
12
+ const sha = (s) => createHash('sha256').update(s).digest();
13
+ function authenticate(credentials, header) {
14
+ const match = header !== undefined ? /^Bearer (.+)$/.exec(header) : null;
15
+ const given = sha(match?.[1] ?? '');
16
+ let found = null;
17
+ for (const [principal, digest] of credentials) {
18
+ if (timingSafeEqual(given, digest) && match !== null && found === null)
19
+ found = principal;
20
+ }
21
+ if (found === null)
22
+ throw new UnauthorizedError('A valid service credential is required: send Authorization: Bearer <secret>.');
23
+ return found;
24
+ }
25
+ function bad(field, problem) {
26
+ throw new BadRequestError(`Invalid ${field}: ${problem}.`, { field });
27
+ }
28
+ function optString(source, field) {
29
+ const value = source?.[field];
30
+ if (value === undefined)
31
+ return undefined;
32
+ if (typeof value !== 'string')
33
+ bad(field, 'must be a string');
34
+ return value;
35
+ }
36
+ function reqString(source, field) {
37
+ const value = optString(source, field);
38
+ if (value === undefined)
39
+ bad(field, 'is required');
40
+ return value;
41
+ }
42
+ function body(raw) {
43
+ if (raw === undefined || raw === null)
44
+ return {};
45
+ if (typeof raw !== 'object' || Array.isArray(raw))
46
+ bad('body', 'must be a JSON object');
47
+ return raw;
48
+ }
49
+ function limitOf(raw) {
50
+ if (raw === undefined)
51
+ return undefined;
52
+ if (!/^[1-9][0-9]*$/.test(raw))
53
+ bad('limit', 'must be a positive integer');
54
+ return Number(raw);
55
+ }
56
+ function validateOptions(options) {
57
+ if (!options.path.startsWith('/') || options.path.length < 2 || options.path.endsWith('/')) {
58
+ throw new Error(`support.http: path "${options.path}" must start with "/" and have no trailing slash, e.g. "/ops/support".`);
59
+ }
60
+ const entries = Object.entries(options.credentials);
61
+ if (entries.length === 0) {
62
+ throw new Error('support.http: credentials needs at least one entry, name -> secret (the secret is at least 32 characters).');
63
+ }
64
+ for (const [name, cred] of entries) {
65
+ const secret = typeof cred === 'string' ? cred : cred?.secret;
66
+ if (typeof secret !== 'string' || secret.length < 32) {
67
+ throw new Error(`support.http: the secret for credential "${name}" is under 32 characters; use a long random value.`);
68
+ }
69
+ if (typeof cred !== 'string' && cred.approve !== undefined && typeof cred.approve !== 'boolean') {
70
+ throw new Error(`support.http: "approve" for credential "${name}" must be true or false.`);
71
+ }
72
+ }
73
+ }
74
+ /**
75
+ * Routes for a support agent, under `options.path` (all JSON, no session, no tenant): GET list (`state`, `category`,
76
+ * `tenantId`, `limit`, `cursor`), GET `/:id` (ticket, messages, links), PATCH `/:id` (`{ category }`, null clears),
77
+ * POST `/:id/transition` (`{ to }`), `/:id/notes` (`{ text }`), `/:id/links` (`{ kind, ref, label? }`),
78
+ * `/:id/drafts` (`{ text, html?, subject? }`, answers `{ draftId, version }`), PATCH and DELETE `/drafts/:id`, and
79
+ * POST `/drafts/:id/approve` (`{ version }`, 403 for a key without `approve: true`). A stale or already-approved draft is 409.
80
+ * Every request needs `Authorization: Bearer <secret>` matching one of `credentials`; the credential's name is the actor
81
+ * (audit rows, a draft's author, the approver), so `canApprove` and `distinctApprover` judge the key's name.
82
+ * Each call is the handle's own, traced and audited by it. Ids are looked up across tenants on the system channel, which a
83
+ * database with `rls.platformRole` refuses over the support tables; there these routes do not work. A bad value is 400 naming the field.
84
+ */
85
+ export function supportHttp(handle, options) {
86
+ validateOptions(options);
87
+ const credentials = Object.entries(options.credentials).map(([name, cred]) => {
88
+ const principal = typeof cred === 'string' ? { name, approve: false } : { name, approve: cred.approve === true };
89
+ return [principal, sha(typeof cred === 'string' ? cred : cred.secret)];
90
+ });
91
+ const base = options.path;
92
+ const any = schema.check.unknown();
93
+ const get = (path) => new Builder().public().request().query(any).params(any).route('GET', path);
94
+ const withBody = (method, path) => new Builder().public().request().query(any).params(any).input(any).route(method, path);
95
+ const del = (path) => new Builder().public().request().query(any).params(any).route('DELETE', path);
96
+ const idOf = (params) => String(params.id);
97
+ // The handle takes its actor from the Flow's auth: run each call as the key's name, in a trace step so its audit
98
+ // records have one to sit under.
99
+ const as = (who, fn) => {
100
+ const flow = requireContext();
101
+ const step = __flowStep({ ref: 'src/infra/support/http.ts:supportHttp' }, fn);
102
+ return runInContext({ ...flow, auth: { userId: who.name } }, step);
103
+ };
104
+ const tenantOfTicket = async (id) => {
105
+ if (UUID_RE.test(id)) {
106
+ const rows = await pipeSystem().execute(sql `SELECT tenant_id FROM support_ticket WHERE id = ${id}::uuid`);
107
+ if (rows[0] !== undefined)
108
+ return rows[0]['tenant_id'];
109
+ }
110
+ throw new NotFoundError('Support ticket', { ticketId: id });
111
+ };
112
+ const tenantOfDraft = async (id) => {
113
+ if (UUID_RE.test(id)) {
114
+ const rows = await pipeSystem().execute(sql `SELECT tenant_id FROM support_message WHERE id = ${id}::uuid AND kind = 'draft'`);
115
+ if (rows[0] !== undefined)
116
+ return rows[0]['tenant_id'];
117
+ }
118
+ throw new NotFoundError('Support draft', { draftId: id });
119
+ };
120
+ const draftPatch = (b) => {
121
+ const text = optString(b, 'text');
122
+ const html = optString(b, 'html');
123
+ const subject = optString(b, 'subject');
124
+ return { ...(text === undefined ? {} : { text }), ...(html === undefined ? {} : { html }), ...(subject === undefined ? {} : { subject }) };
125
+ };
126
+ return [
127
+ get(base).fit(async ({ request, query }) => {
128
+ const who = authenticate(credentials, request.headers['authorization']);
129
+ const state = optString(query, 'state');
130
+ if (state !== undefined && !TICKET_STATES.includes(state))
131
+ bad('state', `"${state}" is not one of ${TICKET_STATES.join(', ')}`);
132
+ const category = optString(query, 'category');
133
+ const tenantId = optString(query, 'tenantId');
134
+ const limit = limitOf(optString(query, 'limit'));
135
+ const cursor = optString(query, 'cursor');
136
+ if (tenantId !== undefined && !UUID_RE.test(tenantId))
137
+ bad('tenantId', 'must be a UUID');
138
+ return as(who, () => handle.listAll({
139
+ ...(state === undefined ? {} : { state: state }), ...(category === undefined ? {} : { category }), ...(tenantId === undefined ? {} : { tenantId }),
140
+ ...(limit === undefined ? {} : { limit }), ...(cursor === undefined ? {} : { cursor }),
141
+ }));
142
+ }),
143
+ get(`${base}/:id`).fit(async ({ request, params }) => {
144
+ const who = authenticate(credentials, request.headers['authorization']);
145
+ const id = idOf(params);
146
+ return as(who, async () => handle.getFor(await tenantOfTicket(id), id));
147
+ }),
148
+ withBody('PATCH', `${base}/:id`).fit(async ({ request, params, input }) => {
149
+ const who = authenticate(credentials, request.headers['authorization']);
150
+ const b = body(input);
151
+ const category = b['category'];
152
+ if (category !== null && typeof category !== 'string')
153
+ bad('category', 'must be a string or null');
154
+ const id = idOf(params);
155
+ return as(who, async () => handle.setCategoryFor(await tenantOfTicket(id), id, category));
156
+ }),
157
+ withBody('POST', `${base}/:id/transition`).fit(async ({ request, params, input }) => {
158
+ const who = authenticate(credentials, request.headers['authorization']);
159
+ const to = reqString(body(input), 'to');
160
+ if (!TICKET_STATES.includes(to))
161
+ bad('to', `"${to}" is not one of ${TICKET_STATES.join(', ')}`);
162
+ const id = idOf(params);
163
+ return as(who, async () => handle.transitionFor(await tenantOfTicket(id), id, to));
164
+ }),
165
+ withBody('POST', `${base}/:id/notes`).fit(async ({ request, params, input }) => {
166
+ const who = authenticate(credentials, request.headers['authorization']);
167
+ const text = reqString(body(input), 'text');
168
+ const id = idOf(params);
169
+ return as(who, async () => handle.addNoteFor(await tenantOfTicket(id), id, text));
170
+ }),
171
+ withBody('POST', `${base}/:id/links`).fit(async ({ request, params, input }) => {
172
+ const who = authenticate(credentials, request.headers['authorization']);
173
+ const b = body(input);
174
+ const kind = reqString(b, 'kind');
175
+ const ref = reqString(b, 'ref');
176
+ const label = optString(b, 'label');
177
+ const id = idOf(params);
178
+ return as(who, async () => handle.linkFor(await tenantOfTicket(id), id, { kind, ref, ...(label === undefined ? {} : { label }) }));
179
+ }),
180
+ withBody('POST', `${base}/:id/drafts`).fit(async ({ request, params, input }) => {
181
+ const who = authenticate(credentials, request.headers['authorization']);
182
+ const b = body(input);
183
+ const text = reqString(b, 'text');
184
+ const html = optString(b, 'html');
185
+ const subject = optString(b, 'subject');
186
+ const id = idOf(params);
187
+ return as(who, async () => handle.draftReplyFor(await tenantOfTicket(id), id, {
188
+ text, ...(html === undefined ? {} : { html }), ...(subject === undefined ? {} : { subject }),
189
+ }));
190
+ }),
191
+ withBody('PATCH', `${base}/drafts/:id`).fit(async ({ request, params, input }) => {
192
+ const who = authenticate(credentials, request.headers['authorization']);
193
+ const patch = draftPatch(body(input));
194
+ const id = idOf(params);
195
+ return as(who, async () => handle.editDraftFor(await tenantOfDraft(id), id, patch));
196
+ }),
197
+ del(`${base}/drafts/:id`).fit(async ({ request, params }) => {
198
+ const who = authenticate(credentials, request.headers['authorization']);
199
+ const id = idOf(params);
200
+ return as(who, async () => {
201
+ await handle.discardDraftFor(await tenantOfDraft(id), id);
202
+ return { discarded: true };
203
+ });
204
+ }),
205
+ withBody('POST', `${base}/drafts/:id/approve`).fit(async ({ request, params, input }) => {
206
+ const who = authenticate(credentials, request.headers['authorization']);
207
+ if (!who.approve)
208
+ throw new ForbiddenError('This credential may not approve replies.', { actorId: who.name });
209
+ const version = body(input)['version'];
210
+ if (typeof version !== 'number' || !Number.isInteger(version))
211
+ bad('version', 'must be an integer');
212
+ const id = idOf(params);
213
+ return as(who, async () => handle.approveFor(await tenantOfDraft(id), id, { expectedVersion: version }));
214
+ }),
215
+ ];
216
+ }
217
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/infra/support/http.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
1
  export { createSupport, supportTemplates, DraftStateError } from './handle.js';
2
+ export { supportHttp } from './http.js';
3
+ export type { SupportHttpOptions } from './http.js';
2
4
  export type { Support, SupportConfig, TicketApi, Ticket, TicketMessage, TicketLink, TicketDetail, TicketState, ListOptions, ListPage, DraftInput, SupportSink, SupportDelivery, ScreenVerdict, ReceiveResult, ReceiveInput, SupportEventKind, SupportEventPayload, } from './handle.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infra/support/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC9E,YAAY,EACV,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EACtH,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,GAC5H,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infra/support/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACnD,YAAY,EACV,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EACtH,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,GAC5H,MAAM,aAAa,CAAA"}
@@ -1,2 +1,3 @@
1
1
  export { createSupport, supportTemplates, DraftStateError } from './handle.js';
2
+ export { supportHttp } from './http.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infra/support/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infra/support/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA"}
@@ -1,8 +1,11 @@
1
1
  import { createSupport } from './handle.js';
2
+ import { supportHttp } from './http.js';
2
3
  /** Support namespace — tickets from email (and later chat), with replies sent only after an approval. */
3
4
  export declare const support: {
4
5
  /** Creates the support handle: tickets, messages, notes, links, drafts, `approve`, `receiveEmail`, and the events job. */
5
6
  readonly create: typeof createSupport;
7
+ /** Routes for a support agent: list, read, triage, notes, links, drafts, approve; bearer credentials that name the actor, and only some may approve. */
8
+ readonly http: typeof supportHttp;
6
9
  /** The reply template to spread into `mail.create({ templates })`; it renders the approved draft verbatim. */
7
10
  readonly templates: {
8
11
  readonly 'pipework.support.reply': ({ subject, text, html }: {
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/infra/support/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAA;AAE7D,yGAAyG;AACzG,eAAO,MAAM,OAAO;IAClB,0HAA0H;;IAE1H,8GAA8G;;;;;gBAG4zb,CAAC;;;;gBAAyD,CAAC;;;CAD79b,CAAA"}
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/infra/support/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,yGAAyG;AACzG,eAAO,MAAM,OAAO;IAClB,0HAA0H;;IAE1H,wJAAwJ;;IAExJ,8GAA8G;;;;;gBAGiyf,CAAC;;;;gBAAyD,CAAC;;;CADl8f,CAAA"}
@@ -1,8 +1,11 @@
1
1
  import { createSupport, supportTemplates } from './handle.js';
2
+ import { supportHttp } from './http.js';
2
3
  /** Support namespace — tickets from email (and later chat), with replies sent only after an approval. */
3
4
  export const support = {
4
5
  /** Creates the support handle: tickets, messages, notes, links, drafts, `approve`, `receiveEmail`, and the events job. */
5
6
  create: createSupport,
7
+ /** Routes for a support agent: list, read, triage, notes, links, drafts, approve; bearer credentials that name the actor, and only some may approve. */
8
+ http: supportHttp,
6
9
  /** The reply template to spread into `mail.create({ templates })`; it renders the approved draft verbatim. */
7
10
  templates: supportTemplates,
8
11
  };
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/infra/support/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE7D,yGAAyG;AACzG,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,0HAA0H;IAC1H,MAAM,EAAE,aAAa;IACrB,8GAA8G;IAC9G,SAAS,EAAE,gBAAgB;CACnB,CAAA"}
1
+ {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/infra/support/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,yGAAyG;AACzG,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,0HAA0H;IAC1H,MAAM,EAAE,aAAa;IACrB,wJAAwJ;IACxJ,IAAI,EAAE,WAAW;IACjB,8GAA8G;IAC9G,SAAS,EAAE,gBAAgB;CACnB,CAAA"}
@@ -20,9 +20,9 @@ export declare const supportTicket: import("../../data/domain/types.js").Defined
20
20
  }> & import("../../data/domain/field.js").FieldModifiers<string, {
21
21
  tenant: true;
22
22
  }>;
23
- state: import("../../data/domain/types.js").FieldDescriptor<"open" | "closed" | "triaged" | "awaiting_approval" | "answered", {
23
+ state: import("../../data/domain/types.js").FieldDescriptor<"open" | "closed" | "awaiting_approval" | "triaged" | "answered", {
24
24
  hasDefault: true;
25
- }> & import("../../data/domain/field.js").FieldModifiers<"open" | "closed" | "triaged" | "awaiting_approval" | "answered", {
25
+ }> & import("../../data/domain/field.js").FieldModifiers<"open" | "closed" | "awaiting_approval" | "triaged" | "answered", {
26
26
  hasDefault: true;
27
27
  }>;
28
28
  category: import("../../data/domain/types.js").FieldDescriptor<string | null, {
@@ -109,9 +109,9 @@ export declare const supportMessage: import("../../data/domain/types.js").Define
109
109
  }> & import("../../data/domain/field.js").FieldModifiers<import("zod/v4").JSONType, {
110
110
  nullable: true;
111
111
  }>;
112
- draftStatus: import("../../data/domain/types.js").FieldDescriptor<"draft" | "approved" | "discarded" | null, {
112
+ draftStatus: import("../../data/domain/types.js").FieldDescriptor<"approved" | "draft" | "discarded" | null, {
113
113
  nullable: true;
114
- }> & import("../../data/domain/field.js").FieldModifiers<"draft" | "approved" | "discarded" | null, {
114
+ }> & import("../../data/domain/field.js").FieldModifiers<"approved" | "draft" | "discarded" | null, {
115
115
  nullable: true;
116
116
  }>;
117
117
  version: import("../../data/domain/types.js").FieldDescriptor<number, {
@@ -1,5 +1,7 @@
1
1
  import type { DB } from '../../data/db/index.js';
2
2
  import { type WebhookSignatureOptions } from './sign.js';
3
+ import type { FetchTarget } from '../fetch/handle.js';
4
+ import type { Socket } from 'node:net';
3
5
  export interface OutboundWebhookConfig {
4
6
  table?: string;
5
7
  deliveryTable?: string;
@@ -10,6 +12,20 @@ export interface OutboundWebhookConfig {
10
12
  maxDelayMs?: number;
11
13
  };
12
14
  timeoutMs?: number;
15
+ /**
16
+ * Where deliveries may go. `'public'` (default): only public addresses; a private, loopback or link-local address, a name
17
+ * resolving to one, or a redirect is refused and recorded on the delivery row's `error` column. `'any'`: for an app that
18
+ * sends webhooks to its own internal services; redirects are still not followed and the kept response is still capped.
19
+ * `'any'` throws at creation when `environment` is `production`.
20
+ */
21
+ addresses?: 'public' | 'any';
22
+ /** The app's environment (`config.environment`); `addresses: 'any'` is refused when it is `production`. */
23
+ environment?: string;
24
+ /** For tests: replaces DNS and the socket of the `'public'` path, as `untrustedFetch.get` takes them. The address check still runs. */
25
+ network?: {
26
+ resolve: (hostname: string) => Promise<string[]>;
27
+ connect: (target: FetchTarget) => Socket;
28
+ };
13
29
  }
14
30
  export interface WebhookEndpoint {
15
31
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"outbound.d.ts","sourceRoot":"","sources":["../../../src/infra/webhook/outbound.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAe,KAAK,uBAAuB,EAAE,MAAM,WAAW,CAAA;AAGrE,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,uBAAuB,CAAA;IACjC,KAAK,CAAC,EAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACtF,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAA;IAC7F,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,QAAQ,CAAC,GAAG;QAAE,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3H,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IACnE,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC/E;AAED,qFAAqF;AACrF,eAAO,MAAM,8BAA8B,kCAAkC,CAAA;AAW7E,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,qBAA0B,GAAG,eAAe,CA4LzF"}
1
+ {"version":3,"file":"outbound.d.ts","sourceRoot":"","sources":["../../../src/infra/webhook/outbound.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { sql } from '../../data/db/sql.js';
2
2
  import { signPayload } from './sign.js';
3
+ import { untrustedPost } from '../fetch/handle.js';
3
4
  import { unscopedExecutor, scopedExecutor, requireUnscopedExecutor } from '../../auth/tenant/scoped-db.js';
4
5
  /** The delivery table `createOutboundWebhook` uses unless `deliveryTable` is set. */
5
6
  export const DEFAULT_WEBHOOK_DELIVERY_TABLE = '__pipework_webhook_deliveries';
@@ -11,6 +12,48 @@ const DEFAULTS = {
11
12
  maxDelayMs: 3_600_000,
12
13
  timeoutMs: 30_000,
13
14
  };
15
+ /** The most of an endpoint's response kept on the delivery row. */
16
+ const RESPONSE_BODY_CAP = 64 * 1024;
17
+ /** Plain fetch, for `addresses: 'any'`: no redirect followed, the kept body capped, one time limit. */
18
+ async function sendAnywhere(url, headers, body, timeoutMs) {
19
+ const controller = new AbortController();
20
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
21
+ try {
22
+ const response = await fetch(url, { method: 'POST', headers, body, signal: controller.signal, redirect: 'manual' });
23
+ const statusCode = response.status;
24
+ if (statusCode >= 300 && statusCode < 400) {
25
+ await response.body?.cancel().catch(() => undefined);
26
+ return { statusCode, responseBody: null, success: false, error: 'redirects' };
27
+ }
28
+ const success = statusCode >= 200 && statusCode < 300;
29
+ const chunks = [];
30
+ let total = 0;
31
+ let over = false;
32
+ const reader = response.body?.getReader();
33
+ try {
34
+ while (reader !== undefined) {
35
+ const { done, value } = await reader.read();
36
+ if (done)
37
+ break;
38
+ total += value.length;
39
+ if (total > RESPONSE_BODY_CAP) {
40
+ over = true;
41
+ break;
42
+ }
43
+ chunks.push(Buffer.from(value));
44
+ }
45
+ }
46
+ catch { /* a body that breaks is not kept; the status decides */ }
47
+ await reader?.cancel().catch(() => undefined);
48
+ return { statusCode, responseBody: over ? null : Buffer.concat(chunks).toString('utf8'), success, error: null };
49
+ }
50
+ catch {
51
+ return { statusCode: null, responseBody: null, success: false, error: controller.signal.aborted ? 'timeout' : 'network' };
52
+ }
53
+ finally {
54
+ clearTimeout(timer);
55
+ }
56
+ }
14
57
  export function createOutboundWebhook(config = {}) {
15
58
  const endpointTable = config.table ?? DEFAULTS.table;
16
59
  const deliveryTable = config.deliveryTable ?? DEFAULTS.deliveryTable;
@@ -19,6 +62,11 @@ export function createOutboundWebhook(config = {}) {
19
62
  const maxDelayMs = config.retry?.maxDelayMs ?? DEFAULTS.maxDelayMs;
20
63
  const timeoutMs = config.timeoutMs ?? DEFAULTS.timeoutMs;
21
64
  const signingOptions = config.signing ?? {};
65
+ const addresses = config.addresses ?? 'public';
66
+ if (addresses === 'any' && config.environment === 'production') {
67
+ throw new Error('[pipework] webhook.createOutbound: `addresses: \'any\'` is refused when the environment is production, because a tenant-registered URL could then reach the app\'s private network (cloud metadata, internal services). '
68
+ + 'Fix: remove `addresses` so deliveries go to public addresses only, or set it only outside production.\n');
69
+ }
22
70
  return {
23
71
  async ensureTables(handle) {
24
72
  const db = unscopedExecutor(handle).db;
@@ -42,6 +90,7 @@ export function createOutboundWebhook(config = {}) {
42
90
  payload JSONB NOT NULL,
43
91
  status_code INTEGER,
44
92
  response_body TEXT,
93
+ error TEXT,
45
94
  attempt INTEGER NOT NULL DEFAULT 0,
46
95
  max_attempts INTEGER NOT NULL,
47
96
  next_retry_at TIMESTAMPTZ,
@@ -49,6 +98,7 @@ export function createOutboundWebhook(config = {}) {
49
98
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
50
99
  )
51
100
  `));
101
+ await db.execute(sql.raw(`ALTER TABLE ${deliveryTable} ADD COLUMN IF NOT EXISTS error TEXT`));
52
102
  },
53
103
  async send(handle, tenantId, eventType, payload) {
54
104
  const db = scopedExecutor(handle, tenantId, 'webhook.send()').db;
@@ -79,37 +129,38 @@ export function createOutboundWebhook(config = {}) {
79
129
  return { success: false, statusCode: null };
80
130
  const attempt = delivery['attempt'] + 1;
81
131
  const signed = signPayload(delivery['payload'], delivery['secret'], signingOptions);
82
- let statusCode = null;
83
- let responseBody = null;
84
- let success = false;
85
- try {
86
- const controller = new AbortController();
87
- const timer = setTimeout(() => controller.abort(), timeoutMs);
88
- const response = await fetch(delivery['url'], {
89
- method: 'POST',
90
- headers: {
91
- 'Content-Type': 'application/json',
92
- 'X-Webhook-Id': signed.messageId,
93
- 'X-Webhook-Timestamp': signed.timestamp.toString(),
94
- 'X-Webhook-Signature': signed.signature,
95
- },
96
- body: signed.body,
97
- signal: controller.signal,
98
- });
99
- clearTimeout(timer);
100
- statusCode = response.status;
101
- responseBody = await response.text().catch(() => null);
102
- success = statusCode >= 200 && statusCode < 300;
132
+ const headers = {
133
+ 'Content-Type': 'application/json',
134
+ 'X-Webhook-Id': signed.messageId,
135
+ 'X-Webhook-Timestamp': signed.timestamp.toString(),
136
+ 'X-Webhook-Signature': signed.signature,
137
+ };
138
+ const url = delivery['url'];
139
+ let outcome;
140
+ if (addresses === 'any') {
141
+ outcome = await sendAnywhere(url, headers, signed.body, timeoutMs);
103
142
  }
104
- catch {
105
- statusCode = null;
106
- responseBody = null;
107
- success = false;
143
+ else {
144
+ const sent = await untrustedPost(url, {
145
+ body: signed.body, headers, maxBytes: RESPONSE_BODY_CAP, timeoutMs, maxRedirects: 0,
146
+ ...(config.network ?? {}),
147
+ });
148
+ if (sent.ok) {
149
+ outcome = { statusCode: sent.status, responseBody: Buffer.from(sent.body).toString('utf8'), success: true, error: null };
150
+ }
151
+ else if (sent.status !== undefined) {
152
+ // The answer arrived; the body is not kept (non-2xx, or a 2xx body over the cap).
153
+ outcome = { statusCode: sent.status, responseBody: null, success: sent.status >= 200 && sent.status < 300, error: null };
154
+ }
155
+ else {
156
+ outcome = { statusCode: null, responseBody: null, success: false, error: sent.reason };
157
+ }
108
158
  }
159
+ const { statusCode, responseBody, success, error } = outcome;
109
160
  if (success || attempt >= delivery['max_attempts']) {
110
161
  await db.execute(sql `UPDATE ${sql.raw(deliveryTable)}
111
162
  SET attempt = ${attempt}, status_code = ${statusCode},
112
- response_body = ${responseBody}, completed_at = now(), next_retry_at = NULL
163
+ response_body = ${responseBody}, error = ${error}, completed_at = now(), next_retry_at = NULL
113
164
  WHERE id = ${deliveryId}`);
114
165
  }
115
166
  else {
@@ -117,7 +168,7 @@ export function createOutboundWebhook(config = {}) {
117
168
  const nextRetry = new Date(Date.now() + delayMs);
118
169
  await db.execute(sql `UPDATE ${sql.raw(deliveryTable)}
119
170
  SET attempt = ${attempt}, status_code = ${statusCode},
120
- response_body = ${responseBody}, next_retry_at = ${nextRetry.toISOString()}
171
+ response_body = ${responseBody}, error = ${error}, next_retry_at = ${nextRetry.toISOString()}
121
172
  WHERE id = ${deliveryId}`);
122
173
  }
123
174
  return { success, statusCode };
@@ -1 +1 @@
1
- {"version":3,"file":"outbound.js","sourceRoot":"","sources":["../../../src/infra/webhook/outbound.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"outbound.js","sourceRoot":"","sources":["../../../src/infra/webhook/outbound.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { Schema, Infer } from '../../data/schema/types.js';
2
2
  import type { DB } from '../../data/db/index.js';
3
- import type { Handler, HttpMethod, RouteMeta, AuthRequirement, PermissionMeta, JobRetryConfig, JobTransactionMode, Checkpoint, RouteScreen, UploadConfig, BinaryUploadConfig, MultipartUploadConfig, BinaryUpload, MultipartUpload, FileConfig } from './types.js';
3
+ import type { Handler, HttpMethod, RouteMeta, AuthRequirement, PermissionMeta, JobRetryConfig, JobTransactionMode, Checkpoint, RouteScreen, UploadConfig, BinaryUploadConfig, MultipartUploadConfig, BinaryUpload, MultipartUpload, FileConfig, RouteRefusedHook } from './types.js';
4
4
  import type { ResourceOperations, Resource, PaginationConfig } from '../fixture/types.js';
5
5
  import type { HttpRequest, HttpResponse, CorsConfig } from '../http/types.js';
6
6
  interface BuilderState {
@@ -24,8 +24,10 @@ interface BuilderState {
24
24
  wantsRequest: boolean;
25
25
  wantsResponse: boolean;
26
26
  wantsRawBody: boolean;
27
+ ignoresBody: boolean;
27
28
  upload: UploadConfig | null;
28
29
  file: FileConfig | null;
30
+ onRefused: RouteRefusedHook<any, any, any> | null;
29
31
  }
30
32
  /**
31
33
  * Deps shape after `.transaction('manual')`: the databases the handler declared
@@ -141,6 +143,14 @@ export declare class Builder<TDeps extends Record<string, unknown>, TDb extends
141
143
  rawBody(): Builder<TDeps & {
142
144
  rawBody: Buffer;
143
145
  }, TDb>;
146
+ /**
147
+ * Makes this route accept a body of any content type and never read it: the body is drained
148
+ * unparsed (a declared length over 64 KiB is refused with 413) and `input` is undefined.
149
+ * For a POST whose body carries nothing the handler needs, such as an RFC 8058 one-click
150
+ * unsubscribe (`List-Unsubscribe=One-Click` as form-urlencoded or multipart). This route only:
151
+ * no other route's parsing changes. Cannot be combined with `.input()`, `.rawBody()` or `.upload()`.
152
+ */
153
+ ignoreBody(): Builder<TDeps, TDb>;
144
154
  /**
145
155
  * Makes this route accept a file upload and hands the handler the file as a
146
156
  * stream in the `upload` dep. The body is never buffered whole.
@@ -228,6 +238,19 @@ export declare class Builder<TDeps extends Record<string, unknown>, TDb extends
228
238
  mediaTypes: readonly string[];
229
239
  status?: number;
230
240
  }): Builder<TDeps, TDb>;
241
+ /**
242
+ * Runs `hook` once for every 4xx this route answers, including those made before
243
+ * the handler: the input/params/query 422, auth 401, permission 403, 429, upload
244
+ * 413/415 and the handler's own thrown 4xx. Never for a 5xx, nor the route's `screen`.
245
+ * It gets `{ status, code, message, fields, auth, params, query, request,
246
+ * requestId }`; `auth` is null where auth itself refused, `params`/`query` are null
247
+ * when they fail their schema. A plain object it returns is merged into the
248
+ * response's `error`; `code`, `message`, `fields` and `details` keep pipework's
249
+ * values (a hook that sets one is warned and dropped). A throw is logged and the
250
+ * refusal is sent as without the hook. Runs in the request's Flow as a trace step
251
+ * after the upload `onRefuse`, once the request transaction has rolled back: it has none.
252
+ */
253
+ onRefused(hook: RouteRefusedHook<DepOf<TDeps, 'auth'>, DepOf<TDeps, 'params'>, DepOf<TDeps, 'query'>>): Builder<TDeps, TDb>;
231
254
  fixture<TAuth>(name: string, operations: ResourceOperations<TAuth>): Resource<TAuth>;
232
255
  fit<TReturn>(fn: (deps: TDeps) => Promise<TReturn>): Handler<TDeps, TReturn>;
233
256
  }