@enricai/barnacle 1.0.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 (448) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +958 -0
  3. package/dist/api/errors.d.ts +88 -0
  4. package/dist/api/errors.d.ts.map +1 -0
  5. package/dist/api/errors.js +164 -0
  6. package/dist/api/errors.js.map +1 -0
  7. package/dist/api/helpers/envelope.d.ts +13 -0
  8. package/dist/api/helpers/envelope.d.ts.map +1 -0
  9. package/dist/api/helpers/envelope.js +20 -0
  10. package/dist/api/helpers/envelope.js.map +1 -0
  11. package/dist/api/helpers/reply.d.ts +9 -0
  12. package/dist/api/helpers/reply.d.ts.map +1 -0
  13. package/dist/api/helpers/reply.js +14 -0
  14. package/dist/api/helpers/reply.js.map +1 -0
  15. package/dist/api/plugins/auth.d.ts +27 -0
  16. package/dist/api/plugins/auth.d.ts.map +1 -0
  17. package/dist/api/plugins/auth.js +111 -0
  18. package/dist/api/plugins/auth.js.map +1 -0
  19. package/dist/api/plugins/error-handler.d.ts +12 -0
  20. package/dist/api/plugins/error-handler.d.ts.map +1 -0
  21. package/dist/api/plugins/error-handler.js +72 -0
  22. package/dist/api/plugins/error-handler.js.map +1 -0
  23. package/dist/api/plugins/request-context.d.ts +17 -0
  24. package/dist/api/plugins/request-context.d.ts.map +1 -0
  25. package/dist/api/plugins/request-context.js +61 -0
  26. package/dist/api/plugins/request-context.js.map +1 -0
  27. package/dist/api/routes/health.d.ts +55 -0
  28. package/dist/api/routes/health.d.ts.map +1 -0
  29. package/dist/api/routes/health.js +137 -0
  30. package/dist/api/routes/health.js.map +1 -0
  31. package/dist/api/routes/plugins-introspection.d.ts +17 -0
  32. package/dist/api/routes/plugins-introspection.d.ts.map +1 -0
  33. package/dist/api/routes/plugins-introspection.js +13 -0
  34. package/dist/api/routes/plugins-introspection.js.map +1 -0
  35. package/dist/api/schemas/common.d.ts +114 -0
  36. package/dist/api/schemas/common.d.ts.map +1 -0
  37. package/dist/api/schemas/common.js +109 -0
  38. package/dist/api/schemas/common.js.map +1 -0
  39. package/dist/api/schemas/telemetry.d.ts +66 -0
  40. package/dist/api/schemas/telemetry.d.ts.map +1 -0
  41. package/dist/api/schemas/telemetry.js +52 -0
  42. package/dist/api/schemas/telemetry.js.map +1 -0
  43. package/dist/cache/keyed-ttl-cache.d.ts +45 -0
  44. package/dist/cache/keyed-ttl-cache.d.ts.map +1 -0
  45. package/dist/cache/keyed-ttl-cache.js +69 -0
  46. package/dist/cache/keyed-ttl-cache.js.map +1 -0
  47. package/dist/cache/response-cache.d.ts +37 -0
  48. package/dist/cache/response-cache.d.ts.map +1 -0
  49. package/dist/cache/response-cache.js +114 -0
  50. package/dist/cache/response-cache.js.map +1 -0
  51. package/dist/config.d.ts +258 -0
  52. package/dist/config.d.ts.map +1 -0
  53. package/dist/config.js +138 -0
  54. package/dist/config.js.map +1 -0
  55. package/dist/lib/applicant-payload.d.ts +28 -0
  56. package/dist/lib/applicant-payload.d.ts.map +1 -0
  57. package/dist/lib/applicant-payload.js +20 -0
  58. package/dist/lib/applicant-payload.js.map +1 -0
  59. package/dist/lib/application-address.d.ts +16 -0
  60. package/dist/lib/application-address.d.ts.map +1 -0
  61. package/dist/lib/application-address.js +20 -0
  62. package/dist/lib/application-address.js.map +1 -0
  63. package/dist/lib/application-answers.d.ts +151 -0
  64. package/dist/lib/application-answers.d.ts.map +1 -0
  65. package/dist/lib/application-answers.js +95 -0
  66. package/dist/lib/application-answers.js.map +1 -0
  67. package/dist/lib/application-identity.d.ts +18 -0
  68. package/dist/lib/application-identity.d.ts.map +1 -0
  69. package/dist/lib/application-identity.js +20 -0
  70. package/dist/lib/application-identity.js.map +1 -0
  71. package/dist/lib/application-resume.d.ts +21 -0
  72. package/dist/lib/application-resume.d.ts.map +1 -0
  73. package/dist/lib/application-resume.js +23 -0
  74. package/dist/lib/application-resume.js.map +1 -0
  75. package/dist/lib/bedrock.d.ts +22 -0
  76. package/dist/lib/bedrock.d.ts.map +1 -0
  77. package/dist/lib/bedrock.js +35 -0
  78. package/dist/lib/bedrock.js.map +1 -0
  79. package/dist/lib/case-insensitive-headers.d.ts +15 -0
  80. package/dist/lib/case-insensitive-headers.d.ts.map +1 -0
  81. package/dist/lib/case-insensitive-headers.js +29 -0
  82. package/dist/lib/case-insensitive-headers.js.map +1 -0
  83. package/dist/lib/chromium-client-hints.d.ts +11 -0
  84. package/dist/lib/chromium-client-hints.d.ts.map +1 -0
  85. package/dist/lib/chromium-client-hints.js +17 -0
  86. package/dist/lib/chromium-client-hints.js.map +1 -0
  87. package/dist/lib/cookie-value.d.ts +8 -0
  88. package/dist/lib/cookie-value.d.ts.map +1 -0
  89. package/dist/lib/cookie-value.js +14 -0
  90. package/dist/lib/cookie-value.js.map +1 -0
  91. package/dist/lib/datadog.d.ts +8 -0
  92. package/dist/lib/datadog.d.ts.map +1 -0
  93. package/dist/lib/datadog.js +27 -0
  94. package/dist/lib/datadog.js.map +1 -0
  95. package/dist/lib/dd-metrics.d.ts +28 -0
  96. package/dist/lib/dd-metrics.d.ts.map +1 -0
  97. package/dist/lib/dd-metrics.js +62 -0
  98. package/dist/lib/dd-metrics.js.map +1 -0
  99. package/dist/lib/dispatch-metrics.d.ts +19 -0
  100. package/dist/lib/dispatch-metrics.d.ts.map +1 -0
  101. package/dist/lib/dispatch-metrics.js +65 -0
  102. package/dist/lib/dispatch-metrics.js.map +1 -0
  103. package/dist/lib/env.d.ts +37 -0
  104. package/dist/lib/env.d.ts.map +1 -0
  105. package/dist/lib/env.js +70 -0
  106. package/dist/lib/env.js.map +1 -0
  107. package/dist/lib/errors.d.ts +15 -0
  108. package/dist/lib/errors.d.ts.map +1 -0
  109. package/dist/lib/errors.js +20 -0
  110. package/dist/lib/errors.js.map +1 -0
  111. package/dist/lib/http.d.ts +7 -0
  112. package/dist/lib/http.d.ts.map +1 -0
  113. package/dist/lib/http.js +14 -0
  114. package/dist/lib/http.js.map +1 -0
  115. package/dist/lib/job-tracking.d.ts +17 -0
  116. package/dist/lib/job-tracking.d.ts.map +1 -0
  117. package/dist/lib/job-tracking.js +19 -0
  118. package/dist/lib/job-tracking.js.map +1 -0
  119. package/dist/lib/llm/anthropic-client.d.ts +12 -0
  120. package/dist/lib/llm/anthropic-client.d.ts.map +1 -0
  121. package/dist/lib/llm/anthropic-client.js +23 -0
  122. package/dist/lib/llm/anthropic-client.js.map +1 -0
  123. package/dist/lib/llm/judge.d.ts +57 -0
  124. package/dist/lib/llm/judge.d.ts.map +1 -0
  125. package/dist/lib/llm/judge.js +123 -0
  126. package/dist/lib/llm/judge.js.map +1 -0
  127. package/dist/lib/llm/judges/error-messages.d.ts +38 -0
  128. package/dist/lib/llm/judges/error-messages.d.ts.map +1 -0
  129. package/dist/lib/llm/judges/error-messages.js +72 -0
  130. package/dist/lib/llm/judges/error-messages.js.map +1 -0
  131. package/dist/lib/llm/judges/invalid-fields.d.ts +43 -0
  132. package/dist/lib/llm/judges/invalid-fields.d.ts.map +1 -0
  133. package/dist/lib/llm/judges/invalid-fields.js +80 -0
  134. package/dist/lib/llm/judges/invalid-fields.js.map +1 -0
  135. package/dist/lib/llm/judges/modal-priority.d.ts +41 -0
  136. package/dist/lib/llm/judges/modal-priority.d.ts.map +1 -0
  137. package/dist/lib/llm/judges/modal-priority.js +74 -0
  138. package/dist/lib/llm/judges/modal-priority.js.map +1 -0
  139. package/dist/lib/llm/judges/select-option.d.ts +49 -0
  140. package/dist/lib/llm/judges/select-option.d.ts.map +1 -0
  141. package/dist/lib/llm/judges/select-option.js +90 -0
  142. package/dist/lib/llm/judges/select-option.js.map +1 -0
  143. package/dist/lib/llm/judges/verify-submit.d.ts +68 -0
  144. package/dist/lib/llm/judges/verify-submit.d.ts.map +1 -0
  145. package/dist/lib/llm/judges/verify-submit.js +89 -0
  146. package/dist/lib/llm/judges/verify-submit.js.map +1 -0
  147. package/dist/lib/llm/schemas.d.ts +220 -0
  148. package/dist/lib/llm/schemas.d.ts.map +1 -0
  149. package/dist/lib/llm/schemas.js +239 -0
  150. package/dist/lib/llm/schemas.js.map +1 -0
  151. package/dist/lib/logging.d.ts +39 -0
  152. package/dist/lib/logging.d.ts.map +1 -0
  153. package/dist/lib/logging.js +219 -0
  154. package/dist/lib/logging.js.map +1 -0
  155. package/dist/lib/multipart.d.ts +34 -0
  156. package/dist/lib/multipart.d.ts.map +1 -0
  157. package/dist/lib/multipart.js +55 -0
  158. package/dist/lib/multipart.js.map +1 -0
  159. package/dist/lib/option-matcher.d.ts +15 -0
  160. package/dist/lib/option-matcher.d.ts.map +1 -0
  161. package/dist/lib/option-matcher.js +69 -0
  162. package/dist/lib/option-matcher.js.map +1 -0
  163. package/dist/lib/phone.d.ts +11 -0
  164. package/dist/lib/phone.d.ts.map +1 -0
  165. package/dist/lib/phone.js +17 -0
  166. package/dist/lib/phone.js.map +1 -0
  167. package/dist/lib/random.d.ts +22 -0
  168. package/dist/lib/random.d.ts.map +1 -0
  169. package/dist/lib/random.js +33 -0
  170. package/dist/lib/random.js.map +1 -0
  171. package/dist/lib/statsd.d.ts +11 -0
  172. package/dist/lib/statsd.d.ts.map +1 -0
  173. package/dist/lib/statsd.js +68 -0
  174. package/dist/lib/statsd.js.map +1 -0
  175. package/dist/lib/telemetry/call-capture.d.ts +89 -0
  176. package/dist/lib/telemetry/call-capture.d.ts.map +1 -0
  177. package/dist/lib/telemetry/call-capture.js +190 -0
  178. package/dist/lib/telemetry/call-capture.js.map +1 -0
  179. package/dist/lib/telemetry/call-types.d.ts +65 -0
  180. package/dist/lib/telemetry/call-types.d.ts.map +1 -0
  181. package/dist/lib/telemetry/call-types.js +68 -0
  182. package/dist/lib/telemetry/call-types.js.map +1 -0
  183. package/dist/lib/telemetry/run-state.d.ts +15 -0
  184. package/dist/lib/telemetry/run-state.d.ts.map +1 -0
  185. package/dist/lib/telemetry/run-state.js +23 -0
  186. package/dist/lib/telemetry/run-state.js.map +1 -0
  187. package/dist/lib/telemetry/s3-sink.d.ts +48 -0
  188. package/dist/lib/telemetry/s3-sink.d.ts.map +1 -0
  189. package/dist/lib/telemetry/s3-sink.js +229 -0
  190. package/dist/lib/telemetry/s3-sink.js.map +1 -0
  191. package/dist/lib/telemetry/submission-capture.d.ts +45 -0
  192. package/dist/lib/telemetry/submission-capture.d.ts.map +1 -0
  193. package/dist/lib/telemetry/submission-capture.js +57 -0
  194. package/dist/lib/telemetry/submission-capture.js.map +1 -0
  195. package/dist/lib/telemetry/telemetry-paths.d.ts +59 -0
  196. package/dist/lib/telemetry/telemetry-paths.d.ts.map +1 -0
  197. package/dist/lib/telemetry/telemetry-paths.js +103 -0
  198. package/dist/lib/telemetry/telemetry-paths.js.map +1 -0
  199. package/dist/lib/tracking-click.d.ts +20 -0
  200. package/dist/lib/tracking-click.d.ts.map +1 -0
  201. package/dist/lib/tracking-click.js +75 -0
  202. package/dist/lib/tracking-click.js.map +1 -0
  203. package/dist/lib/url-capture.d.ts +8 -0
  204. package/dist/lib/url-capture.d.ts.map +1 -0
  205. package/dist/lib/url-capture.js +17 -0
  206. package/dist/lib/url-capture.js.map +1 -0
  207. package/dist/lib/us-states.d.ts +20 -0
  208. package/dist/lib/us-states.d.ts.map +1 -0
  209. package/dist/lib/us-states.js +86 -0
  210. package/dist/lib/us-states.js.map +1 -0
  211. package/dist/lib/zod-multipart.d.ts +18 -0
  212. package/dist/lib/zod-multipart.d.ts.map +1 -0
  213. package/dist/lib/zod-multipart.js +35 -0
  214. package/dist/lib/zod-multipart.js.map +1 -0
  215. package/dist/plugins/config-plugin.d.ts +77 -0
  216. package/dist/plugins/config-plugin.d.ts.map +1 -0
  217. package/dist/plugins/config-plugin.js +216 -0
  218. package/dist/plugins/config-plugin.js.map +1 -0
  219. package/dist/plugins/discover.d.ts +72 -0
  220. package/dist/plugins/discover.d.ts.map +1 -0
  221. package/dist/plugins/discover.js +265 -0
  222. package/dist/plugins/discover.js.map +1 -0
  223. package/dist/plugins/json-schema-to-zod.d.ts +47 -0
  224. package/dist/plugins/json-schema-to-zod.d.ts.map +1 -0
  225. package/dist/plugins/json-schema-to-zod.js +85 -0
  226. package/dist/plugins/json-schema-to-zod.js.map +1 -0
  227. package/dist/plugins/loader.d.ts +34 -0
  228. package/dist/plugins/loader.d.ts.map +1 -0
  229. package/dist/plugins/loader.js +348 -0
  230. package/dist/plugins/loader.js.map +1 -0
  231. package/dist/plugins/plugin-api-version.d.ts +8 -0
  232. package/dist/plugins/plugin-api-version.d.ts.map +1 -0
  233. package/dist/plugins/plugin-api-version.js +11 -0
  234. package/dist/plugins/plugin-api-version.js.map +1 -0
  235. package/dist/plugins/plugin-manifest-envelope.d.ts +16 -0
  236. package/dist/plugins/plugin-manifest-envelope.d.ts.map +1 -0
  237. package/dist/plugins/plugin-manifest-envelope.js +19 -0
  238. package/dist/plugins/plugin-manifest-envelope.js.map +1 -0
  239. package/dist/scraper/behavioral-signals.d.ts +16 -0
  240. package/dist/scraper/behavioral-signals.d.ts.map +1 -0
  241. package/dist/scraper/behavioral-signals.js +30 -0
  242. package/dist/scraper/behavioral-signals.js.map +1 -0
  243. package/dist/scraper/errors.d.ts +193 -0
  244. package/dist/scraper/errors.d.ts.map +1 -0
  245. package/dist/scraper/errors.js +226 -0
  246. package/dist/scraper/errors.js.map +1 -0
  247. package/dist/scraper/fixtures.d.ts +23 -0
  248. package/dist/scraper/fixtures.d.ts.map +1 -0
  249. package/dist/scraper/fixtures.js +48 -0
  250. package/dist/scraper/fixtures.js.map +1 -0
  251. package/dist/scraper/flow-runner.d.ts +1319 -0
  252. package/dist/scraper/flow-runner.d.ts.map +1 -0
  253. package/dist/scraper/flow-runner.js +5637 -0
  254. package/dist/scraper/flow-runner.js.map +1 -0
  255. package/dist/scraper/graphql-client.d.ts +30 -0
  256. package/dist/scraper/graphql-client.d.ts.map +1 -0
  257. package/dist/scraper/graphql-client.js +14 -0
  258. package/dist/scraper/graphql-client.js.map +1 -0
  259. package/dist/scraper/http-client.d.ts +75 -0
  260. package/dist/scraper/http-client.d.ts.map +1 -0
  261. package/dist/scraper/http-client.js +189 -0
  262. package/dist/scraper/http-client.js.map +1 -0
  263. package/dist/scraper/http-status-classifier.d.ts +12 -0
  264. package/dist/scraper/http-status-classifier.d.ts.map +1 -0
  265. package/dist/scraper/http-status-classifier.js +29 -0
  266. package/dist/scraper/http-status-classifier.js.map +1 -0
  267. package/dist/scraper/metrics.d.ts +50 -0
  268. package/dist/scraper/metrics.d.ts.map +1 -0
  269. package/dist/scraper/metrics.js +85 -0
  270. package/dist/scraper/metrics.js.map +1 -0
  271. package/dist/scraper/navigate.d.ts +20 -0
  272. package/dist/scraper/navigate.d.ts.map +1 -0
  273. package/dist/scraper/navigate.js +30 -0
  274. package/dist/scraper/navigate.js.map +1 -0
  275. package/dist/scraper/oracle-sentinels.d.ts +22 -0
  276. package/dist/scraper/oracle-sentinels.d.ts.map +1 -0
  277. package/dist/scraper/oracle-sentinels.js +40 -0
  278. package/dist/scraper/oracle-sentinels.js.map +1 -0
  279. package/dist/scraper/parse-json-response.d.ts +16 -0
  280. package/dist/scraper/parse-json-response.d.ts.map +1 -0
  281. package/dist/scraper/parse-json-response.js +37 -0
  282. package/dist/scraper/parse-json-response.js.map +1 -0
  283. package/dist/scraper/pool.d.ts +37 -0
  284. package/dist/scraper/pool.d.ts.map +1 -0
  285. package/dist/scraper/pool.js +105 -0
  286. package/dist/scraper/pool.js.map +1 -0
  287. package/dist/scraper/rate-limited-json-client.d.ts +35 -0
  288. package/dist/scraper/rate-limited-json-client.d.ts.map +1 -0
  289. package/dist/scraper/rate-limited-json-client.js +29 -0
  290. package/dist/scraper/rate-limited-json-client.js.map +1 -0
  291. package/dist/scraper/raw-fetch.d.ts +49 -0
  292. package/dist/scraper/raw-fetch.d.ts.map +1 -0
  293. package/dist/scraper/raw-fetch.js +40 -0
  294. package/dist/scraper/raw-fetch.js.map +1 -0
  295. package/dist/scraper/require-response-field.d.ts +23 -0
  296. package/dist/scraper/require-response-field.d.ts.map +1 -0
  297. package/dist/scraper/require-response-field.js +42 -0
  298. package/dist/scraper/require-response-field.js.map +1 -0
  299. package/dist/scraper/retry.d.ts +33 -0
  300. package/dist/scraper/retry.d.ts.map +1 -0
  301. package/dist/scraper/retry.js +122 -0
  302. package/dist/scraper/retry.js.map +1 -0
  303. package/dist/scraper/session-browserbase.d.ts +35 -0
  304. package/dist/scraper/session-browserbase.d.ts.map +1 -0
  305. package/dist/scraper/session-browserbase.js +198 -0
  306. package/dist/scraper/session-browserbase.js.map +1 -0
  307. package/dist/scraper/session-shared.d.ts +29 -0
  308. package/dist/scraper/session-shared.d.ts.map +1 -0
  309. package/dist/scraper/session-shared.js +35 -0
  310. package/dist/scraper/session-shared.js.map +1 -0
  311. package/dist/scraper/session-steel.d.ts +31 -0
  312. package/dist/scraper/session-steel.d.ts.map +1 -0
  313. package/dist/scraper/session-steel.js +140 -0
  314. package/dist/scraper/session-steel.js.map +1 -0
  315. package/dist/scraper/session-warmup.d.ts +31 -0
  316. package/dist/scraper/session-warmup.d.ts.map +1 -0
  317. package/dist/scraper/session-warmup.js +46 -0
  318. package/dist/scraper/session-warmup.js.map +1 -0
  319. package/dist/scraper/session.d.ts +21 -0
  320. package/dist/scraper/session.d.ts.map +1 -0
  321. package/dist/scraper/session.js +28 -0
  322. package/dist/scraper/session.js.map +1 -0
  323. package/dist/scraper/stagehand-guard.d.ts +128 -0
  324. package/dist/scraper/stagehand-guard.d.ts.map +1 -0
  325. package/dist/scraper/stagehand-guard.js +337 -0
  326. package/dist/scraper/stagehand-guard.js.map +1 -0
  327. package/dist/scraper/throttle.d.ts +21 -0
  328. package/dist/scraper/throttle.d.ts.map +1 -0
  329. package/dist/scraper/throttle.js +45 -0
  330. package/dist/scraper/throttle.js.map +1 -0
  331. package/dist/scripts/hca-inbox-poll.d.ts +19 -0
  332. package/dist/scripts/hca-inbox-poll.d.ts.map +1 -0
  333. package/dist/scripts/hca-inbox-poll.js +151 -0
  334. package/dist/scripts/hca-inbox-poll.js.map +1 -0
  335. package/dist/scripts/judge-llm-batch.d.ts +98 -0
  336. package/dist/scripts/judge-llm-batch.d.ts.map +1 -0
  337. package/dist/scripts/judge-llm-batch.js +350 -0
  338. package/dist/scripts/judge-llm-batch.js.map +1 -0
  339. package/dist/scripts/llm-heal.d.ts +165 -0
  340. package/dist/scripts/llm-heal.d.ts.map +1 -0
  341. package/dist/scripts/llm-heal.js +595 -0
  342. package/dist/scripts/llm-heal.js.map +1 -0
  343. package/dist/scripts/migrate-telemetry-dir-names.d.ts +57 -0
  344. package/dist/scripts/migrate-telemetry-dir-names.d.ts.map +1 -0
  345. package/dist/scripts/migrate-telemetry-dir-names.js +156 -0
  346. package/dist/scripts/migrate-telemetry-dir-names.js.map +1 -0
  347. package/dist/scripts/probe-setinputfiles.d.ts +28 -0
  348. package/dist/scripts/probe-setinputfiles.d.ts.map +1 -0
  349. package/dist/scripts/probe-setinputfiles.js +95 -0
  350. package/dist/scripts/probe-setinputfiles.js.map +1 -0
  351. package/dist/scripts/recon-browser.d.ts +304 -0
  352. package/dist/scripts/recon-browser.d.ts.map +1 -0
  353. package/dist/scripts/recon-browser.js +1833 -0
  354. package/dist/scripts/recon-browser.js.map +1 -0
  355. package/dist/scripts/recon-generate.d.ts +182 -0
  356. package/dist/scripts/recon-generate.d.ts.map +1 -0
  357. package/dist/scripts/recon-generate.js +2572 -0
  358. package/dist/scripts/recon-generate.js.map +1 -0
  359. package/dist/scripts/recon-heal.d.ts +176 -0
  360. package/dist/scripts/recon-heal.d.ts.map +1 -0
  361. package/dist/scripts/recon-heal.js +584 -0
  362. package/dist/scripts/recon-heal.js.map +1 -0
  363. package/dist/scripts/recon-http.d.ts +19 -0
  364. package/dist/scripts/recon-http.d.ts.map +1 -0
  365. package/dist/scripts/recon-http.js +377 -0
  366. package/dist/scripts/recon-http.js.map +1 -0
  367. package/dist/scripts/recon-replay-jobs.d.ts +21 -0
  368. package/dist/scripts/recon-replay-jobs.d.ts.map +1 -0
  369. package/dist/scripts/recon-replay-jobs.js +221 -0
  370. package/dist/scripts/recon-replay-jobs.js.map +1 -0
  371. package/dist/scripts/recon-shared.d.ts +52 -0
  372. package/dist/scripts/recon-shared.d.ts.map +1 -0
  373. package/dist/scripts/recon-shared.js +68 -0
  374. package/dist/scripts/recon-shared.js.map +1 -0
  375. package/dist/scripts/recon-summarize.d.ts +15 -0
  376. package/dist/scripts/recon-summarize.d.ts.map +1 -0
  377. package/dist/scripts/recon-summarize.js +233 -0
  378. package/dist/scripts/recon-summarize.js.map +1 -0
  379. package/dist/scripts/smoke-test.d.ts +22 -0
  380. package/dist/scripts/smoke-test.d.ts.map +1 -0
  381. package/dist/scripts/smoke-test.js +236 -0
  382. package/dist/scripts/smoke-test.js.map +1 -0
  383. package/dist/server.d.ts +10 -0
  384. package/dist/server.d.ts.map +1 -0
  385. package/dist/server.js +189 -0
  386. package/dist/server.js.map +1 -0
  387. package/dist/site-plugin.d.ts +226 -0
  388. package/dist/site-plugin.d.ts.map +1 -0
  389. package/dist/site-plugin.js +13 -0
  390. package/dist/site-plugin.js.map +1 -0
  391. package/dist/testing/answers-fixture.d.ts +13 -0
  392. package/dist/testing/answers-fixture.d.ts.map +1 -0
  393. package/dist/testing/answers-fixture.js +37 -0
  394. package/dist/testing/answers-fixture.js.map +1 -0
  395. package/dist/testing/batch-email-confirmation.d.ts +58 -0
  396. package/dist/testing/batch-email-confirmation.d.ts.map +1 -0
  397. package/dist/testing/batch-email-confirmation.js +62 -0
  398. package/dist/testing/batch-email-confirmation.js.map +1 -0
  399. package/dist/testing/batch-report.d.ts +33 -0
  400. package/dist/testing/batch-report.d.ts.map +1 -0
  401. package/dist/testing/batch-report.js +30 -0
  402. package/dist/testing/batch-report.js.map +1 -0
  403. package/dist/testing/contract-parity-suite.d.ts +55 -0
  404. package/dist/testing/contract-parity-suite.d.ts.map +1 -0
  405. package/dist/testing/contract-parity-suite.js +39 -0
  406. package/dist/testing/contract-parity-suite.js.map +1 -0
  407. package/dist/testing/coverage-guard-suite.d.ts +46 -0
  408. package/dist/testing/coverage-guard-suite.d.ts.map +1 -0
  409. package/dist/testing/coverage-guard-suite.js +39 -0
  410. package/dist/testing/coverage-guard-suite.js.map +1 -0
  411. package/dist/testing/fixtures/resume.pdf +54 -0
  412. package/dist/testing/integration-runner.d.ts +62 -0
  413. package/dist/testing/integration-runner.d.ts.map +1 -0
  414. package/dist/testing/integration-runner.js +46 -0
  415. package/dist/testing/integration-runner.js.map +1 -0
  416. package/dist/testing/mock-fetch-response.d.ts +7 -0
  417. package/dist/testing/mock-fetch-response.d.ts.map +1 -0
  418. package/dist/testing/mock-fetch-response.js +16 -0
  419. package/dist/testing/mock-fetch-response.js.map +1 -0
  420. package/dist/testing/persona-fixture.d.ts +77 -0
  421. package/dist/testing/persona-fixture.d.ts.map +1 -0
  422. package/dist/testing/persona-fixture.js +83 -0
  423. package/dist/testing/persona-fixture.js.map +1 -0
  424. package/dist/testing/replay-integration-suite.d.ts +50 -0
  425. package/dist/testing/replay-integration-suite.d.ts.map +1 -0
  426. package/dist/testing/replay-integration-suite.js +45 -0
  427. package/dist/testing/replay-integration-suite.js.map +1 -0
  428. package/dist/testing/resume-fixture.d.ts +39 -0
  429. package/dist/testing/resume-fixture.d.ts.map +1 -0
  430. package/dist/testing/resume-fixture.js +38 -0
  431. package/dist/testing/resume-fixture.js.map +1 -0
  432. package/dist/testmail/client.d.ts +61 -0
  433. package/dist/testmail/client.d.ts.map +1 -0
  434. package/dist/testmail/client.js +190 -0
  435. package/dist/testmail/client.js.map +1 -0
  436. package/dist/testmail/errors.d.ts +18 -0
  437. package/dist/testmail/errors.d.ts.map +1 -0
  438. package/dist/testmail/errors.js +29 -0
  439. package/dist/testmail/errors.js.map +1 -0
  440. package/dist/types/dispatch-metrics.d.ts +46 -0
  441. package/dist/types/dispatch-metrics.d.ts.map +1 -0
  442. package/dist/types/dispatch-metrics.js +25 -0
  443. package/dist/types/dispatch-metrics.js.map +1 -0
  444. package/dist/types/logging.d.ts +11 -0
  445. package/dist/types/logging.d.ts.map +1 -0
  446. package/dist/types/logging.js +3 -0
  447. package/dist/types/logging.js.map +1 -0
  448. package/package.json +283 -0
