pipework 0.212.0 → 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 (312) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/REFERENCE.md +94 -2
  3. package/dist/cli/commands/openapi.d.ts +8 -0
  4. package/dist/cli/commands/openapi.d.ts.map +1 -0
  5. package/dist/cli/commands/openapi.js +49 -0
  6. package/dist/cli/commands/openapi.js.map +1 -0
  7. package/dist/cli/commands/serve.d.ts +8 -0
  8. package/dist/cli/commands/serve.d.ts.map +1 -1
  9. package/dist/cli/commands/serve.js +22 -3
  10. package/dist/cli/commands/serve.js.map +1 -1
  11. package/dist/cli/dev-bootstrap.js +6 -1
  12. package/dist/cli/dev-bootstrap.js.map +1 -1
  13. package/dist/cli/index.d.ts.map +1 -1
  14. package/dist/cli/index.js +15 -1
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/surface-kinds.d.ts +5 -0
  17. package/dist/cli/surface-kinds.d.ts.map +1 -0
  18. package/dist/cli/surface-kinds.js +15 -0
  19. package/dist/cli/surface-kinds.js.map +1 -0
  20. package/dist/core/config/load.d.ts +1 -0
  21. package/dist/core/config/load.d.ts.map +1 -1
  22. package/dist/core/config/load.js +1 -0
  23. package/dist/core/config/load.js.map +1 -1
  24. package/dist/core/config/namespace.d.ts +6 -0
  25. package/dist/core/config/namespace.d.ts.map +1 -1
  26. package/dist/core/config/schema.d.ts +15 -0
  27. package/dist/core/config/schema.d.ts.map +1 -1
  28. package/dist/core/config/schema.js +11 -2
  29. package/dist/core/config/schema.js.map +1 -1
  30. package/dist/core/lifecycle/health.js +2 -2
  31. package/dist/core/lifecycle/health.js.map +1 -1
  32. package/dist/core/lifecycle/types.d.ts +2 -0
  33. package/dist/core/lifecycle/types.d.ts.map +1 -1
  34. package/dist/core/pipework.d.ts +14 -1
  35. package/dist/core/pipework.d.ts.map +1 -1
  36. package/dist/core/pipework.js +18 -2
  37. package/dist/core/pipework.js.map +1 -1
  38. package/dist/core/surface/http.d.ts +3 -0
  39. package/dist/core/surface/http.d.ts.map +1 -1
  40. package/dist/core/surface/http.js +27 -8
  41. package/dist/core/surface/http.js.map +1 -1
  42. package/dist/core/surface/start.d.ts.map +1 -1
  43. package/dist/core/surface/start.js +19 -3
  44. package/dist/core/surface/start.js.map +1 -1
  45. package/dist/core/surface/types.d.ts +8 -0
  46. package/dist/core/surface/types.d.ts.map +1 -1
  47. package/dist/data/db/filter.d.ts +3 -0
  48. package/dist/data/db/filter.d.ts.map +1 -1
  49. package/dist/data/db/filter.js +3 -0
  50. package/dist/data/db/filter.js.map +1 -1
  51. package/dist/data/db/in-list.d.ts +15 -0
  52. package/dist/data/db/in-list.d.ts.map +1 -0
  53. package/dist/data/db/in-list.js +51 -0
  54. package/dist/data/db/in-list.js.map +1 -0
  55. package/dist/data/db/namespace.d.ts +2 -0
  56. package/dist/data/db/namespace.d.ts.map +1 -1
  57. package/dist/data/db/pool.d.ts +1 -1
  58. package/dist/data/db/pool.d.ts.map +1 -1
  59. package/dist/data/db/pool.js +4 -2
  60. package/dist/data/db/pool.js.map +1 -1
  61. package/dist/data/db/reservation.d.ts +40 -0
  62. package/dist/data/db/reservation.d.ts.map +1 -0
  63. package/dist/data/db/reservation.js +108 -0
  64. package/dist/data/db/reservation.js.map +1 -0
  65. package/dist/data/domain/build-table.js +32 -1
  66. package/dist/data/domain/build-table.js.map +1 -1
  67. package/dist/data/domain/index.d.ts +2 -1
  68. package/dist/data/domain/index.d.ts.map +1 -1
  69. package/dist/data/domain/types.d.ts +9 -1
  70. package/dist/data/domain/types.d.ts.map +1 -1
  71. package/dist/data/domain/types.js.map +1 -1
  72. package/dist/data/migrate/apply.d.ts.map +1 -1
  73. package/dist/data/migrate/apply.js +3 -11
  74. package/dist/data/migrate/apply.js.map +1 -1
  75. package/dist/data/migrate/check.d.ts.map +1 -1
  76. package/dist/data/migrate/check.js +3 -6
  77. package/dist/data/migrate/check.js.map +1 -1
  78. package/dist/data/migrate/diff.d.ts +16 -0
  79. package/dist/data/migrate/diff.d.ts.map +1 -1
  80. package/dist/data/migrate/diff.js +44 -4
  81. package/dist/data/migrate/diff.js.map +1 -1
  82. package/dist/data/migrate/generate.d.ts +1 -1
  83. package/dist/data/migrate/generate.d.ts.map +1 -1
  84. package/dist/data/migrate/generate.js +19 -51
  85. package/dist/data/migrate/generate.js.map +1 -1
  86. package/dist/data/migrate/history.d.ts +36 -0
  87. package/dist/data/migrate/history.d.ts.map +1 -0
  88. package/dist/data/migrate/history.js +185 -0
  89. package/dist/data/migrate/history.js.map +1 -0
  90. package/dist/data/migrate/internal-definitions.d.ts.map +1 -1
  91. package/dist/data/migrate/internal-definitions.js +22 -1
  92. package/dist/data/migrate/internal-definitions.js.map +1 -1
  93. package/dist/data/migrate/provision-framework.d.ts +2 -0
  94. package/dist/data/migrate/provision-framework.d.ts.map +1 -1
  95. package/dist/data/migrate/provision-framework.js +11 -3
  96. package/dist/data/migrate/provision-framework.js.map +1 -1
  97. package/dist/data/migrate/snapshot.d.ts +4 -0
  98. package/dist/data/migrate/snapshot.d.ts.map +1 -1
  99. package/dist/data/migrate/snapshot.js +2 -0
  100. package/dist/data/migrate/snapshot.js.map +1 -1
  101. package/dist/data/migrate/sql-emit.js +66 -12
  102. package/dist/data/migrate/sql-emit.js.map +1 -1
  103. package/dist/data/query/pg-core/foreign-keys.d.ts +5 -0
  104. package/dist/data/query/pg-core/foreign-keys.d.ts.map +1 -1
  105. package/dist/data/query/pg-core/foreign-keys.js +9 -0
  106. package/dist/data/query/pg-core/foreign-keys.js.map +1 -1
  107. package/dist/data/query/pg-core/indexes.d.ts +5 -0
  108. package/dist/data/query/pg-core/indexes.d.ts.map +1 -1
  109. package/dist/data/query/pg-core/indexes.js +7 -0
  110. package/dist/data/query/pg-core/indexes.js.map +1 -1
  111. package/dist/data/schema/json-schema.js +29 -1
  112. package/dist/data/schema/json-schema.js.map +1 -1
  113. package/dist/data/schema/types.d.ts +2 -2
  114. package/dist/data/schema/types.d.ts.map +1 -1
  115. package/dist/index.d.ts +18 -9
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +5 -1
  118. package/dist/index.js.map +1 -1
  119. package/dist/infra/alerts/handle.d.ts +33 -5
  120. package/dist/infra/alerts/handle.d.ts.map +1 -1
  121. package/dist/infra/alerts/handle.js +56 -12
  122. package/dist/infra/alerts/handle.js.map +1 -1
  123. package/dist/infra/alerts/http.d.ts +2 -2
  124. package/dist/infra/alerts/http.d.ts.map +1 -1
  125. package/dist/infra/alerts/http.js +21 -3
  126. package/dist/infra/alerts/http.js.map +1 -1
  127. package/dist/infra/alerts/index.d.ts +1 -1
  128. package/dist/infra/alerts/index.d.ts.map +1 -1
  129. package/dist/infra/alerts/schema.d.ts +5 -0
  130. package/dist/infra/alerts/schema.d.ts.map +1 -1
  131. package/dist/infra/alerts/schema.js +1 -0
  132. package/dist/infra/alerts/schema.js.map +1 -1
  133. package/dist/infra/crawl/audit.d.ts +6 -0
  134. package/dist/infra/crawl/audit.d.ts.map +1 -0
  135. package/dist/infra/crawl/audit.js +38 -0
  136. package/dist/infra/crawl/audit.js.map +1 -0
  137. package/dist/infra/crawl/errors.d.ts +14 -0
  138. package/dist/infra/crawl/errors.d.ts.map +1 -0
  139. package/dist/infra/crawl/errors.js +22 -0
  140. package/dist/infra/crawl/errors.js.map +1 -0
  141. package/dist/infra/crawl/handle.d.ts +149 -0
  142. package/dist/infra/crawl/handle.d.ts.map +1 -0
  143. package/dist/infra/crawl/handle.js +550 -0
  144. package/dist/infra/crawl/handle.js.map +1 -0
  145. package/dist/infra/crawl/index.d.ts +7 -0
  146. package/dist/infra/crawl/index.d.ts.map +1 -0
  147. package/dist/infra/crawl/index.js +5 -0
  148. package/dist/infra/crawl/index.js.map +1 -0
  149. package/dist/infra/crawl/links.d.ts +9 -0
  150. package/dist/infra/crawl/links.d.ts.map +1 -0
  151. package/dist/infra/crawl/links.js +194 -0
  152. package/dist/infra/crawl/links.js.map +1 -0
  153. package/dist/infra/crawl/namespace.d.ts +36 -0
  154. package/dist/infra/crawl/namespace.d.ts.map +1 -0
  155. package/dist/infra/crawl/namespace.js +36 -0
  156. package/dist/infra/crawl/namespace.js.map +1 -0
  157. package/dist/infra/crawl/robots.d.ts +16 -0
  158. package/dist/infra/crawl/robots.d.ts.map +1 -0
  159. package/dist/infra/crawl/robots.js +98 -0
  160. package/dist/infra/crawl/robots.js.map +1 -0
  161. package/dist/infra/crawl/schema.d.ts +222 -0
  162. package/dist/infra/crawl/schema.d.ts.map +1 -0
  163. package/dist/infra/crawl/schema.js +84 -0
  164. package/dist/infra/crawl/schema.js.map +1 -0
  165. package/dist/infra/credit-line/handle.d.ts +250 -0
  166. package/dist/infra/credit-line/handle.d.ts.map +1 -0
  167. package/dist/infra/credit-line/handle.js +618 -0
  168. package/dist/infra/credit-line/handle.js.map +1 -0
  169. package/dist/infra/credit-line/index.d.ts +3 -0
  170. package/dist/infra/credit-line/index.d.ts.map +1 -0
  171. package/dist/infra/credit-line/index.js +2 -0
  172. package/dist/infra/credit-line/index.js.map +1 -0
  173. package/dist/infra/credit-line/namespace.d.ts +7 -0
  174. package/dist/infra/credit-line/namespace.d.ts.map +1 -0
  175. package/dist/infra/credit-line/namespace.js +7 -0
  176. package/dist/infra/credit-line/namespace.js.map +1 -0
  177. package/dist/infra/credit-line/schema.d.ts +194 -0
  178. package/dist/infra/credit-line/schema.d.ts.map +1 -0
  179. package/dist/infra/credit-line/schema.js +89 -0
  180. package/dist/infra/credit-line/schema.js.map +1 -0
  181. package/dist/infra/email/inbound.d.ts +14 -2
  182. package/dist/infra/email/inbound.d.ts.map +1 -1
  183. package/dist/infra/email/inbound.js +5 -1
  184. package/dist/infra/email/inbound.js.map +1 -1
  185. package/dist/infra/email/index.d.ts +2 -2
  186. package/dist/infra/email/index.d.ts.map +1 -1
  187. package/dist/infra/email/index.js.map +1 -1
  188. package/dist/infra/email/mail.d.ts +43 -5
  189. package/dist/infra/email/mail.d.ts.map +1 -1
  190. package/dist/infra/email/mail.js +124 -9
  191. package/dist/infra/email/mail.js.map +1 -1
  192. package/dist/infra/email/mime.d.ts +6 -0
  193. package/dist/infra/email/mime.d.ts.map +1 -1
  194. package/dist/infra/email/mime.js +10 -2
  195. package/dist/infra/email/mime.js.map +1 -1
  196. package/dist/infra/email/schema.d.ts +17 -3
  197. package/dist/infra/email/schema.d.ts.map +1 -1
  198. package/dist/infra/email/schema.js +15 -4
  199. package/dist/infra/email/schema.js.map +1 -1
  200. package/dist/infra/email/sns.js +2 -2
  201. package/dist/infra/email/sns.js.map +1 -1
  202. package/dist/infra/email/unsubscribe.d.ts +13 -0
  203. package/dist/infra/email/unsubscribe.d.ts.map +1 -0
  204. package/dist/infra/email/unsubscribe.js +43 -0
  205. package/dist/infra/email/unsubscribe.js.map +1 -0
  206. package/dist/infra/fetch/handle.d.ts +20 -1
  207. package/dist/infra/fetch/handle.d.ts.map +1 -1
  208. package/dist/infra/fetch/handle.js +60 -28
  209. package/dist/infra/fetch/handle.js.map +1 -1
  210. package/dist/infra/fetch/index.d.ts +2 -2
  211. package/dist/infra/fetch/index.d.ts.map +1 -1
  212. package/dist/infra/fetch/index.js +1 -1
  213. package/dist/infra/fetch/index.js.map +1 -1
  214. package/dist/infra/fetch/namespace.d.ts +20 -2
  215. package/dist/infra/fetch/namespace.d.ts.map +1 -1
  216. package/dist/infra/fetch/namespace.js +20 -2
  217. package/dist/infra/fetch/namespace.js.map +1 -1
  218. package/dist/infra/join-requests/handle.d.ts +86 -0
  219. package/dist/infra/join-requests/handle.d.ts.map +1 -0
  220. package/dist/infra/join-requests/handle.js +233 -0
  221. package/dist/infra/join-requests/handle.js.map +1 -0
  222. package/dist/infra/join-requests/index.d.ts +3 -0
  223. package/dist/infra/join-requests/index.d.ts.map +1 -0
  224. package/dist/infra/join-requests/index.js +2 -0
  225. package/dist/infra/join-requests/index.js.map +1 -0
  226. package/dist/infra/join-requests/namespace.d.ts +7 -0
  227. package/dist/infra/join-requests/namespace.d.ts.map +1 -0
  228. package/dist/infra/join-requests/namespace.js +7 -0
  229. package/dist/infra/join-requests/namespace.js.map +1 -0
  230. package/dist/infra/join-requests/schema.d.ts +58 -0
  231. package/dist/infra/join-requests/schema.d.ts.map +1 -0
  232. package/dist/infra/join-requests/schema.js +31 -0
  233. package/dist/infra/join-requests/schema.js.map +1 -0
  234. package/dist/infra/outbox/core.d.ts +9 -0
  235. package/dist/infra/outbox/core.d.ts.map +1 -1
  236. package/dist/infra/outbox/core.js +14 -0
  237. package/dist/infra/outbox/core.js.map +1 -1
  238. package/dist/infra/support/handle.d.ts +43 -0
  239. package/dist/infra/support/handle.d.ts.map +1 -1
  240. package/dist/infra/support/handle.js +35 -7
  241. package/dist/infra/support/handle.js.map +1 -1
  242. package/dist/infra/support/http.d.ts +28 -0
  243. package/dist/infra/support/http.d.ts.map +1 -0
  244. package/dist/infra/support/http.js +217 -0
  245. package/dist/infra/support/http.js.map +1 -0
  246. package/dist/infra/support/index.d.ts +2 -0
  247. package/dist/infra/support/index.d.ts.map +1 -1
  248. package/dist/infra/support/index.js +1 -0
  249. package/dist/infra/support/index.js.map +1 -1
  250. package/dist/infra/support/namespace.d.ts +3 -0
  251. package/dist/infra/support/namespace.d.ts.map +1 -1
  252. package/dist/infra/support/namespace.js +3 -0
  253. package/dist/infra/support/namespace.js.map +1 -1
  254. package/dist/infra/support/schema.d.ts +4 -4
  255. package/dist/infra/webhook/outbound.d.ts +16 -0
  256. package/dist/infra/webhook/outbound.d.ts.map +1 -1
  257. package/dist/infra/webhook/outbound.js +78 -27
  258. package/dist/infra/webhook/outbound.js.map +1 -1
  259. package/dist/request/di/builder.d.ts +24 -1
  260. package/dist/request/di/builder.d.ts.map +1 -1
  261. package/dist/request/di/builder.js +35 -0
  262. package/dist/request/di/builder.js.map +1 -1
  263. package/dist/request/di/types.d.ts +30 -0
  264. package/dist/request/di/types.d.ts.map +1 -1
  265. package/dist/request/http/server.d.ts.map +1 -1
  266. package/dist/request/http/server.js +111 -20
  267. package/dist/request/http/server.js.map +1 -1
  268. package/dist/test/auto-setup.js +2 -2
  269. package/dist/test/auto-setup.js.map +1 -1
  270. package/dist/test/crawl-fixture.d.ts +53 -0
  271. package/dist/test/crawl-fixture.d.ts.map +1 -0
  272. package/dist/test/crawl-fixture.js +130 -0
  273. package/dist/test/crawl-fixture.js.map +1 -0
  274. package/dist/test/index.d.ts +2 -1
  275. package/dist/test/index.d.ts.map +1 -1
  276. package/dist/test/index.js +2 -1
  277. package/dist/test/index.js.map +1 -1
  278. package/dist/test/progress.d.ts +7 -1
  279. package/dist/test/progress.d.ts.map +1 -1
  280. package/dist/test/progress.js +6 -0
  281. package/dist/test/progress.js.map +1 -1
  282. package/dist/test/reap-after-run.d.ts +3 -0
  283. package/dist/test/reap-after-run.d.ts.map +1 -0
  284. package/dist/test/reap-after-run.js +29 -0
  285. package/dist/test/reap-after-run.js.map +1 -0
  286. package/dist/test/reap.d.ts +11 -2
  287. package/dist/test/reap.d.ts.map +1 -1
  288. package/dist/test/reap.js +19 -12
  289. package/dist/test/reap.js.map +1 -1
  290. package/dist/test/setup.d.ts +2 -0
  291. package/dist/test/setup.d.ts.map +1 -1
  292. package/dist/test/setup.js +87 -30
  293. package/dist/test/setup.js.map +1 -1
  294. package/dist/test/vitest-plugin.d.ts.map +1 -1
  295. package/dist/test/vitest-plugin.js +8 -1
  296. package/dist/test/vitest-plugin.js.map +1 -1
  297. package/dist/test/vitest-workspace.d.ts +1 -0
  298. package/dist/test/vitest-workspace.d.ts.map +1 -1
  299. package/dist/test/vitest-workspace.js +1 -1
  300. package/dist/test/vitest-workspace.js.map +1 -1
  301. package/dist/test/vitest.d.ts +20 -0
  302. package/dist/test/vitest.d.ts.map +1 -1
  303. package/dist/test/vitest.js +41 -1
  304. package/dist/test/vitest.js.map +1 -1
  305. package/dist/trace/partition/sync.d.ts +8 -2
  306. package/dist/trace/partition/sync.d.ts.map +1 -1
  307. package/dist/trace/partition/sync.js +6 -3
  308. package/dist/trace/partition/sync.js.map +1 -1
  309. package/dist/workspace/generate.d.ts.map +1 -1
  310. package/dist/workspace/generate.js +1 -0
  311. package/dist/workspace/generate.js.map +1 -1
  312. package/package.json +1 -1
