@storyshelf/core 0.7.0 → 0.9.0-next-d2cc082
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/dist/adapter/capture-queue.d.mts +0 -2
- package/dist/adapter/capture-runner.d.mts +10 -4
- package/dist/adapter/capture-runner.mjs +7 -2
- package/dist/adapter/database.d.mts +63 -3
- package/dist/adapter/database.mjs +4 -3
- package/dist/adapter/database.mjs.map +1 -1
- package/dist/adapter/design.d.mts +0 -2
- package/dist/adapter/design.mjs +1 -2
- package/dist/adapter/email-sender.d.mts +0 -2
- package/dist/adapter/metadata.d.mts +0 -2
- package/dist/adapter/oauth.d.mts +0 -2
- package/dist/adapter/setup.d.mts +0 -2
- package/dist/adapter/setup.mjs +1 -2
- package/dist/adapter/storage.d.mts +1 -3
- package/dist/adapter/webhook-events.d.mts +0 -2
- package/dist/adapter/webhook-events.mjs +12 -13
- package/dist/adapter/webhook-events.mjs.map +1 -1
- package/dist/adapters/capture-target-offers.d.mts +0 -2
- package/dist/adapters/capture-target-offers.mjs +1 -2
- package/dist/adapters/capture-target.d.mts +0 -2
- package/dist/adapters/capture-target.mjs +1 -2
- package/dist/adapters/notifier/build-comment.d.mts +0 -2
- package/dist/adapters/notifier/build-comment.mjs +1 -2
- package/dist/adapters/notifier/build-state.d.mts +0 -2
- package/dist/adapters/notifier/build-state.mjs +1 -2
- package/dist/adapters/notifier/events.d.mts +0 -2
- package/dist/adapters/notifier/events.mjs +1 -2
- package/dist/adapters/notifier/format.d.mts +0 -2
- package/dist/adapters/notifier/format.mjs +1 -2
- package/dist/adapters/notifier/provider.d.mts +0 -2
- package/dist/adapters/notifier/provider.mjs +1 -2
- package/dist/adapters/notifier/state.d.mts +0 -2
- package/dist/adapters/notifier/state.mjs +1 -2
- package/dist/adapters/notifier/types.d.mts +0 -2
- package/dist/adapters/remote-browser.d.mts +120 -31
- package/dist/adapters/remote-browser.mjs +134 -34
- package/dist/adapters/remote-browser.mjs.map +1 -1
- package/dist/adapters/remote-lease-attempt.mjs +39 -0
- package/dist/adapters/remote-lease-attempt.mjs.map +1 -0
- package/dist/adapters/remote-lease-error.d.mts +25 -0
- package/dist/adapters/remote-lease-error.mjs +54 -0
- package/dist/adapters/remote-lease-error.mjs.map +1 -0
- package/dist/adapters/remote-lease-held.d.mts +15 -0
- package/dist/adapters/remote-lease-held.mjs +86 -0
- package/dist/adapters/remote-lease-held.mjs.map +1 -0
- package/dist/adapters/remote-lease-shutdown.d.mts +12 -0
- package/dist/adapters/remote-lease-shutdown.mjs +32 -0
- package/dist/adapters/remote-lease-shutdown.mjs.map +1 -0
- package/dist/adapters/remote-lease.d.mts +39 -0
- package/dist/adapters/remote-lease.mjs +175 -0
- package/dist/adapters/remote-lease.mjs.map +1 -0
- package/dist/adapters/remote-limiter.mjs +121 -0
- package/dist/adapters/remote-limiter.mjs.map +1 -0
- package/dist/adapters/remote-pool.d.mts +56 -0
- package/dist/adapters/remote-pool.mjs +195 -0
- package/dist/adapters/remote-pool.mjs.map +1 -0
- package/dist/adapters/remote-sizing.d.mts +44 -0
- package/dist/adapters/remote-sizing.mjs +53 -0
- package/dist/adapters/remote-sizing.mjs.map +1 -0
- package/dist/adapters/render-runs.d.mts +0 -2
- package/dist/adapters/render-runs.mjs +1 -2
- package/dist/adapters/setup-runner.d.mts +0 -2
- package/dist/adapters/setup-runner.mjs +1 -2
- package/dist/adapters/sources.d.mts +0 -2
- package/dist/adapters/sources.mjs +1 -2
- package/dist/adapters/validate.d.mts +0 -2
- package/dist/adapters/validate.mjs +2 -2
- package/dist/adapters/validate.mjs.map +1 -1
- package/dist/ai.d.mts +0 -2
- package/dist/ai.mjs +1 -2
- package/dist/auth.d.mts +0 -2
- package/dist/auth.mjs +1 -2
- package/dist/brand-packs.d.mts +0 -2
- package/dist/brand-packs.mjs +0 -1
- package/dist/capture/a11y/axe-source.d.mts +0 -2
- package/dist/capture/a11y/axe-source.mjs +1 -2
- package/dist/capture/a11y/in-page.d.mts +1 -3
- package/dist/capture/a11y/in-page.mjs +3 -4
- package/dist/capture/a11y/in-page.mjs.map +1 -1
- package/dist/capture/a11y/map.d.mts +0 -2
- package/dist/capture/a11y/map.mjs +1 -2
- package/dist/capture/a11y/options.d.mts +0 -2
- package/dist/capture/a11y/options.mjs +1 -2
- package/dist/capture/adapter.d.mts +5 -2
- package/dist/capture/adapter.mjs +1 -2
- package/dist/capture/adapter.mjs.map +1 -1
- package/dist/capture/affected.d.mts +0 -2
- package/dist/capture/affected.mjs +1 -2
- package/dist/capture/attempt-logger.mjs +1 -2
- package/dist/capture/browsers.d.mts +0 -2
- package/dist/capture/browsers.mjs +1 -2
- package/dist/capture/build-state/deliver.d.mts +0 -2
- package/dist/capture/build-state/deliver.mjs +1 -2
- package/dist/capture/build-state/notify-job.d.mts +0 -2
- package/dist/capture/build-state/notify-job.mjs +1 -2
- package/dist/capture/build-state/publisher.d.mts +0 -2
- package/dist/capture/build-state/publisher.mjs +1 -2
- package/dist/capture/build-state/resume.d.mts +0 -2
- package/dist/capture/build-state/resume.mjs +1 -2
- package/dist/capture/build-state/types.d.mts +1 -3
- package/dist/capture/catalog/catalogue.d.mts +0 -2
- package/dist/capture/catalog/catalogue.mjs +1 -2
- package/dist/capture/catalog/components.d.mts +0 -2
- package/dist/capture/catalog/components.mjs +1 -2
- package/dist/capture/catalog/history.d.mts +0 -2
- package/dist/capture/catalog/history.mjs +1 -2
- package/dist/capture/catalog/hook.d.mts +0 -2
- package/dist/capture/catalog/hook.mjs +1 -2
- package/dist/capture/catalog/index.d.mts +2 -2
- package/dist/capture/catalog/load.d.mts +0 -2
- package/dist/capture/catalog/load.mjs +1 -2
- package/dist/capture/catalog/parse.d.mts +0 -2
- package/dist/capture/catalog/parse.mjs +1 -2
- package/dist/capture/catalog/read.d.mts +6 -3
- package/dist/capture/catalog/read.mjs +14 -8
- package/dist/capture/catalog/read.mjs.map +1 -1
- package/dist/capture/catalog/types.d.mts +0 -2
- package/dist/capture/comparison-reference.d.mts +27 -0
- package/dist/capture/comparison-reference.mjs +75 -0
- package/dist/capture/comparison-reference.mjs.map +1 -0
- package/dist/capture/consumer/capture-handler.d.mts +1 -3
- package/dist/capture/consumer/capture-handler.mjs +1 -2
- package/dist/capture/consumer/idle.d.mts +0 -2
- package/dist/capture/consumer/idle.mjs +1 -2
- package/dist/capture/consumer/index.d.mts +0 -2
- package/dist/capture/consumer/index.mjs +1 -2
- package/dist/capture/consumer/loop.mjs +1 -2
- package/dist/capture/consumer/metrics.d.mts +0 -2
- package/dist/capture/consumer/metrics.mjs +1 -2
- package/dist/capture/consumer/retry.d.mts +0 -2
- package/dist/capture/consumer/retry.mjs +1 -2
- package/dist/capture/consumer/run-job.mjs +1 -2
- package/dist/capture/consumer/startup.mjs +1 -2
- package/dist/capture/consumer/types.d.mts +0 -2
- package/dist/capture/crash-failure.d.mts +0 -2
- package/dist/capture/crash-failure.mjs +1 -2
- package/dist/capture/db-queue/cadence.d.mts +0 -2
- package/dist/capture/db-queue/cadence.mjs +1 -2
- package/dist/capture/db-queue/claim.d.mts +0 -2
- package/dist/capture/db-queue/claim.mjs +20 -4
- package/dist/capture/db-queue/claim.mjs.map +1 -1
- package/dist/capture/db-queue/clock.mjs +1 -2
- package/dist/capture/db-queue/codec.mjs +1 -2
- package/dist/capture/db-queue/index.d.mts +0 -2
- package/dist/capture/db-queue/index.mjs +3 -3
- package/dist/capture/db-queue/index.mjs.map +1 -1
- package/dist/capture/db-queue/keeper.d.mts +0 -2
- package/dist/capture/db-queue/keeper.mjs +1 -2
- package/dist/capture/db-queue/lease.mjs +1 -2
- package/dist/capture/db-queue/lifecycle.mjs +1 -2
- package/dist/capture/db-queue/operations.mjs +1 -2
- package/dist/capture/db-queue/poll-loop.d.mts +0 -2
- package/dist/capture/db-queue/poll-loop.mjs +1 -2
- package/dist/capture/db-queue/poll.d.mts +0 -2
- package/dist/capture/db-queue/poll.mjs +1 -2
- package/dist/capture/db-queue/timers.d.mts +0 -2
- package/dist/capture/db-queue/timers.mjs +1 -2
- package/dist/capture/db-queue/types.d.mts +0 -2
- package/dist/capture/db-queue/types.mjs +1 -2
- package/dist/capture/db-queue/types.mjs.map +1 -1
- package/dist/capture/db-queue/wake.mjs +1 -2
- package/dist/capture/design.mjs +1 -2
- package/dist/capture/diff-record.mjs +1 -2
- package/dist/capture/dispatch.d.mts +1 -3
- package/dist/capture/dispatch.mjs +17 -5
- package/dist/capture/dispatch.mjs.map +1 -1
- package/dist/capture/enrich.mjs +1 -2
- package/dist/capture/failure-sets.mjs +1 -2
- package/dist/capture/fingerprint.d.mts +19 -8
- package/dist/capture/fingerprint.mjs +43 -14
- package/dist/capture/fingerprint.mjs.map +1 -1
- package/dist/capture/forked/channel.d.mts +0 -2
- package/dist/capture/forked/child.d.mts +0 -2
- package/dist/capture/forked/child.mjs +1 -2
- package/dist/capture/forked/crash-tracker.mjs +1 -2
- package/dist/capture/forked/decision.d.mts +0 -2
- package/dist/capture/forked/decision.mjs +1 -2
- package/dist/capture/forked/exit.mjs +1 -2
- package/dist/capture/forked/fork.d.mts +0 -2
- package/dist/capture/forked/fork.mjs +1 -2
- package/dist/capture/forked/forked-capture.d.mts +0 -2
- package/dist/capture/forked/forked-capture.mjs +1 -2
- package/dist/capture/forked/lease-book.mjs +1 -2
- package/dist/capture/forked/protocol.d.mts +0 -2
- package/dist/capture/forked/protocol.mjs +1 -2
- package/dist/capture/forked/runs.mjs +1 -2
- package/dist/capture/guards.mjs +1 -2
- package/dist/capture/ignore-regions.d.mts +36 -0
- package/dist/capture/ignore-regions.mjs +65 -0
- package/dist/capture/ignore-regions.mjs.map +1 -0
- package/dist/capture/isolate.mjs +1 -2
- package/dist/capture/job-lease.d.mts +0 -2
- package/dist/capture/job-lease.mjs +1 -2
- package/dist/capture/matrix.mjs +4 -4
- package/dist/capture/matrix.mjs.map +1 -1
- package/dist/capture/modes.d.mts +0 -2
- package/dist/capture/modes.mjs +2 -3
- package/dist/capture/modes.mjs.map +1 -1
- package/dist/capture/orchestrator.d.mts +0 -2
- package/dist/capture/orchestrator.mjs +2 -3
- package/dist/capture/pipeline.d.mts +0 -2
- package/dist/capture/pipeline.mjs +44 -10
- package/dist/capture/pipeline.mjs.map +1 -1
- package/dist/capture/progress.d.mts +0 -2
- package/dist/capture/progress.mjs +1 -2
- package/dist/capture/publish/accept.d.mts +0 -2
- package/dist/capture/publish/accept.mjs +1 -2
- package/dist/capture/publish/complete.d.mts +1 -3
- package/dist/capture/publish/complete.mjs +1 -2
- package/dist/capture/publish/extract.d.mts +0 -2
- package/dist/capture/publish/extract.mjs +6 -5
- package/dist/capture/publish/extract.mjs.map +1 -1
- package/dist/capture/publish/handler.d.mts +1 -3
- package/dist/capture/publish/handler.mjs +1 -2
- package/dist/capture/publish/index.d.mts +2 -1
- package/dist/capture/publish/invalid-zip.d.mts +8 -0
- package/dist/capture/publish/invalid-zip.mjs +11 -0
- package/dist/capture/publish/invalid-zip.mjs.map +1 -0
- package/dist/capture/publish/limits.d.mts +0 -2
- package/dist/capture/publish/limits.mjs +1 -2
- package/dist/capture/publish/published.d.mts +0 -2
- package/dist/capture/publish/published.mjs +1 -2
- package/dist/capture/publish/run.d.mts +1 -3
- package/dist/capture/publish/run.mjs +1 -2
- package/dist/capture/rediff.d.mts +1 -3
- package/dist/capture/rediff.mjs +19 -6
- package/dist/capture/rediff.mjs.map +1 -1
- package/dist/capture/render.mjs +1 -2
- package/dist/capture/render.mjs.map +1 -1
- package/dist/capture/scratch.d.mts +0 -2
- package/dist/capture/scratch.mjs +2 -4
- package/dist/capture/scratch.mjs.map +1 -1
- package/dist/capture/shard-plan.mjs +1 -2
- package/dist/capture/shards/context.mjs +3 -3
- package/dist/capture/shards/context.mjs.map +1 -1
- package/dist/capture/shards/execute.mjs +4 -3
- package/dist/capture/shards/execute.mjs.map +1 -1
- package/dist/capture/shards/fan-out.mjs +1 -2
- package/dist/capture/shards/history.mjs +1 -2
- package/dist/capture/shards/reduce.mjs +1 -2
- package/dist/capture/sizing.d.mts +0 -2
- package/dist/capture/sizing.mjs +1 -2
- package/dist/capture/skip-checks.mjs +1 -2
- package/dist/capture/statics.d.mts +0 -2
- package/dist/capture/statics.mjs +2 -4
- package/dist/capture/statics.mjs.map +1 -1
- package/dist/capture/storybook-urls.d.mts +0 -2
- package/dist/capture/storybook-urls.mjs +3 -3
- package/dist/capture/storybook-urls.mjs.map +1 -1
- package/dist/capture/storybook.d.mts +0 -2
- package/dist/capture/storybook.mjs +8 -4
- package/dist/capture/storybook.mjs.map +1 -1
- package/dist/capture/target.mjs +1 -2
- package/dist/capture/targets.d.mts +0 -2
- package/dist/capture/targets.mjs +1 -2
- package/dist/capture/tests.d.mts +0 -2
- package/dist/capture/tests.mjs +13 -3
- package/dist/capture/tests.mjs.map +1 -1
- package/dist/capture/token-chunks.mjs +24 -7
- package/dist/capture/token-chunks.mjs.map +1 -1
- package/dist/capture.d.mts +5 -2
- package/dist/capture.mjs +5 -2
- package/dist/config.d.mts +16 -3
- package/dist/config.mjs +6 -3
- package/dist/config.mjs.map +1 -1
- package/dist/diff.d.mts +0 -2
- package/dist/diff.mjs +1 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/insights/budget.d.mts +0 -2
- package/dist/insights/budget.mjs +1 -2
- package/dist/insights/envelope.d.mts +0 -2
- package/dist/insights/envelope.mjs +1 -2
- package/dist/insights/evidence-health.d.mts +0 -2
- package/dist/insights/evidence-health.mjs +1 -2
- package/dist/insights/evidence.d.mts +0 -2
- package/dist/insights/evidence.mjs +1 -2
- package/dist/insights/hash.d.mts +0 -2
- package/dist/insights/hash.mjs +1 -2
- package/dist/insights/limits.d.mts +0 -2
- package/dist/insights/limits.mjs +1 -2
- package/dist/insights/prompts/v1.d.mts +0 -2
- package/dist/insights/prompts/v1.mjs +1 -2
- package/dist/insights/redact.d.mts +0 -2
- package/dist/insights/redact.mjs +1 -2
- package/dist/insights/text.mjs +1 -2
- package/dist/logger.d.mts +0 -2
- package/dist/logger.mjs +1 -2
- package/dist/models/ai-budget-alert.d.mts +0 -2
- package/dist/models/ai-budget-alert.mjs +1 -2
- package/dist/models/ai-usage.d.mts +0 -2
- package/dist/models/ai-usage.mjs +1 -2
- package/dist/models/baseline-approval.d.mts +18 -0
- package/dist/models/baseline-approval.mjs +41 -0
- package/dist/models/baseline-approval.mjs.map +1 -0
- package/dist/models/baseline-archive.d.mts +0 -2
- package/dist/models/baseline-archive.mjs +1 -2
- package/dist/models/baseline-atomic.mjs +66 -0
- package/dist/models/baseline-atomic.mjs.map +1 -0
- package/dist/models/baseline-conflict.d.mts +6 -0
- package/dist/models/baseline-conflict.mjs +9 -0
- package/dist/models/baseline-conflict.mjs.map +1 -0
- package/dist/models/baseline-export.d.mts +0 -2
- package/dist/models/baseline-export.mjs +1 -2
- package/dist/models/baseline-import.mjs +1 -2
- package/dist/models/baseline-origin.d.mts +16 -0
- package/dist/models/baseline-origin.mjs +35 -0
- package/dist/models/baseline-origin.mjs.map +1 -0
- package/dist/models/baseline-status.d.mts +0 -2
- package/dist/models/baseline-status.mjs +1 -2
- package/dist/models/baseline-transfer.d.mts +1 -2
- package/dist/models/baseline-transfer.mjs +30 -2
- package/dist/models/baseline-transfer.mjs.map +1 -1
- package/dist/models/baseline.d.mts +5 -2
- package/dist/models/baseline.mjs +91 -12
- package/dist/models/baseline.mjs.map +1 -1
- package/dist/models/build-component.d.mts +0 -2
- package/dist/models/build-component.mjs +1 -2
- package/dist/models/build-review-status.d.mts +0 -2
- package/dist/models/build-review-status.mjs +1 -2
- package/dist/models/build-review.d.mts +0 -2
- package/dist/models/build-review.mjs +1 -2
- package/dist/models/build.d.mts +1 -3
- package/dist/models/build.mjs +14 -15
- package/dist/models/build.mjs.map +1 -1
- package/dist/models/capture-attempt.d.mts +0 -2
- package/dist/models/capture-attempt.mjs +1 -2
- package/dist/models/capture-job.d.mts +0 -2
- package/dist/models/capture-job.mjs +1 -2
- package/dist/models/capture-log.d.mts +0 -2
- package/dist/models/capture-log.mjs +1 -2
- package/dist/models/capture-shard.d.mts +0 -2
- package/dist/models/capture-shard.mjs +1 -2
- package/dist/models/changeset.d.mts +0 -2
- package/dist/models/changeset.mjs +1 -2
- package/dist/models/columns.mjs +1 -2
- package/dist/models/comment.d.mts +0 -2
- package/dist/models/comment.mjs +1 -2
- package/dist/models/component.d.mts +0 -2
- package/dist/models/component.mjs +1 -2
- package/dist/models/connections.d.mts +0 -2
- package/dist/models/connections.mjs +1 -2
- package/dist/models/content-ref.d.mts +0 -2
- package/dist/models/content-ref.mjs +1 -2
- package/dist/models/credentials.d.mts +0 -2
- package/dist/models/credentials.mjs +1 -2
- package/dist/models/design-credentials.d.mts +0 -2
- package/dist/models/design-credentials.mjs +1 -2
- package/dist/models/design-health.d.mts +16 -3
- package/dist/models/design-health.mjs +21 -3
- package/dist/models/design-health.mjs.map +1 -1
- package/dist/models/design-nodes.d.mts +11 -4
- package/dist/models/design-nodes.mjs +18 -3
- package/dist/models/design-nodes.mjs.map +1 -1
- package/dist/models/design-renders.mjs +1 -2
- package/dist/models/design-resolve.d.mts +0 -2
- package/dist/models/design-resolve.mjs +1 -2
- package/dist/models/design.d.mts +0 -2
- package/dist/models/design.mjs +1 -2
- package/dist/models/inherited-ratio.d.mts +0 -2
- package/dist/models/inherited-ratio.mjs +1 -2
- package/dist/models/insight.d.mts +0 -2
- package/dist/models/insight.mjs +1 -2
- package/dist/models/label.d.mts +0 -2
- package/dist/models/label.mjs +1 -2
- package/dist/models/member.d.mts +0 -2
- package/dist/models/member.mjs +1 -2
- package/dist/models/notification-channel.d.mts +0 -2
- package/dist/models/notification-channel.mjs +1 -2
- package/dist/models/notification-subscription.d.mts +0 -2
- package/dist/models/notification-subscription.mjs +1 -2
- package/dist/models/project-group-mapping.d.mts +0 -2
- package/dist/models/project-group-mapping.mjs +1 -2
- package/dist/models/project.d.mts +0 -2
- package/dist/models/project.mjs +1 -2
- package/dist/models/public-origin.d.mts +0 -2
- package/dist/models/public-origin.mjs +1 -2
- package/dist/models/review-switch-off.d.mts +0 -2
- package/dist/models/review-switch-off.mjs +1 -2
- package/dist/models/site-settings.d.mts +0 -2
- package/dist/models/site-settings.mjs +1 -2
- package/dist/models/snapshot.d.mts +3 -2
- package/dist/models/snapshot.mjs +4 -2
- package/dist/models/snapshot.mjs.map +1 -1
- package/dist/models/token.d.mts +0 -2
- package/dist/models/token.mjs +1 -2
- package/dist/models/usage.d.mts +0 -2
- package/dist/models/usage.mjs +1 -2
- package/dist/models/user.d.mts +0 -2
- package/dist/models/user.mjs +1 -2
- package/dist/models/webhook.d.mts +0 -2
- package/dist/models/webhook.mjs +1 -2
- package/dist/models.d.mts +6 -3
- package/dist/models.mjs +6 -3
- package/dist/options.d.mts +0 -2
- package/dist/options.mjs +2 -4
- package/dist/options.mjs.map +1 -1
- package/dist/paths.d.mts +3 -3
- package/dist/paths.mjs +7 -3
- package/dist/paths.mjs.map +1 -1
- package/dist/retention/ai.d.mts +1 -3
- package/dist/retention/ai.mjs +0 -1
- package/dist/retention/pending.mjs +1 -2
- package/dist/retention/published-gzip-sweep.mjs +28 -0
- package/dist/retention/published-gzip-sweep.mjs.map +1 -0
- package/dist/retention/screenshot-sweep.d.mts +0 -2
- package/dist/retention/screenshot-sweep.mjs +1 -2
- package/dist/retention.d.mts +0 -2
- package/dist/retention.mjs +5 -2
- package/dist/retention.mjs.map +1 -1
- package/dist/schema/baseline.d.mts +2 -2
- package/dist/schema/build-component.d.mts +0 -2
- package/dist/schema/build-review.d.mts +0 -2
- package/dist/schema/build.d.mts +0 -2
- package/dist/schema/capture-attempt.d.mts +0 -2
- package/dist/schema/capture-job.d.mts +0 -2
- package/dist/schema/capture-shard.d.mts +0 -2
- package/dist/schema/comment.d.mts +0 -2
- package/dist/schema/connection.d.mts +0 -2
- package/dist/schema/content-ref.d.mts +0 -2
- package/dist/schema/design.d.mts +2 -2
- package/dist/schema/insight.d.mts +0 -2
- package/dist/schema/label.d.mts +0 -2
- package/dist/schema/member.d.mts +0 -2
- package/dist/schema/notification.d.mts +0 -2
- package/dist/schema/project-group-mapping.d.mts +0 -2
- package/dist/schema/project.d.mts +0 -2
- package/dist/schema/site-setting.d.mts +0 -2
- package/dist/schema/snapshot.d.mts +5 -2
- package/dist/schema/token.d.mts +0 -2
- package/dist/schema/usage.d.mts +0 -2
- package/dist/schema/user.d.mts +0 -2
- package/dist/schema/webhook.d.mts +0 -2
- package/dist/schema.d.mts +4 -6
- package/dist/serverless.d.mts +0 -2
- package/dist/serverless.mjs +1 -2
- package/dist/test-helpers/build-reference-contract.d.mts +14 -0
- package/dist/test-helpers/build-reference-contract.mjs +66 -0
- package/dist/test-helpers/build-reference-contract.mjs.map +1 -0
- package/dist/test-helpers/create-project.d.mts +0 -2
- package/dist/test-helpers/create-project.mjs +1 -2
- package/dist/test-helpers/database-contract.d.mts +0 -2
- package/dist/test-helpers/database-contract.mjs +37 -2
- package/dist/test-helpers/database-contract.mjs.map +1 -1
- package/dist/test-helpers/deferred.d.mts +0 -2
- package/dist/test-helpers/deferred.mjs +1 -2
- package/dist/test-helpers/design-contract.d.mts +0 -2
- package/dist/test-helpers/design-contract.mjs +1 -2
- package/dist/test-helpers/fake-adapters.d.mts +0 -2
- package/dist/test-helpers/fake-adapters.mjs +1 -2
- package/dist/test-helpers/fake-database.d.mts +0 -2
- package/dist/test-helpers/fake-database.mjs +7 -2
- package/dist/test-helpers/fake-database.mjs.map +1 -1
- package/dist/test-helpers/fake-design.d.mts +0 -2
- package/dist/test-helpers/fake-design.mjs +1 -2
- package/dist/test-helpers/fake-notifier.d.mts +0 -2
- package/dist/test-helpers/fake-notifier.mjs +1 -2
- package/dist/test-helpers/fake-storage.d.mts +0 -2
- package/dist/test-helpers/fake-storage.mjs +1 -2
- package/dist/test-helpers/fake-tables.mjs +6 -2
- package/dist/test-helpers/fake-tables.mjs.map +1 -1
- package/dist/test-helpers/manual-clock.d.mts +0 -2
- package/dist/test-helpers/manual-clock.mjs +1 -2
- package/dist/test-helpers/notifier-contract.d.mts +0 -2
- package/dist/test-helpers/notifier-contract.mjs +1 -2
- package/dist/test-helpers/queue-contract.d.mts +0 -2
- package/dist/test-helpers/queue-contract.mjs +1 -2
- package/dist/test-helpers/queue-multi-instance.d.mts +0 -2
- package/dist/test-helpers/queue-multi-instance.mjs +1 -2
- package/dist/test-helpers/runner-contract.d.mts +0 -2
- package/dist/test-helpers/runner-contract.mjs +1 -2
- package/dist/test-helpers/sql-chunks.mjs +2 -2
- package/dist/test-helpers/sql-chunks.mjs.map +1 -1
- package/dist/test-helpers/storage-contract.d.mts +0 -2
- package/dist/test-helpers/storage-contract.mjs +1 -2
- package/dist/test-helpers.d.mts +2 -1
- package/dist/test-helpers.mjs +2 -1
- package/dist/tracing.mjs +36 -6
- package/dist/tracing.mjs.map +1 -1
- package/dist/types.d.mts +0 -2
- package/dist/types.mjs +1 -2
- package/dist/urls.d.mts +0 -2
- package/dist/urls.mjs +1 -2
- package/dist/utils/adaptive-concurrency.d.mts +0 -2
- package/dist/utils/adaptive-concurrency.mjs +1 -2
- package/dist/utils/connect-retry.d.mts +2 -2
- package/dist/utils/connect-retry.mjs +2 -3
- package/dist/utils/connect-retry.mjs.map +1 -1
- package/dist/utils/encrypt.d.mts +0 -2
- package/dist/utils/encrypt.mjs +1 -2
- package/dist/utils/environment.d.mts +0 -2
- package/dist/utils/environment.mjs +1 -2
- package/dist/utils/hash.d.mts +0 -2
- package/dist/utils/hash.mjs +1 -2
- package/dist/utils/http.d.mts +13 -3
- package/dist/utils/http.mjs +79 -17
- package/dist/utils/http.mjs.map +1 -1
- package/dist/utils/map-adaptive.d.mts +0 -2
- package/dist/utils/map-adaptive.mjs +1 -2
- package/dist/utils/map-limit.d.mts +0 -2
- package/dist/utils/map-limit.mjs +1 -2
- package/dist/utils/mime.d.mts +0 -2
- package/dist/utils/mime.mjs +1 -2
- package/dist/utils/page-limiter.d.mts +0 -2
- package/dist/utils/page-limiter.mjs +1 -2
- package/dist/utils/path-security.d.mts +0 -2
- package/dist/utils/path-security.mjs +2 -4
- package/dist/utils/path-security.mjs.map +1 -1
- package/dist/utils/public-origin.d.mts +0 -2
- package/dist/utils/public-origin.mjs +1 -2
- package/dist/utils/redact.d.mts +0 -2
- package/dist/utils/redact.mjs +1 -2
- package/dist/utils/remote-environment.d.mts +40 -3
- package/dist/utils/remote-environment.mjs +52 -3
- package/dist/utils/remote-environment.mjs.map +1 -1
- package/dist/utils/resources.d.mts +0 -2
- package/dist/utils/resources.mjs +1 -2
- package/dist/utils/screenshot-store.d.mts +0 -2
- package/dist/utils/screenshot-store.mjs +1 -2
- package/dist/utils/session-gate.d.mts +7 -6
- package/dist/utils/session-gate.mjs +28 -12
- package/dist/utils/session-gate.mjs.map +1 -1
- package/dist/utils/storybook-token.d.mts +11 -3
- package/dist/utils/storybook-token.mjs +10 -9
- package/dist/utils/storybook-token.mjs.map +1 -1
- package/dist/utils/storybook-url.d.mts +0 -2
- package/dist/utils/storybook-url.mjs +1 -2
- package/dist/utils/timing.d.mts +0 -2
- package/dist/utils/timing.mjs +1 -2
- package/dist/utils/ulid.d.mts +0 -2
- package/dist/utils/ulid.mjs +1 -2
- package/dist/utils/zip-read.mjs +1 -2
- package/dist/utils/zip-write.d.mts +0 -2
- package/dist/utils/zip-write.mjs +1 -2
- package/dist/utils.d.mts +5 -5
- package/dist/utils.mjs +5 -5
- package/package.json +6 -15
package/dist/test-helpers.d.mts
CHANGED
|
@@ -15,4 +15,5 @@ import { ManualClock, createManualClock } from "./test-helpers/manual-clock.mjs"
|
|
|
15
15
|
import { runnerContractSuite } from "./test-helpers/runner-contract.mjs";
|
|
16
16
|
import { storageContractSuite } from "./test-helpers/storage-contract.mjs";
|
|
17
17
|
import { FakeStateNotifier, makeFakeStateNotifier } from "./test-helpers/fake-notifier.mjs";
|
|
18
|
-
|
|
18
|
+
import { BuildReferenceContractFixture, BuildReferenceContractFixtureRunner, buildReferenceContractSuite } from "./test-helpers/build-reference-contract.mjs";
|
|
19
|
+
export { type BuildReferenceContractFixture, type BuildReferenceContractFixtureRunner, type Deferred, type DesignContractSamples, FAKE_PNG, type FakeDesign, type FakeStateNotifier, type FakeStorage, type Latch, type ManualClock, type MultiInstanceOptions, type PollableContractOptions, type QueueContractOptions, type QueueFactory, REQUIRED_TABLES, type ReleaseQueue, type SharedDatabaseFactory, buildReferenceContractSuite, createLatch, createManualClock, createReleaseQueue, createTestBuild, createTestProject, databaseContractSuite, databaseQueueMultiInstanceSuite, deferred, designContractSuite, fakeUrl, makeDatabase, makeFakeDesign, makeFakeStateNotifier, makeStorage, notifierContractSuite, queueContractSuite, runnerContractSuite, stateNotifierContractSuite, storageContractSuite, stubTables };
|
package/dist/test-helpers.mjs
CHANGED
|
@@ -16,4 +16,5 @@ import { createManualClock } from "./test-helpers/manual-clock.mjs";
|
|
|
16
16
|
import { runnerContractSuite } from "./test-helpers/runner-contract.mjs";
|
|
17
17
|
import { storageContractSuite } from "./test-helpers/storage-contract.mjs";
|
|
18
18
|
import { makeFakeStateNotifier } from "./test-helpers/fake-notifier.mjs";
|
|
19
|
-
|
|
19
|
+
import { buildReferenceContractSuite } from "./test-helpers/build-reference-contract.mjs";
|
|
20
|
+
export { FAKE_PNG, REQUIRED_TABLES, buildReferenceContractSuite, createLatch, createManualClock, createReleaseQueue, createTestBuild, createTestProject, databaseContractSuite, databaseQueueMultiInstanceSuite, deferred, designContractSuite, fakeUrl, makeDatabase, makeFakeDesign, makeFakeStateNotifier, makeStorage, notifierContractSuite, queueContractSuite, runnerContractSuite, stateNotifierContractSuite, storageContractSuite, stubTables };
|
package/dist/tracing.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
+
import { redactSecrets } from "./utils/redact.mjs";
|
|
4
5
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
5
|
-
|
|
6
|
+
// src/tracing.ts
|
|
6
7
|
/**
|
|
7
8
|
* Internal span and propagation helpers over `@opentelemetry/api`.
|
|
8
9
|
*
|
|
@@ -15,11 +16,41 @@ import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentele
|
|
|
15
16
|
const SCOPE = "storyshelf.core";
|
|
16
17
|
/** W3C traceparent header name. */
|
|
17
18
|
const TRACEPARENT_HEADER = "traceparent";
|
|
19
|
+
/** What a span records of an error instead of its message, set by the code that knows the error. */
|
|
20
|
+
const spanMessages = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
/**
|
|
22
|
+
* State what spans record as the message of `error`, instead of its own: an outbound HTTP failure
|
|
23
|
+
* is recorded as its status, never the response body it carries. The error itself is not touched,
|
|
24
|
+
* so what a caller catches is unchanged.
|
|
25
|
+
*/
|
|
26
|
+
function setSpanMessage(error, message) {
|
|
27
|
+
if (typeof error === "object" && error !== null) spanMessages.set(error, message);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The form of a failure that may be recorded on a span: a new error of the same name whose message
|
|
31
|
+
* (the one given to {@link setSpanMessage}, else the error's own) has gone through
|
|
32
|
+
* `redactSecrets`, with the original's stack frames. Never the original, whose message, stack
|
|
33
|
+
* header or `cause` can repeat a URL, a token or a response body. A thrown non-error is stringified
|
|
34
|
+
* and redacted. This is the one way core records an exception on a span.
|
|
35
|
+
*/
|
|
36
|
+
function spanException(error) {
|
|
37
|
+
if (!(error instanceof Error)) return redactSecrets(String(error));
|
|
38
|
+
const message = redactSecrets(spanMessages.get(error) ?? error.message);
|
|
39
|
+
const copy = new Error(message);
|
|
40
|
+
copy.name = error.name;
|
|
41
|
+
copy.stack = `${error.name}: ${message}${redactSecrets(framesOf(error))}`;
|
|
42
|
+
return copy;
|
|
43
|
+
}
|
|
44
|
+
/** The stack after its `Name: message` header, which may hold what the span must not record. */
|
|
45
|
+
function framesOf(error) {
|
|
46
|
+
const header = `${error.name}: ${error.message}`;
|
|
47
|
+
return error.stack?.startsWith(header) ? error.stack.slice(header.length) : "";
|
|
48
|
+
}
|
|
18
49
|
/**
|
|
19
50
|
* Run `fn` inside an internal span.
|
|
20
51
|
*
|
|
21
|
-
* On throw the span records the exception, is marked
|
|
22
|
-
* is rethrown — mirroring the pino `{ err }` convention.
|
|
52
|
+
* On throw the span records a redacted copy of the exception ({@link spanException}), is marked
|
|
53
|
+
* ERROR, and the original error is rethrown untouched — mirroring the pino `{ err }` convention.
|
|
23
54
|
*
|
|
24
55
|
* @param name - Span name (`domain.operation`, never a high-cardinality value).
|
|
25
56
|
* @param fn - Work to run with the span active.
|
|
@@ -35,7 +66,7 @@ async function withSpan(name, fn, attributes, parent) {
|
|
|
35
66
|
try {
|
|
36
67
|
return await fn(span);
|
|
37
68
|
} catch (error) {
|
|
38
|
-
span.recordException(
|
|
69
|
+
span.recordException(spanException(error));
|
|
39
70
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
40
71
|
throw error;
|
|
41
72
|
} finally {
|
|
@@ -57,7 +88,6 @@ function parentContext(traceparent) {
|
|
|
57
88
|
function injectTraceContext(headers) {
|
|
58
89
|
propagation.inject(context.active(), headers);
|
|
59
90
|
}
|
|
60
|
-
|
|
61
|
-
export { injectTraceContext, parentContext, withSpan };
|
|
91
|
+
export { injectTraceContext, parentContext, setSpanMessage, spanException, withSpan };
|
|
62
92
|
|
|
63
93
|
//# sourceMappingURL=tracing.mjs.map
|
package/dist/tracing.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.mjs","names":[],"sources":["../src/tracing.ts"],"sourcesContent":["/**\n * Internal span and propagation helpers over `@opentelemetry/api`.\n *\n * Not exported from the package surface (see `package.json` exports): other\n * packages use `@storyshelf/observability`. Without a configured provider\n * every helper is a cheap noop, so call sites need no enabled-checks and\n * the hermetic vitest suite stays network-free.\n */\nimport {\n SpanKind,\n SpanStatusCode,\n context,\n propagation,\n trace,\n type Attributes,\n type Context,\n type Span,\n} from \"@opentelemetry/api\";\n\n/** Instrumentation scope for core spans. */\nconst SCOPE = \"storyshelf.core\";\n\n/** W3C traceparent header name. */\nconst TRACEPARENT_HEADER = \"traceparent\";\n\n/**\n * Run `fn` inside an internal span.\n *\n * On throw the span records the exception, is marked ERROR, and the error
|
|
1
|
+
{"version":3,"file":"tracing.mjs","names":[],"sources":["../src/tracing.ts"],"sourcesContent":["/**\n * Internal span and propagation helpers over `@opentelemetry/api`.\n *\n * Not exported from the package surface (see `package.json` exports): other\n * packages use `@storyshelf/observability`. Without a configured provider\n * every helper is a cheap noop, so call sites need no enabled-checks and\n * the hermetic vitest suite stays network-free.\n */\nimport {\n SpanKind,\n SpanStatusCode,\n context,\n propagation,\n trace,\n type Attributes,\n type Context,\n type Span,\n} from \"@opentelemetry/api\";\nimport { redactSecrets } from \"./utils/redact.ts\";\n\n/** Instrumentation scope for core spans. */\nconst SCOPE = \"storyshelf.core\";\n\n/** W3C traceparent header name. */\nconst TRACEPARENT_HEADER = \"traceparent\";\n\n/** What a span records of an error instead of its message, set by the code that knows the error. */\nconst spanMessages = new WeakMap<object, string>();\n\n/**\n * State what spans record as the message of `error`, instead of its own: an outbound HTTP failure\n * is recorded as its status, never the response body it carries. The error itself is not touched,\n * so what a caller catches is unchanged.\n */\nexport function setSpanMessage(error: unknown, message: string): void {\n if (typeof error === \"object\" && error !== null) {\n spanMessages.set(error, message);\n }\n}\n\n/**\n * The form of a failure that may be recorded on a span: a new error of the same name whose message\n * (the one given to {@link setSpanMessage}, else the error's own) has gone through\n * `redactSecrets`, with the original's stack frames. Never the original, whose message, stack\n * header or `cause` can repeat a URL, a token or a response body. A thrown non-error is stringified\n * and redacted. This is the one way core records an exception on a span.\n */\nexport function spanException(error: unknown): Error | string {\n if (!(error instanceof Error)) {\n return redactSecrets(String(error));\n }\n const message = redactSecrets(spanMessages.get(error) ?? error.message);\n const copy = new Error(message);\n copy.name = error.name;\n copy.stack = `${error.name}: ${message}${redactSecrets(framesOf(error))}`;\n return copy;\n}\n\n/** The stack after its `Name: message` header, which may hold what the span must not record. */\nfunction framesOf(error: Error): string {\n const header = `${error.name}: ${error.message}`;\n return error.stack?.startsWith(header) ? error.stack.slice(header.length) : \"\";\n}\n\n/**\n * Run `fn` inside an internal span.\n *\n * On throw the span records a redacted copy of the exception ({@link spanException}), is marked\n * ERROR, and the original error is rethrown untouched — mirroring the pino `{ err }` convention.\n *\n * @param name - Span name (`domain.operation`, never a high-cardinality value).\n * @param fn - Work to run with the span active.\n * @param attributes - Fixed span attributes.\n * @param parent - Parent context (defaults to the active context).\n * @returns Whatever `fn` returns.\n */\nexport async function withSpan<T>(\n name: string,\n fn: (span: Span) => Promise<T>,\n attributes?: Attributes,\n parent?: Context,\n): Promise<T> {\n const tracer = trace.getTracer(SCOPE);\n return await tracer.startActiveSpan(\n name,\n { kind: SpanKind.INTERNAL, attributes },\n parent ?? context.active(),\n async (span) => {\n try {\n return await fn(span);\n } catch (error) {\n span.recordException(spanException(error));\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n } finally {\n span.end();\n }\n },\n );\n}\n\n/**\n * Resolve the parent context from an inbound `traceparent` value.\n *\n * @param traceparent - W3C value from a queue payload; absent keeps context.\n * @returns The extracted remote context, or the active context when absent.\n */\nexport function parentContext(traceparent?: string): Context {\n if (!traceparent) {\n return context.active();\n }\n return propagation.extract(context.active(), { [TRACEPARENT_HEADER]: traceparent });\n}\n\n/** Inject the active span context into a mutable header record. */\nexport function injectTraceContext(headers: Record<string, string>): void {\n propagation.inject(context.active(), headers);\n}\n\n/**\n * Read the current W3C `traceparent` value for queue payloads.\n *\n * @returns The header value, or undefined when no span is active.\n */\nexport function currentTraceparent(): string | undefined {\n const carrier: Record<string, string> = {};\n propagation.inject(context.active(), carrier);\n return carrier[TRACEPARENT_HEADER];\n}\n"],"mappings":";;;;;;;;;;;;;;;AAqBA,MAAM,QAAQ;;AAGd,MAAM,qBAAqB;;AAG3B,MAAM,+BAAe,IAAI,QAAwB;;;;;;AAOjD,SAAgB,eAAe,OAAgB,SAAuB;CACpE,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,aAAa,IAAI,OAAO,OAAO;AAEnC;;;;;;;;AASA,SAAgB,cAAc,OAAgC;CAC5D,IAAI,EAAE,iBAAiB,QACrB,OAAO,cAAc,OAAO,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,aAAa,IAAI,KAAK,KAAK,MAAM,OAAO;CACtE,MAAM,OAAO,IAAI,MAAM,OAAO;CAC9B,KAAK,OAAO,MAAM;CAClB,KAAK,QAAQ,GAAG,MAAM,KAAK,IAAI,UAAU,cAAc,SAAS,KAAK,CAAC;CACtE,OAAO;AACT;;AAGA,SAAS,SAAS,OAAsB;CACtC,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,MAAM;CACvC,OAAO,MAAM,OAAO,WAAW,MAAM,IAAI,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI;AAC9E;;;;;;;;;;;;;AAcA,eAAsB,SACpB,MACA,IACA,YACA,QACY;CAEZ,OAAO,MADQ,MAAM,UAAU,KACb,CAAC,CAAC,gBAClB,MACA;EAAE,MAAM,SAAS;EAAU;CAAW,GACtC,UAAU,QAAQ,OAAO,GACzB,OAAO,SAAS;EACd,IAAI;GACF,OAAO,MAAM,GAAG,IAAI;EACtB,SAAS,OAAO;GACd,KAAK,gBAAgB,cAAc,KAAK,CAAC;GACzC,KAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;GAC7C,MAAM;EACR,UAAU;GACR,KAAK,IAAI;EACX;CACF,CACF;AACF;;;;;;;AAQA,SAAgB,cAAc,aAA+B;CAC3D,IAAI,CAAC,aACH,OAAO,QAAQ,OAAO;CAExB,OAAO,YAAY,QAAQ,QAAQ,OAAO,GAAG,GAAG,qBAAqB,YAAY,CAAC;AACpF;;AAGA,SAAgB,mBAAmB,SAAuC;CACxE,YAAY,OAAO,QAAQ,OAAO,GAAG,OAAO;AAC9C"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
//#region src/types.d.ts
|
|
4
3
|
/** All lifecycle statuses a build can carry. */
|
|
5
4
|
declare const BUILD_STATUSES: readonly ["pending", "capturing", "comparing", "reviewing", "approved", "rejected", "failed", "cancelled"];
|
|
6
5
|
/** Lifecycle status of a build. */
|
|
@@ -69,6 +68,5 @@ declare const RESERVED_LABEL_KEYS: readonly ["build"];
|
|
|
69
68
|
* Attach `persistent=true` to keep a build indefinitely, even after its TTL expires.
|
|
70
69
|
*/
|
|
71
70
|
declare const PERSISTENT_LABEL_KEY = "persistent";
|
|
72
|
-
//#endregion
|
|
73
71
|
export { AuthUser, BUILD_STATUSES, BuildStatus, CANCELLABLE_BUILD_STATUSES, PERSISTENT_LABEL_KEY, PROJECT_ROLES, ProjectRole, RESERVED_LABEL_KEYS, REVIEW_VERDICTS, ReviewVerdict, SEEDED_LABEL_KEYS, SESSION_COOKIE, SITE_ROLES, SNAPSHOT_STATUSES, SiteRole, SnapshotStatus, TERMINAL_BUILD_STATUSES, isProjectRole };
|
|
74
72
|
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/types.ts
|
|
5
5
|
/** All lifecycle statuses a build can carry. */
|
|
6
6
|
const BUILD_STATUSES = [
|
|
7
7
|
"pending",
|
|
@@ -81,7 +81,6 @@ const RESERVED_LABEL_KEYS = ["build"];
|
|
|
81
81
|
* Attach `persistent=true` to keep a build indefinitely, even after its TTL expires.
|
|
82
82
|
*/
|
|
83
83
|
const PERSISTENT_LABEL_KEY = "persistent";
|
|
84
|
-
//#endregion
|
|
85
84
|
export { BUILD_STATUSES, CANCELLABLE_BUILD_STATUSES, PERSISTENT_LABEL_KEY, PROJECT_ROLES, RESERVED_LABEL_KEYS, REVIEW_VERDICTS, SEEDED_LABEL_KEYS, SESSION_COOKIE, SITE_ROLES, SNAPSHOT_STATUSES, TERMINAL_BUILD_STATUSES, isProjectRole };
|
|
86
85
|
|
|
87
86
|
//# sourceMappingURL=types.mjs.map
|
package/dist/urls.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
//#region src/urls.d.ts
|
|
4
3
|
/** Type-safe URL builder for project pages and published Storybooks. */
|
|
5
4
|
interface UrlBuilder {
|
|
6
5
|
projectsList(): string;
|
|
@@ -37,6 +36,5 @@ declare function createUrlBuilder(baseUrl: string, publishedBaseDomain?: string)
|
|
|
37
36
|
* app-relative paths only, so `javascript:`/`data:` payloads fall back.
|
|
38
37
|
*/
|
|
39
38
|
declare function safeImageUrl(value: string | undefined): string | null;
|
|
40
|
-
//#endregion
|
|
41
39
|
export { UrlBuilder, createUrlBuilder, safeImageUrl };
|
|
42
40
|
//# sourceMappingURL=urls.d.mts.map
|
package/dist/urls.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/urls.ts
|
|
5
5
|
/**
|
|
6
6
|
* Create a URL builder rooted at the given base URL.
|
|
7
7
|
*
|
|
@@ -52,7 +52,6 @@ function safeImageUrl(value) {
|
|
|
52
52
|
function encodePath(value) {
|
|
53
53
|
return value.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
54
54
|
}
|
|
55
|
-
//#endregion
|
|
56
55
|
export { createUrlBuilder, safeImageUrl };
|
|
57
56
|
|
|
58
57
|
//# sourceMappingURL=urls.mjs.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
import { Logger } from "../logger.mjs";
|
|
4
|
-
//#region src/utils/adaptive-concurrency.d.ts
|
|
5
4
|
/** Tuning for {@link AdaptiveConcurrency}. */
|
|
6
5
|
interface AdaptiveOptions {
|
|
7
6
|
/** Starting in-flight limit. */
|
|
@@ -61,6 +60,5 @@ declare class AdaptiveConcurrency {
|
|
|
61
60
|
}
|
|
62
61
|
/** Whether an error is a navigation/action timeout (Playwright and Puppeteer both name it `TimeoutError`). */
|
|
63
62
|
declare function isTimeoutError(error: unknown): boolean;
|
|
64
|
-
//#endregion
|
|
65
63
|
export { AdaptiveConcurrency, AdaptiveOptions, Observation, isTimeoutError };
|
|
66
64
|
//# sourceMappingURL=adaptive-concurrency.d.mts.map
|
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { monitorEventLoopDelay } from "node:perf_hooks";
|
|
5
|
-
|
|
5
|
+
// src/utils/adaptive-concurrency.ts
|
|
6
6
|
/** Adaptive page concurrency: raise while capture stays healthy, back off when it does not. */
|
|
7
7
|
const MIN_WINDOW = 8;
|
|
8
8
|
/**
|
|
@@ -143,7 +143,6 @@ function eventLoopLagReader() {
|
|
|
143
143
|
}
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
|
-
//#endregion
|
|
147
146
|
export { AdaptiveConcurrency, isTimeoutError };
|
|
148
147
|
|
|
149
148
|
//# sourceMappingURL=adaptive-concurrency.mjs.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
//#region src/utils/connect-retry.d.ts
|
|
4
3
|
/** Retrying a connection to a remote browser service (ADR 0007, decision 4). */
|
|
5
4
|
/** Options of {@link retryConnect}. */
|
|
6
5
|
interface RetryConnectOptions {
|
|
@@ -8,6 +7,8 @@ interface RetryConnectOptions {
|
|
|
8
7
|
retries: number;
|
|
9
8
|
/** Delay before the first retry in ms; doubles each time, with jitter, capped at 10 s. */
|
|
10
9
|
backoffMs: number;
|
|
10
|
+
/** Whether an error is worth another attempt; defaults to {@link isRetryableConnectError}. */
|
|
11
|
+
retryable?: (error: unknown) => boolean;
|
|
11
12
|
/** Called before each retry with the error, the retry's number (from 1) and its delay. */
|
|
12
13
|
onRetry?: (error: unknown, retry: number, delayMs: number) => void;
|
|
13
14
|
/** Injectable for tests. */
|
|
@@ -21,6 +22,5 @@ declare function isRetryableConnectError(error: unknown): boolean;
|
|
|
21
22
|
* while rendering. The last error is thrown once the retries are spent.
|
|
22
23
|
*/
|
|
23
24
|
declare function retryConnect<T>(connect: () => Promise<T>, options: RetryConnectOptions): Promise<T>;
|
|
24
|
-
//#endregion
|
|
25
25
|
export { RetryConnectOptions, isRetryableConnectError, retryConnect };
|
|
26
26
|
//# sourceMappingURL=connect-retry.d.mts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/utils/connect-retry.ts
|
|
5
5
|
const MAX_DELAY_MS = 1e4;
|
|
6
6
|
/** Errors that no retry fixes: a refused credential, a missing endpoint, mismatched versions. */
|
|
7
7
|
const PERMANENT = /\b(?:401|403|404|428|unauthorized|forbidden|version mismatch|invalid (?:token|credentials)|not found)\b/iu;
|
|
@@ -22,7 +22,7 @@ async function retryConnect(connect, options) {
|
|
|
22
22
|
for (let retry = 0;; retry += 1) try {
|
|
23
23
|
return await connect();
|
|
24
24
|
} catch (error) {
|
|
25
|
-
if (retry >= options.retries || !isRetryableConnectError(error)) throw error;
|
|
25
|
+
if (retry >= options.retries || !(options.retryable ?? isRetryableConnectError)(error)) throw error;
|
|
26
26
|
const delayMs = Math.min(MAX_DELAY_MS, options.backoffMs * 2 ** retry) * jitter();
|
|
27
27
|
options.onRetry?.(error, retry + 1, Math.round(delayMs));
|
|
28
28
|
await sleep(delayMs);
|
|
@@ -37,7 +37,6 @@ async function sleepFor(ms) {
|
|
|
37
37
|
setTimeout(resolve, ms);
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
//#endregion
|
|
41
40
|
export { isRetryableConnectError, retryConnect };
|
|
42
41
|
|
|
43
42
|
//# sourceMappingURL=connect-retry.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect-retry.mjs","names":[],"sources":["../../src/utils/connect-retry.ts"],"sourcesContent":["/** Retrying a connection to a remote browser service (ADR 0007, decision 4). */\n\n/** Options of {@link retryConnect}. */\nexport interface RetryConnectOptions {\n /** Retries after the first attempt. */\n retries: number;\n /** Delay before the first retry in ms; doubles each time, with jitter, capped at 10 s. */\n backoffMs: number;\n /** Called before each retry with the error, the retry's number (from 1) and its delay. */\n onRetry?: (error: unknown, retry: number, delayMs: number) => void;\n /** Injectable for tests. */\n sleep?: (ms: number) => Promise<void>;\n}\n\nconst MAX_DELAY_MS = 10_000;\n\n/** Errors that no retry fixes: a refused credential, a missing endpoint, mismatched versions. */\nconst PERMANENT =\n /\\b(?:401|403|404|428|unauthorized|forbidden|version mismatch|invalid (?:token|credentials)|not found)\\b/iu;\n\n/** Errors of the connection itself: refused, dropped, timed out, or a service with no free session. */\nconst CONNECTION =\n /(?:ECONNREFUSED|ECONNRESET|EPIPE|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|EHOSTUNREACH|socket hang up|websocket error|connection (?:closed|refused|reset)|timeout|timed out|capacity|too many|queue(?:d)? full|no (?:free )?(?:session|browser)|\\b(?:408|425|429|500|502|503|504)\\b)/iu;\n\n/** Whether a connect error is worth retrying: connection-level, not a configuration mistake. */\nexport function isRetryableConnectError(error: unknown): boolean {\n const text = error instanceof Error ? error.message : String(error);\n return !PERMANENT.test(text) && CONNECTION.test(text);\n}\n\n/**\n * Run `connect`, retrying a connection-level failure with exponential backoff, so a provider\n * outage or a full plan is absorbed here and crash isolation only ever sees a browser that died\n * while rendering. The last error is thrown once the retries are spent.\n */\nexport async function retryConnect<T>(\n connect: () => Promise<T>,\n options: RetryConnectOptions,\n): Promise<T> {\n const sleep = options.sleep ?? sleepFor;\n for (let retry = 0; ; retry += 1) {\n try {\n // oxlint-disable-next-line eslint/no-await-in-loop -- attempts are sequential by design\n return await connect();\n } catch (error) {\n if (retry >= options.retries || !isRetryableConnectError(error)) {\n throw error;\n }\n const delayMs = Math.min(MAX_DELAY_MS, options.backoffMs * 2 ** retry) * jitter();\n options.onRetry?.(error, retry + 1, Math.round(delayMs));\n // oxlint-disable-next-line eslint/no-await-in-loop -- backoff between sequential attempts\n await sleep(delayMs);\n }\n }\n}\n\n/** 0.75 to 1.25: providers refusing for capacity should not see every shard retry in step. */\nfunction jitter(): number {\n return 0.75 + Math.random() * 0.5;\n}\n\nasync function sleepFor(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"connect-retry.mjs","names":[],"sources":["../../src/utils/connect-retry.ts"],"sourcesContent":["/** Retrying a connection to a remote browser service (ADR 0007, decision 4). */\n\n/** Options of {@link retryConnect}. */\nexport interface RetryConnectOptions {\n /** Retries after the first attempt. */\n retries: number;\n /** Delay before the first retry in ms; doubles each time, with jitter, capped at 10 s. */\n backoffMs: number;\n /** Whether an error is worth another attempt; defaults to {@link isRetryableConnectError}. */\n retryable?: (error: unknown) => boolean;\n /** Called before each retry with the error, the retry's number (from 1) and its delay. */\n onRetry?: (error: unknown, retry: number, delayMs: number) => void;\n /** Injectable for tests. */\n sleep?: (ms: number) => Promise<void>;\n}\n\nconst MAX_DELAY_MS = 10_000;\n\n/** Errors that no retry fixes: a refused credential, a missing endpoint, mismatched versions. */\nconst PERMANENT =\n /\\b(?:401|403|404|428|unauthorized|forbidden|version mismatch|invalid (?:token|credentials)|not found)\\b/iu;\n\n/** Errors of the connection itself: refused, dropped, timed out, or a service with no free session. */\nconst CONNECTION =\n /(?:ECONNREFUSED|ECONNRESET|EPIPE|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|EHOSTUNREACH|socket hang up|websocket error|connection (?:closed|refused|reset)|timeout|timed out|capacity|too many|queue(?:d)? full|no (?:free )?(?:session|browser)|\\b(?:408|425|429|500|502|503|504)\\b)/iu;\n\n/** Whether a connect error is worth retrying: connection-level, not a configuration mistake. */\nexport function isRetryableConnectError(error: unknown): boolean {\n const text = error instanceof Error ? error.message : String(error);\n return !PERMANENT.test(text) && CONNECTION.test(text);\n}\n\n/**\n * Run `connect`, retrying a connection-level failure with exponential backoff, so a provider\n * outage or a full plan is absorbed here and crash isolation only ever sees a browser that died\n * while rendering. The last error is thrown once the retries are spent.\n */\nexport async function retryConnect<T>(\n connect: () => Promise<T>,\n options: RetryConnectOptions,\n): Promise<T> {\n const sleep = options.sleep ?? sleepFor;\n for (let retry = 0; ; retry += 1) {\n try {\n // oxlint-disable-next-line eslint/no-await-in-loop -- attempts are sequential by design\n return await connect();\n } catch (error) {\n if (retry >= options.retries || !(options.retryable ?? isRetryableConnectError)(error)) {\n throw error;\n }\n const delayMs = Math.min(MAX_DELAY_MS, options.backoffMs * 2 ** retry) * jitter();\n options.onRetry?.(error, retry + 1, Math.round(delayMs));\n // oxlint-disable-next-line eslint/no-await-in-loop -- backoff between sequential attempts\n await sleep(delayMs);\n }\n }\n}\n\n/** 0.75 to 1.25: providers refusing for capacity should not see every shard retry in step. */\nfunction jitter(): number {\n return 0.75 + Math.random() * 0.5;\n}\n\nasync function sleepFor(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"],"mappings":";;;;AAgBA,MAAM,eAAe;;AAGrB,MAAM,YACJ;;AAGF,MAAM,aACJ;;AAGF,SAAgB,wBAAwB,OAAyB;CAC/D,MAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CAClE,OAAO,CAAC,UAAU,KAAK,IAAI,KAAK,WAAW,KAAK,IAAI;AACtD;;;;;;AAOA,eAAsB,aACpB,SACA,SACY;CACZ,MAAM,QAAQ,QAAQ,SAAS;CAC/B,KAAK,IAAI,QAAQ,IAAK,SAAS,GAC7B,IAAI;EAEF,OAAO,MAAM,QAAQ;CACvB,SAAS,OAAO;EACd,IAAI,SAAS,QAAQ,WAAW,EAAE,QAAQ,aAAa,wBAAA,CAAyB,KAAK,GACnF,MAAM;EAER,MAAM,UAAU,KAAK,IAAI,cAAc,QAAQ,YAAY,KAAK,KAAK,IAAI,OAAO;EAChF,QAAQ,UAAU,OAAO,QAAQ,GAAG,KAAK,MAAM,OAAO,CAAC;EAEvD,MAAM,MAAM,OAAO;CACrB;AAEJ;;AAGA,SAAS,SAAiB;CACxB,OAAO,MAAO,KAAK,OAAO,IAAI;AAChC;AAEA,eAAe,SAAS,IAA2B;CACjD,MAAM,IAAI,SAAe,YAAY;EACnC,WAAW,SAAS,EAAE;CACxB,CAAC;AACH"}
|
package/dist/utils/encrypt.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
//#region src/utils/encrypt.d.ts
|
|
4
3
|
/** Current server secret plus the one it replaced, kept only to decrypt older rows. */
|
|
5
4
|
interface SecretKeys {
|
|
6
5
|
current: string;
|
|
@@ -43,6 +42,5 @@ declare function decryptWithKey(input: SecretInput, ciphertext: string): {
|
|
|
43
42
|
* rotation hint. A missing secret keeps its own configuration error.
|
|
44
43
|
*/
|
|
45
44
|
declare function decryptCredential(input: SecretInput, ciphertext: string): string;
|
|
46
|
-
//#endregion
|
|
47
45
|
export { KeyUsed, SecretInput, SecretKeys, UndecryptableCredentialError, decrypt, decryptCredential, decryptWithKey, encrypt };
|
|
48
46
|
//# sourceMappingURL=encrypt.d.mts.map
|
package/dist/utils/encrypt.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:crypto";
|
|
5
|
-
|
|
5
|
+
// src/utils/encrypt.ts
|
|
6
6
|
/** Thrown when a stored credential cannot be decrypted with any configured key. */
|
|
7
7
|
var UndecryptableCredentialError = class extends Error {
|
|
8
8
|
constructor(cause) {
|
|
@@ -97,7 +97,6 @@ function decryptWith(secret, ciphertext) {
|
|
|
97
97
|
function deriveKey(secret) {
|
|
98
98
|
return createHash("sha256").update(secret).digest();
|
|
99
99
|
}
|
|
100
|
-
//#endregion
|
|
101
100
|
export { UndecryptableCredentialError, decrypt, decryptCredential, decryptWithKey, encrypt };
|
|
102
101
|
|
|
103
102
|
//# sourceMappingURL=encrypt.mjs.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
import { CaptureEnvironment } from "../adapter/capture-runner.mjs";
|
|
4
|
-
//#region src/utils/environment.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Digest of the installed system font families (`fc-list`), or undefined where fontconfig is not
|
|
7
6
|
* available. Cached for the process (fonts do not change under a running server), except a failed
|
|
@@ -14,6 +13,5 @@ declare function systemFontsHash(): Promise<string | undefined>;
|
|
|
14
13
|
* font digest. Runners call this once per render with the version their driver reports.
|
|
15
14
|
*/
|
|
16
15
|
declare function detectCaptureEnvironment(browserVersion?: string, deviceScaleFactor?: number): Promise<CaptureEnvironment>;
|
|
17
|
-
//#endregion
|
|
18
16
|
export { detectCaptureEnvironment, systemFontsHash };
|
|
19
17
|
//# sourceMappingURL=environment.d.mts.map
|
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { sha256 } from "./hash.mjs";
|
|
5
|
-
|
|
5
|
+
// src/utils/environment.ts
|
|
6
6
|
let fonts;
|
|
7
7
|
/**
|
|
8
8
|
* Digest of the installed system font families (`fc-list`), or undefined where fontconfig is not
|
|
@@ -53,7 +53,6 @@ function digestOf(stdout) {
|
|
|
53
53
|
const families = [...new Set(stdout.split("\n").map((line) => line.trim()))].filter(Boolean);
|
|
54
54
|
return families.length > 0 ? sha256(families.toSorted().join("\n")).slice(0, 16) : void 0;
|
|
55
55
|
}
|
|
56
|
-
//#endregion
|
|
57
56
|
export { detectCaptureEnvironment, systemFontsHash };
|
|
58
57
|
|
|
59
58
|
//# sourceMappingURL=environment.mjs.map
|
package/dist/utils/hash.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
//#region src/utils/hash.d.ts
|
|
4
3
|
/** Hash a value with SHA-256, returning lowercase hex. */
|
|
5
4
|
declare function sha256(value: string): string;
|
|
6
5
|
/** Sign a value with HMAC-SHA-256, returning lowercase hex. */
|
|
@@ -12,6 +11,5 @@ declare function randomToken(prefix: string): {
|
|
|
12
11
|
};
|
|
13
12
|
/** Compare two strings in constant time to avoid timing leaks. */
|
|
14
13
|
declare function timingSafeEqualString(a: string, b: string): boolean;
|
|
15
|
-
//#endregion
|
|
16
14
|
export { hmacSha256, randomToken, sha256, timingSafeEqualString };
|
|
17
15
|
//# sourceMappingURL=hash.d.mts.map
|
package/dist/utils/hash.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { createHash, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
5
|
-
|
|
5
|
+
// src/utils/hash.ts
|
|
6
6
|
/** Hash a value with SHA-256, returning lowercase hex. */
|
|
7
7
|
function sha256(value) {
|
|
8
8
|
return createHash("sha256").update(value).digest("hex");
|
|
@@ -25,7 +25,6 @@ function timingSafeEqualString(a, b) {
|
|
|
25
25
|
const bb = Buffer.from(b);
|
|
26
26
|
return ab.length === bb.length && timingSafeEqual(ab, bb);
|
|
27
27
|
}
|
|
28
|
-
//#endregion
|
|
29
28
|
export { hmacSha256, randomToken, sha256, timingSafeEqualString };
|
|
30
29
|
|
|
31
30
|
//# sourceMappingURL=hash.mjs.map
|
package/dist/utils/http.d.mts
CHANGED
|
@@ -2,7 +2,6 @@ import __tsdown_shims_path from 'node:path';
|
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
import { Logger } from "../logger.mjs";
|
|
4
4
|
import { Buffer } from "node:buffer";
|
|
5
|
-
//#region src/utils/http.d.ts
|
|
6
5
|
/**
|
|
7
6
|
* Fetch JSON with timeout, retries, and structured errors.
|
|
8
7
|
*
|
|
@@ -32,6 +31,18 @@ declare function httpBytes(url: string, options?: HttpRequestOptions): Promise<B
|
|
|
32
31
|
* @returns The raw response body text.
|
|
33
32
|
*/
|
|
34
33
|
declare function httpText(url: string, options?: HttpTextOptions): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Send a request and resolve with the response status, without ever reading the response body (it
|
|
36
|
+
* is cancelled on every response). Use it when the answer is only "did it succeed", such as webhook
|
|
37
|
+
* delivery, so a receiver cannot make the process buffer an arbitrarily large body. Retries,
|
|
38
|
+
* timeouts, redaction and tracing are those of {@link httpText}. A non-2xx response throws
|
|
39
|
+
* {@link HttpError} with an empty `body`.
|
|
40
|
+
*
|
|
41
|
+
* @param url - Absolute request URL.
|
|
42
|
+
* @param options - Method, headers, JSON body, timeout, retries, logger.
|
|
43
|
+
* @returns The 2xx response status.
|
|
44
|
+
*/
|
|
45
|
+
declare function httpStatus(url: string, options?: HttpTextOptions): Promise<number>;
|
|
35
46
|
/** Failed HTTP response: status code plus a snippet of the response body. */
|
|
36
47
|
declare class HttpError extends Error {
|
|
37
48
|
readonly status: number;
|
|
@@ -69,6 +80,5 @@ interface HttpTextOptions {
|
|
|
69
80
|
signal?: AbortSignal;
|
|
70
81
|
logger?: Logger;
|
|
71
82
|
}
|
|
72
|
-
|
|
73
|
-
export { HttpError, HttpRequestOptions, HttpTextOptions, httpBytes, httpJson, httpText };
|
|
83
|
+
export { HttpError, HttpRequestOptions, HttpTextOptions, httpBytes, httpJson, httpStatus, httpText };
|
|
74
84
|
//# sourceMappingURL=http.d.mts.map
|
package/dist/utils/http.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
import { injectTraceContext, withSpan } from "../tracing.mjs";
|
|
4
|
+
import { injectTraceContext, setSpanMessage, spanException, withSpan } from "../tracing.mjs";
|
|
5
5
|
import { Buffer } from "node:buffer";
|
|
6
|
-
|
|
6
|
+
// src/utils/http.ts
|
|
7
7
|
/**
|
|
8
8
|
* Fetch JSON with timeout, retries, and structured errors.
|
|
9
9
|
*
|
|
@@ -39,6 +39,20 @@ async function httpBytes(url, options = {}) {
|
|
|
39
39
|
async function httpText(url, options = {}) {
|
|
40
40
|
return await requestWithRetry(url, options, options.retries ?? DEFAULT_RETRIES, options.timeoutMs ?? DEFAULT_TIMEOUT_MS, doFetchText);
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Send a request and resolve with the response status, without ever reading the response body (it
|
|
44
|
+
* is cancelled on every response). Use it when the answer is only "did it succeed", such as webhook
|
|
45
|
+
* delivery, so a receiver cannot make the process buffer an arbitrarily large body. Retries,
|
|
46
|
+
* timeouts, redaction and tracing are those of {@link httpText}. A non-2xx response throws
|
|
47
|
+
* {@link HttpError} with an empty `body`.
|
|
48
|
+
*
|
|
49
|
+
* @param url - Absolute request URL.
|
|
50
|
+
* @param options - Method, headers, JSON body, timeout, retries, logger.
|
|
51
|
+
* @returns The 2xx response status.
|
|
52
|
+
*/
|
|
53
|
+
async function httpStatus(url, options = {}) {
|
|
54
|
+
return await requestWithRetry(url, options, options.retries ?? DEFAULT_RETRIES, options.timeoutMs ?? DEFAULT_TIMEOUT_MS, doFetchStatus);
|
|
55
|
+
}
|
|
42
56
|
/** Failed HTTP response: status code plus a snippet of the response body. */
|
|
43
57
|
var HttpError = class extends Error {
|
|
44
58
|
status;
|
|
@@ -91,25 +105,54 @@ async function requestWithRetry(url, options, maxAttempts, timeoutMs, perform) {
|
|
|
91
105
|
for (let attempt = 1;; attempt += 1) try {
|
|
92
106
|
return await perform(url, options, timeoutMs);
|
|
93
107
|
} catch (error) {
|
|
94
|
-
span
|
|
108
|
+
describeFailure(span, error, url);
|
|
95
109
|
if (options.signal?.aborted || !shouldRetry(error, attempt, maxAttempts)) throw error;
|
|
110
|
+
span.recordException(spanException(error));
|
|
96
111
|
span.setAttribute("http.retry.count", attempt);
|
|
97
112
|
await backoff(error, attempt, url, options.logger);
|
|
98
113
|
}
|
|
99
114
|
}, {
|
|
100
115
|
"http.request.method": options.method ?? "GET",
|
|
101
|
-
"url.full":
|
|
116
|
+
"url.full": redactUrlForLog(url)
|
|
102
117
|
});
|
|
103
118
|
}
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
119
|
+
/**
|
|
120
|
+
* The form of a request URL that may appear in logs and span attributes: its origin
|
|
121
|
+
* (`protocol//host`) and nothing else. The path of an incoming webhook (Slack, Teams) is the secret,
|
|
122
|
+
* a bot token can be the first segment (Telegram), and other URLs carry credentials in the userinfo
|
|
123
|
+
* or the query, so the path, query, fragment and userinfo are dropped by construction. There is no
|
|
124
|
+
* opt-out.
|
|
125
|
+
*/
|
|
126
|
+
function redactUrlForLog(url) {
|
|
127
|
+
try {
|
|
128
|
+
const { protocol, host } = new URL(url);
|
|
129
|
+
return `${protocol}//${host}`;
|
|
130
|
+
} catch {
|
|
131
|
+
return "[invalid url]";
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* What a span may say about a failed request. An HTTP failure carries its status and never the
|
|
136
|
+
* response body, which can echo the request URL in any encoding. Any other failure keeps its
|
|
137
|
+
* message with the request URL replaced by its origin, because native `fetch` repeats the whole
|
|
138
|
+
* URL, userinfo included, when it refuses one. The error a caller catches is not changed.
|
|
139
|
+
*/
|
|
140
|
+
function describeFailure(span, error, url) {
|
|
141
|
+
if (error instanceof HttpError) {
|
|
142
|
+
span.setAttribute("http.response.status_code", error.status);
|
|
143
|
+
setSpanMessage(error, `HTTP ${String(error.status)}`);
|
|
144
|
+
} else if (error instanceof Error) setSpanMessage(error, scrubUrl(error.message, url));
|
|
145
|
+
}
|
|
146
|
+
/** `text` with the request URL, as given and as normalized, replaced by its origin. */
|
|
147
|
+
function scrubUrl(text, url) {
|
|
148
|
+
const origin = redactUrlForLog(url);
|
|
149
|
+
const normalized = URL.canParse(url) ? new URL(url).href : url;
|
|
150
|
+
return text.replaceAll(url, origin).replaceAll(normalized, origin);
|
|
108
151
|
}
|
|
109
152
|
async function backoff(error, attempt, url, logger) {
|
|
110
153
|
const delay = retryDelayMs(error, attempt);
|
|
111
154
|
logger?.warn({
|
|
112
|
-
url,
|
|
155
|
+
url: redactUrlForLog(url),
|
|
113
156
|
attempt,
|
|
114
157
|
delayMs: delay
|
|
115
158
|
}, "http request failed, retrying");
|
|
@@ -137,15 +180,20 @@ async function doFetchJson(url, options, timeoutMs) {
|
|
|
137
180
|
async function doFetchText(url, options, timeoutMs) {
|
|
138
181
|
return await (await doFetchResponse(url, options, timeoutMs)).text();
|
|
139
182
|
}
|
|
183
|
+
async function doFetchStatus(url, options, timeoutMs) {
|
|
184
|
+
const response = await doFetchResponse(url, options, timeoutMs, false);
|
|
185
|
+
await discardBody(response);
|
|
186
|
+
return response.status;
|
|
187
|
+
}
|
|
140
188
|
async function doFetchBytes(url, options, timeoutMs) {
|
|
141
189
|
const response = await doFetchResponse(url, options, timeoutMs);
|
|
142
190
|
return Buffer.from(await response.arrayBuffer());
|
|
143
191
|
}
|
|
144
|
-
async function doFetchResponse(url, options, timeoutMs) {
|
|
192
|
+
async function doFetchResponse(url, options, timeoutMs, readErrorBody = true) {
|
|
145
193
|
const request = buildRequest(options);
|
|
146
194
|
injectTraceContext(request.headers);
|
|
147
195
|
options.logger?.debug({
|
|
148
|
-
url,
|
|
196
|
+
url: redactUrlForLog(url),
|
|
149
197
|
method: request.method
|
|
150
198
|
}, "http request");
|
|
151
199
|
const response = await fetch(url, {
|
|
@@ -154,13 +202,27 @@ async function doFetchResponse(url, options, timeoutMs) {
|
|
|
154
202
|
body: request.body,
|
|
155
203
|
signal: options.signal ? AbortSignal.any([options.signal, AbortSignal.timeout(timeoutMs)]) : AbortSignal.timeout(timeoutMs)
|
|
156
204
|
});
|
|
157
|
-
if (!response.ok)
|
|
158
|
-
const text = await response.text();
|
|
159
|
-
throw new HttpError(response.status, text.slice(0, MAX_BODY_SNIPPET), response.headers);
|
|
160
|
-
}
|
|
205
|
+
if (!response.ok) throw await failureOf(response, readErrorBody);
|
|
161
206
|
return response;
|
|
162
207
|
}
|
|
163
|
-
|
|
164
|
-
|
|
208
|
+
/**
|
|
209
|
+
* Cancel an unread body. Cleanup only: a rejected cancel must never replace the request's outcome,
|
|
210
|
+
* or a delivered request would look failed and be retried.
|
|
211
|
+
*/
|
|
212
|
+
async function discardBody(response) {
|
|
213
|
+
try {
|
|
214
|
+
await response.body?.cancel();
|
|
215
|
+
} catch {}
|
|
216
|
+
}
|
|
217
|
+
/** The {@link HttpError} for a non-2xx response; the body is read (and capped) only on request. */
|
|
218
|
+
async function failureOf(response, readBody) {
|
|
219
|
+
if (!readBody) {
|
|
220
|
+
await discardBody(response);
|
|
221
|
+
return new HttpError(response.status, "", response.headers);
|
|
222
|
+
}
|
|
223
|
+
const text = await response.text();
|
|
224
|
+
return new HttpError(response.status, text.slice(0, MAX_BODY_SNIPPET), response.headers);
|
|
225
|
+
}
|
|
226
|
+
export { HttpError, httpBytes, httpJson, httpStatus, httpText, redactUrlForLog };
|
|
165
227
|
|
|
166
228
|
//# sourceMappingURL=http.mjs.map
|