@@ -0,0 +1,88 @@
1
+ import { type ErrorCode } from "../api/schemas/common";
2
+ /**
3
+ * Representation of the error envelope on the wire. Every non-2xx
4
+ * response from Barnacle conforms to this shape so clients can share a
5
+ * single parser across all error types.
6
+ */
7
+ interface ApiStatusDetail {
8
+ code: number;
9
+ codeDescription: string;
10
+ detailType: string;
11
+ message: string;
12
+ }
13
+ interface ApiErrorEnvelope {
14
+ status: {
15
+ httpStatus: string;
16
+ dateTime: string;
17
+ details: ApiStatusDetail[];
18
+ };
19
+ }
20
+ /**
21
+ * Maps an error code to the HTTP status we return. Status codes come
22
+ * from the `http-status-codes` package (battle-tested, RFC-aligned, used
23
+ * by Express and thousands of production APIs) so we don't maintain our
24
+ * own numeric table.
25
+ *
26
+ * The envelope uses `httpStatus` as a string. Barnacle also sets the actual
27
+ * HTTP status code so modern clients can branch on either.
28
+ */
29
+ export declare function httpStatusForCode(code: ErrorCode): number;
30
+ /**
31
+ * Converts an HTTP status number into the upper-snake-case string used in
32
+ * the response envelope (e.g. 400 → `"BAD_REQUEST"`). Uses `getReasonPhrase`
33
+ * from `http-status-codes`, then uppercases and replaces non-alphanumeric
34
+ * runs with `_` (e.g. `I'm a teapot` → `I_M_A_TEAPOT`).
35
+ */
36
+ export declare function httpStatusString(status: number): string;
37
+ /**
38
+ * Base class for every structured error Barnacle surfaces to clients. Each
39
+ * subclass hard-codes an error code; the plugin-level error handler
40
+ * reads `code` + `message` and builds the envelope.
41
+ */
42
+ export declare class ApiError extends Error {
43
+ readonly code: ErrorCode;
44
+ readonly detailType: string;
45
+ constructor(code: ErrorCode, message: string, detailType?: string);
46
+ }
47
+ export declare class UnauthorizedError extends ApiError {
48
+ constructor(message?: string);
49
+ }
50
+ export declare class FieldViolationError extends ApiError {
51
+ constructor(message: string);
52
+ }
53
+ export declare class ThrottledRequestError extends ApiError {
54
+ constructor(message?: string);
55
+ }
56
+ /**
57
+ * The upstream vendor has locked the target URL (e.g. Oracle ORA_URL_LOCKED).
58
+ * Signals "back off and retry later" — not a browser-fallback trigger.
59
+ */
60
+ export declare class UrlLockedError extends ApiError {
61
+ constructor(message?: string);
62
+ }
63
+ export declare class ScrapeFailureError extends ApiError {
64
+ constructor(message?: string);
65
+ }
66
+ export declare class CaptchaEncounteredError extends ApiError {
67
+ constructor(message?: string);
68
+ }
69
+ export declare class EmptyResultsApiError extends ApiError {
70
+ constructor(message?: string);
71
+ }
72
+ /**
73
+ * The OTP a candidate supplied to /resume was rejected by Oracle HCM, which
74
+ * surfaces as a 401/403 on the first AccessCode-authed call. Distinct from a
75
+ * generic scrape failure so Vivian can re-prompt for the code rather than
76
+ * treating the resume as terminally failed.
77
+ */
78
+ export declare class InvalidOtpError extends ApiError {
79
+ constructor(message?: string);
80
+ }
81
+ /**
82
+ * Builds an error envelope for the given code + message. Used by the
83
+ * Fastify error handler and anywhere else a manual non-200 response needs
84
+ * to be emitted (e.g. Fastify's built-in rate-limit 429).
85
+ */
86
+ export declare function buildErrorEnvelope(code: ErrorCode, message: string, detailType?: string): ApiErrorEnvelope;
87
+ export {};
88
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE5F;;;;GAIG;AACH,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,eAAe,EAAE,CAAC;KAC5B,CAAC;CACH;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAgCzD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,IAAI,EAAE,SAAS,CAAC;IAChC,SAAgB,UAAU,EAAE,MAAM,CAAC;gBAEvB,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,SAAU;CAMnE;AAED,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,SAA4C;CAGhE;AAED,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,OAAO,EAAE,MAAM;CAG5B;AAED,qBAAa,qBAAsB,SAAQ,QAAQ;gBACrC,OAAO,SAAwB;CAG5C;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,SAA6D;CAGjF;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,OAAO,SAA0C;CAG9D;AAED,qBAAa,uBAAwB,SAAQ,QAAQ;gBACvC,OAAO,SAA2C;CAG/D;AAED,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,OAAO,SAA6C;CAGjE;AAED;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,SAA4C;CAGhE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,EACf,UAAU,SAAU,GACnB,gBAAgB,CAgBlB"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidOtpError = exports.EmptyResultsApiError = exports.CaptchaEncounteredError = exports.ScrapeFailureError = exports.UrlLockedError = exports.ThrottledRequestError = exports.FieldViolationError = exports.UnauthorizedError = exports.ApiError = void 0;
4
+ exports.httpStatusForCode = httpStatusForCode;
5
+ exports.httpStatusString = httpStatusString;
6
+ exports.buildErrorEnvelope = buildErrorEnvelope;
7
+ const date_fns_1 = require("date-fns");
8
+ const http_status_codes_1 = require("http-status-codes");
9
+ const common_1 = require("../api/schemas/common");
10
+ /**
11
+ * Maps an error code to the HTTP status we return. Status codes come
12
+ * from the `http-status-codes` package (battle-tested, RFC-aligned, used
13
+ * by Express and thousands of production APIs) so we don't maintain our
14
+ * own numeric table.
15
+ *
16
+ * The envelope uses `httpStatus` as a string. Barnacle also sets the actual
17
+ * HTTP status code so modern clients can branch on either.
18
+ */
19
+ function httpStatusForCode(code) {
20
+ switch (code) {
21
+ case common_1.ERROR_CODES.PARTIAL_CONTENT_SUCCESS:
22
+ return http_status_codes_1.StatusCodes.PARTIAL_CONTENT;
23
+ case common_1.ERROR_CODES.AUTHORIZATION_ERROR:
24
+ return http_status_codes_1.StatusCodes.UNAUTHORIZED;
25
+ case common_1.ERROR_CODES.DECODING_ERROR:
26
+ case common_1.ERROR_CODES.FIELD_VIOLATION:
27
+ case common_1.ERROR_CODES.EMPTY_REQUEST:
28
+ return http_status_codes_1.StatusCodes.BAD_REQUEST;
29
+ case common_1.ERROR_CODES.RESOURCE_NOT_FOUND:
30
+ case common_1.ERROR_CODES.INDEX_NOT_FOUND:
31
+ return http_status_codes_1.StatusCodes.NOT_FOUND;
32
+ case common_1.ERROR_CODES.THROTTLED_REQUEST:
33
+ case common_1.ERROR_CODES.URL_LOCKED:
34
+ return http_status_codes_1.StatusCodes.TOO_MANY_REQUESTS;
35
+ case common_1.ERROR_CODES.TIME_OUT:
36
+ return http_status_codes_1.StatusCodes.GATEWAY_TIMEOUT;
37
+ case common_1.ERROR_CODES.EMPTY_RESULTS:
38
+ return http_status_codes_1.StatusCodes.NOT_FOUND;
39
+ case common_1.ERROR_CODES.CLIENT_CALL_ERROR:
40
+ case common_1.ERROR_CODES.GENERIC_ERROR:
41
+ case common_1.ERROR_CODES.EXTRA_DETAIL:
42
+ case common_1.ERROR_CODES.SCRAPE_FAILURE:
43
+ case common_1.ERROR_CODES.CAPTCHA_ENCOUNTERED:
44
+ case common_1.ERROR_CODES.VERIFICATION_TRIGGER_FAILED:
45
+ return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR;
46
+ case common_1.ERROR_CODES.RESUME_INVALID_OTP:
47
+ return http_status_codes_1.StatusCodes.BAD_REQUEST;
48
+ default:
49
+ return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR;
50
+ }
51
+ }
52
+ /**
53
+ * Converts an HTTP status number into the upper-snake-case string used in
54
+ * the response envelope (e.g. 400 → `"BAD_REQUEST"`). Uses `getReasonPhrase`
55
+ * from `http-status-codes`, then uppercases and replaces non-alphanumeric
56
+ * runs with `_` (e.g. `I'm a teapot` → `I_M_A_TEAPOT`).
57
+ */
58
+ function httpStatusString(status) {
59
+ try {
60
+ return (0, http_status_codes_1.getReasonPhrase)(status)
61
+ .toUpperCase()
62
+ .replace(/[^A-Z0-9]+/g, "_");
63
+ }
64
+ catch {
65
+ return `HTTP_${status}`;
66
+ }
67
+ }
68
+ /**
69
+ * Base class for every structured error Barnacle surfaces to clients. Each
70
+ * subclass hard-codes an error code; the plugin-level error handler
71
+ * reads `code` + `message` and builds the envelope.
72
+ */
73
+ class ApiError extends Error {
74
+ code;
75
+ detailType;
76
+ constructor(code, message, detailType = "ERROR") {
77
+ super(message);
78
+ this.name = new.target.name;
79
+ this.code = code;
80
+ this.detailType = detailType;
81
+ }
82
+ }
83
+ exports.ApiError = ApiError;
84
+ class UnauthorizedError extends ApiError {
85
+ constructor(message = "missing or invalid Authorization header") {
86
+ super(common_1.ERROR_CODES.AUTHORIZATION_ERROR, message);
87
+ }
88
+ }
89
+ exports.UnauthorizedError = UnauthorizedError;
90
+ class FieldViolationError extends ApiError {
91
+ constructor(message) {
92
+ super(common_1.ERROR_CODES.FIELD_VIOLATION, message);
93
+ }
94
+ }
95
+ exports.FieldViolationError = FieldViolationError;
96
+ class ThrottledRequestError extends ApiError {
97
+ constructor(message = "rate limit exceeded") {
98
+ super(common_1.ERROR_CODES.THROTTLED_REQUEST, message);
99
+ }
100
+ }
101
+ exports.ThrottledRequestError = ThrottledRequestError;
102
+ /**
103
+ * The upstream vendor has locked the target URL (e.g. Oracle ORA_URL_LOCKED).
104
+ * Signals "back off and retry later" — not a browser-fallback trigger.
105
+ */
106
+ class UrlLockedError extends ApiError {
107
+ constructor(message = "target URL is locked by the upstream vendor; retry later") {
108
+ super(common_1.ERROR_CODES.URL_LOCKED, message);
109
+ }
110
+ }
111
+ exports.UrlLockedError = UrlLockedError;
112
+ class ScrapeFailureError extends ApiError {
113
+ constructor(message = "scraper failed to fulfill the request") {
114
+ super(common_1.ERROR_CODES.SCRAPE_FAILURE, message);
115
+ }
116
+ }
117
+ exports.ScrapeFailureError = ScrapeFailureError;
118
+ class CaptchaEncounteredError extends ApiError {
119
+ constructor(message = "captcha challenge encountered upstream") {
120
+ super(common_1.ERROR_CODES.CAPTCHA_ENCOUNTERED, message);
121
+ }
122
+ }
123
+ exports.CaptchaEncounteredError = CaptchaEncounteredError;
124
+ class EmptyResultsApiError extends ApiError {
125
+ constructor(message = "scrape completed but returned no results") {
126
+ super(common_1.ERROR_CODES.EMPTY_RESULTS, message);
127
+ }
128
+ }
129
+ exports.EmptyResultsApiError = EmptyResultsApiError;
130
+ /**
131
+ * The OTP a candidate supplied to /resume was rejected by Oracle HCM, which
132
+ * surfaces as a 401/403 on the first AccessCode-authed call. Distinct from a
133
+ * generic scrape failure so Vivian can re-prompt for the code rather than
134
+ * treating the resume as terminally failed.
135
+ */
136
+ class InvalidOtpError extends ApiError {
137
+ constructor(message = "provided OTP was rejected by Oracle HCM") {
138
+ super(common_1.ERROR_CODES.RESUME_INVALID_OTP, message);
139
+ }
140
+ }
141
+ exports.InvalidOtpError = InvalidOtpError;
142
+ /**
143
+ * Builds an error envelope for the given code + message. Used by the
144
+ * Fastify error handler and anywhere else a manual non-200 response needs
145
+ * to be emitted (e.g. Fastify's built-in rate-limit 429).
146
+ */
147
+ function buildErrorEnvelope(code, message, detailType = "ERROR") {
148
+ const httpStatus = httpStatusForCode(code);
149
+ return {
150
+ status: {
151
+ httpStatus: httpStatusString(httpStatus),
152
+ dateTime: (0, date_fns_1.formatISO)(new Date()),
153
+ details: [
154
+ {
155
+ code,
156
+ codeDescription: common_1.ERROR_CODE_DESCRIPTIONS[code],
157
+ detailType,
158
+ message,
159
+ },
160
+ ],
161
+ },
162
+ };
163
+ }
164
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Builds the success envelope — `{ status: { httpStatus: "OK", ... } }`
3
+ * merged with the domain payload. Service methods return the complete
4
+ * envelope-shaped object so route handlers just pass them through.
5
+ */
6
+ export declare function successEnvelope<T extends object>(payload: T): {
7
+ status: {
8
+ httpStatus: string;
9
+ dateTime: string;
10
+ details: unknown[];
11
+ };
12
+ } & T;
13
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../../src/api/helpers/envelope.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,OAAO,EAAE,CAAC,GACT;IACD,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,CAAC;KACpB,CAAC;CACH,GAAG,CAAC,CASJ"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.successEnvelope = successEnvelope;
4
+ const date_fns_1 = require("date-fns");
5
+ /**
6
+ * Builds the success envelope — `{ status: { httpStatus: "OK", ... } }`
7
+ * merged with the domain payload. Service methods return the complete
8
+ * envelope-shaped object so route handlers just pass them through.
9
+ */
10
+ function successEnvelope(payload) {
11
+ return {
12
+ status: {
13
+ httpStatus: "OK",
14
+ dateTime: (0, date_fns_1.formatISO)(new Date()),
15
+ details: [],
16
+ },
17
+ ...payload,
18
+ };
19
+ }
20
+ //# sourceMappingURL=envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../../src/api/helpers/envelope.ts"],"names":[],"mappings":";;AAOA,0CAiBC;AAxBD,uCAAqC;AAErC;;;;GAIG;AACH,SAAgB,eAAe,CAC7B,OAAU;IAQV,OAAO;QACL,MAAM,EAAE;YACN,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,IAAA,oBAAS,EAAC,IAAI,IAAI,EAAE,CAAC;YAC/B,OAAO,EAAE,EAAE;SACZ;QACD,GAAG,OAAO;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { FastifyReply } from "fastify";
2
+ import type { ErrorCode } from "../../api/schemas/common";
3
+ import type { DispatchMetrics } from "../../types/dispatch-metrics";
4
+ /**
5
+ * Sends a standard error envelope on the given reply, optionally including
6
+ * dispatch metrics so Vivian can forward step-level detail even on failures.
7
+ */
8
+ export declare function replyWithError(reply: FastifyReply, code: ErrorCode, message: string, detailType?: string, statusOverride?: number, metrics?: DispatchMetrics): void;
9
+ //# sourceMappingURL=reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply.d.ts","sourceRoot":"","sources":["../../../src/api/helpers/reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,eAAe,GACxB,IAAI,CAIN"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.replyWithError = replyWithError;
4
+ const errors_1 = require("../../api/errors");
5
+ /**
6
+ * Sends a standard error envelope on the given reply, optionally including
7
+ * dispatch metrics so Vivian can forward step-level detail even on failures.
8
+ */
9
+ function replyWithError(reply, code, message, detailType, statusOverride, metrics) {
10
+ const envelope = (0, errors_1.buildErrorEnvelope)(code, message, detailType);
11
+ const body = metrics ? { ...envelope, metrics } : envelope;
12
+ void reply.status(statusOverride ?? (0, errors_1.httpStatusForCode)(code)).send(body);
13
+ }
14
+ //# sourceMappingURL=reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply.js","sourceRoot":"","sources":["../../../src/api/helpers/reply.ts"],"names":[],"mappings":";;AAUA,wCAWC;AAnBD,yCAAqE;AAIrE;;;GAGG;AACH,SAAgB,cAAc,CAC5B,KAAmB,EACnB,IAAe,EACf,OAAe,EACf,UAAmB,EACnB,cAAuB,EACvB,OAAyB;IAEzB,MAAM,QAAQ,GAAG,IAAA,2BAAkB,EAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC3D,KAAK,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,IAAA,0BAAiB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ declare module "fastify" {
3
+ interface FastifyInstance {
4
+ authenticate: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
5
+ }
6
+ interface FastifyRequest {
7
+ apiKeyTier?: string;
8
+ /**
9
+ * Short SHA-256 fingerprint of the matching bcrypt hash, or the
10
+ * literal `"dev-bypass"` when DEV_BYPASS_AUTH is used. Lets ops
11
+ * trace "which client hit this route" in logs without leaking the
12
+ * plaintext token or the full bcrypt hash.
13
+ */
14
+ apiKeyFingerprint?: string;
15
+ }
16
+ }
17
+ /**
18
+ * Fastify plugin exposing `app.authenticate`. Routes attach it via
19
+ * `{ onRequest: [app.authenticate] }` to require a valid Bearer token.
20
+ *
21
+ * Dev-only escape hatch: `DEV_BYPASS_AUTH=true` allows unauthenticated
22
+ * access in non-production environments. NEVER set this in prod.
23
+ */
24
+ declare function authPlugin(app: FastifyInstance): Promise<void>;
25
+ declare const _default: typeof authPlugin;
26
+ export default _default;
27
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/api/plugins/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAS7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,YAAY,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC/E;IACD,UAAU,cAAc;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;;;;WAKG;QACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B;CACF;AAsCD;;;;;;GAMG;AACH,iBAAe,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6D7D;;AAED,wBAEG"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_crypto_1 = require("node:crypto");
7
+ const bcryptjs_1 = require("bcryptjs");
8
+ const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
9
+ const errors_1 = require("../../api/errors");
10
+ const config_1 = require("../../config");
11
+ const logging_1 = require("../../lib/logging");
12
+ const logger = (0, logging_1.getLogger)({ name: "api/plugins/auth" });
13
+ /**
14
+ * Derives a short, stable fingerprint from a bcrypt hash. 12 hex chars
15
+ * = 48 bits — enough to tell registered keys apart in a log stream
16
+ * without making offline collision attacks viable.
17
+ */
18
+ function fingerprintHash(hash) {
19
+ return (0, node_crypto_1.createHash)("sha256").update(hash).digest("hex").slice(0, 12);
20
+ }
21
+ /**
22
+ * Extracts the Bearer token from the Authorization header. Returns `null`
23
+ * if the header is missing or malformed — callers must translate that
24
+ * into the UnauthorizedError.
25
+ */
26
+ function extractBearer(authHeader) {
27
+ if (!authHeader)
28
+ return null;
29
+ const parts = authHeader.trim().split(/\s+/);
30
+ if (parts.length !== 2)
31
+ return null;
32
+ if (parts[0]?.toLowerCase() !== "bearer")
33
+ return null;
34
+ const token = parts[1];
35
+ if (!token || token.length < 8)
36
+ return null;
37
+ return token;
38
+ }
39
+ /**
40
+ * Compares the plaintext token against every registered bcrypt hash. We
41
+ * walk the array linearly — bcrypt.compare is constant-time for a given
42
+ * input + hash, and the hash count is small (tens).
43
+ */
44
+ async function findMatchingHash(token, hashes) {
45
+ for (const hash of hashes) {
46
+ if (await (0, bcryptjs_1.compare)(token, hash))
47
+ return hash;
48
+ }
49
+ return null;
50
+ }
51
+ /**
52
+ * Fastify plugin exposing `app.authenticate`. Routes attach it via
53
+ * `{ onRequest: [app.authenticate] }` to require a valid Bearer token.
54
+ *
55
+ * Dev-only escape hatch: `DEV_BYPASS_AUTH=true` allows unauthenticated
56
+ * access in non-production environments. NEVER set this in prod.
57
+ */
58
+ async function authPlugin(app) {
59
+ // Reload config at plugin-registration time so tests can toggle
60
+ // DEV_BYPASS_AUTH and spin up a fresh server instance without the
61
+ // frozen module-scope `config` singleton getting in the way.
62
+ const cfg = (0, config_1.loadConfig)();
63
+ // Loud startup warn if dev-bypass is active. NODE_ENV unset defaults
64
+ // to "development" (see lib/env.ts), so a container that forgets to
65
+ // set NODE_ENV while DEV_BYPASS_AUTH=true would silently accept
66
+ // unauthenticated traffic without any runtime signal. Emitting at
67
+ // plugin registration means every boot of every environment logs
68
+ // the state — much harder to miss than discovering it via a breach.
69
+ if (cfg.auth.devBypass && cfg.nodeEnv !== "production") {
70
+ logger.warn(`DEV_BYPASS_AUTH is active (NODE_ENV=${cfg.nodeEnv}) — all requests will bypass authentication. DO NOT use this in production.`);
71
+ }
72
+ else if (cfg.auth.devBypass && cfg.nodeEnv === "production") {
73
+ // devBypass=true + NODE_ENV=production means the env var is present
74
+ // but the production guard disarmed it. Still loud-warn because
75
+ // that's a misconfiguration worth catching.
76
+ logger.warn("DEV_BYPASS_AUTH=true in production — the production guard disarmed it, but the env var should be removed from the deploy.");
77
+ }
78
+ app.decorate("authenticate", async (request, _reply) => {
79
+ if (cfg.auth.devBypass && cfg.nodeEnv !== "production") {
80
+ request.apiKeyTier = "dev";
81
+ // Stamp a stable sentinel fingerprint so log-aggregator
82
+ // filters on `apiKeyFingerprint` don't miss dev-bypass traffic.
83
+ request.apiKeyFingerprint = "dev-bypass";
84
+ request.log = request.log.child({ apiKeyFingerprint: "dev-bypass" });
85
+ return;
86
+ }
87
+ const token = extractBearer(request.headers.authorization);
88
+ if (!token) {
89
+ throw new errors_1.UnauthorizedError("missing or malformed Authorization: Bearer header");
90
+ }
91
+ if (cfg.auth.hashedKeys.length === 0) {
92
+ throw new errors_1.UnauthorizedError("no API keys configured on server");
93
+ }
94
+ const match = await findMatchingHash(token, cfg.auth.hashedKeys);
95
+ if (!match) {
96
+ throw new errors_1.UnauthorizedError("invalid API key");
97
+ }
98
+ request.apiKeyTier = "standard";
99
+ const fingerprint = fingerprintHash(match);
100
+ request.apiKeyFingerprint = fingerprint;
101
+ // Bind the fingerprint onto the per-request pino child so every
102
+ // subsequent log line for this request carries the identity
103
+ // automatically — no scattered `{ apiKeyFingerprint: ... }`
104
+ // calls in service code.
105
+ request.log = request.log.child({ apiKeyFingerprint: fingerprint });
106
+ });
107
+ }
108
+ exports.default = (0, fastify_plugin_1.default)(authPlugin, {
109
+ name: "auth",
110
+ });
111
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/api/plugins/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ /**
3
+ * Fastify plugin that replaces Fastify's default error serializer with the
4
+ * engine error envelope. Every non-2xx response — Zod validation failures,
5
+ * thrown `ApiError` subclasses, 404s, unhandled crashes — serializes through
6
+ * the same `{ status: { httpStatus, dateTime, details: [...] } }` shape all
7
+ * clients expect.
8
+ */
9
+ declare function errorHandlerPlugin(app: FastifyInstance): Promise<void>;
10
+ declare const _default: typeof errorHandlerPlugin;
11
+ export default _default;
12
+ //# sourceMappingURL=error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/api/plugins/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAW/C;;;;;;GAMG;AACH,iBAAe,kBAAkB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFrE;;AAED,wBAEG"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
7
+ const fastify_type_provider_zod_1 = require("fastify-type-provider-zod");
8
+ const v4_1 = require("zod/v4");
9
+ const errors_1 = require("../../api/errors");
10
+ const reply_1 = require("../../api/helpers/reply");
11
+ const common_1 = require("../../api/schemas/common");
12
+ const errors_2 = require("../../scraper/errors");
13
+ /**
14
+ * Fastify plugin that replaces Fastify's default error serializer with the
15
+ * engine error envelope. Every non-2xx response — Zod validation failures,
16
+ * thrown `ApiError` subclasses, 404s, unhandled crashes — serializes through
17
+ * the same `{ status: { httpStatus, dateTime, details: [...] } }` shape all
18
+ * clients expect.
19
+ */
20
+ async function errorHandlerPlugin(app) {
21
+ app.setNotFoundHandler((_request, reply) => {
22
+ (0, reply_1.replyWithError)(reply, common_1.ERROR_CODES.RESOURCE_NOT_FOUND, `route ${_request.method} ${_request.url} not found`);
23
+ });
24
+ app.setErrorHandler((error, request, reply) => {
25
+ const metrics = error.metrics;
26
+ if ((0, fastify_type_provider_zod_1.hasZodFastifySchemaValidationErrors)(error)) {
27
+ const message = error.validation
28
+ .map((issue) => `${issue.instancePath || "body"}: ${issue.message}`)
29
+ .join("; ");
30
+ (0, reply_1.replyWithError)(reply, common_1.ERROR_CODES.FIELD_VIOLATION, message, undefined, undefined, metrics);
31
+ return;
32
+ }
33
+ if (error instanceof v4_1.ZodError) {
34
+ const message = error.issues
35
+ .map((issue) => `${issue.path.join(".") || "body"}: ${issue.message}`)
36
+ .join("; ");
37
+ (0, reply_1.replyWithError)(reply, common_1.ERROR_CODES.FIELD_VIOLATION, message, undefined, undefined, metrics);
38
+ return;
39
+ }
40
+ if (error instanceof errors_1.ApiError) {
41
+ (0, reply_1.replyWithError)(reply, error.code, error.message, error.detailType, undefined, metrics);
42
+ return;
43
+ }
44
+ // Scraper errors that escaped the service-layer catch (captcha hits,
45
+ // exhausted selector retries, session timeouts) surface to clients as
46
+ // the dedicated codes 2004 / 2003 rather than a generic 1008 — the
47
+ // whole reason those codes exist is for clients to distinguish scrape
48
+ // failures from upstream target-site failures.
49
+ if (error instanceof errors_2.ScraperError) {
50
+ const code = error instanceof errors_2.CaptchaError
51
+ ? common_1.ERROR_CODES.CAPTCHA_ENCOUNTERED
52
+ : common_1.ERROR_CODES.SCRAPE_FAILURE;
53
+ (0, reply_1.replyWithError)(reply, code, error.message, undefined, undefined, metrics);
54
+ return;
55
+ }
56
+ const err = error;
57
+ if (typeof err.statusCode === "number" && err.statusCode === 429) {
58
+ (0, reply_1.replyWithError)(reply, common_1.ERROR_CODES.THROTTLED_REQUEST, err.message || "rate limit exceeded", undefined, undefined, metrics);
59
+ return;
60
+ }
61
+ if (typeof err.statusCode === "number" && err.statusCode < 500) {
62
+ (0, reply_1.replyWithError)(reply, common_1.ERROR_CODES.GENERIC_ERROR, err.message || "request failed", undefined, err.statusCode, metrics);
63
+ return;
64
+ }
65
+ request.log.error({ err }, "unhandled error");
66
+ (0, reply_1.replyWithError)(reply, common_1.ERROR_CODES.GENERIC_ERROR, "internal server error", undefined, undefined, metrics);
67
+ });
68
+ }
69
+ exports.default = (0, fastify_plugin_1.default)(errorHandlerPlugin, {
70
+ name: "error-handler",
71
+ });
72
+ //# sourceMappingURL=error-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/api/plugins/error-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ declare module "fastify" {
3
+ interface FastifyRequest {
4
+ correlationId?: string;
5
+ }
6
+ }
7
+ /**
8
+ * Propagates request IDs and correlation IDs so logs can be stitched across
9
+ * services. We echo an inbound X-Request-ID when provided, otherwise
10
+ * generate a nanoid (replacing Fastify's per-process `req-N` default,
11
+ * which collides across pods), and always echo on response. Correlation
12
+ * IDs are echo-only — we never invent one.
13
+ */
14
+ declare function requestContextPlugin(app: FastifyInstance): Promise<void>;
15
+ declare const _default: typeof requestContextPlugin;
16
+ export default _default;
17
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../../src/api/plugins/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AA0B/D,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;CACF;AAED;;;;;;GAMG;AACH,iBAAe,oBAAoB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBvE;;AAED,wBAEG"}