@@ -0,0 +1,550 @@
1
+ import { Readable } from 'node:stream';
2
+ import { sql } from '../../data/db/sql.js';
3
+ import { pipeSystem } from '../../data/db/db.js';
4
+ import { fitting } from '../../request/di/index.js';
5
+ import { getContext } from '../../request/context/store.js';
6
+ import { resolveActorId } from '../../data/write/audit/actor.js';
7
+ import { schema } from '../../data/schema/namespace.js';
8
+ import { __flowStep } from '../../trace/runtime/flow-step.js';
9
+ import { getBaseLogger } from '../../core/logging/index.js';
10
+ import { ConflictError, NotFoundError } from '../../core/errors/index.js';
11
+ import { untrustedGet } from '../fetch/handle.js';
12
+ import { auditCrawl } from './audit.js';
13
+ import { CrawlNotEnabledError, CrawlSeedError } from './errors.js';
14
+ import { extractLinks } from './links.js';
15
+ import { ALLOW_ALL, DISALLOW_ALL, parseRobots } from './robots.js';
16
+ export const DEFAULT_LIMITS = {
17
+ perHostConcurrency: 1, minGapMs: 1000, maxPages: 1000, maxDepth: 10, maxBytes: 1024 ** 3, maxBytesPerResponse: 25 * 1024 * 1024,
18
+ maxWallMs: 3_600_000, requestTimeoutMs: 30_000, maxRedirects: 5, pageHookMs: 5000,
19
+ };
20
+ const NAME_RE = /^[A-Za-z][A-Za-z0-9_.-]*$/;
21
+ const ROBOTS_MAX_BYTES = 500 * 1024;
22
+ const ROBOTS_TRIES = 4;
23
+ const barred = (reason, message) => ({ ...DISALLOW_ALL, refusal: { reason, message } });
24
+ const HTML_TYPES = new Set(['text/html', 'application/xhtml+xml']);
25
+ const num = (v) => Number(v ?? 0);
26
+ const str = (v) => (v === null || v === undefined ? null : String(v));
27
+ const baseType = (contentType) => (contentType ?? '').split(';')[0].trim().toLowerCase();
28
+ const describeError = (err) => (err instanceof Error ? err.message : String(err)).slice(0, 500);
29
+ function sleep(ms, signal) {
30
+ return new Promise(resolve => {
31
+ if (ms <= 0 || signal.aborted) {
32
+ resolve();
33
+ return;
34
+ }
35
+ const done = () => { clearTimeout(timer); signal.removeEventListener('abort', done); resolve(); };
36
+ const timer = setTimeout(done, ms);
37
+ signal.addEventListener('abort', done, { once: true });
38
+ });
39
+ }
40
+ function inScope(scope, hostname) {
41
+ if (scope.kind === 'host')
42
+ return hostname === scope.host;
43
+ return hostname === scope.domain || hostname.endsWith('.' + scope.domain);
44
+ }
45
+ function resolveLimits(given) {
46
+ const out = { ...DEFAULT_LIMITS };
47
+ for (const [key, value] of Object.entries(given ?? {})) {
48
+ if (!(key in DEFAULT_LIMITS))
49
+ throw new CrawlSeedError(`unknown limit "${key}" (limits: ${Object.keys(DEFAULT_LIMITS).join(', ')}).`);
50
+ if (value === undefined)
51
+ continue;
52
+ const min = key === 'minGapMs' || key === 'maxRedirects' || key === 'maxDepth' ? 0 : 1;
53
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < min)
54
+ throw new CrawlSeedError(`limit ${key} must be a number of at least ${String(min)}, got ${String(value)}.`);
55
+ out[key] = value;
56
+ }
57
+ return out;
58
+ }
59
+ function parseSeed(seed, scope) {
60
+ let url;
61
+ try {
62
+ url = new URL(seed);
63
+ }
64
+ catch {
65
+ throw new CrawlSeedError(`the seed "${seed}" is not a URL.`);
66
+ }
67
+ if (url.protocol !== 'http:' && url.protocol !== 'https:')
68
+ throw new CrawlSeedError(`the seed must be an http or https URL, got ${url.protocol}`);
69
+ url.hash = '';
70
+ let stored;
71
+ if (scope === undefined || scope === 'host') {
72
+ stored = { kind: 'host', host: url.hostname };
73
+ }
74
+ else if (typeof scope === 'object' && typeof scope.domain === 'string' && scope.domain.trim() !== '') {
75
+ stored = { kind: 'domain', domain: scope.domain.trim().toLowerCase().replace(/^\.+|\.+$/g, '') };
76
+ }
77
+ else {
78
+ throw new CrawlSeedError(`scope must be 'host' or { domain: 'example.gov.uk' }.`);
79
+ }
80
+ if (!inScope(stored, url.hostname)) {
81
+ throw new CrawlSeedError(`the seed's host ${url.hostname} is not inside its scope (${stored.kind === 'host' ? stored.host : stored.domain}).`);
82
+ }
83
+ return { url, stored };
84
+ }
85
+ /** Creates a site crawler; see `crawl.create`. */
86
+ export function createCrawl(config) {
87
+ const blueprint = config.instance.config.raw.crawl;
88
+ if (blueprint === undefined)
89
+ throw new CrawlNotEnabledError();
90
+ if (typeof config.name !== 'string' || !NAME_RE.test(config.name)) {
91
+ throw new Error(`[pipework] crawl.create: name "${String(config.name)}" must start with a letter and use letters, digits, "_", "." or "-".\n`);
92
+ }
93
+ if (typeof config.userAgent !== 'string' || config.userAgent.trim() === '')
94
+ throw new Error('[pipework] crawl.create: userAgent is required: sites read it to decide what you may fetch.\n');
95
+ const requireApproval = blueprint.requireApproval === true;
96
+ const jobType = `pipework.crawl.${config.name}`;
97
+ const database = config.database;
98
+ const db = () => pipeSystem(database);
99
+ const robotsRetryMs = config.robotsRetryMs ?? 2000;
100
+ const urlIsSafeToTrace = config.traceUrls !== false;
101
+ const enqueue = async (id) => {
102
+ await config.queue.enqueue(db(), { type: jobType, payload: { crawlId: id }, liveKey: id, continueFlow: true, maxAttempts: config.maxAttempts ?? 5 });
103
+ };
104
+ const startStep = __flowStep({ ref: 'pipework/crawl:start', capture: [null] }, async (options) => {
105
+ const { url, stored } = parseSeed(options.seed, options.scope);
106
+ const limits = resolveLimits(options.limits);
107
+ const flow = getContext();
108
+ const actor = flow === undefined ? null : resolveActorId(flow);
109
+ const state = requireApproval ? 'awaiting_approval' : 'running';
110
+ const rows = await db().execute(sql `
111
+ INSERT INTO pipework_crawl (site, seed, scope, limits, state, tenant_id, started_by, run_started_at)
112
+ VALUES (${config.name}, ${url.href}, ${JSON.stringify(stored)}::jsonb, ${JSON.stringify(limits)}::jsonb, ${state},
113
+ ${flow?.tenant ?? null}, ${actor}, ${requireApproval ? null : sql `now()`})
114
+ RETURNING id::text AS id`);
115
+ const id = rows[0]['id'];
116
+ await db().execute(sql `INSERT INTO pipework_crawl_url (crawl_id, url, depth, seed_chain) VALUES (${id}::uuid, ${url.href}, 0, true)`);
117
+ await auditCrawl('start', id, { site: config.name, seed: url.href, scope: stored, limits, awaitingApproval: requireApproval }, database);
118
+ if (!requireApproval)
119
+ await enqueue(id);
120
+ return { id };
121
+ });
122
+ const approveStep = __flowStep({ ref: 'pipework/crawl:approve', capture: [null] }, async (id) => {
123
+ await requireCrawl(id);
124
+ const flow = getContext();
125
+ const actor = flow === undefined ? null : resolveActorId(flow);
126
+ const rows = await db().execute(sql `
127
+ UPDATE pipework_crawl SET state = 'running', approved_by = ${actor}, run_started_at = now()
128
+ WHERE id = ${id}::uuid AND site = ${config.name} AND state = 'awaiting_approval' RETURNING seed`);
129
+ if (rows.length === 0) {
130
+ const found = await db().execute(sql `SELECT state FROM pipework_crawl WHERE id = ${id}::uuid AND site = ${config.name}`);
131
+ if (found.length === 0)
132
+ throw new NotFoundError(`Crawl ${id}`);
133
+ throw new ConflictError(`Crawl ${id} is not awaiting approval (it is ${String(found[0]['state'])}).`);
134
+ }
135
+ await auditCrawl('approve', id, { site: config.name, seed: rows[0]['seed'] }, database);
136
+ await enqueue(id);
137
+ });
138
+ async function loadCrawl(id) {
139
+ const rows = await db().execute(sql `
140
+ SELECT state, limits, scope, seed, tenant_id, stopped_by, error, bytes::float8 AS bytes,
141
+ (extract(epoch from run_started_at) * 1000)::float8 AS run_started_ms
142
+ FROM pipework_crawl WHERE id = ${id}::uuid AND site = ${config.name}`);
143
+ const r = rows[0];
144
+ if (r === undefined)
145
+ return null;
146
+ return {
147
+ state: r['state'], limits: r['limits'], scope: r['scope'], seed: r['seed'],
148
+ runStartedAt: num(r['run_started_ms']), tenantId: str(r['tenant_id']),
149
+ stoppedBy: str(r['stopped_by']), error: str(r['error']), bytes: num(r['bytes']),
150
+ };
151
+ }
152
+ /** The crawl, or NotFoundError: also when it belongs to another tenant than the Flow's. */
153
+ const requireCrawl = async (id) => {
154
+ const crawl = await loadCrawl(id);
155
+ const tenant = getContext()?.tenant ?? null;
156
+ if (crawl === null || (crawl.tenantId !== null && crawl.tenantId !== tenant))
157
+ throw new NotFoundError(`Crawl ${id}`);
158
+ return crawl;
159
+ };
160
+ const status = async (id) => {
161
+ const crawl = await requireCrawl(id);
162
+ const counted = await db().execute(sql `
163
+ SELECT count(*) FILTER (WHERE state = 'queued')::int AS queued, count(*) FILTER (WHERE state = 'fetching')::int AS fetching,
164
+ count(*) FILTER (WHERE state = 'done')::int AS done, count(*) FILTER (WHERE state = 'refused')::int AS refused
165
+ FROM pipework_crawl_url WHERE crawl_id = ${id}::uuid`);
166
+ const listed = await db().execute(sql `
167
+ SELECT count(*)::int AS listed, count(*) FILTER (WHERE unchanged)::int AS unchanged FROM pipework_crawl_resource WHERE crawl_id = ${id}::uuid`);
168
+ const c = counted[0];
169
+ return {
170
+ state: crawl.state,
171
+ scope: crawl.scope.kind === 'host' ? { host: crawl.scope.host } : { domain: crawl.scope.domain },
172
+ ...(crawl.stoppedBy !== null ? { stoppedBy: crawl.stoppedBy } : {}),
173
+ ...(crawl.error !== null ? { error: crawl.error } : {}),
174
+ counts: {
175
+ queued: num(c['queued']), fetching: num(c['fetching']), done: num(c['done']), refused: num(c['refused']),
176
+ listed: num(listed[0]['listed']), unchanged: num(listed[0]['unchanged']), bytes: crawl.bytes,
177
+ },
178
+ };
179
+ };
180
+ const resources = async (id) => {
181
+ await requireCrawl(id);
182
+ const rows = await db().execute(sql `
183
+ SELECT r.url, r.from_url, r.status, r.content_type, r.bytes::float8 AS bytes, r.etag, r.last_modified, r.sha256, r.file_id, r.unchanged
184
+ FROM pipework_crawl_resource r JOIN pipework_crawl c ON c.id = r.crawl_id
185
+ WHERE r.crawl_id = ${id}::uuid AND c.site = ${config.name} ORDER BY r.created_at, r.id`);
186
+ return rows.map(r => ({
187
+ url: r['url'], from: str(r['from_url']), status: num(r['status']), contentType: str(r['content_type']), bytes: num(r['bytes']),
188
+ etag: str(r['etag']), lastModified: str(r['last_modified']), sha256: str(r['sha256']), fileId: str(r['file_id']), unchanged: r['unchanged'] === true,
189
+ }));
190
+ };
191
+ const refusals = async (id) => {
192
+ await requireCrawl(id);
193
+ const rows = await db().execute(sql `
194
+ SELECT u.url, u.from_url, u.reason, u.message
195
+ FROM pipework_crawl_url u JOIN pipework_crawl c ON c.id = u.crawl_id
196
+ WHERE u.crawl_id = ${id}::uuid AND c.site = ${config.name} AND (u.state = 'refused' OR u.reason = 'page_hook') ORDER BY u.seq`);
197
+ return rows.map(r => ({ url: r['url'], from: str(r['from_url']), reason: str(r['reason']) ?? '', message: str(r['message']) ?? '' }));
198
+ };
199
+ // ---- the job ----
200
+ async function run(crawlId, signal) {
201
+ const crawl = await loadCrawl(crawlId);
202
+ if (crawl === null || crawl.state !== 'running')
203
+ return;
204
+ const { limits } = crawl;
205
+ let scope = crawl.scope;
206
+ const state = { stop: null, inFlight: 0, last: new Map(), hostInit: new Map(), robots: new Map() };
207
+ // Only one job runs a crawl, so a row still 'fetching' is the one that was in flight when the last attempt died.
208
+ await db().execute(sql `UPDATE pipework_crawl_url SET state = 'queued' WHERE crawl_id = ${crawlId}::uuid AND state = 'fetching'`);
209
+ const hostRow = async (host) => {
210
+ await db().execute(sql `INSERT INTO pipework_crawl_host (crawl_id, host) VALUES (${crawlId}::uuid, ${host}) ON CONFLICT (crawl_id, host) DO NOTHING`);
211
+ const r = (await db().execute(sql `
212
+ SELECT robots_state, robots_text, robots_attempts, last_request_at_ms::float8 AS last_ms FROM pipework_crawl_host WHERE crawl_id = ${crawlId}::uuid AND host = ${host}`))[0];
213
+ return { robotsState: str(r['robots_state']), robotsText: str(r['robots_text']), attempts: num(r['robots_attempts']), lastMs: num(r['last_ms']) };
214
+ };
215
+ const gapFor = (rules) => Math.max(limits.minGapMs, (rules?.crawlDelaySeconds ?? 0) * 1000);
216
+ /** Waits for this host's turn, then returns a function that records the request's end. A request starts at least `gap` after the last one ended (started, with several in flight). */
217
+ const takeTurn = async (host, gap) => {
218
+ let init = state.hostInit.get(host);
219
+ if (init === undefined) {
220
+ init = hostRow(host).then(row => { state.last.set(host, row.lastMs); });
221
+ state.hostInit.set(host, init);
222
+ }
223
+ await init;
224
+ const start = Math.max(Date.now(), state.last.get(host) + gap);
225
+ if (limits.perHostConcurrency > 1)
226
+ state.last.set(host, start);
227
+ await sleep(start - Date.now(), signal);
228
+ return async () => {
229
+ const end = Date.now();
230
+ state.last.set(host, Math.max(state.last.get(host), end));
231
+ await db().execute(sql `UPDATE pipework_crawl_host SET last_request_at_ms = ${end} WHERE crawl_id = ${crawlId}::uuid AND host = ${host}`);
232
+ };
233
+ };
234
+ const ua = { 'user-agent': config.userAgent };
235
+ const network = {
236
+ ...(config.network?.resolve !== undefined ? { resolve: config.network.resolve } : {}),
237
+ ...(config.network?.connect !== undefined ? { connect: config.network.connect } : {}),
238
+ };
239
+ /** The host's robots rules, fetched once before any other request to it; null when it stayed unreachable (the crawl stops). */
240
+ const robotsFor = (host, protocol) => {
241
+ let pending = state.robots.get(host);
242
+ if (pending === undefined) {
243
+ pending = loadRobots(host, protocol);
244
+ state.robots.set(host, pending);
245
+ }
246
+ return pending;
247
+ };
248
+ const loadRobots = async (host, protocol) => {
249
+ const row = await hostRow(host);
250
+ if (row.robotsState === 'ok')
251
+ return parseRobots(row.robotsText ?? '', config.userAgent);
252
+ if (row.robotsState === 'allow_all')
253
+ return ALLOW_ALL;
254
+ if (row.robotsState === 'disallow_all') {
255
+ const kept = JSON.parse(row.robotsText ?? 'null');
256
+ return kept === null ? DISALLOW_ALL : barred(kept.reason, kept.message);
257
+ }
258
+ const settle = async (robotsState, text) => {
259
+ await db().execute(sql `UPDATE pipework_crawl_host SET robots_state = ${robotsState}, robots_text = ${text} WHERE crawl_id = ${crawlId}::uuid AND host = ${host}`);
260
+ };
261
+ for (let attempt = row.attempts; attempt < ROBOTS_TRIES; attempt++) {
262
+ if (signal.aborted)
263
+ return null;
264
+ if (attempt > 0)
265
+ await sleep(robotsRetryMs * 2 ** (attempt - 1), signal);
266
+ const done = await takeTurn(host, limits.minGapMs);
267
+ const got = await untrustedGet(`${protocol}//${host}/robots.txt`, {
268
+ maxBytes: ROBOTS_MAX_BYTES, timeoutMs: limits.requestTimeoutMs, maxRedirects: limits.maxRedirects, headers: ua, urlIsSafeToTrace,
269
+ followRedirect: (to) => new URL(to).host === host ? true : 'robots.txt redirects to another host',
270
+ ...network,
271
+ });
272
+ await done();
273
+ if (got.ok) {
274
+ const text = new TextDecoder().decode(got.body);
275
+ await settle('ok', text);
276
+ return parseRobots(text, config.userAgent);
277
+ }
278
+ if (got.reason === 'status' && got.status !== undefined && got.status >= 400 && got.status < 500) {
279
+ await settle('allow_all', null);
280
+ return ALLOW_ALL;
281
+ }
282
+ if (got.reason === 'status' || got.reason === 'network' || got.reason === 'timeout') {
283
+ await db().execute(sql `UPDATE pipework_crawl_host SET robots_attempts = ${attempt + 1} WHERE crawl_id = ${crawlId}::uuid AND host = ${host}`);
284
+ continue;
285
+ }
286
+ const refusal = { reason: got.reason, message: got.message };
287
+ await settle('disallow_all', JSON.stringify(refusal));
288
+ return barred(refusal.reason, refusal.message);
289
+ }
290
+ return signal.aborted ? null : (state.stop = 'robots_unreachable', null);
291
+ };
292
+ const insertLinks = async (tx, rows) => {
293
+ if (rows.length === 0)
294
+ return;
295
+ await tx.execute(sql `
296
+ INSERT INTO pipework_crawl_url (crawl_id, url, depth, from_url, redirects, state, reason, message, seed_chain)
297
+ SELECT ${crawlId}::uuid, x.url, x.depth, x.from_url, x.redirects, x.state, x.reason, x.message, x.seed_chain
298
+ FROM jsonb_to_recordset(${JSON.stringify(rows.map(r => ({ url: r.url, depth: r.depth, from_url: r.from, redirects: r.redirects, state: r.state, reason: r.reason, message: r.message, seed_chain: r.seedChain === true })))}::jsonb)
299
+ AS x(url text, depth int, from_url text, redirects int, state text, reason text, message text, seed_chain boolean)
300
+ ON CONFLICT (crawl_id, url) DO NOTHING`);
301
+ };
302
+ const finishUrl = async (row, outcome, extra) => {
303
+ await db().transaction(async (tx) => {
304
+ await extra?.(tx);
305
+ await tx.execute(sql `
306
+ UPDATE pipework_crawl_url SET state = ${outcome.state}, reason = ${outcome.reason ?? null}, message = ${outcome.message ?? null}, status = ${outcome.status ?? null}, requested = requested OR ${outcome.requested === true}
307
+ WHERE id = ${row.id}::uuid`);
308
+ });
309
+ };
310
+ const runHook = async (url, html) => {
311
+ const hook = config.onPage;
312
+ if (hook === undefined)
313
+ return null;
314
+ const controller = new AbortController();
315
+ let timer;
316
+ const overrun = new Promise((_, reject) => {
317
+ timer = setTimeout(() => {
318
+ const err = new Error(`onPage took longer than ${String(limits.pageHookMs)} ms.`);
319
+ controller.abort(err);
320
+ reject(err);
321
+ }, limits.pageHookMs);
322
+ });
323
+ try {
324
+ const work = Promise.resolve().then(() => hook({ url, html, signal: controller.signal }));
325
+ work.catch(() => undefined);
326
+ await Promise.race([work, overrun]);
327
+ return null;
328
+ }
329
+ catch (err) {
330
+ return describeError(err);
331
+ }
332
+ finally {
333
+ clearTimeout(timer);
334
+ }
335
+ };
336
+ const previous = async (url) => {
337
+ const rows = await db().execute(sql `
338
+ SELECT r.etag, r.last_modified, r.status, r.content_type, r.bytes::float8 AS bytes, r.sha256, r.file_id
339
+ FROM pipework_crawl_resource r JOIN pipework_crawl c ON c.id = r.crawl_id
340
+ WHERE c.site = ${config.name} AND c.seed = ${crawl.seed} AND c.id <> ${crawlId}::uuid AND c.created_at < (SELECT created_at FROM pipework_crawl WHERE id = ${crawlId}::uuid)
341
+ AND r.url = ${url} AND (r.etag IS NOT NULL OR r.last_modified IS NOT NULL)
342
+ ORDER BY c.created_at DESC LIMIT 1`);
343
+ const r = rows[0];
344
+ if (r === undefined)
345
+ return null;
346
+ return { etag: str(r['etag']), lastModified: str(r['last_modified']), status: num(r['status']), contentType: str(r['content_type']), bytes: num(r['bytes']), sha256: str(r['sha256']), fileId: str(r['file_id']) };
347
+ };
348
+ const movesScope = (row, to) => scope.kind === 'host' && row.seedChain && row.depth === 0 && !inScope(scope, to.hostname);
349
+ const processUrl = async (row) => {
350
+ const target = new URL(row.url);
351
+ const rules = await robotsFor(target.host, target.protocol);
352
+ if (rules === null) {
353
+ if (!signal.aborted)
354
+ await db().execute(sql `UPDATE pipework_crawl_url SET state = 'queued' WHERE id = ${row.id}::uuid`);
355
+ return;
356
+ }
357
+ if (!rules.allows(target.pathname + target.search)) {
358
+ const why = rules.refusal;
359
+ await finishUrl(row, { state: 'refused', reason: why?.reason ?? 'robots', message: why?.message ?? 'robots.txt does not allow this path.' });
360
+ return;
361
+ }
362
+ const done = await takeTurn(target.host, gapFor(rules));
363
+ if (signal.aborted) {
364
+ await db().execute(sql `UPDATE pipework_crawl_url SET state = 'queued' WHERE id = ${row.id}::uuid`);
365
+ return;
366
+ }
367
+ const prior = await previous(row.url);
368
+ const headers = { ...ua };
369
+ if (prior?.etag != null)
370
+ headers['if-none-match'] = prior.etag;
371
+ if (prior?.lastModified != null)
372
+ headers['if-modified-since'] = prior.lastModified;
373
+ const hop = { to: null };
374
+ const got = await untrustedGet(row.url, {
375
+ maxBytes: limits.maxBytesPerResponse, timeoutMs: limits.requestTimeoutMs, maxRedirects: limits.maxRedirects, headers, urlIsSafeToTrace,
376
+ // A redirect is not followed inside the request: its target is a URL of the crawl like any link, so it meets scope, robots and the host's gap.
377
+ followRedirect: (to) => { hop.to = to; return 'The crawler handles redirects itself.'; },
378
+ accept: (head) => {
379
+ const type = baseType(head.contentType);
380
+ if (HTML_TYPES.has(type))
381
+ return true;
382
+ return config.accept({ url: row.url, contentType: type }) || 'This is neither a page nor a file the app lists.';
383
+ },
384
+ ...network,
385
+ });
386
+ await done();
387
+ if (!got.ok) {
388
+ if (got.reason === 'rejected' && hop.to !== null) {
389
+ const hops = row.redirects + 1;
390
+ let to = null;
391
+ try {
392
+ to = new URL(hop.to);
393
+ }
394
+ catch { /* refused below */ }
395
+ if (hops > limits.maxRedirects)
396
+ await finishUrl(row, { requested: true, state: 'refused', reason: 'redirects', message: 'The link redirects too many times.' });
397
+ else if (to === null || (!inScope(scope, to.hostname) && !movesScope(row, to)))
398
+ await finishUrl(row, { requested: true, state: 'refused', reason: 'scope', message: 'The link redirects to a page outside the crawl\'s scope.' });
399
+ else {
400
+ to.hash = '';
401
+ // The seed's own redirect chain may move a host scope (example.gov.uk to www.example.gov.uk).
402
+ const moved = inScope(scope, to.hostname) ? null : { kind: 'host', host: to.hostname };
403
+ await finishUrl(row, { requested: true, state: 'done', reason: 'redirected', message: 'Redirected; the target is queued.' }, async (tx) => {
404
+ if (moved !== null)
405
+ await tx.execute(sql `UPDATE pipework_crawl SET scope = ${JSON.stringify(moved)}::jsonb WHERE id = ${crawlId}::uuid`);
406
+ await insertLinks(tx, [{ url: to.href, depth: row.depth, from: row.fromUrl ?? row.url, state: 'queued', reason: null, message: null, redirects: hops, seedChain: row.seedChain }]);
407
+ });
408
+ if (moved !== null)
409
+ scope = moved;
410
+ }
411
+ return;
412
+ }
413
+ if (got.reason === 'status' && got.status === 304 && prior !== null) {
414
+ await finishUrl(row, { requested: true, state: 'done', status: 304 }, tx => tx.execute(sql `
415
+ INSERT INTO pipework_crawl_resource (crawl_id, url, from_url, status, content_type, bytes, etag, last_modified, sha256, file_id, unchanged)
416
+ VALUES (${crawlId}::uuid, ${row.url}, ${row.fromUrl}, ${prior.status}, ${prior.contentType}, ${prior.bytes}, ${prior.etag}, ${prior.lastModified}, ${prior.sha256}, ${prior.fileId}, true)
417
+ ON CONFLICT (crawl_id, url) DO NOTHING`).then(() => undefined));
418
+ return;
419
+ }
420
+ await finishUrl(row, { requested: true, state: 'refused', reason: got.reason, message: got.message, status: got.status ?? null });
421
+ return;
422
+ }
423
+ const type = baseType(got.contentType);
424
+ const isHtml = HTML_TYPES.has(type);
425
+ const listed = config.accept({ url: got.url, contentType: type });
426
+ let hookFault = null;
427
+ let links = [];
428
+ if (isHtml) {
429
+ const html = new TextDecoder().decode(got.body);
430
+ links = extractLinks(html, got.url);
431
+ hookFault = await runHook(row.url, html);
432
+ }
433
+ let sha256 = null;
434
+ let fileId = null;
435
+ if (listed && config.store !== undefined) {
436
+ const file = await config.store.put({ body: Readable.from(Buffer.from(got.body)), mediaType: type === '' ? 'application/octet-stream' : type, metadata: { url: got.url, crawl: crawlId } });
437
+ sha256 = file.sha256;
438
+ fileId = file.id;
439
+ }
440
+ const children = links.map(link => {
441
+ const u = new URL(link);
442
+ const depth = row.depth + 1;
443
+ if (!inScope(scope, u.hostname))
444
+ return { url: link, depth, from: row.url, state: 'refused', reason: 'scope', message: 'The link points outside the crawl\'s scope.', redirects: 0 };
445
+ if (depth > limits.maxDepth)
446
+ return { url: link, depth, from: row.url, state: 'refused', reason: 'depth', message: `The link is more than ${String(limits.maxDepth)} links from the seed.`, redirects: 0 };
447
+ return { url: link, depth, from: row.url, state: 'queued', reason: null, message: null, redirects: 0 };
448
+ });
449
+ await finishUrl(row, hookFault === null ? { requested: true, state: 'done', status: got.status } : { requested: true, state: 'done', status: got.status, reason: 'page_hook', message: hookFault }, async (tx) => {
450
+ await tx.execute(sql `UPDATE pipework_crawl SET bytes = bytes + ${got.bytes} WHERE id = ${crawlId}::uuid`);
451
+ if (listed) {
452
+ await tx.execute(sql `
453
+ INSERT INTO pipework_crawl_resource (crawl_id, url, from_url, status, content_type, bytes, etag, last_modified, sha256, file_id)
454
+ VALUES (${crawlId}::uuid, ${row.url}, ${row.fromUrl}, ${got.status}, ${type === '' ? null : type}, ${got.bytes}, ${got.etag}, ${got.lastModified}, ${sha256}, ${fileId})
455
+ ON CONFLICT (crawl_id, url) DO NOTHING`);
456
+ }
457
+ await insertLinks(tx, children);
458
+ });
459
+ };
460
+ /** The next queued URL, claimed so no other lane takes it; breadth first. */
461
+ const claim = async () => {
462
+ const rows = await db().execute(sql `
463
+ UPDATE pipework_crawl_url SET state = 'fetching'
464
+ WHERE id = (SELECT id FROM pipework_crawl_url WHERE crawl_id = ${crawlId}::uuid AND state = 'queued'
465
+ ORDER BY depth, seq LIMIT 1 FOR UPDATE SKIP LOCKED)
466
+ RETURNING id::text AS id, url, depth, from_url, redirects, seed_chain`);
467
+ const r = rows[0];
468
+ return r === undefined ? null : { id: r['id'], url: r['url'], depth: num(r['depth']), fromUrl: str(r['from_url']), redirects: num(r['redirects']), seedChain: r['seed_chain'] === true };
469
+ };
470
+ const limitHit = async () => {
471
+ if (Date.now() - crawl.runStartedAt > limits.maxWallMs)
472
+ return 'wall';
473
+ const r = (await db().execute(sql `
474
+ SELECT (SELECT count(*) FROM pipework_crawl_url WHERE crawl_id = ${crawlId}::uuid AND requested)::int AS pages,
475
+ (SELECT bytes::float8 FROM pipework_crawl WHERE id = ${crawlId}::uuid) AS bytes`))[0];
476
+ if (num(r['pages']) >= limits.maxPages)
477
+ return 'pages';
478
+ if (num(r['bytes']) >= limits.maxBytes)
479
+ return 'bytes';
480
+ return null;
481
+ };
482
+ const lane = async () => {
483
+ while (!signal.aborted && state.stop === null) {
484
+ const hit = await limitHit();
485
+ if (hit !== null) {
486
+ const queued = hit === 'wall' || hit === 'bytes' || num((await db().execute(sql `SELECT count(*)::int AS n FROM pipework_crawl_url WHERE crawl_id = ${crawlId}::uuid AND state = 'queued'`))[0]['n']) > 0;
487
+ if (queued)
488
+ state.stop = hit;
489
+ else if (state.inFlight === 0)
490
+ return;
491
+ }
492
+ if (state.stop !== null)
493
+ return;
494
+ const row = await claim();
495
+ if (row === null) {
496
+ if (state.inFlight === 0)
497
+ return;
498
+ await sleep(25, signal);
499
+ continue;
500
+ }
501
+ state.inFlight++;
502
+ try {
503
+ await processUrl(row);
504
+ }
505
+ finally {
506
+ state.inFlight--;
507
+ }
508
+ }
509
+ };
510
+ await Promise.all(Array.from({ length: limits.perHostConcurrency }, () => lane()));
511
+ if (signal.aborted)
512
+ return;
513
+ if (state.stop !== null) {
514
+ await db().execute(sql `UPDATE pipework_crawl SET state = 'stopped', stopped_by = ${state.stop}, finished_at = now() WHERE id = ${crawlId}::uuid`);
515
+ return;
516
+ }
517
+ const depthCut = await db().execute(sql `SELECT 1 FROM pipework_crawl_url WHERE crawl_id = ${crawlId}::uuid AND reason = 'depth' LIMIT 1`);
518
+ if (depthCut.length > 0) {
519
+ await db().execute(sql `UPDATE pipework_crawl SET state = 'stopped', stopped_by = 'depth', finished_at = now() WHERE id = ${crawlId}::uuid`);
520
+ return;
521
+ }
522
+ await db().execute(sql `UPDATE pipework_crawl SET state = 'done', finished_at = now() WHERE id = ${crawlId}::uuid`);
523
+ }
524
+ const builder = database !== undefined ? fitting.use(database) : fitting.use();
525
+ const job = builder.job(jobType)
526
+ .transaction('manual')
527
+ .input(schema.check.object({ crawlId: schema.check.string() }))
528
+ .fit((async ({ input, signal }) => {
529
+ try {
530
+ await run(input.crawlId, signal);
531
+ }
532
+ catch (err) {
533
+ const flow = getContext();
534
+ const last = flow?.jobAttempt != null && flow.jobMaxAttempts != null && flow.jobAttempt >= flow.jobMaxAttempts;
535
+ if (last) {
536
+ getBaseLogger().error({ err, crawlId: input.crawlId }, 'Crawl job failed on its last attempt');
537
+ await db().execute(sql `UPDATE pipework_crawl SET state = 'failed', error = ${describeError(err)}, finished_at = now() WHERE id = ${input.crawlId}::uuid`);
538
+ }
539
+ throw err;
540
+ }
541
+ }));
542
+ return {
543
+ job,
544
+ jobType,
545
+ start: (options) => startStep(options),
546
+ approve: (id) => approveStep(id),
547
+ status, resources, refusals,
548
+ };
549
+ }
550
+ //# sourceMappingURL=handle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle.js","sourceRoot":"","sources":["../../../src/infra/crawl/handle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { createCrawl, DEFAULT_LIMITS } from './handle.js';
2
+ export type { CrawlConfig, CrawlSite, CrawlStartOptions, CrawlLimits, ResolvedCrawlLimits, CrawlScope, CrawlState, CrawlStoppedBy, CrawlStatus, CrawlCounts, CrawlResource, CrawlRefusal, CrawlPage, } from './handle.js';
3
+ export { CrawlNotEnabledError, CrawlSeedError } from './errors.js';
4
+ export { parseRobots, productToken, ALLOW_ALL, DISALLOW_ALL } from './robots.js';
5
+ export type { RobotsRules } from './robots.js';
6
+ export { extractLinks } from './links.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infra/crawl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACzD,YAAY,EACV,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EACnH,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,GACjE,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAChF,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { createCrawl, DEFAULT_LIMITS } from './handle.js';
2
+ export { CrawlNotEnabledError, CrawlSeedError } from './errors.js';
3
+ export { parseRobots, productToken, ALLOW_ALL, DISALLOW_ALL } from './robots.js';
4
+ export { extractLinks } from './links.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infra/crawl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAKzD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEhF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}