@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.
- package/LICENSE +21 -0
- package/README.md +958 -0
- package/dist/api/errors.d.ts +88 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +164 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/helpers/envelope.d.ts +13 -0
- package/dist/api/helpers/envelope.d.ts.map +1 -0
- package/dist/api/helpers/envelope.js +20 -0
- package/dist/api/helpers/envelope.js.map +1 -0
- package/dist/api/helpers/reply.d.ts +9 -0
- package/dist/api/helpers/reply.d.ts.map +1 -0
- package/dist/api/helpers/reply.js +14 -0
- package/dist/api/helpers/reply.js.map +1 -0
- package/dist/api/plugins/auth.d.ts +27 -0
- package/dist/api/plugins/auth.d.ts.map +1 -0
- package/dist/api/plugins/auth.js +111 -0
- package/dist/api/plugins/auth.js.map +1 -0
- package/dist/api/plugins/error-handler.d.ts +12 -0
- package/dist/api/plugins/error-handler.d.ts.map +1 -0
- package/dist/api/plugins/error-handler.js +72 -0
- package/dist/api/plugins/error-handler.js.map +1 -0
- package/dist/api/plugins/request-context.d.ts +17 -0
- package/dist/api/plugins/request-context.d.ts.map +1 -0
- package/dist/api/plugins/request-context.js +61 -0
- package/dist/api/plugins/request-context.js.map +1 -0
- package/dist/api/routes/health.d.ts +55 -0
- package/dist/api/routes/health.d.ts.map +1 -0
- package/dist/api/routes/health.js +137 -0
- package/dist/api/routes/health.js.map +1 -0
- package/dist/api/routes/plugins-introspection.d.ts +17 -0
- package/dist/api/routes/plugins-introspection.d.ts.map +1 -0
- package/dist/api/routes/plugins-introspection.js +13 -0
- package/dist/api/routes/plugins-introspection.js.map +1 -0
- package/dist/api/schemas/common.d.ts +114 -0
- package/dist/api/schemas/common.d.ts.map +1 -0
- package/dist/api/schemas/common.js +109 -0
- package/dist/api/schemas/common.js.map +1 -0
- package/dist/api/schemas/telemetry.d.ts +66 -0
- package/dist/api/schemas/telemetry.d.ts.map +1 -0
- package/dist/api/schemas/telemetry.js +52 -0
- package/dist/api/schemas/telemetry.js.map +1 -0
- package/dist/cache/keyed-ttl-cache.d.ts +45 -0
- package/dist/cache/keyed-ttl-cache.d.ts.map +1 -0
- package/dist/cache/keyed-ttl-cache.js +69 -0
- package/dist/cache/keyed-ttl-cache.js.map +1 -0
- package/dist/cache/response-cache.d.ts +37 -0
- package/dist/cache/response-cache.d.ts.map +1 -0
- package/dist/cache/response-cache.js +114 -0
- package/dist/cache/response-cache.js.map +1 -0
- package/dist/config.d.ts +258 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +138 -0
- package/dist/config.js.map +1 -0
- package/dist/lib/applicant-payload.d.ts +28 -0
- package/dist/lib/applicant-payload.d.ts.map +1 -0
- package/dist/lib/applicant-payload.js +20 -0
- package/dist/lib/applicant-payload.js.map +1 -0
- package/dist/lib/application-address.d.ts +16 -0
- package/dist/lib/application-address.d.ts.map +1 -0
- package/dist/lib/application-address.js +20 -0
- package/dist/lib/application-address.js.map +1 -0
- package/dist/lib/application-answers.d.ts +151 -0
- package/dist/lib/application-answers.d.ts.map +1 -0
- package/dist/lib/application-answers.js +95 -0
- package/dist/lib/application-answers.js.map +1 -0
- package/dist/lib/application-identity.d.ts +18 -0
- package/dist/lib/application-identity.d.ts.map +1 -0
- package/dist/lib/application-identity.js +20 -0
- package/dist/lib/application-identity.js.map +1 -0
- package/dist/lib/application-resume.d.ts +21 -0
- package/dist/lib/application-resume.d.ts.map +1 -0
- package/dist/lib/application-resume.js +23 -0
- package/dist/lib/application-resume.js.map +1 -0
- package/dist/lib/bedrock.d.ts +22 -0
- package/dist/lib/bedrock.d.ts.map +1 -0
- package/dist/lib/bedrock.js +35 -0
- package/dist/lib/bedrock.js.map +1 -0
- package/dist/lib/case-insensitive-headers.d.ts +15 -0
- package/dist/lib/case-insensitive-headers.d.ts.map +1 -0
- package/dist/lib/case-insensitive-headers.js +29 -0
- package/dist/lib/case-insensitive-headers.js.map +1 -0
- package/dist/lib/chromium-client-hints.d.ts +11 -0
- package/dist/lib/chromium-client-hints.d.ts.map +1 -0
- package/dist/lib/chromium-client-hints.js +17 -0
- package/dist/lib/chromium-client-hints.js.map +1 -0
- package/dist/lib/cookie-value.d.ts +8 -0
- package/dist/lib/cookie-value.d.ts.map +1 -0
- package/dist/lib/cookie-value.js +14 -0
- package/dist/lib/cookie-value.js.map +1 -0
- package/dist/lib/datadog.d.ts +8 -0
- package/dist/lib/datadog.d.ts.map +1 -0
- package/dist/lib/datadog.js +27 -0
- package/dist/lib/datadog.js.map +1 -0
- package/dist/lib/dd-metrics.d.ts +28 -0
- package/dist/lib/dd-metrics.d.ts.map +1 -0
- package/dist/lib/dd-metrics.js +62 -0
- package/dist/lib/dd-metrics.js.map +1 -0
- package/dist/lib/dispatch-metrics.d.ts +19 -0
- package/dist/lib/dispatch-metrics.d.ts.map +1 -0
- package/dist/lib/dispatch-metrics.js +65 -0
- package/dist/lib/dispatch-metrics.js.map +1 -0
- package/dist/lib/env.d.ts +37 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +70 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/errors.d.ts +15 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +20 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/http.d.ts +7 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +14 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/job-tracking.d.ts +17 -0
- package/dist/lib/job-tracking.d.ts.map +1 -0
- package/dist/lib/job-tracking.js +19 -0
- package/dist/lib/job-tracking.js.map +1 -0
- package/dist/lib/llm/anthropic-client.d.ts +12 -0
- package/dist/lib/llm/anthropic-client.d.ts.map +1 -0
- package/dist/lib/llm/anthropic-client.js +23 -0
- package/dist/lib/llm/anthropic-client.js.map +1 -0
- package/dist/lib/llm/judge.d.ts +57 -0
- package/dist/lib/llm/judge.d.ts.map +1 -0
- package/dist/lib/llm/judge.js +123 -0
- package/dist/lib/llm/judge.js.map +1 -0
- package/dist/lib/llm/judges/error-messages.d.ts +38 -0
- package/dist/lib/llm/judges/error-messages.d.ts.map +1 -0
- package/dist/lib/llm/judges/error-messages.js +72 -0
- package/dist/lib/llm/judges/error-messages.js.map +1 -0
- package/dist/lib/llm/judges/invalid-fields.d.ts +43 -0
- package/dist/lib/llm/judges/invalid-fields.d.ts.map +1 -0
- package/dist/lib/llm/judges/invalid-fields.js +80 -0
- package/dist/lib/llm/judges/invalid-fields.js.map +1 -0
- package/dist/lib/llm/judges/modal-priority.d.ts +41 -0
- package/dist/lib/llm/judges/modal-priority.d.ts.map +1 -0
- package/dist/lib/llm/judges/modal-priority.js +74 -0
- package/dist/lib/llm/judges/modal-priority.js.map +1 -0
- package/dist/lib/llm/judges/select-option.d.ts +49 -0
- package/dist/lib/llm/judges/select-option.d.ts.map +1 -0
- package/dist/lib/llm/judges/select-option.js +90 -0
- package/dist/lib/llm/judges/select-option.js.map +1 -0
- package/dist/lib/llm/judges/verify-submit.d.ts +68 -0
- package/dist/lib/llm/judges/verify-submit.d.ts.map +1 -0
- package/dist/lib/llm/judges/verify-submit.js +89 -0
- package/dist/lib/llm/judges/verify-submit.js.map +1 -0
- package/dist/lib/llm/schemas.d.ts +220 -0
- package/dist/lib/llm/schemas.d.ts.map +1 -0
- package/dist/lib/llm/schemas.js +239 -0
- package/dist/lib/llm/schemas.js.map +1 -0
- package/dist/lib/logging.d.ts +39 -0
- package/dist/lib/logging.d.ts.map +1 -0
- package/dist/lib/logging.js +219 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/multipart.d.ts +34 -0
- package/dist/lib/multipart.d.ts.map +1 -0
- package/dist/lib/multipart.js +55 -0
- package/dist/lib/multipart.js.map +1 -0
- package/dist/lib/option-matcher.d.ts +15 -0
- package/dist/lib/option-matcher.d.ts.map +1 -0
- package/dist/lib/option-matcher.js +69 -0
- package/dist/lib/option-matcher.js.map +1 -0
- package/dist/lib/phone.d.ts +11 -0
- package/dist/lib/phone.d.ts.map +1 -0
- package/dist/lib/phone.js +17 -0
- package/dist/lib/phone.js.map +1 -0
- package/dist/lib/random.d.ts +22 -0
- package/dist/lib/random.d.ts.map +1 -0
- package/dist/lib/random.js +33 -0
- package/dist/lib/random.js.map +1 -0
- package/dist/lib/statsd.d.ts +11 -0
- package/dist/lib/statsd.d.ts.map +1 -0
- package/dist/lib/statsd.js +68 -0
- package/dist/lib/statsd.js.map +1 -0
- package/dist/lib/telemetry/call-capture.d.ts +89 -0
- package/dist/lib/telemetry/call-capture.d.ts.map +1 -0
- package/dist/lib/telemetry/call-capture.js +190 -0
- package/dist/lib/telemetry/call-capture.js.map +1 -0
- package/dist/lib/telemetry/call-types.d.ts +65 -0
- package/dist/lib/telemetry/call-types.d.ts.map +1 -0
- package/dist/lib/telemetry/call-types.js +68 -0
- package/dist/lib/telemetry/call-types.js.map +1 -0
- package/dist/lib/telemetry/run-state.d.ts +15 -0
- package/dist/lib/telemetry/run-state.d.ts.map +1 -0
- package/dist/lib/telemetry/run-state.js +23 -0
- package/dist/lib/telemetry/run-state.js.map +1 -0
- package/dist/lib/telemetry/s3-sink.d.ts +48 -0
- package/dist/lib/telemetry/s3-sink.d.ts.map +1 -0
- package/dist/lib/telemetry/s3-sink.js +229 -0
- package/dist/lib/telemetry/s3-sink.js.map +1 -0
- package/dist/lib/telemetry/submission-capture.d.ts +45 -0
- package/dist/lib/telemetry/submission-capture.d.ts.map +1 -0
- package/dist/lib/telemetry/submission-capture.js +57 -0
- package/dist/lib/telemetry/submission-capture.js.map +1 -0
- package/dist/lib/telemetry/telemetry-paths.d.ts +59 -0
- package/dist/lib/telemetry/telemetry-paths.d.ts.map +1 -0
- package/dist/lib/telemetry/telemetry-paths.js +103 -0
- package/dist/lib/telemetry/telemetry-paths.js.map +1 -0
- package/dist/lib/tracking-click.d.ts +20 -0
- package/dist/lib/tracking-click.d.ts.map +1 -0
- package/dist/lib/tracking-click.js +75 -0
- package/dist/lib/tracking-click.js.map +1 -0
- package/dist/lib/url-capture.d.ts +8 -0
- package/dist/lib/url-capture.d.ts.map +1 -0
- package/dist/lib/url-capture.js +17 -0
- package/dist/lib/url-capture.js.map +1 -0
- package/dist/lib/us-states.d.ts +20 -0
- package/dist/lib/us-states.d.ts.map +1 -0
- package/dist/lib/us-states.js +86 -0
- package/dist/lib/us-states.js.map +1 -0
- package/dist/lib/zod-multipart.d.ts +18 -0
- package/dist/lib/zod-multipart.d.ts.map +1 -0
- package/dist/lib/zod-multipart.js +35 -0
- package/dist/lib/zod-multipart.js.map +1 -0
- package/dist/plugins/config-plugin.d.ts +77 -0
- package/dist/plugins/config-plugin.d.ts.map +1 -0
- package/dist/plugins/config-plugin.js +216 -0
- package/dist/plugins/config-plugin.js.map +1 -0
- package/dist/plugins/discover.d.ts +72 -0
- package/dist/plugins/discover.d.ts.map +1 -0
- package/dist/plugins/discover.js +265 -0
- package/dist/plugins/discover.js.map +1 -0
- package/dist/plugins/json-schema-to-zod.d.ts +47 -0
- package/dist/plugins/json-schema-to-zod.d.ts.map +1 -0
- package/dist/plugins/json-schema-to-zod.js +85 -0
- package/dist/plugins/json-schema-to-zod.js.map +1 -0
- package/dist/plugins/loader.d.ts +34 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +348 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/plugin-api-version.d.ts +8 -0
- package/dist/plugins/plugin-api-version.d.ts.map +1 -0
- package/dist/plugins/plugin-api-version.js +11 -0
- package/dist/plugins/plugin-api-version.js.map +1 -0
- package/dist/plugins/plugin-manifest-envelope.d.ts +16 -0
- package/dist/plugins/plugin-manifest-envelope.d.ts.map +1 -0
- package/dist/plugins/plugin-manifest-envelope.js +19 -0
- package/dist/plugins/plugin-manifest-envelope.js.map +1 -0
- package/dist/scraper/behavioral-signals.d.ts +16 -0
- package/dist/scraper/behavioral-signals.d.ts.map +1 -0
- package/dist/scraper/behavioral-signals.js +30 -0
- package/dist/scraper/behavioral-signals.js.map +1 -0
- package/dist/scraper/errors.d.ts +193 -0
- package/dist/scraper/errors.d.ts.map +1 -0
- package/dist/scraper/errors.js +226 -0
- package/dist/scraper/errors.js.map +1 -0
- package/dist/scraper/fixtures.d.ts +23 -0
- package/dist/scraper/fixtures.d.ts.map +1 -0
- package/dist/scraper/fixtures.js +48 -0
- package/dist/scraper/fixtures.js.map +1 -0
- package/dist/scraper/flow-runner.d.ts +1319 -0
- package/dist/scraper/flow-runner.d.ts.map +1 -0
- package/dist/scraper/flow-runner.js +5637 -0
- package/dist/scraper/flow-runner.js.map +1 -0
- package/dist/scraper/graphql-client.d.ts +30 -0
- package/dist/scraper/graphql-client.d.ts.map +1 -0
- package/dist/scraper/graphql-client.js +14 -0
- package/dist/scraper/graphql-client.js.map +1 -0
- package/dist/scraper/http-client.d.ts +75 -0
- package/dist/scraper/http-client.d.ts.map +1 -0
- package/dist/scraper/http-client.js +189 -0
- package/dist/scraper/http-client.js.map +1 -0
- package/dist/scraper/http-status-classifier.d.ts +12 -0
- package/dist/scraper/http-status-classifier.d.ts.map +1 -0
- package/dist/scraper/http-status-classifier.js +29 -0
- package/dist/scraper/http-status-classifier.js.map +1 -0
- package/dist/scraper/metrics.d.ts +50 -0
- package/dist/scraper/metrics.d.ts.map +1 -0
- package/dist/scraper/metrics.js +85 -0
- package/dist/scraper/metrics.js.map +1 -0
- package/dist/scraper/navigate.d.ts +20 -0
- package/dist/scraper/navigate.d.ts.map +1 -0
- package/dist/scraper/navigate.js +30 -0
- package/dist/scraper/navigate.js.map +1 -0
- package/dist/scraper/oracle-sentinels.d.ts +22 -0
- package/dist/scraper/oracle-sentinels.d.ts.map +1 -0
- package/dist/scraper/oracle-sentinels.js +40 -0
- package/dist/scraper/oracle-sentinels.js.map +1 -0
- package/dist/scraper/parse-json-response.d.ts +16 -0
- package/dist/scraper/parse-json-response.d.ts.map +1 -0
- package/dist/scraper/parse-json-response.js +37 -0
- package/dist/scraper/parse-json-response.js.map +1 -0
- package/dist/scraper/pool.d.ts +37 -0
- package/dist/scraper/pool.d.ts.map +1 -0
- package/dist/scraper/pool.js +105 -0
- package/dist/scraper/pool.js.map +1 -0
- package/dist/scraper/rate-limited-json-client.d.ts +35 -0
- package/dist/scraper/rate-limited-json-client.d.ts.map +1 -0
- package/dist/scraper/rate-limited-json-client.js +29 -0
- package/dist/scraper/rate-limited-json-client.js.map +1 -0
- package/dist/scraper/raw-fetch.d.ts +49 -0
- package/dist/scraper/raw-fetch.d.ts.map +1 -0
- package/dist/scraper/raw-fetch.js +40 -0
- package/dist/scraper/raw-fetch.js.map +1 -0
- package/dist/scraper/require-response-field.d.ts +23 -0
- package/dist/scraper/require-response-field.d.ts.map +1 -0
- package/dist/scraper/require-response-field.js +42 -0
- package/dist/scraper/require-response-field.js.map +1 -0
- package/dist/scraper/retry.d.ts +33 -0
- package/dist/scraper/retry.d.ts.map +1 -0
- package/dist/scraper/retry.js +122 -0
- package/dist/scraper/retry.js.map +1 -0
- package/dist/scraper/session-browserbase.d.ts +35 -0
- package/dist/scraper/session-browserbase.d.ts.map +1 -0
- package/dist/scraper/session-browserbase.js +198 -0
- package/dist/scraper/session-browserbase.js.map +1 -0
- package/dist/scraper/session-shared.d.ts +29 -0
- package/dist/scraper/session-shared.d.ts.map +1 -0
- package/dist/scraper/session-shared.js +35 -0
- package/dist/scraper/session-shared.js.map +1 -0
- package/dist/scraper/session-steel.d.ts +31 -0
- package/dist/scraper/session-steel.d.ts.map +1 -0
- package/dist/scraper/session-steel.js +140 -0
- package/dist/scraper/session-steel.js.map +1 -0
- package/dist/scraper/session-warmup.d.ts +31 -0
- package/dist/scraper/session-warmup.d.ts.map +1 -0
- package/dist/scraper/session-warmup.js +46 -0
- package/dist/scraper/session-warmup.js.map +1 -0
- package/dist/scraper/session.d.ts +21 -0
- package/dist/scraper/session.d.ts.map +1 -0
- package/dist/scraper/session.js +28 -0
- package/dist/scraper/session.js.map +1 -0
- package/dist/scraper/stagehand-guard.d.ts +128 -0
- package/dist/scraper/stagehand-guard.d.ts.map +1 -0
- package/dist/scraper/stagehand-guard.js +337 -0
- package/dist/scraper/stagehand-guard.js.map +1 -0
- package/dist/scraper/throttle.d.ts +21 -0
- package/dist/scraper/throttle.d.ts.map +1 -0
- package/dist/scraper/throttle.js +45 -0
- package/dist/scraper/throttle.js.map +1 -0
- package/dist/scripts/hca-inbox-poll.d.ts +19 -0
- package/dist/scripts/hca-inbox-poll.d.ts.map +1 -0
- package/dist/scripts/hca-inbox-poll.js +151 -0
- package/dist/scripts/hca-inbox-poll.js.map +1 -0
- package/dist/scripts/judge-llm-batch.d.ts +98 -0
- package/dist/scripts/judge-llm-batch.d.ts.map +1 -0
- package/dist/scripts/judge-llm-batch.js +350 -0
- package/dist/scripts/judge-llm-batch.js.map +1 -0
- package/dist/scripts/llm-heal.d.ts +165 -0
- package/dist/scripts/llm-heal.d.ts.map +1 -0
- package/dist/scripts/llm-heal.js +595 -0
- package/dist/scripts/llm-heal.js.map +1 -0
- package/dist/scripts/migrate-telemetry-dir-names.d.ts +57 -0
- package/dist/scripts/migrate-telemetry-dir-names.d.ts.map +1 -0
- package/dist/scripts/migrate-telemetry-dir-names.js +156 -0
- package/dist/scripts/migrate-telemetry-dir-names.js.map +1 -0
- package/dist/scripts/probe-setinputfiles.d.ts +28 -0
- package/dist/scripts/probe-setinputfiles.d.ts.map +1 -0
- package/dist/scripts/probe-setinputfiles.js +95 -0
- package/dist/scripts/probe-setinputfiles.js.map +1 -0
- package/dist/scripts/recon-browser.d.ts +304 -0
- package/dist/scripts/recon-browser.d.ts.map +1 -0
- package/dist/scripts/recon-browser.js +1833 -0
- package/dist/scripts/recon-browser.js.map +1 -0
- package/dist/scripts/recon-generate.d.ts +182 -0
- package/dist/scripts/recon-generate.d.ts.map +1 -0
- package/dist/scripts/recon-generate.js +2572 -0
- package/dist/scripts/recon-generate.js.map +1 -0
- package/dist/scripts/recon-heal.d.ts +176 -0
- package/dist/scripts/recon-heal.d.ts.map +1 -0
- package/dist/scripts/recon-heal.js +584 -0
- package/dist/scripts/recon-heal.js.map +1 -0
- package/dist/scripts/recon-http.d.ts +19 -0
- package/dist/scripts/recon-http.d.ts.map +1 -0
- package/dist/scripts/recon-http.js +377 -0
- package/dist/scripts/recon-http.js.map +1 -0
- package/dist/scripts/recon-replay-jobs.d.ts +21 -0
- package/dist/scripts/recon-replay-jobs.d.ts.map +1 -0
- package/dist/scripts/recon-replay-jobs.js +221 -0
- package/dist/scripts/recon-replay-jobs.js.map +1 -0
- package/dist/scripts/recon-shared.d.ts +52 -0
- package/dist/scripts/recon-shared.d.ts.map +1 -0
- package/dist/scripts/recon-shared.js +68 -0
- package/dist/scripts/recon-shared.js.map +1 -0
- package/dist/scripts/recon-summarize.d.ts +15 -0
- package/dist/scripts/recon-summarize.d.ts.map +1 -0
- package/dist/scripts/recon-summarize.js +233 -0
- package/dist/scripts/recon-summarize.js.map +1 -0
- package/dist/scripts/smoke-test.d.ts +22 -0
- package/dist/scripts/smoke-test.d.ts.map +1 -0
- package/dist/scripts/smoke-test.js +236 -0
- package/dist/scripts/smoke-test.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +189 -0
- package/dist/server.js.map +1 -0
- package/dist/site-plugin.d.ts +226 -0
- package/dist/site-plugin.d.ts.map +1 -0
- package/dist/site-plugin.js +13 -0
- package/dist/site-plugin.js.map +1 -0
- package/dist/testing/answers-fixture.d.ts +13 -0
- package/dist/testing/answers-fixture.d.ts.map +1 -0
- package/dist/testing/answers-fixture.js +37 -0
- package/dist/testing/answers-fixture.js.map +1 -0
- package/dist/testing/batch-email-confirmation.d.ts +58 -0
- package/dist/testing/batch-email-confirmation.d.ts.map +1 -0
- package/dist/testing/batch-email-confirmation.js +62 -0
- package/dist/testing/batch-email-confirmation.js.map +1 -0
- package/dist/testing/batch-report.d.ts +33 -0
- package/dist/testing/batch-report.d.ts.map +1 -0
- package/dist/testing/batch-report.js +30 -0
- package/dist/testing/batch-report.js.map +1 -0
- package/dist/testing/contract-parity-suite.d.ts +55 -0
- package/dist/testing/contract-parity-suite.d.ts.map +1 -0
- package/dist/testing/contract-parity-suite.js +39 -0
- package/dist/testing/contract-parity-suite.js.map +1 -0
- package/dist/testing/coverage-guard-suite.d.ts +46 -0
- package/dist/testing/coverage-guard-suite.d.ts.map +1 -0
- package/dist/testing/coverage-guard-suite.js +39 -0
- package/dist/testing/coverage-guard-suite.js.map +1 -0
- package/dist/testing/fixtures/resume.pdf +54 -0
- package/dist/testing/integration-runner.d.ts +62 -0
- package/dist/testing/integration-runner.d.ts.map +1 -0
- package/dist/testing/integration-runner.js +46 -0
- package/dist/testing/integration-runner.js.map +1 -0
- package/dist/testing/mock-fetch-response.d.ts +7 -0
- package/dist/testing/mock-fetch-response.d.ts.map +1 -0
- package/dist/testing/mock-fetch-response.js +16 -0
- package/dist/testing/mock-fetch-response.js.map +1 -0
- package/dist/testing/persona-fixture.d.ts +77 -0
- package/dist/testing/persona-fixture.d.ts.map +1 -0
- package/dist/testing/persona-fixture.js +83 -0
- package/dist/testing/persona-fixture.js.map +1 -0
- package/dist/testing/replay-integration-suite.d.ts +50 -0
- package/dist/testing/replay-integration-suite.d.ts.map +1 -0
- package/dist/testing/replay-integration-suite.js +45 -0
- package/dist/testing/replay-integration-suite.js.map +1 -0
- package/dist/testing/resume-fixture.d.ts +39 -0
- package/dist/testing/resume-fixture.d.ts.map +1 -0
- package/dist/testing/resume-fixture.js +38 -0
- package/dist/testing/resume-fixture.js.map +1 -0
- package/dist/testmail/client.d.ts +61 -0
- package/dist/testmail/client.d.ts.map +1 -0
- package/dist/testmail/client.js +190 -0
- package/dist/testmail/client.js.map +1 -0
- package/dist/testmail/errors.d.ts +18 -0
- package/dist/testmail/errors.d.ts.map +1 -0
- package/dist/testmail/errors.js +29 -0
- package/dist/testmail/errors.js.map +1 -0
- package/dist/types/dispatch-metrics.d.ts +46 -0
- package/dist/types/dispatch-metrics.d.ts.map +1 -0
- package/dist/types/dispatch-metrics.js +25 -0
- package/dist/types/dispatch-metrics.js.map +1 -0
- package/dist/types/logging.d.ts +11 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/logging.js +3 -0
- package/dist/types/logging.js.map +1 -0
- package/package.json +283 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site-agnostic fetch scaffold shared by plugins that cannot use
|
|
3
|
+
* `createHttpClient` — typically because they need multipart Buffer bodies
|
|
4
|
+
* or per-response header rotation (appcast token churn). Owns the
|
|
5
|
+
* try/catch network-error conversion, the onResponse hook, and the
|
|
6
|
+
* classifyHttpStatus call so callers only supply the what (URL, headers,
|
|
7
|
+
* body) and the where (their token-rotation / audit hook and context label).
|
|
8
|
+
*/
|
|
9
|
+
/** Return value: raw outcome before any Zod parsing. */
|
|
10
|
+
export interface RawFetchResult {
|
|
11
|
+
status: number;
|
|
12
|
+
rawBody: string;
|
|
13
|
+
}
|
|
14
|
+
/** Input options for {@link rawFetch}. */
|
|
15
|
+
export interface RawFetchOptions {
|
|
16
|
+
method: string;
|
|
17
|
+
headers: Record<string, string>;
|
|
18
|
+
/** Optional request body — pass `undefined` for GET requests. */
|
|
19
|
+
body?: Buffer | string;
|
|
20
|
+
/**
|
|
21
|
+
* Called with the response `Headers` on every fetch outcome, including
|
|
22
|
+
* non-2xx. Fires before `classifyHttpStatus` so the caller can harvest
|
|
23
|
+
* rotating session tokens even when the request ultimately fails.
|
|
24
|
+
*/
|
|
25
|
+
onResponse: (headers: Headers) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Short label used in error messages from `classifyHttpStatus`, e.g.
|
|
28
|
+
* `"appcast /integrated_questions"`. Should identify the endpoint so
|
|
29
|
+
* logs and error surfaces are actionable.
|
|
30
|
+
*/
|
|
31
|
+
contextLabel: string;
|
|
32
|
+
/**
|
|
33
|
+
* When `true`, skip the automatic `classifyHttpStatus` call and return
|
|
34
|
+
* `{ status, rawBody }` for every response. Use when the caller needs
|
|
35
|
+
* to inspect the body before deciding how to classify (e.g. transient-500
|
|
36
|
+
* detection that must precede the generic 5xx path).
|
|
37
|
+
*/
|
|
38
|
+
skipClassify?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Issues an undici fetch with caller-supplied URL / method / headers / body,
|
|
42
|
+
* invokes `onResponse` with the response headers (for token rotation or audit),
|
|
43
|
+
* delegates status classification to `classifyHttpStatus`, and returns
|
|
44
|
+
* `{ status, rawBody }` for the caller to parse. Network errors are wrapped
|
|
45
|
+
* in `HttpServerError` so callers get a typed, non-retryable error from the
|
|
46
|
+
* same error hierarchy as classification errors.
|
|
47
|
+
*/
|
|
48
|
+
export declare function rawFetch(url: string, options: RawFetchOptions): Promise<RawFetchResult>;
|
|
49
|
+
//# sourceMappingURL=raw-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-fetch.d.ts","sourceRoot":"","sources":["../../src/scraper/raw-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB;;;;OAIG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAkB7F"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Site-agnostic fetch scaffold shared by plugins that cannot use
|
|
4
|
+
* `createHttpClient` — typically because they need multipart Buffer bodies
|
|
5
|
+
* or per-response header rotation (appcast token churn). Owns the
|
|
6
|
+
* try/catch network-error conversion, the onResponse hook, and the
|
|
7
|
+
* classifyHttpStatus call so callers only supply the what (URL, headers,
|
|
8
|
+
* body) and the where (their token-rotation / audit hook and context label).
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.rawFetch = rawFetch;
|
|
12
|
+
const undici_1 = require("undici");
|
|
13
|
+
const errors_1 = require("../lib/errors");
|
|
14
|
+
const errors_2 = require("../scraper/errors");
|
|
15
|
+
const http_status_classifier_1 = require("../scraper/http-status-classifier");
|
|
16
|
+
/**
|
|
17
|
+
* Issues an undici fetch with caller-supplied URL / method / headers / body,
|
|
18
|
+
* invokes `onResponse` with the response headers (for token rotation or audit),
|
|
19
|
+
* delegates status classification to `classifyHttpStatus`, and returns
|
|
20
|
+
* `{ status, rawBody }` for the caller to parse. Network errors are wrapped
|
|
21
|
+
* in `HttpServerError` so callers get a typed, non-retryable error from the
|
|
22
|
+
* same error hierarchy as classification errors.
|
|
23
|
+
*/
|
|
24
|
+
async function rawFetch(url, options) {
|
|
25
|
+
const { method, headers, body, onResponse, contextLabel, skipClassify = false } = options;
|
|
26
|
+
let response;
|
|
27
|
+
try {
|
|
28
|
+
response = await (0, undici_1.fetch)(url, { method, headers, body });
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
throw new errors_2.HttpServerError(`${contextLabel} network error: ${(0, errors_1.toErrorMessage)(err)}`);
|
|
32
|
+
}
|
|
33
|
+
onResponse(response.headers);
|
|
34
|
+
const rawBody = await response.text();
|
|
35
|
+
if (!skipClassify) {
|
|
36
|
+
(0, http_status_classifier_1.classifyHttpStatus)(response.status, rawBody.slice(0, 200), contextLabel);
|
|
37
|
+
}
|
|
38
|
+
return { status: response.status, rawBody };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=raw-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-fetch.js","sourceRoot":"","sources":["../../src/scraper/raw-fetch.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAiDH,4BAkBC;AAjED,mCAA8C;AAE9C,yCAA8C;AAC9C,6CAAmD;AACnD,6EAAsE;AAmCtE;;;;;;;GAOG;AACI,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,OAAwB;IAClE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAE1F,IAAI,QAAiD,CAAC;IACtD,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,IAAA,cAAW,EAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,wBAAe,CAAC,GAAG,YAAY,mBAAmB,IAAA,uBAAc,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE7B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,IAAA,2CAAkB,EAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for extracting required fields from already-parsed HTTP
|
|
3
|
+
* response objects. Each plugin that calls createHttpClient receives a plain
|
|
4
|
+
* object — these helpers standardise the "field must exist or throw" idiom so
|
|
5
|
+
* every plugin surfaces the same HttpSchemaError shape and the log grep stays
|
|
6
|
+
* stable across sites.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Returns `obj[key]` cast to `T`. Throws {@link HttpSchemaError} when the
|
|
10
|
+
* value is `null`, `undefined`, or the key is absent — with `contextLabel`
|
|
11
|
+
* prefixed so the error is immediately actionable without additional wrapping.
|
|
12
|
+
*/
|
|
13
|
+
export declare function requireResponseField<T>(obj: Record<string, unknown>, key: string, contextLabel: string): T;
|
|
14
|
+
/**
|
|
15
|
+
* Returns `resp.items[0][key]` cast to `T`. Throws {@link HttpSchemaError}
|
|
16
|
+
* when `items` is absent or empty, or when the field itself is nullish.
|
|
17
|
+
* Covers the Oracle HCM `?finder=...` pattern where results always arrive as
|
|
18
|
+
* `{ items: [...] }` and the first element carries the required field.
|
|
19
|
+
*/
|
|
20
|
+
export declare function requireFirstItemField<T>(resp: {
|
|
21
|
+
items?: Array<Record<string, unknown>>;
|
|
22
|
+
}, key: string, contextLabel: string): T;
|
|
23
|
+
//# sourceMappingURL=require-response-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-response-field.d.ts","sourceRoot":"","sources":["../../src/scraper/require-response-field.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,GACnB,CAAC,CAMH;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAAE,EAChD,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,GACnB,CAAC,CAUH"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared helpers for extracting required fields from already-parsed HTTP
|
|
4
|
+
* response objects. Each plugin that calls createHttpClient receives a plain
|
|
5
|
+
* object — these helpers standardise the "field must exist or throw" idiom so
|
|
6
|
+
* every plugin surfaces the same HttpSchemaError shape and the log grep stays
|
|
7
|
+
* stable across sites.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.requireResponseField = requireResponseField;
|
|
11
|
+
exports.requireFirstItemField = requireFirstItemField;
|
|
12
|
+
const errors_1 = require("../scraper/errors");
|
|
13
|
+
/**
|
|
14
|
+
* Returns `obj[key]` cast to `T`. Throws {@link HttpSchemaError} when the
|
|
15
|
+
* value is `null`, `undefined`, or the key is absent — with `contextLabel`
|
|
16
|
+
* prefixed so the error is immediately actionable without additional wrapping.
|
|
17
|
+
*/
|
|
18
|
+
function requireResponseField(obj, key, contextLabel) {
|
|
19
|
+
const value = obj[key];
|
|
20
|
+
if (value === null || value === undefined) {
|
|
21
|
+
throw new errors_1.HttpSchemaError(`${contextLabel} missing ${key}`);
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns `resp.items[0][key]` cast to `T`. Throws {@link HttpSchemaError}
|
|
27
|
+
* when `items` is absent or empty, or when the field itself is nullish.
|
|
28
|
+
* Covers the Oracle HCM `?finder=...` pattern where results always arrive as
|
|
29
|
+
* `{ items: [...] }` and the first element carries the required field.
|
|
30
|
+
*/
|
|
31
|
+
function requireFirstItemField(resp, key, contextLabel) {
|
|
32
|
+
const first = resp.items?.[0];
|
|
33
|
+
if (!first) {
|
|
34
|
+
throw new errors_1.HttpSchemaError(`${contextLabel} missing items`);
|
|
35
|
+
}
|
|
36
|
+
const value = first[key];
|
|
37
|
+
if (value === null || value === undefined) {
|
|
38
|
+
throw new errors_1.HttpSchemaError(`${contextLabel} missing ${key}`);
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=require-response-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-response-field.js","sourceRoot":"","sources":["../../src/scraper/require-response-field.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AASH,oDAUC;AAQD,sDAcC;AAvCD,6CAAmD;AAEnD;;;;GAIG;AACH,SAAgB,oBAAoB,CAClC,GAA4B,EAC5B,GAAW,EACX,YAAoB;IAEpB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,IAAI,wBAAe,CAAC,GAAG,YAAY,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,KAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CACnC,IAAgD,EAChD,GAAW,EACX,YAAoB;IAEpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,wBAAe,CAAC,GAAG,YAAY,gBAAgB,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,IAAI,wBAAe,CAAC,GAAG,YAAY,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,KAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ScraperError } from "../scraper/errors";
|
|
2
|
+
/**
|
|
3
|
+
* Tuning knobs for `withScraperRetry`. All fields are optional — callers that
|
|
4
|
+
* only need the default 3-attempt policy can pass an empty object or omit the
|
|
5
|
+
* argument entirely.
|
|
6
|
+
*/
|
|
7
|
+
export interface RetryOptions {
|
|
8
|
+
/** Max attempts including the first try. Defaults to 3. */
|
|
9
|
+
maxAttempts?: number;
|
|
10
|
+
/** Called when a session needs to be torn down and re-created. */
|
|
11
|
+
onSessionRestart?: () => Promise<void>;
|
|
12
|
+
/** Called before each retry attempt so callers can bust caches. */
|
|
13
|
+
onRetry?: (error: ScraperError, attempt: number) => void | Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Wraps a scraper task with p-retry and a classification policy aligned
|
|
17
|
+
* with our ScraperError hierarchy:
|
|
18
|
+
*
|
|
19
|
+
* - CaptchaError + EmptyResultsError → AbortError, no retry.
|
|
20
|
+
* - SessionTimeoutError → invoke onSessionRestart once (guarded by sessionRestartEntry.done), then retry up to maxAttempts.
|
|
21
|
+
* - SelectorFailureError + UnknownScraperError → retry up to maxAttempts.
|
|
22
|
+
* - Anything non-ScraperError → wrap in UnknownScraperError and retry.
|
|
23
|
+
*
|
|
24
|
+
* We lean on p-retry entirely for backoff, jitter, and attempt counting —
|
|
25
|
+
* this module just supplies the policy.
|
|
26
|
+
*/
|
|
27
|
+
export declare function withScraperRetry<T>(task: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
28
|
+
/**
|
|
29
|
+
* Maps a raw thrown value (Error, string, or anything) onto our typed
|
|
30
|
+
* ScraperError hierarchy so the retry policy can branch on it.
|
|
31
|
+
*/
|
|
32
|
+
export declare function classifyScraperError(raw: unknown): ScraperError;
|
|
33
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/scraper/retry.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,YAAY,EAIb,MAAM,kBAAkB,CAAC;AAI1B;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mEAAmE;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAkDZ;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAmB/D"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.withScraperRetry = withScraperRetry;
|
|
37
|
+
exports.classifyScraperError = classifyScraperError;
|
|
38
|
+
const p_retry_1 = __importStar(require("p-retry"));
|
|
39
|
+
const errors_1 = require("../lib/errors");
|
|
40
|
+
const logging_1 = require("../lib/logging");
|
|
41
|
+
const errors_2 = require("../scraper/errors");
|
|
42
|
+
const logger = (0, logging_1.getLogger)({ name: "scraper/retry" });
|
|
43
|
+
/**
|
|
44
|
+
* Wraps a scraper task with p-retry and a classification policy aligned
|
|
45
|
+
* with our ScraperError hierarchy:
|
|
46
|
+
*
|
|
47
|
+
* - CaptchaError + EmptyResultsError → AbortError, no retry.
|
|
48
|
+
* - SessionTimeoutError → invoke onSessionRestart once (guarded by sessionRestartEntry.done), then retry up to maxAttempts.
|
|
49
|
+
* - SelectorFailureError + UnknownScraperError → retry up to maxAttempts.
|
|
50
|
+
* - Anything non-ScraperError → wrap in UnknownScraperError and retry.
|
|
51
|
+
*
|
|
52
|
+
* We lean on p-retry entirely for backoff, jitter, and attempt counting —
|
|
53
|
+
* this module just supplies the policy.
|
|
54
|
+
*/
|
|
55
|
+
async function withScraperRetry(task, options = {}) {
|
|
56
|
+
const maxAttempts = options.maxAttempts ?? 3;
|
|
57
|
+
const sessionRestartEntry = { done: false };
|
|
58
|
+
return (0, p_retry_1.default)(async () => {
|
|
59
|
+
try {
|
|
60
|
+
return await task();
|
|
61
|
+
}
|
|
62
|
+
catch (raw) {
|
|
63
|
+
const err = classifyScraperError(raw);
|
|
64
|
+
if (err instanceof errors_2.CaptchaError) {
|
|
65
|
+
// Task 10: CAPTCHA hit — log it. p-retry skips onFailedAttempt
|
|
66
|
+
// for AbortError, so the warn log below is the only signal a
|
|
67
|
+
// captcha was encountered before it propagates to callers.
|
|
68
|
+
logger.error(`captcha encountered upstream — aborting retry: ${err.message}`);
|
|
69
|
+
throw new p_retry_1.AbortError(err.message);
|
|
70
|
+
}
|
|
71
|
+
if (err instanceof errors_2.EmptyResultsError) {
|
|
72
|
+
logger.warn(`scraper returned empty results — aborting retry: ${err.message}`);
|
|
73
|
+
throw new p_retry_1.AbortError(err.message);
|
|
74
|
+
}
|
|
75
|
+
if (err instanceof errors_2.SessionTimeoutError && !sessionRestartEntry.done) {
|
|
76
|
+
sessionRestartEntry.done = true;
|
|
77
|
+
if (options.onSessionRestart) {
|
|
78
|
+
await options.onSessionRestart();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}, {
|
|
84
|
+
retries: Math.max(0, maxAttempts - 1),
|
|
85
|
+
factor: 2,
|
|
86
|
+
minTimeout: 500,
|
|
87
|
+
maxTimeout: 5_000,
|
|
88
|
+
randomize: true,
|
|
89
|
+
onFailedAttempt: async (context) => {
|
|
90
|
+
const { error, attemptNumber, retriesLeft } = context;
|
|
91
|
+
logger.warn(`scraper attempt ${attemptNumber} failed (${error.name}): ${error.message}; ${retriesLeft} retries left`);
|
|
92
|
+
if (options.onRetry && error instanceof errors_2.ScraperError) {
|
|
93
|
+
await options.onRetry(error, attemptNumber);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Maps a raw thrown value (Error, string, or anything) onto our typed
|
|
100
|
+
* ScraperError hierarchy so the retry policy can branch on it.
|
|
101
|
+
*/
|
|
102
|
+
function classifyScraperError(raw) {
|
|
103
|
+
if (raw instanceof errors_2.ScraperError)
|
|
104
|
+
return raw;
|
|
105
|
+
const message = (0, errors_1.toErrorMessage)(raw);
|
|
106
|
+
const lower = message.toLowerCase();
|
|
107
|
+
if (lower.includes("captcha"))
|
|
108
|
+
return new errors_2.CaptchaError(message);
|
|
109
|
+
if (lower.includes("timeout") || lower.includes("timed out")) {
|
|
110
|
+
return new errors_2.SessionTimeoutError(message);
|
|
111
|
+
}
|
|
112
|
+
if (lower.includes("selector") ||
|
|
113
|
+
lower.includes("could not find") ||
|
|
114
|
+
lower.includes("not found")) {
|
|
115
|
+
return new errors_2.SelectorFailureError(message);
|
|
116
|
+
}
|
|
117
|
+
if (lower.includes("empty") || lower.includes("no results")) {
|
|
118
|
+
return new errors_2.EmptyResultsError(message);
|
|
119
|
+
}
|
|
120
|
+
return new errors_2.UnknownScraperError(message);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/scraper/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type BrowserSession } from "../scraper/session-shared";
|
|
2
|
+
/**
|
|
3
|
+
* Spins up one Browserbase cloud session with the configured Stagehand LLM.
|
|
4
|
+
*
|
|
5
|
+
* Why Browserbase (and why it's the default): Stagehand v3 has five distinct
|
|
6
|
+
* code paths gated on `env === "BROWSERBASE"` — file-input payload injection
|
|
7
|
+
* for remote uploads, tuned CDP connection timeouts, session-recovery logic,
|
|
8
|
+
* and event-window timing for the active-page detection. Steel-over-CDP
|
|
9
|
+
* (env: "LOCAL") misses all five. Defaulting to Browserbase keeps us on the
|
|
10
|
+
* code path Stagehand validates first.
|
|
11
|
+
*
|
|
12
|
+
* Session lifecycle: Stagehand owns Browserbase session creation when
|
|
13
|
+
* `env: "BROWSERBASE"` is set. `stagehand.close()` releases the session;
|
|
14
|
+
* no separate Browserbase SDK release call is needed (unlike Steel).
|
|
15
|
+
*
|
|
16
|
+
* Viewport rotation: forwarded via `fingerprint.screen.{min,max}{Width,Height}`
|
|
17
|
+
* pinned to the chosen viewport. The min/max bracket forces Browserbase's
|
|
18
|
+
* fingerprint generator to pick that exact size rather than negotiating it.
|
|
19
|
+
*
|
|
20
|
+
* Proxies: `proxies: true` enables Browserbase's residential proxy pool. The
|
|
21
|
+
* boolean form takes Browserbase's default region; per-region routing is
|
|
22
|
+
* available via the array form (not used here — out of scope until needed).
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* `advancedStealth` opts into Browserbase's Scale Plan stealth profile. When
|
|
26
|
+
* enabled we also force `solveCaptchas: true` (explicit; Browserbase defaults
|
|
27
|
+
* it on) and pin a Windows desktop fingerprint — DataDome-protected sites
|
|
28
|
+
* (notably `apply.appcast.io`) react significantly better to Windows OS
|
|
29
|
+
* signals than the default mac/linux mix. Pattern mirrors nursefly-web's
|
|
30
|
+
* production preset at `server/jobs/ingest/scraped/browserbase/stagehand.config.ts`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createBrowserbaseBrowserSession(opts?: {
|
|
33
|
+
advancedStealth?: boolean;
|
|
34
|
+
}): Promise<BrowserSession>;
|
|
35
|
+
//# sourceMappingURL=session-browserbase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-browserbase.d.ts","sourceRoot":"","sources":["../../src/scraper/session-browserbase.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,0BAA0B,CAAC;AA6ElC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;;;;;;;GAOG;AACH,wBAAsB,+BAA+B,CAAC,IAAI,CAAC,EAAE;IAC3D,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,GAAG,OAAO,CAAC,cAAc,CAAC,CA8G1B"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBrowserbaseBrowserSession = createBrowserbaseBrowserSession;
|
|
4
|
+
const stagehand_1 = require("@browserbasehq/stagehand");
|
|
5
|
+
const config_1 = require("../config");
|
|
6
|
+
const bedrock_1 = require("../lib/bedrock");
|
|
7
|
+
const errors_1 = require("../lib/errors");
|
|
8
|
+
const logging_1 = require("../lib/logging");
|
|
9
|
+
const session_shared_1 = require("../scraper/session-shared");
|
|
10
|
+
const throttle_1 = require("../scraper/throttle");
|
|
11
|
+
const logger = (0, logging_1.getLogger)({ name: "scraper/session-browserbase" });
|
|
12
|
+
/**
|
|
13
|
+
* Build a custom Stagehand logger that filters out the noisy upstream
|
|
14
|
+
* `AI_TypeValidationError` schema-validation spam. The errors come from
|
|
15
|
+
* Stagehand's internal Haiku LLM returning bare integers like "4671"
|
|
16
|
+
* when its Zod schema requires "N-N" format (regex /^\\d+-\\d+$/ at
|
|
17
|
+
* stagehand inference.js:147+240). Each error stack-trace is ~500 bytes
|
|
18
|
+
* of pino I/O — verified at 118 occurrences in run 1781485435455
|
|
19
|
+
* (2026-06-14), totaling ~5-7 min of wasted wall clock.
|
|
20
|
+
*
|
|
21
|
+
* The existing cascade Fix 1B (resolvedAction-null fast-skip) already
|
|
22
|
+
* handles the consequence: when Stagehand returns success=false due to
|
|
23
|
+
* this schema error, attempt 1 short-circuits cleanly and attempt 2
|
|
24
|
+
* (observe-act) runs on a structured target instead. The error log
|
|
25
|
+
* lines are pure noise.
|
|
26
|
+
*
|
|
27
|
+
* Filter is precise — only matches when category is "AISDK error"
|
|
28
|
+
* AND the cause body contains both `AI_TypeValidationError` and
|
|
29
|
+
* `elementId`. Other AISDK errors (rate limits, malformed requests,
|
|
30
|
+
* server errors) pass through unchanged. Site-agnostic — the
|
|
31
|
+
* upstream Stagehand bug is universal across tenants.
|
|
32
|
+
*
|
|
33
|
+
* Returns the callback + a `reportSuppressed` function that the
|
|
34
|
+
* session teardown calls to log the final suppression count — keeps
|
|
35
|
+
* the noise out of the running log while preserving the diagnostic
|
|
36
|
+
* for run-completion summary.
|
|
37
|
+
*/
|
|
38
|
+
function makeFilteredStagehandLogger(pinoLogger) {
|
|
39
|
+
let suppressedCount = 0;
|
|
40
|
+
const callback = (line) => {
|
|
41
|
+
if (line.category === "AISDK error") {
|
|
42
|
+
const cause = line.auxiliary?.cause?.value ?? "";
|
|
43
|
+
if (cause.includes("AI_TypeValidationError") && cause.includes("elementId")) {
|
|
44
|
+
suppressedCount++;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Forward everything else as today — Stagehand's default logger
|
|
49
|
+
// emits via console; we route through pino for consistency.
|
|
50
|
+
if (line.level === 0) {
|
|
51
|
+
pinoLogger.error({ stagehand: line.category }, line.message);
|
|
52
|
+
}
|
|
53
|
+
else if (line.level === 1) {
|
|
54
|
+
pinoLogger.info({ stagehand: line.category }, line.message);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
pinoLogger.debug({ stagehand: line.category }, line.message);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const reportSuppressed = () => {
|
|
61
|
+
if (suppressedCount > 0) {
|
|
62
|
+
pinoLogger.info(`stagehand-logger: suppressed ${suppressedCount} AISDK elementId-regex errors (upstream Stagehand bug; cascade Fix 1B handles consequence)`);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return { callback, reportSuppressed };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Spins up one Browserbase cloud session with the configured Stagehand LLM.
|
|
69
|
+
*
|
|
70
|
+
* Why Browserbase (and why it's the default): Stagehand v3 has five distinct
|
|
71
|
+
* code paths gated on `env === "BROWSERBASE"` — file-input payload injection
|
|
72
|
+
* for remote uploads, tuned CDP connection timeouts, session-recovery logic,
|
|
73
|
+
* and event-window timing for the active-page detection. Steel-over-CDP
|
|
74
|
+
* (env: "LOCAL") misses all five. Defaulting to Browserbase keeps us on the
|
|
75
|
+
* code path Stagehand validates first.
|
|
76
|
+
*
|
|
77
|
+
* Session lifecycle: Stagehand owns Browserbase session creation when
|
|
78
|
+
* `env: "BROWSERBASE"` is set. `stagehand.close()` releases the session;
|
|
79
|
+
* no separate Browserbase SDK release call is needed (unlike Steel).
|
|
80
|
+
*
|
|
81
|
+
* Viewport rotation: forwarded via `fingerprint.screen.{min,max}{Width,Height}`
|
|
82
|
+
* pinned to the chosen viewport. The min/max bracket forces Browserbase's
|
|
83
|
+
* fingerprint generator to pick that exact size rather than negotiating it.
|
|
84
|
+
*
|
|
85
|
+
* Proxies: `proxies: true` enables Browserbase's residential proxy pool. The
|
|
86
|
+
* boolean form takes Browserbase's default region; per-region routing is
|
|
87
|
+
* available via the array form (not used here — out of scope until needed).
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* `advancedStealth` opts into Browserbase's Scale Plan stealth profile. When
|
|
91
|
+
* enabled we also force `solveCaptchas: true` (explicit; Browserbase defaults
|
|
92
|
+
* it on) and pin a Windows desktop fingerprint — DataDome-protected sites
|
|
93
|
+
* (notably `apply.appcast.io`) react significantly better to Windows OS
|
|
94
|
+
* signals than the default mac/linux mix. Pattern mirrors nursefly-web's
|
|
95
|
+
* production preset at `server/jobs/ingest/scraped/browserbase/stagehand.config.ts`.
|
|
96
|
+
*/
|
|
97
|
+
async function createBrowserbaseBrowserSession(opts) {
|
|
98
|
+
if (!config_1.config.scraper.browserbaseApiKey) {
|
|
99
|
+
throw new Error("BROWSERBASE_API_KEY is required for the browserbase provider");
|
|
100
|
+
}
|
|
101
|
+
if (!config_1.config.scraper.browserbaseProjectId) {
|
|
102
|
+
throw new Error("BROWSERBASE_PROJECT_ID is required for the browserbase provider");
|
|
103
|
+
}
|
|
104
|
+
if (!config_1.config.scraper.useBedrock && !config_1.config.scraper.anthropicApiKey) {
|
|
105
|
+
throw new Error("ANTHROPIC_API_KEY is required for the Stagehand LLM client");
|
|
106
|
+
}
|
|
107
|
+
const viewport = (0, session_shared_1.pickRandomViewport)();
|
|
108
|
+
const useResidentialProxy = config_1.config.scraper.proxyType.toLowerCase() === "residential";
|
|
109
|
+
const advancedStealth = opts?.advancedStealth === true;
|
|
110
|
+
if (config_1.config.scraper.useBedrock) {
|
|
111
|
+
logger.info(`using bedrock model ${config_1.config.bedrock.model} in region ${config_1.config.bedrock.region}`);
|
|
112
|
+
}
|
|
113
|
+
const llmClient = config_1.config.scraper.useBedrock
|
|
114
|
+
? new stagehand_1.AISdkClient({ model: (0, bedrock_1.createBedrockModel)(config_1.config.bedrock) })
|
|
115
|
+
: undefined;
|
|
116
|
+
// Base fingerprint always pins the screen size. Advanced stealth layers on
|
|
117
|
+
// desktop + Windows OS hints; the stronger fingerprint is required for
|
|
118
|
+
// DataDome-protected flows.
|
|
119
|
+
const baseFingerprint = {
|
|
120
|
+
screen: {
|
|
121
|
+
minWidth: viewport.width,
|
|
122
|
+
maxWidth: viewport.width,
|
|
123
|
+
minHeight: viewport.height,
|
|
124
|
+
maxHeight: viewport.height,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
const fingerprint = advancedStealth
|
|
128
|
+
? {
|
|
129
|
+
...baseFingerprint,
|
|
130
|
+
devices: ["desktop"],
|
|
131
|
+
operatingSystems: ["windows"],
|
|
132
|
+
}
|
|
133
|
+
: baseFingerprint;
|
|
134
|
+
const { callback: stagehandLoggerCallback, reportSuppressed: reportSuppressedAisdkErrors } = makeFilteredStagehandLogger(logger);
|
|
135
|
+
let stagehand;
|
|
136
|
+
try {
|
|
137
|
+
stagehand = new stagehand_1.Stagehand({
|
|
138
|
+
env: "BROWSERBASE",
|
|
139
|
+
apiKey: config_1.config.scraper.browserbaseApiKey,
|
|
140
|
+
projectId: config_1.config.scraper.browserbaseProjectId,
|
|
141
|
+
browserbaseSessionCreateParams: {
|
|
142
|
+
projectId: config_1.config.scraper.browserbaseProjectId,
|
|
143
|
+
proxies: useResidentialProxy,
|
|
144
|
+
browserSettings: {
|
|
145
|
+
...(advancedStealth ? { advancedStealth: true, solveCaptchas: true } : {}),
|
|
146
|
+
fingerprint,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
model: config_1.config.scraper.useBedrock
|
|
150
|
+
? undefined
|
|
151
|
+
: {
|
|
152
|
+
modelName: config_1.config.scraper.model,
|
|
153
|
+
apiKey: config_1.config.scraper.anthropicApiKey,
|
|
154
|
+
// @ai-sdk/anthropic has no `timeout` option; inject timeout at the fetch layer.
|
|
155
|
+
fetch: (0, session_shared_1.createTimeoutFetch)(config_1.config.scraper.anthropicTimeoutMs),
|
|
156
|
+
},
|
|
157
|
+
llmClient,
|
|
158
|
+
serverCache: true,
|
|
159
|
+
selfHeal: false,
|
|
160
|
+
verbose: 0,
|
|
161
|
+
// Custom logger to filter AISDK schema-error spam — see
|
|
162
|
+
// makeFilteredStagehandLogger TSDoc for rationale.
|
|
163
|
+
logger: stagehandLoggerCallback,
|
|
164
|
+
});
|
|
165
|
+
await stagehand.init();
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
try {
|
|
169
|
+
if (stagehand)
|
|
170
|
+
await stagehand.close();
|
|
171
|
+
}
|
|
172
|
+
catch (closeErr) {
|
|
173
|
+
logger.warn(`stagehand close during failed init: ${(0, errors_1.toErrorMessage)(closeErr)}`);
|
|
174
|
+
}
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
const sessionId = stagehand.browserbaseSessionID ?? "unknown";
|
|
178
|
+
logger.info(`created browserbase session ${sessionId} viewport=${viewport.width}x${viewport.height} proxies=${useResidentialProxy} advancedStealth=${advancedStealth}`);
|
|
179
|
+
const limiter = (0, throttle_1.createSessionLimiter)();
|
|
180
|
+
const close = async () => {
|
|
181
|
+
try {
|
|
182
|
+
await stagehand.close();
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
logger.warn(`stagehand close failed for session ${sessionId}: ${(0, errors_1.toErrorMessage)(err)}`);
|
|
186
|
+
}
|
|
187
|
+
await limiter.stop({ dropWaitingJobs: true });
|
|
188
|
+
reportSuppressedAisdkErrors();
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
stagehand,
|
|
192
|
+
limiter,
|
|
193
|
+
sessionId,
|
|
194
|
+
provider: "browserbase",
|
|
195
|
+
close,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=session-browserbase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-browserbase.js","sourceRoot":"","sources":["../../src/scraper/session-browserbase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Stagehand } from "@browserbasehq/stagehand";
|
|
2
|
+
import type Bottleneck from "bottleneck";
|
|
3
|
+
/** Allowed provider names. */
|
|
4
|
+
export type ProviderName = "browserbase" | "steel";
|
|
5
|
+
/**
|
|
6
|
+
* A live browser session paired with the per-session action limiter.
|
|
7
|
+
* Callers MUST call `close()` in a `finally` block so the upstream provider
|
|
8
|
+
* stops billing and the underlying browser process is released.
|
|
9
|
+
*/
|
|
10
|
+
export interface BrowserSession {
|
|
11
|
+
stagehand: Stagehand;
|
|
12
|
+
limiter: Bottleneck;
|
|
13
|
+
/** Provider-issued session id; useful for log correlation. */
|
|
14
|
+
sessionId: string;
|
|
15
|
+
/** Which provider produced this session — informational, useful for logs. */
|
|
16
|
+
provider: ProviderName;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns a fetch wrapper that aborts after `timeoutMs` milliseconds.
|
|
21
|
+
* Handles the total request timeout for Anthropic API calls; the TCP connect
|
|
22
|
+
* timeout is handled separately via setGlobalDispatcher in server.ts.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createTimeoutFetch(timeoutMs: number): typeof fetch;
|
|
25
|
+
export declare function pickRandomViewport(): {
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=session-shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-shared.d.ts","sourceRoot":"","sources":["../../src/scraper/session-shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AAIzC,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC;AAEnD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,KAAK,CAYlE;AAaD,wBAAgB,kBAAkB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAEtE"}
|