@storyshelf/core 0.6.2 → 0.7.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/README.md +49 -32
- package/dist/adapter/capture-queue.d.mts +44 -2
- package/dist/adapter/capture-runner.d.mts +127 -10
- package/dist/adapter/capture-runner.mjs +5 -12
- package/dist/adapter/database.d.mts +27 -8
- package/dist/adapter/database.mjs.map +1 -1
- package/dist/adapter/design.d.mts +85 -0
- package/dist/adapter/design.mjs +28 -0
- package/dist/adapter/design.mjs.map +1 -0
- package/dist/adapter/metadata.d.mts +3 -10
- package/dist/adapter/notifier.d.mts +6 -3
- package/dist/adapter/notifier.mjs +5 -1
- package/dist/adapter/oauth.d.mts +52 -0
- package/dist/adapter/setup.d.mts +4 -5
- package/dist/adapter/setup.mjs +2 -1
- package/dist/adapter/setup.mjs.map +1 -1
- package/dist/adapter/webhook-events.mjs +1 -1
- package/dist/adapters/capture-target-offers.d.mts +28 -0
- package/dist/adapters/capture-target-offers.mjs +58 -0
- package/dist/adapters/capture-target-offers.mjs.map +1 -0
- package/dist/adapters/capture-target.d.mts +71 -0
- package/dist/adapters/capture-target.mjs +76 -0
- package/dist/adapters/capture-target.mjs.map +1 -0
- package/dist/adapters/notifier/build-comment.d.mts +24 -0
- package/dist/adapters/notifier/build-comment.mjs +24 -0
- package/dist/adapters/notifier/build-comment.mjs.map +1 -0
- package/dist/adapters/notifier/build-state.d.mts +99 -0
- package/dist/adapters/notifier/build-state.mjs +218 -0
- package/dist/adapters/notifier/build-state.mjs.map +1 -0
- package/dist/adapters/notifier/events.d.mts +4 -2
- package/dist/adapters/notifier/events.mjs +31 -18
- package/dist/adapters/notifier/events.mjs.map +1 -1
- package/dist/adapters/notifier/provider.d.mts +53 -7
- package/dist/adapters/notifier/provider.mjs +12 -0
- package/dist/adapters/notifier/provider.mjs.map +1 -0
- package/dist/adapters/notifier/state.d.mts +24 -0
- package/dist/adapters/notifier/state.mjs +66 -0
- package/dist/adapters/notifier/state.mjs.map +1 -0
- package/dist/adapters/notifier/types.d.mts +51 -2
- package/dist/adapters/remote-browser.d.mts +87 -0
- package/dist/adapters/remote-browser.mjs +103 -0
- package/dist/adapters/remote-browser.mjs.map +1 -0
- package/dist/adapters/render-runs.d.mts +25 -0
- package/dist/adapters/render-runs.mjs +41 -0
- package/dist/adapters/render-runs.mjs.map +1 -0
- package/dist/adapters/setup-runner.mjs +2 -4
- package/dist/adapters/setup-runner.mjs.map +1 -1
- package/dist/adapters/sources.d.mts +12 -0
- package/dist/adapters/sources.mjs +20 -0
- package/dist/adapters/sources.mjs.map +1 -0
- package/dist/adapters/validate.mjs +25 -18
- package/dist/adapters/validate.mjs.map +1 -1
- package/dist/ai.d.mts +105 -0
- package/dist/ai.mjs +19 -0
- package/dist/ai.mjs.map +1 -0
- package/dist/capture/a11y/axe-source.d.mts +18 -0
- package/dist/capture/a11y/axe-source.mjs +37 -0
- package/dist/capture/a11y/axe-source.mjs.map +1 -0
- package/dist/capture/a11y/in-page.d.mts +27 -0
- package/dist/capture/a11y/in-page.mjs +60 -0
- package/dist/capture/a11y/in-page.mjs.map +1 -0
- package/dist/capture/a11y/map.d.mts +24 -0
- package/dist/capture/a11y/map.mjs +48 -0
- package/dist/capture/a11y/map.mjs.map +1 -0
- package/dist/capture/a11y/options.d.mts +23 -0
- package/dist/capture/a11y/options.mjs +75 -0
- package/dist/capture/a11y/options.mjs.map +1 -0
- package/dist/capture/adapter.d.mts +41 -3
- package/dist/capture/adapter.mjs.map +1 -1
- package/dist/capture/affected.d.mts +2 -0
- package/dist/capture/affected.mjs +13 -4
- package/dist/capture/affected.mjs.map +1 -1
- package/dist/capture/attempt-logger.mjs +84 -0
- package/dist/capture/attempt-logger.mjs.map +1 -0
- package/dist/capture/browsers.d.mts +35 -0
- package/dist/capture/browsers.mjs +67 -0
- package/dist/capture/browsers.mjs.map +1 -0
- package/dist/capture/build-state/deliver.d.mts +32 -0
- package/dist/capture/build-state/deliver.mjs +118 -0
- package/dist/capture/build-state/deliver.mjs.map +1 -0
- package/dist/capture/build-state/index.d.mts +8 -0
- package/dist/capture/build-state/notify-job.d.mts +56 -0
- package/dist/capture/build-state/notify-job.mjs +133 -0
- package/dist/capture/build-state/notify-job.mjs.map +1 -0
- package/dist/capture/build-state/publisher.d.mts +23 -0
- package/dist/capture/build-state/publisher.mjs +107 -0
- package/dist/capture/build-state/publisher.mjs.map +1 -0
- package/dist/capture/build-state/resume.d.mts +9 -0
- package/dist/capture/build-state/resume.mjs +47 -0
- package/dist/capture/build-state/resume.mjs.map +1 -0
- package/dist/capture/build-state/types.d.mts +49 -0
- package/dist/capture/catalog/catalogue.d.mts +22 -0
- package/dist/capture/catalog/catalogue.mjs +53 -0
- package/dist/capture/catalog/catalogue.mjs.map +1 -0
- package/dist/capture/catalog/components.d.mts +23 -0
- package/dist/capture/catalog/components.mjs +55 -0
- package/dist/capture/catalog/components.mjs.map +1 -0
- package/dist/capture/catalog/history.d.mts +30 -0
- package/dist/capture/catalog/history.mjs +51 -0
- package/dist/capture/catalog/history.mjs.map +1 -0
- package/dist/capture/catalog/hook.d.mts +14 -0
- package/dist/capture/catalog/hook.mjs +19 -0
- package/dist/capture/catalog/hook.mjs.map +1 -0
- package/dist/capture/catalog/index.d.mts +11 -0
- package/dist/capture/catalog/load.d.mts +26 -0
- package/dist/capture/catalog/load.mjs +49 -0
- package/dist/capture/catalog/load.mjs.map +1 -0
- package/dist/capture/catalog/parse.d.mts +15 -0
- package/dist/capture/catalog/parse.mjs +56 -0
- package/dist/capture/catalog/parse.mjs.map +1 -0
- package/dist/capture/catalog/read.d.mts +12 -0
- package/dist/capture/catalog/read.mjs +33 -0
- package/dist/capture/catalog/read.mjs.map +1 -0
- package/dist/capture/catalog/types.d.mts +33 -0
- package/dist/capture/consumer/capture-handler.d.mts +58 -0
- package/dist/capture/consumer/capture-handler.mjs +118 -0
- package/dist/capture/consumer/capture-handler.mjs.map +1 -0
- package/dist/capture/consumer/idle.d.mts +17 -0
- package/dist/capture/consumer/idle.mjs +25 -0
- package/dist/capture/consumer/idle.mjs.map +1 -0
- package/dist/capture/consumer/index.d.mts +13 -0
- package/dist/capture/consumer/index.mjs +139 -0
- package/dist/capture/consumer/index.mjs.map +1 -0
- package/dist/capture/consumer/loop.mjs +110 -0
- package/dist/capture/consumer/loop.mjs.map +1 -0
- package/dist/capture/consumer/metrics.d.mts +41 -0
- package/dist/capture/consumer/metrics.mjs +38 -0
- package/dist/capture/consumer/metrics.mjs.map +1 -0
- package/dist/capture/consumer/retry.d.mts +33 -0
- package/dist/capture/consumer/retry.mjs +34 -0
- package/dist/capture/consumer/retry.mjs.map +1 -0
- package/dist/capture/consumer/run-job.mjs +195 -0
- package/dist/capture/consumer/run-job.mjs.map +1 -0
- package/dist/capture/consumer/startup.mjs +38 -0
- package/dist/capture/consumer/startup.mjs.map +1 -0
- package/dist/capture/consumer/types.d.mts +97 -0
- package/dist/capture/crash-failure.d.mts +25 -0
- package/dist/capture/crash-failure.mjs +70 -0
- package/dist/capture/crash-failure.mjs.map +1 -0
- package/dist/capture/db-queue/cadence.d.mts +32 -0
- package/dist/capture/db-queue/cadence.mjs +38 -0
- package/dist/capture/db-queue/cadence.mjs.map +1 -0
- package/dist/capture/db-queue/claim.d.mts +9 -0
- package/dist/capture/db-queue/claim.mjs +132 -0
- package/dist/capture/db-queue/claim.mjs.map +1 -0
- package/dist/capture/db-queue/clock.mjs +12 -0
- package/dist/capture/db-queue/clock.mjs.map +1 -0
- package/dist/capture/db-queue/codec.mjs +76 -0
- package/dist/capture/db-queue/codec.mjs.map +1 -0
- package/dist/capture/db-queue/index.d.mts +20 -0
- package/dist/capture/db-queue/index.mjs +89 -0
- package/dist/capture/db-queue/index.mjs.map +1 -0
- package/dist/capture/db-queue/keeper.d.mts +36 -0
- package/dist/capture/db-queue/keeper.mjs +92 -0
- package/dist/capture/db-queue/keeper.mjs.map +1 -0
- package/dist/capture/db-queue/lease.mjs +46 -0
- package/dist/capture/db-queue/lease.mjs.map +1 -0
- package/dist/capture/db-queue/lifecycle.mjs +36 -0
- package/dist/capture/db-queue/lifecycle.mjs.map +1 -0
- package/dist/capture/db-queue/operations.mjs +94 -0
- package/dist/capture/db-queue/operations.mjs.map +1 -0
- package/dist/capture/db-queue/poll-loop.d.mts +30 -0
- package/dist/capture/db-queue/poll-loop.mjs +89 -0
- package/dist/capture/db-queue/poll-loop.mjs.map +1 -0
- package/dist/capture/db-queue/poll.d.mts +10 -0
- package/dist/capture/db-queue/poll.mjs +69 -0
- package/dist/capture/db-queue/poll.mjs.map +1 -0
- package/dist/capture/db-queue/timers.d.mts +12 -0
- package/dist/capture/db-queue/timers.mjs +37 -0
- package/dist/capture/db-queue/timers.mjs.map +1 -0
- package/dist/capture/db-queue/types.d.mts +83 -0
- package/dist/capture/db-queue/types.mjs +12 -0
- package/dist/capture/db-queue/types.mjs.map +1 -0
- package/dist/capture/db-queue/wake.mjs +48 -0
- package/dist/capture/db-queue/wake.mjs.map +1 -0
- package/dist/capture/design.mjs +39 -0
- package/dist/capture/design.mjs.map +1 -0
- package/dist/capture/diff-record.mjs +23 -3
- package/dist/capture/diff-record.mjs.map +1 -1
- package/dist/capture/dispatch.d.mts +12 -7
- package/dist/capture/dispatch.mjs +86 -107
- package/dist/capture/dispatch.mjs.map +1 -1
- package/dist/capture/enrich.mjs +60 -0
- package/dist/capture/enrich.mjs.map +1 -0
- package/dist/capture/failure-sets.mjs +22 -0
- package/dist/capture/failure-sets.mjs.map +1 -0
- package/dist/capture/fingerprint.d.mts +42 -0
- package/dist/capture/fingerprint.mjs +83 -0
- package/dist/capture/fingerprint.mjs.map +1 -0
- package/dist/capture/forked/channel.d.mts +25 -0
- package/dist/capture/forked/child.d.mts +34 -0
- package/dist/capture/forked/child.mjs +202 -0
- package/dist/capture/forked/child.mjs.map +1 -0
- package/dist/capture/forked/crash-tracker.mjs +23 -0
- package/dist/capture/forked/crash-tracker.mjs.map +1 -0
- package/dist/capture/forked/decision.d.mts +26 -0
- package/dist/capture/forked/decision.mjs +27 -0
- package/dist/capture/forked/decision.mjs.map +1 -0
- package/dist/capture/forked/exit.mjs +12 -0
- package/dist/capture/forked/exit.mjs.map +1 -0
- package/dist/capture/forked/fork.d.mts +31 -0
- package/dist/capture/forked/fork.mjs +93 -0
- package/dist/capture/forked/fork.mjs.map +1 -0
- package/dist/capture/forked/forked-capture.d.mts +40 -0
- package/dist/capture/forked/forked-capture.mjs +240 -0
- package/dist/capture/forked/forked-capture.mjs.map +1 -0
- package/dist/capture/forked/lease-book.mjs +46 -0
- package/dist/capture/forked/lease-book.mjs.map +1 -0
- package/dist/capture/forked/protocol.d.mts +38 -0
- package/dist/capture/forked/protocol.mjs +25 -0
- package/dist/capture/forked/protocol.mjs.map +1 -0
- package/dist/capture/forked/runs.mjs +75 -0
- package/dist/capture/forked/runs.mjs.map +1 -0
- package/dist/capture/isolate.mjs +141 -0
- package/dist/capture/isolate.mjs.map +1 -0
- package/dist/capture/job-lease.d.mts +28 -0
- package/dist/capture/job-lease.mjs +57 -0
- package/dist/capture/job-lease.mjs.map +1 -0
- package/dist/capture/matrix.mjs +298 -0
- package/dist/capture/matrix.mjs.map +1 -0
- package/dist/capture/modes.d.mts +25 -0
- package/dist/capture/modes.mjs +107 -0
- package/dist/capture/modes.mjs.map +1 -0
- package/dist/capture/orchestrator.d.mts +37 -5
- package/dist/capture/orchestrator.mjs +118 -107
- package/dist/capture/orchestrator.mjs.map +1 -1
- package/dist/capture/pipeline.d.mts +9 -2
- package/dist/capture/pipeline.mjs +250 -45
- package/dist/capture/pipeline.mjs.map +1 -1
- package/dist/capture/progress.d.mts +11 -0
- package/dist/capture/progress.mjs +28 -0
- package/dist/capture/progress.mjs.map +1 -0
- package/dist/capture/publish/accept.d.mts +39 -0
- package/dist/capture/publish/accept.mjs +28 -0
- package/dist/capture/publish/accept.mjs.map +1 -0
- package/dist/capture/publish/complete.d.mts +46 -0
- package/dist/capture/publish/complete.mjs +64 -0
- package/dist/capture/publish/complete.mjs.map +1 -0
- package/dist/capture/publish/extract.d.mts +20 -0
- package/dist/capture/publish/extract.mjs +119 -0
- package/dist/capture/publish/extract.mjs.map +1 -0
- package/dist/capture/publish/handler.d.mts +28 -0
- package/dist/capture/publish/handler.mjs +62 -0
- package/dist/capture/publish/handler.mjs.map +1 -0
- package/dist/capture/publish/index.d.mts +10 -0
- package/dist/capture/publish/limits.d.mts +37 -0
- package/dist/capture/publish/limits.mjs +39 -0
- package/dist/capture/publish/limits.mjs.map +1 -0
- package/dist/capture/publish/published.d.mts +15 -0
- package/dist/capture/publish/published.mjs +18 -0
- package/dist/capture/publish/published.mjs.map +1 -0
- package/dist/capture/publish/run.d.mts +33 -0
- package/dist/capture/publish/run.mjs +30 -0
- package/dist/capture/publish/run.mjs.map +1 -0
- package/dist/capture/rediff.d.mts +1 -1
- package/dist/capture/rediff.mjs +4 -3
- package/dist/capture/rediff.mjs.map +1 -1
- package/dist/capture/render.mjs +53 -0
- package/dist/capture/render.mjs.map +1 -0
- package/dist/capture/scratch.d.mts +44 -0
- package/dist/capture/scratch.mjs +138 -0
- package/dist/capture/scratch.mjs.map +1 -0
- package/dist/capture/shard-plan.mjs +128 -0
- package/dist/capture/shard-plan.mjs.map +1 -0
- package/dist/capture/shards/context.mjs +51 -0
- package/dist/capture/shards/context.mjs.map +1 -0
- package/dist/capture/shards/execute.mjs +174 -0
- package/dist/capture/shards/execute.mjs.map +1 -0
- package/dist/capture/shards/fan-out.mjs +126 -0
- package/dist/capture/shards/fan-out.mjs.map +1 -0
- package/dist/capture/shards/history.mjs +35 -0
- package/dist/capture/shards/history.mjs.map +1 -0
- package/dist/capture/shards/reduce.mjs +97 -0
- package/dist/capture/shards/reduce.mjs.map +1 -0
- package/dist/capture/sizing.mjs +1 -11
- package/dist/capture/sizing.mjs.map +1 -1
- package/dist/capture/skip-checks.mjs +2 -65
- package/dist/capture/skip-checks.mjs.map +1 -1
- package/dist/capture/statics.d.mts +7 -8
- package/dist/capture/statics.mjs +25 -71
- package/dist/capture/statics.mjs.map +1 -1
- package/dist/capture/storybook-urls.d.mts +40 -0
- package/dist/capture/storybook-urls.mjs +41 -0
- package/dist/capture/storybook-urls.mjs.map +1 -0
- package/dist/capture/storybook.d.mts +12 -4
- package/dist/capture/storybook.mjs +56 -16
- package/dist/capture/storybook.mjs.map +1 -1
- package/dist/capture/target.mjs +21 -0
- package/dist/capture/target.mjs.map +1 -0
- package/dist/capture/targets.d.mts +25 -0
- package/dist/capture/targets.mjs +32 -0
- package/dist/capture/targets.mjs.map +1 -0
- package/dist/capture/tests.d.mts +37 -0
- package/dist/capture/tests.mjs +126 -0
- package/dist/capture/tests.mjs.map +1 -0
- package/dist/capture/token-chunks.mjs +74 -0
- package/dist/capture/token-chunks.mjs.map +1 -0
- package/dist/capture.d.mts +60 -7
- package/dist/capture.mjs +48 -3
- package/dist/config.d.mts +121 -12
- package/dist/config.mjs +9 -6
- package/dist/config.mjs.map +1 -1
- package/dist/diff.d.mts +9 -3
- package/dist/diff.mjs +16 -3
- package/dist/diff.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/insights/budget.d.mts +20 -0
- package/dist/insights/budget.mjs +33 -0
- package/dist/insights/budget.mjs.map +1 -0
- package/dist/insights/envelope.d.mts +59 -0
- package/dist/insights/envelope.mjs +60 -0
- package/dist/insights/envelope.mjs.map +1 -0
- package/dist/insights/evidence-health.d.mts +32 -0
- package/dist/insights/evidence-health.mjs +28 -0
- package/dist/insights/evidence-health.mjs.map +1 -0
- package/dist/insights/evidence.d.mts +55 -0
- package/dist/insights/evidence.mjs +64 -0
- package/dist/insights/evidence.mjs.map +1 -0
- package/dist/insights/hash.d.mts +18 -0
- package/dist/insights/hash.mjs +21 -0
- package/dist/insights/hash.mjs.map +1 -0
- package/dist/insights/limits.d.mts +24 -0
- package/dist/insights/limits.mjs +24 -0
- package/dist/insights/limits.mjs.map +1 -0
- package/dist/insights/prompts/v1.d.mts +13 -0
- package/dist/insights/prompts/v1.mjs +34 -0
- package/dist/insights/prompts/v1.mjs.map +1 -0
- package/dist/insights/redact.d.mts +9 -0
- package/dist/insights/redact.mjs +24 -0
- package/dist/insights/redact.mjs.map +1 -0
- package/dist/insights/text.mjs +44 -0
- package/dist/insights/text.mjs.map +1 -0
- package/dist/insights.d.mts +11 -0
- package/dist/insights.mjs +12 -0
- package/dist/logger.mjs +17 -1
- package/dist/logger.mjs.map +1 -1
- package/dist/models/ai-budget-alert.d.mts +23 -0
- package/dist/models/ai-budget-alert.mjs +38 -0
- package/dist/models/ai-budget-alert.mjs.map +1 -0
- package/dist/models/ai-usage.d.mts +40 -0
- package/dist/models/ai-usage.mjs +61 -0
- package/dist/models/ai-usage.mjs.map +1 -0
- package/dist/models/baseline-archive.d.mts +84 -0
- package/dist/models/baseline-archive.mjs +106 -0
- package/dist/models/baseline-archive.mjs.map +1 -0
- package/dist/models/baseline-export.d.mts +19 -0
- package/dist/models/baseline-export.mjs +136 -0
- package/dist/models/baseline-export.mjs.map +1 -0
- package/dist/models/baseline-import.mjs +118 -0
- package/dist/models/baseline-import.mjs.map +1 -0
- package/dist/models/baseline-transfer.d.mts +49 -0
- package/dist/models/baseline-transfer.mjs +121 -0
- package/dist/models/baseline-transfer.mjs.map +1 -0
- package/dist/models/baseline.d.mts +32 -5
- package/dist/models/baseline.mjs +65 -20
- package/dist/models/baseline.mjs.map +1 -1
- package/dist/models/build-component.d.mts +28 -0
- package/dist/models/build-component.mjs +55 -0
- package/dist/models/build-component.mjs.map +1 -0
- package/dist/models/build-review-status.d.mts +29 -0
- package/dist/models/build-review-status.mjs +37 -0
- package/dist/models/build-review-status.mjs.map +1 -0
- package/dist/models/build-review.d.mts +28 -0
- package/dist/models/build-review.mjs +54 -0
- package/dist/models/build-review.mjs.map +1 -0
- package/dist/models/build.d.mts +25 -3
- package/dist/models/build.mjs +50 -11
- package/dist/models/build.mjs.map +1 -1
- package/dist/models/capture-attempt.d.mts +7 -1
- package/dist/models/capture-attempt.mjs +29 -4
- package/dist/models/capture-attempt.mjs.map +1 -1
- package/dist/models/capture-job.d.mts +106 -0
- package/dist/models/capture-job.mjs +288 -0
- package/dist/models/capture-job.mjs.map +1 -0
- package/dist/models/capture-log.d.mts +1 -1
- package/dist/models/capture-log.mjs +4 -3
- package/dist/models/capture-log.mjs.map +1 -1
- package/dist/models/capture-shard.d.mts +62 -0
- package/dist/models/capture-shard.mjs +190 -0
- package/dist/models/capture-shard.mjs.map +1 -0
- package/dist/models/changeset.d.mts +48 -0
- package/dist/models/changeset.mjs +81 -0
- package/dist/models/changeset.mjs.map +1 -0
- package/dist/models/columns.mjs +19 -0
- package/dist/models/columns.mjs.map +1 -0
- package/dist/models/comment.d.mts +4 -1
- package/dist/models/comment.mjs +7 -4
- package/dist/models/comment.mjs.map +1 -1
- package/dist/models/component.d.mts +43 -0
- package/dist/models/component.mjs +60 -0
- package/dist/models/component.mjs.map +1 -0
- package/dist/models/connections.d.mts +41 -0
- package/dist/models/connections.mjs +112 -0
- package/dist/models/connections.mjs.map +1 -0
- package/dist/models/content-ref.d.mts +1 -1
- package/dist/models/content-ref.mjs +1 -1
- package/dist/models/content-ref.mjs.map +1 -1
- package/dist/models/credentials.mjs +12 -2
- package/dist/models/credentials.mjs.map +1 -1
- package/dist/models/design-credentials.d.mts +41 -0
- package/dist/models/design-credentials.mjs +86 -0
- package/dist/models/design-credentials.mjs.map +1 -0
- package/dist/models/design-health.d.mts +16 -0
- package/dist/models/design-health.mjs +25 -0
- package/dist/models/design-health.mjs.map +1 -0
- package/dist/models/design-nodes.d.mts +83 -0
- package/dist/models/design-nodes.mjs +222 -0
- package/dist/models/design-nodes.mjs.map +1 -0
- package/dist/models/design-renders.mjs +74 -0
- package/dist/models/design-renders.mjs.map +1 -0
- package/dist/models/design-resolve.d.mts +29 -0
- package/dist/models/design-resolve.mjs +41 -0
- package/dist/models/design-resolve.mjs.map +1 -0
- package/dist/models/design.d.mts +39 -0
- package/dist/models/design.mjs +90 -0
- package/dist/models/design.mjs.map +1 -0
- package/dist/models/inherited-ratio.d.mts +21 -0
- package/dist/models/inherited-ratio.mjs +22 -0
- package/dist/models/inherited-ratio.mjs.map +1 -0
- package/dist/models/insight.d.mts +70 -0
- package/dist/models/insight.mjs +162 -0
- package/dist/models/insight.mjs.map +1 -0
- package/dist/models/label.d.mts +4 -2
- package/dist/models/label.mjs +25 -10
- package/dist/models/label.mjs.map +1 -1
- package/dist/models/member.d.mts +1 -1
- package/dist/models/member.mjs +5 -4
- package/dist/models/member.mjs.map +1 -1
- package/dist/models/notification-channel.d.mts +37 -3
- package/dist/models/notification-channel.mjs +88 -9
- package/dist/models/notification-channel.mjs.map +1 -1
- package/dist/models/notification-subscription.d.mts +1 -2
- package/dist/models/notification-subscription.mjs +7 -9
- package/dist/models/notification-subscription.mjs.map +1 -1
- package/dist/models/project-group-mapping.d.mts +6 -1
- package/dist/models/project-group-mapping.mjs +14 -4
- package/dist/models/project-group-mapping.mjs.map +1 -1
- package/dist/models/project.d.mts +9 -1
- package/dist/models/project.mjs +9 -4
- package/dist/models/project.mjs.map +1 -1
- package/dist/models/public-origin.d.mts +63 -0
- package/dist/models/public-origin.mjs +114 -0
- package/dist/models/public-origin.mjs.map +1 -0
- package/dist/models/review-switch-off.d.mts +14 -0
- package/dist/models/review-switch-off.mjs +26 -0
- package/dist/models/review-switch-off.mjs.map +1 -0
- package/dist/models/site-settings.d.mts +23 -0
- package/dist/models/site-settings.mjs +48 -0
- package/dist/models/site-settings.mjs.map +1 -0
- package/dist/models/snapshot.d.mts +36 -1
- package/dist/models/snapshot.mjs +50 -3
- package/dist/models/snapshot.mjs.map +1 -1
- package/dist/models/token.d.mts +13 -1
- package/dist/models/token.mjs +23 -5
- package/dist/models/token.mjs.map +1 -1
- package/dist/models/usage.d.mts +76 -0
- package/dist/models/usage.mjs +149 -0
- package/dist/models/usage.mjs.map +1 -0
- package/dist/models/user.d.mts +1 -1
- package/dist/models/user.mjs +4 -3
- package/dist/models/user.mjs.map +1 -1
- package/dist/models/webhook.d.mts +15 -1
- package/dist/models/webhook.mjs +33 -4
- package/dist/models/webhook.mjs.map +1 -1
- package/dist/models.d.mts +26 -3
- package/dist/models.mjs +27 -5
- package/dist/options.d.mts +18 -0
- package/dist/options.mjs +90 -0
- package/dist/options.mjs.map +1 -0
- package/dist/paths.d.mts +19 -4
- package/dist/paths.mjs +51 -10
- package/dist/paths.mjs.map +1 -1
- package/dist/retention/ai.d.mts +18 -0
- package/dist/retention/ai.mjs +23 -0
- package/dist/retention/ai.mjs.map +1 -0
- package/dist/retention/pending.mjs +47 -0
- package/dist/retention/pending.mjs.map +1 -0
- package/dist/retention/screenshot-sweep.d.mts +51 -0
- package/dist/retention/screenshot-sweep.mjs +128 -0
- package/dist/retention/screenshot-sweep.mjs.map +1 -0
- package/dist/retention.d.mts +16 -2
- package/dist/retention.mjs +71 -14
- package/dist/retention.mjs.map +1 -1
- package/dist/schema/baseline.d.mts +6 -0
- package/dist/schema/build-component.d.mts +25 -0
- package/dist/schema/build-review.d.mts +17 -0
- package/dist/schema/build.d.mts +7 -0
- package/dist/schema/capture-job.d.mts +60 -0
- package/dist/schema/capture-shard.d.mts +35 -0
- package/dist/schema/comment.d.mts +2 -0
- package/dist/schema/connection.d.mts +24 -0
- package/dist/schema/design.d.mts +58 -0
- package/dist/schema/insight.d.mts +54 -0
- package/dist/schema/notification.d.mts +4 -0
- package/dist/schema/project.d.mts +21 -0
- package/dist/schema/site-setting.d.mts +21 -0
- package/dist/schema/snapshot.d.mts +12 -0
- package/dist/schema/usage.d.mts +30 -0
- package/dist/schema.d.mts +11 -3
- package/dist/serverless.d.mts +21 -0
- package/dist/serverless.mjs +37 -0
- package/dist/serverless.mjs.map +1 -0
- package/dist/test-helpers/create-project.d.mts +1 -1
- package/dist/test-helpers/deferred.d.mts +39 -0
- package/dist/test-helpers/deferred.mjs +61 -0
- package/dist/test-helpers/deferred.mjs.map +1 -0
- package/dist/test-helpers/design-contract.d.mts +21 -0
- package/dist/test-helpers/design-contract.mjs +40 -0
- package/dist/test-helpers/design-contract.mjs.map +1 -0
- package/dist/test-helpers/fake-database.mjs +14 -2
- package/dist/test-helpers/fake-database.mjs.map +1 -1
- package/dist/test-helpers/fake-design.d.mts +43 -0
- package/dist/test-helpers/fake-design.mjs +114 -0
- package/dist/test-helpers/fake-design.mjs.map +1 -0
- package/dist/test-helpers/fake-notifier.d.mts +21 -0
- package/dist/test-helpers/fake-notifier.mjs +44 -0
- package/dist/test-helpers/fake-notifier.mjs.map +1 -0
- package/dist/test-helpers/fake-tables.mjs +255 -67
- package/dist/test-helpers/fake-tables.mjs.map +1 -1
- package/dist/test-helpers/manual-clock.d.mts +27 -0
- package/dist/test-helpers/manual-clock.mjs +56 -0
- package/dist/test-helpers/manual-clock.mjs.map +1 -0
- package/dist/test-helpers/notifier-contract.d.mts +7 -1
- package/dist/test-helpers/notifier-contract.mjs +32 -3
- package/dist/test-helpers/notifier-contract.mjs.map +1 -1
- package/dist/test-helpers/queue-contract.d.mts +16 -2
- package/dist/test-helpers/queue-contract.mjs +195 -1
- package/dist/test-helpers/queue-contract.mjs.map +1 -1
- package/dist/test-helpers/queue-multi-instance.d.mts +20 -0
- package/dist/test-helpers/queue-multi-instance.mjs +206 -0
- package/dist/test-helpers/queue-multi-instance.mjs.map +1 -0
- package/dist/test-helpers/runner-contract.mjs +11 -0
- package/dist/test-helpers/runner-contract.mjs.map +1 -1
- package/dist/test-helpers/sql-chunks.mjs +23 -0
- package/dist/test-helpers/sql-chunks.mjs.map +1 -1
- package/dist/test-helpers/storage-contract.mjs +1 -1
- package/dist/test-helpers.d.mts +9 -4
- package/dist/test-helpers.mjs +8 -3
- package/dist/types.d.mts +14 -3
- package/dist/types.mjs +21 -4
- package/dist/types.mjs.map +1 -1
- package/dist/urls.d.mts +4 -0
- package/dist/urls.mjs +11 -2
- package/dist/urls.mjs.map +1 -1
- package/dist/utils/adaptive-concurrency.d.mts +66 -0
- package/dist/utils/adaptive-concurrency.mjs +149 -0
- package/dist/utils/adaptive-concurrency.mjs.map +1 -0
- package/dist/utils/connect-retry.d.mts +26 -0
- package/dist/utils/connect-retry.mjs +43 -0
- package/dist/utils/connect-retry.mjs.map +1 -0
- package/dist/utils/environment.d.mts +19 -0
- package/dist/utils/environment.mjs +59 -0
- package/dist/utils/environment.mjs.map +1 -0
- package/dist/utils/http.d.mts +17 -1
- package/dist/utils/http.mjs +22 -3
- package/dist/utils/http.mjs.map +1 -1
- package/dist/utils/map-adaptive.d.mts +15 -0
- package/dist/utils/map-adaptive.mjs +72 -0
- package/dist/utils/map-adaptive.mjs.map +1 -0
- package/dist/utils/map-limit.d.mts +10 -0
- package/dist/utils/map-limit.mjs +32 -0
- package/dist/utils/map-limit.mjs.map +1 -0
- package/dist/utils/page-limiter.d.mts +37 -0
- package/dist/utils/page-limiter.mjs +56 -0
- package/dist/utils/page-limiter.mjs.map +1 -0
- package/dist/utils/public-origin.d.mts +20 -0
- package/dist/utils/public-origin.mjs +75 -0
- package/dist/utils/public-origin.mjs.map +1 -0
- package/dist/utils/redact.mjs +3 -0
- package/dist/utils/redact.mjs.map +1 -1
- package/dist/utils/remote-environment.d.mts +39 -0
- package/dist/utils/remote-environment.mjs +114 -0
- package/dist/utils/remote-environment.mjs.map +1 -0
- package/dist/utils/resources.d.mts +64 -0
- package/dist/utils/resources.mjs +122 -0
- package/dist/utils/resources.mjs.map +1 -0
- package/dist/utils/screenshot-store.d.mts +15 -0
- package/dist/utils/screenshot-store.mjs +41 -0
- package/dist/utils/screenshot-store.mjs.map +1 -0
- package/dist/utils/session-gate.d.mts +22 -0
- package/dist/utils/session-gate.mjs +53 -0
- package/dist/utils/session-gate.mjs.map +1 -0
- package/dist/utils/storybook-token.d.mts +81 -0
- package/dist/utils/storybook-token.mjs +134 -0
- package/dist/utils/storybook-token.mjs.map +1 -0
- package/dist/utils/storybook-url.d.mts +15 -0
- package/dist/utils/storybook-url.mjs +21 -0
- package/dist/utils/storybook-url.mjs.map +1 -0
- package/dist/utils/timing.mjs +1 -1
- package/dist/utils/timing.mjs.map +1 -1
- package/dist/utils/zip-read.mjs +129 -0
- package/dist/utils/zip-read.mjs.map +1 -0
- package/dist/utils/zip-write.d.mts +18 -0
- package/dist/utils/zip-write.mjs +188 -0
- package/dist/utils/zip-write.mjs.map +1 -0
- package/dist/utils.d.mts +17 -3
- package/dist/utils.mjs +18 -4
- package/package.json +32 -23
- package/dist/adapter/capture-runner.mjs.map +0 -1
- package/dist/adapter/git-host/comments.d.mts +0 -41
- package/dist/adapter/git-host/comments.mjs +0 -54
- package/dist/adapter/git-host/comments.mjs.map +0 -1
- package/dist/adapter/git-host/helpers.d.mts +0 -13
- package/dist/adapter/git-host/helpers.mjs +0 -30
- package/dist/adapter/git-host/helpers.mjs.map +0 -1
- package/dist/adapter/git-host.d.mts +0 -42
- package/dist/capture/queue.d.mts +0 -38
- package/dist/capture/queue.mjs +0 -98
- package/dist/capture/queue.mjs.map +0 -1
- package/dist/capture/recovery.d.mts +0 -21
- package/dist/capture/recovery.mjs +0 -83
- package/dist/capture/recovery.mjs.map +0 -1
- package/dist/capture/status-fanout.mjs +0 -72
- package/dist/capture/status-fanout.mjs.map +0 -1
- package/dist/diff/engine.d.mts +0 -16
- package/dist/diff/engine.mjs +0 -87
- package/dist/diff/engine.mjs.map +0 -1
- package/dist/diff/options.d.mts +0 -42
- package/dist/diff/options.mjs +0 -15
- package/dist/diff/options.mjs.map +0 -1
- package/dist/models/status-config.d.mts +0 -38
- package/dist/models/status-config.mjs +0 -63
- package/dist/models/status-config.mjs.map +0 -1
- package/dist/schema/status-config.d.mts +0 -16
- package/dist/test-helpers/git-contract.d.mts +0 -11
- package/dist/test-helpers/git-contract.mjs +0 -34
- package/dist/test-helpers/git-contract.mjs.map +0 -1
- /package/dist/adapter/{git-host.mjs → oauth.mjs} +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import __tsdown_shims_path from 'node:path';
|
|
2
|
+
import __tsdown_shims_url from 'node:url';
|
|
3
|
+
import { Logger } from "../../logger.mjs";
|
|
4
|
+
import { NotificationChannel } from "./types.mjs";
|
|
5
|
+
import { StateNotifierProvider } from "./provider.mjs";
|
|
6
|
+
import { BuildStateSet } from "./build-state.mjs";
|
|
7
|
+
//#region src/adapters/notifier/state.d.ts
|
|
8
|
+
/** Default status-name prefix of a git channel (`<prefix>/testing`). */
|
|
9
|
+
declare const DEFAULT_STATUS_PREFIX = "storyshelf";
|
|
10
|
+
/** The channel's status-name prefix: its `prefix` config, else {@link DEFAULT_STATUS_PREFIX}. */
|
|
11
|
+
declare function channelPrefix(channel: NotificationChannel): string;
|
|
12
|
+
/**
|
|
13
|
+
* Make the channel's host show `states` for the commit `sha`: every status, then the comment.
|
|
14
|
+
* Each write is idempotent (latest call wins). A failed status write throws so the caller can
|
|
15
|
+
* retry; a failed comment write is logged and never fails the statuses.
|
|
16
|
+
*/
|
|
17
|
+
declare function writeBuildState(provider: StateNotifierProvider, channel: NotificationChannel, write: {
|
|
18
|
+
sha: string;
|
|
19
|
+
states: BuildStateSet;
|
|
20
|
+
logger?: Logger | undefined;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { DEFAULT_STATUS_PREFIX, channelPrefix, writeBuildState };
|
|
24
|
+
//# sourceMappingURL=state.d.mts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
//#region src/adapters/notifier/state.ts
|
|
5
|
+
/** Default status-name prefix of a git channel (`<prefix>/testing`). */
|
|
6
|
+
const DEFAULT_STATUS_PREFIX = "storyshelf";
|
|
7
|
+
/** The channel's status-name prefix: its `prefix` config, else {@link DEFAULT_STATUS_PREFIX}. */
|
|
8
|
+
function channelPrefix(channel) {
|
|
9
|
+
const prefix = channel.config["prefix"];
|
|
10
|
+
return typeof prefix === "string" && prefix.length > 0 ? prefix : DEFAULT_STATUS_PREFIX;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Make the channel's host show `states` for the commit `sha`: every status, then the comment.
|
|
14
|
+
* Each write is idempotent (latest call wins). A failed status write throws so the caller can
|
|
15
|
+
* retry; a failed comment write is logged and never fails the statuses.
|
|
16
|
+
*/
|
|
17
|
+
async function writeBuildState(provider, channel, write) {
|
|
18
|
+
const { sha, states, logger } = write;
|
|
19
|
+
const adapter = provider.create({
|
|
20
|
+
config: channel.config,
|
|
21
|
+
secret: channel.secret,
|
|
22
|
+
logger
|
|
23
|
+
});
|
|
24
|
+
const failed = (await Promise.allSettled(states.statuses.map(async (status) => {
|
|
25
|
+
await adapter.setState({
|
|
26
|
+
channel,
|
|
27
|
+
target: {
|
|
28
|
+
kind: "status",
|
|
29
|
+
sha,
|
|
30
|
+
context: status.context,
|
|
31
|
+
description: status.description,
|
|
32
|
+
...status.informational === true ? { informational: true } : {},
|
|
33
|
+
...status.progress === void 0 ? {} : { progress: status.progress },
|
|
34
|
+
...status.annotations === void 0 ? {} : { annotations: status.annotations },
|
|
35
|
+
...status.omitted === void 0 ? {} : { omitted: status.omitted }
|
|
36
|
+
},
|
|
37
|
+
state: status.state,
|
|
38
|
+
url: status.url,
|
|
39
|
+
logger
|
|
40
|
+
});
|
|
41
|
+
}))).find((result) => result.status === "rejected");
|
|
42
|
+
if (failed?.status === "rejected") throw failed.reason;
|
|
43
|
+
if (states.comment !== null) {
|
|
44
|
+
const { comment } = states;
|
|
45
|
+
await adapter.setState({
|
|
46
|
+
channel,
|
|
47
|
+
target: {
|
|
48
|
+
kind: "comment",
|
|
49
|
+
sha,
|
|
50
|
+
markdown: comment.markdown
|
|
51
|
+
},
|
|
52
|
+
state: comment.state,
|
|
53
|
+
url: comment.url,
|
|
54
|
+
logger
|
|
55
|
+
}).catch((error) => {
|
|
56
|
+
logger?.warn({
|
|
57
|
+
err: error,
|
|
58
|
+
channelId: channel.id
|
|
59
|
+
}, "failed to upsert comment");
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { DEFAULT_STATUS_PREFIX, channelPrefix, writeBuildState };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=state.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.mjs","names":[],"sources":["../../../src/adapters/notifier/state.ts"],"sourcesContent":["/** Writing a build's desired states to one `state` channel (git hosts); see `build-state.ts` for what they are. */\nimport type { Logger } from \"../../logger.ts\";\nimport type { BuildStateSet } from \"./build-state.ts\";\nimport type { StateNotifierProvider } from \"./provider.ts\";\nimport type { NotificationChannel } from \"./types.ts\";\n\n/** Default status-name prefix of a git channel (`<prefix>/testing`). */\nexport const DEFAULT_STATUS_PREFIX = \"storyshelf\";\n\n/** The channel's status-name prefix: its `prefix` config, else {@link DEFAULT_STATUS_PREFIX}. */\nexport function channelPrefix(channel: NotificationChannel): string {\n const prefix = channel.config[\"prefix\"];\n return typeof prefix === \"string\" && prefix.length > 0 ? prefix : DEFAULT_STATUS_PREFIX;\n}\n\n/**\n * Make the channel's host show `states` for the commit `sha`: every status, then the comment.\n * Each write is idempotent (latest call wins). A failed status write throws so the caller can\n * retry; a failed comment write is logged and never fails the statuses.\n */\nexport async function writeBuildState(\n provider: StateNotifierProvider,\n channel: NotificationChannel,\n write: { sha: string; states: BuildStateSet; logger?: Logger | undefined },\n): Promise<void> {\n const { sha, states, logger } = write;\n const adapter = provider.create({ config: channel.config, secret: channel.secret, logger });\n const results = await Promise.allSettled(\n states.statuses.map(async (status) => {\n await adapter.setState({\n channel,\n target: {\n kind: \"status\",\n sha,\n context: status.context,\n description: status.description,\n ...(status.informational === true ? { informational: true } : {}),\n ...(status.progress === undefined ? {} : { progress: status.progress }),\n ...(status.annotations === undefined ? {} : { annotations: status.annotations }),\n ...(status.omitted === undefined ? {} : { omitted: status.omitted }),\n },\n state: status.state,\n url: status.url,\n logger,\n });\n }),\n );\n const failed = results.find((result) => result.status === \"rejected\");\n if (failed?.status === \"rejected\") {\n throw failed.reason;\n }\n if (states.comment !== null) {\n const { comment } = states;\n await adapter\n .setState({\n channel,\n target: { kind: \"comment\", sha, markdown: comment.markdown },\n state: comment.state,\n url: comment.url,\n logger,\n })\n .catch((error: unknown) => {\n logger?.warn({ err: error, channelId: channel.id }, \"failed to upsert comment\");\n });\n }\n}\n"],"mappings":";;;;;AAOA,MAAa,wBAAwB;;AAGrC,SAAgB,cAAc,SAAsC;CAClE,MAAM,SAAS,QAAQ,OAAO;CAC9B,OAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,SAAS;AACpE;;;;;;AAOA,eAAsB,gBACpB,UACA,SACA,OACe;CACf,MAAM,EAAE,KAAK,QAAQ,WAAW;CAChC,MAAM,UAAU,SAAS,OAAO;EAAE,QAAQ,QAAQ;EAAQ,QAAQ,QAAQ;EAAQ;CAAO,CAAC;CAqB1F,MAAM,UAAS,MApBO,QAAQ,WAC5B,OAAO,SAAS,IAAI,OAAO,WAAW;EACpC,MAAM,QAAQ,SAAS;GACrB;GACA,QAAQ;IACN,MAAM;IACN;IACA,SAAS,OAAO;IAChB,aAAa,OAAO;IACpB,GAAI,OAAO,kBAAkB,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/D,GAAI,OAAO,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,OAAO,SAAS;IACrE,GAAI,OAAO,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,OAAO,YAAY;IAC9E,GAAI,OAAO,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;GACpE;GACA,OAAO,OAAO;GACd,KAAK,OAAO;GACZ;EACF,CAAC;CACH,CAAC,CACH,EAAA,CACuB,MAAM,WAAW,OAAO,WAAW,UAAU;CACpE,IAAI,QAAQ,WAAW,YACrB,MAAM,OAAO;CAEf,IAAI,OAAO,YAAY,MAAM;EAC3B,MAAM,EAAE,YAAY;EACpB,MAAM,QACH,SAAS;GACR;GACA,QAAQ;IAAE,MAAM;IAAW;IAAK,UAAU,QAAQ;GAAS;GAC3D,OAAO,QAAQ;GACf,KAAK,QAAQ;GACb;EACF,CAAC,CAAC,CACD,OAAO,UAAmB;GACzB,QAAQ,KAAK;IAAE,KAAK;IAAO,WAAW,QAAQ;GAAG,GAAG,0BAA0B;EAChF,CAAC;CACL;AACF"}
|
|
@@ -42,6 +42,55 @@ interface NotificationChannel {
|
|
|
42
42
|
secret?: string;
|
|
43
43
|
events: string[];
|
|
44
44
|
enabled: boolean;
|
|
45
|
+
/** Last delivery error, cleared by the next successful delivery. */
|
|
46
|
+
lastError?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* What a `state` provider shows for a build: pending, passed, failed, or cancelled by a user
|
|
50
|
+
* (a host without a cancelled state shows it like the nearest failure-class state).
|
|
51
|
+
*/
|
|
52
|
+
type NotifierState = "pending" | "success" | "failure" | "cancelled";
|
|
53
|
+
/**
|
|
54
|
+
* One per-story finding a host that supports it (GitHub check runs) shows beside a status: a
|
|
55
|
+
* changed snapshot that deep-links to its review page.
|
|
56
|
+
*/
|
|
57
|
+
interface StateAnnotation {
|
|
58
|
+
/** The story file the snapshot belongs to (the host anchors the finding there). */
|
|
59
|
+
path: string;
|
|
60
|
+
/** Short heading, e.g. `Button / Primary (chromium)`. */
|
|
61
|
+
title: string;
|
|
62
|
+
message: string;
|
|
63
|
+
/** Absolute link to the snapshot's review page. */
|
|
64
|
+
url: string;
|
|
65
|
+
level: "notice" | "warning";
|
|
66
|
+
}
|
|
67
|
+
/** Where a `state` provider writes: a commit status or a pull-request comment. */
|
|
68
|
+
type NotifierStateTarget = {
|
|
69
|
+
kind: "status";
|
|
70
|
+
sha: string;
|
|
71
|
+
/** Full status name on the host, e.g. `storyshelf/testing` (the caller owns the prefix). */
|
|
72
|
+
context: string;
|
|
73
|
+
/** Short text beside the status; the provider supplies a default. */
|
|
74
|
+
description?: string;
|
|
75
|
+
/** For a `pending` state: not started (`queued`) or under way (`running`; the default). */
|
|
76
|
+
progress?: "queued" | "running";
|
|
77
|
+
/** Never a merge gate (the Storybook status): a failure is shown as neutral where the host has it. */
|
|
78
|
+
informational?: boolean;
|
|
79
|
+
/** Per-snapshot findings of the build; only a host with annotations shows them. */
|
|
80
|
+
annotations?: StateAnnotation[];
|
|
81
|
+
/** Changed snapshots beyond `annotations` (cut at the cap); the host says "and N more". */
|
|
82
|
+
omitted?: number;
|
|
83
|
+
} | {
|
|
84
|
+
kind: "comment";
|
|
85
|
+
sha: string;
|
|
86
|
+
/** Comment body below the idempotency marker. */
|
|
87
|
+
markdown: string;
|
|
88
|
+
};
|
|
89
|
+
/** Result of one delivery attempt to a channel, reported to the host for health display. */
|
|
90
|
+
interface ChannelOutcome {
|
|
91
|
+
channelId: string;
|
|
92
|
+
/** Sanitized error text, absent on success. */
|
|
93
|
+
error?: string;
|
|
45
94
|
}
|
|
46
95
|
/** App-level (site-wide) admin alert — no project scope. */
|
|
47
96
|
interface SystemNotification {
|
|
@@ -50,7 +99,7 @@ interface SystemNotification {
|
|
|
50
99
|
timestamp: string;
|
|
51
100
|
}
|
|
52
101
|
/** Site-wide events for admins (new users, failures, purge). */
|
|
53
|
-
type SystemEventName = "sys:user-created" | "sys:invite-issued" | "sys:auth-failed" | "sys:capture-failed" | "sys:purge-completed";
|
|
102
|
+
type SystemEventName = "sys:user-created" | "sys:invite-issued" | "sys:auth-failed" | "sys:capture-failed" | "sys:purge-completed" | "sys:notify-failed" | "sys:ai-budget";
|
|
54
103
|
//#endregion
|
|
55
|
-
export { ChannelToggles, FormattedNotification, NotificationBrand, NotificationChannel, NotificationEvent, SystemEventName, SystemNotification };
|
|
104
|
+
export { ChannelOutcome, ChannelToggles, FormattedNotification, NotificationBrand, NotificationChannel, NotificationEvent, NotifierState, NotifierStateTarget, StateAnnotation, SystemEventName, SystemNotification };
|
|
56
105
|
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import __tsdown_shims_path from 'node:path';
|
|
2
|
+
import __tsdown_shims_url from 'node:url';
|
|
3
|
+
import { BrowserName, CaptureTarget, TargetReach } from "./capture-target.mjs";
|
|
4
|
+
//#region src/adapters/remote-browser.d.ts
|
|
5
|
+
/** How a runner talks to the service: Playwright's own protocol, or the Chrome DevTools Protocol. */
|
|
6
|
+
type RemoteProtocol = "playwright" | "cdp";
|
|
7
|
+
/** Where and how to connect for one engine. Re-evaluated on every connect, so a token can be fresh. */
|
|
8
|
+
interface RemoteConnection {
|
|
9
|
+
protocol: RemoteProtocol;
|
|
10
|
+
/** `ws(s)://…` (CDP also accepts `http(s)://…`). May carry credentials: it is never logged. */
|
|
11
|
+
endpoint: string;
|
|
12
|
+
/** Request headers for the handshake, such as `authorization`. Never logged. */
|
|
13
|
+
headers?: Record<string, string>;
|
|
14
|
+
/**
|
|
15
|
+
* Playwright `connect` only: `"<loopback>"` routes the remote browser's requests for `127.0.0.1`
|
|
16
|
+
* back through the connection, so the loopback Storybook server works unchanged (decision 5).
|
|
17
|
+
*/
|
|
18
|
+
exposeNetwork?: string;
|
|
19
|
+
}
|
|
20
|
+
/** What {@link defineRemote} takes: what `remote()` exposes to operators. */
|
|
21
|
+
interface RemoteOptions {
|
|
22
|
+
/** The target name half (`chromium@<name>`): lowercase letters, digits and hyphens, at most 32. */
|
|
23
|
+
name: string;
|
|
24
|
+
/** The engines to offer (a subset of what the service has). */
|
|
25
|
+
engines: readonly BrowserName[];
|
|
26
|
+
/** The connection for an engine. Pure: it is called once at creation to validate it. */
|
|
27
|
+
connect: (engine: BrowserName) => RemoteConnection;
|
|
28
|
+
/** Parallel sessions the plan allows: the page cap of the target, per process (decision 4). */
|
|
29
|
+
sessions: number;
|
|
30
|
+
/** OS the service renders on, reported when the page cannot tell (`linux-x64`, `windows`, …). */
|
|
31
|
+
platform?: string | undefined;
|
|
32
|
+
/** Connect retries before the render fails (default 3). */
|
|
33
|
+
connectRetries?: number | undefined;
|
|
34
|
+
/** First backoff between connect attempts in ms, doubling each time (default 500). */
|
|
35
|
+
connectBackoffMs?: number | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* How long one connect attempt waits in ms (default 30 000). A farm with a client cap queues
|
|
38
|
+
* extra connections instead of refusing them, so a busy farm shows up as this timeout.
|
|
39
|
+
*/
|
|
40
|
+
connectTimeoutMs?: number | undefined;
|
|
41
|
+
}
|
|
42
|
+
/** One remote service, validated: an entry of a runner's `browsers`. */
|
|
43
|
+
interface RemoteBrowser extends Required<Pick<RemoteOptions, "name" | "engines" | "connect" | "sessions">> {
|
|
44
|
+
readonly kind: "remote";
|
|
45
|
+
readonly platform: string | undefined;
|
|
46
|
+
readonly connectRetries: number;
|
|
47
|
+
readonly connectBackoffMs: number;
|
|
48
|
+
readonly connectTimeoutMs: number;
|
|
49
|
+
}
|
|
50
|
+
/** What a runner supports, which {@link defineRemote} checks the service against. */
|
|
51
|
+
interface RemoteSupport {
|
|
52
|
+
/** Engines the runner can drive. */
|
|
53
|
+
engines: readonly BrowserName[];
|
|
54
|
+
/** Protocols the runner can speak. */
|
|
55
|
+
protocols: readonly RemoteProtocol[];
|
|
56
|
+
/** Shown in errors, for example `remote()`. */
|
|
57
|
+
label: string;
|
|
58
|
+
}
|
|
59
|
+
/** One target a remote service offers. */
|
|
60
|
+
interface RemoteTarget {
|
|
61
|
+
kind: "remote";
|
|
62
|
+
target: CaptureTarget;
|
|
63
|
+
engine: BrowserName;
|
|
64
|
+
remote: RemoteBrowser;
|
|
65
|
+
/** How the browser reaches the Storybook. */
|
|
66
|
+
reach: TargetReach;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validate a remote service eagerly, so a mistake fails when the runner is created and not when the
|
|
70
|
+
* first build runs: the name, the sessions, the engines against what the runner drives, and the
|
|
71
|
+
* connection of every engine (protocol, endpoint scheme, CDP being Chromium only).
|
|
72
|
+
*/
|
|
73
|
+
declare function defineRemote(options: RemoteOptions, support: RemoteSupport): RemoteBrowser;
|
|
74
|
+
/** The targets a service offers, in the order of its `engines`. */
|
|
75
|
+
declare function remoteTargetsOf(remote: RemoteBrowser): RemoteTarget[];
|
|
76
|
+
/** `loopback` when the remote browser can route back to this host, else it needs a URL (decision 5). */
|
|
77
|
+
declare function reachOf(connection: RemoteConnection): TargetReach;
|
|
78
|
+
/** Whether a value is a remote service entry. */
|
|
79
|
+
declare function isRemoteBrowser(value: unknown): value is RemoteBrowser;
|
|
80
|
+
/**
|
|
81
|
+
* Remove what identifies the connection from text surfaced to operators: the endpoint (it can carry
|
|
82
|
+
* a key in its path or query), its host and path, its query values and every header value.
|
|
83
|
+
*/
|
|
84
|
+
declare function scrubConnection(text: string, connection: RemoteConnection): string;
|
|
85
|
+
//#endregion
|
|
86
|
+
export { RemoteBrowser, RemoteConnection, RemoteOptions, RemoteProtocol, RemoteSupport, RemoteTarget, defineRemote, isRemoteBrowser, reachOf, remoteTargetsOf, scrubConnection };
|
|
87
|
+
//# sourceMappingURL=remote-browser.d.mts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { TARGET_NAME_PATTERN, isBrowserName } from "./capture-target.mjs";
|
|
5
|
+
//#region src/adapters/remote-browser.ts
|
|
6
|
+
/**
|
|
7
|
+
* Remote browsers (ADR 0007, decisions 1 and 3): one service a runner connects to instead of
|
|
8
|
+
* launching a browser, expanding to one `<engine>@<name>` target per engine. Presets are plain
|
|
9
|
+
* configuration over {@link defineRemote}; the runners add only what they can drive.
|
|
10
|
+
*/
|
|
11
|
+
const CDP_ENGINES = /* @__PURE__ */ new Set(["chromium", "chrome"]);
|
|
12
|
+
const SCHEMES = {
|
|
13
|
+
playwright: ["ws:", "wss:"],
|
|
14
|
+
cdp: [
|
|
15
|
+
"ws:",
|
|
16
|
+
"wss:",
|
|
17
|
+
"http:",
|
|
18
|
+
"https:"
|
|
19
|
+
]
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Validate a remote service eagerly, so a mistake fails when the runner is created and not when the
|
|
23
|
+
* first build runs: the name, the sessions, the engines against what the runner drives, and the
|
|
24
|
+
* connection of every engine (protocol, endpoint scheme, CDP being Chromium only).
|
|
25
|
+
*/
|
|
26
|
+
function defineRemote(options, support) {
|
|
27
|
+
const { label } = support;
|
|
28
|
+
if (!TARGET_NAME_PATTERN.test(options.name)) throw new Error(`${label}: name "${options.name}" must be lowercase letters, digits and hyphens, start with a letter or digit and be at most 32 characters`);
|
|
29
|
+
if (!Number.isInteger(options.sessions) || options.sessions < 1) throw new Error(`${label} "${options.name}": sessions must be a positive integer`);
|
|
30
|
+
checkEngines(options, support);
|
|
31
|
+
for (const engine of options.engines) checkConnection(label, options, engine, support);
|
|
32
|
+
return {
|
|
33
|
+
kind: "remote",
|
|
34
|
+
name: options.name,
|
|
35
|
+
engines: [...options.engines],
|
|
36
|
+
connect: options.connect,
|
|
37
|
+
sessions: options.sessions,
|
|
38
|
+
platform: options.platform,
|
|
39
|
+
connectRetries: options.connectRetries ?? 3,
|
|
40
|
+
connectBackoffMs: options.connectBackoffMs ?? 500,
|
|
41
|
+
connectTimeoutMs: options.connectTimeoutMs ?? 3e4
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The targets a service offers, in the order of its `engines`. */
|
|
45
|
+
function remoteTargetsOf(remote) {
|
|
46
|
+
return remote.engines.map((engine) => ({
|
|
47
|
+
kind: "remote",
|
|
48
|
+
target: `${engine}@${remote.name}`,
|
|
49
|
+
engine,
|
|
50
|
+
remote,
|
|
51
|
+
reach: reachOf(remote.connect(engine))
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
/** `loopback` when the remote browser can route back to this host, else it needs a URL (decision 5). */
|
|
55
|
+
function reachOf(connection) {
|
|
56
|
+
return connection.protocol === "playwright" && connection.exposeNetwork !== void 0 ? "loopback" : "url";
|
|
57
|
+
}
|
|
58
|
+
/** Whether a value is a remote service entry. */
|
|
59
|
+
function isRemoteBrowser(value) {
|
|
60
|
+
return typeof value === "object" && value !== null && value.kind === "remote";
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Remove what identifies the connection from text surfaced to operators: the endpoint (it can carry
|
|
64
|
+
* a key in its path or query), its host and path, its query values and every header value.
|
|
65
|
+
*/
|
|
66
|
+
function scrubConnection(text, connection) {
|
|
67
|
+
const secrets = [connection.endpoint, ...Object.values(connection.headers ?? {})];
|
|
68
|
+
try {
|
|
69
|
+
const url = new URL(connection.endpoint);
|
|
70
|
+
secrets.push(url.password, ...url.searchParams.values(), decodeURIComponent(url.search), `${url.protocol}//${url.host}${url.pathname}`, url.host, url.pathname);
|
|
71
|
+
} catch {}
|
|
72
|
+
let scrubbed = text;
|
|
73
|
+
for (const secret of secrets.filter((value) => value.length >= 4).toSorted((a, b) => b.length - a.length)) scrubbed = scrubbed.replaceAll(secret, "[redacted]");
|
|
74
|
+
return scrubbed;
|
|
75
|
+
}
|
|
76
|
+
function checkEngines(options, support) {
|
|
77
|
+
const where = `${support.label} "${options.name}"`;
|
|
78
|
+
if (options.engines.length === 0) throw new Error(`${where}: engines must list at least one engine`);
|
|
79
|
+
for (const [index, engine] of options.engines.entries()) {
|
|
80
|
+
if (!isBrowserName(engine)) throw new Error(`${where}: unknown engine "${String(engine)}"`);
|
|
81
|
+
if (!support.engines.includes(engine)) throw new Error(`${where}: this runner cannot drive "${engine}" (it drives ${support.engines.join(", ")})`);
|
|
82
|
+
if (options.engines.indexOf(engine) !== index) throw new Error(`${where}: engine "${engine}" is listed twice`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function checkConnection(label, options, engine, support) {
|
|
86
|
+
const where = `${label} "${options.name}" (${engine})`;
|
|
87
|
+
const connection = options.connect(engine);
|
|
88
|
+
if (!support.protocols.includes(connection.protocol)) throw new Error(`${where}: protocol "${connection.protocol}" is not supported by this runner (it speaks ${support.protocols.join(", ")})`);
|
|
89
|
+
if (connection.protocol === "cdp" && !CDP_ENGINES.has(engine)) throw new Error(`${where}: the CDP protocol drives Chromium only, not "${engine}"`);
|
|
90
|
+
if (connection.protocol === "cdp" && connection.exposeNetwork !== void 0) throw new Error(`${where}: exposeNetwork needs the "playwright" protocol`);
|
|
91
|
+
if (!SCHEMES[connection.protocol].some((scheme) => isScheme(connection.endpoint, scheme))) throw new Error(`${where}: the endpoint must be a ${SCHEMES[connection.protocol].join(" or ")} URL`);
|
|
92
|
+
}
|
|
93
|
+
function isScheme(endpoint, scheme) {
|
|
94
|
+
try {
|
|
95
|
+
return new URL(endpoint).protocol === scheme;
|
|
96
|
+
} catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { defineRemote, isRemoteBrowser, reachOf, remoteTargetsOf, scrubConnection };
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=remote-browser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-browser.mjs","names":[],"sources":["../../src/adapters/remote-browser.ts"],"sourcesContent":["/**\n * Remote browsers (ADR 0007, decisions 1 and 3): one service a runner connects to instead of\n * launching a browser, expanding to one `<engine>@<name>` target per engine. Presets are plain\n * configuration over {@link defineRemote}; the runners add only what they can drive.\n */\nimport {\n TARGET_NAME_PATTERN,\n isBrowserName,\n type BrowserName,\n type CaptureTarget,\n type TargetReach,\n} from \"./capture-target.ts\";\n\n/** How a runner talks to the service: Playwright's own protocol, or the Chrome DevTools Protocol. */\nexport type RemoteProtocol = \"playwright\" | \"cdp\";\n\n/** Where and how to connect for one engine. Re-evaluated on every connect, so a token can be fresh. */\nexport interface RemoteConnection {\n protocol: RemoteProtocol;\n /** `ws(s)://…` (CDP also accepts `http(s)://…`). May carry credentials: it is never logged. */\n endpoint: string;\n /** Request headers for the handshake, such as `authorization`. Never logged. */\n headers?: Record<string, string>;\n /**\n * Playwright `connect` only: `\"<loopback>\"` routes the remote browser's requests for `127.0.0.1`\n * back through the connection, so the loopback Storybook server works unchanged (decision 5).\n */\n exposeNetwork?: string;\n}\n\n/** What {@link defineRemote} takes: what `remote()` exposes to operators. */\nexport interface RemoteOptions {\n /** The target name half (`chromium@<name>`): lowercase letters, digits and hyphens, at most 32. */\n name: string;\n /** The engines to offer (a subset of what the service has). */\n engines: readonly BrowserName[];\n /** The connection for an engine. Pure: it is called once at creation to validate it. */\n connect: (engine: BrowserName) => RemoteConnection;\n /** Parallel sessions the plan allows: the page cap of the target, per process (decision 4). */\n sessions: number;\n /** OS the service renders on, reported when the page cannot tell (`linux-x64`, `windows`, …). */\n platform?: string | undefined;\n /** Connect retries before the render fails (default 3). */\n connectRetries?: number | undefined;\n /** First backoff between connect attempts in ms, doubling each time (default 500). */\n connectBackoffMs?: number | undefined;\n /**\n * How long one connect attempt waits in ms (default 30 000). A farm with a client cap queues\n * extra connections instead of refusing them, so a busy farm shows up as this timeout.\n */\n connectTimeoutMs?: number | undefined;\n}\n\n/** One remote service, validated: an entry of a runner's `browsers`. */\nexport interface RemoteBrowser extends Required<\n Pick<RemoteOptions, \"name\" | \"engines\" | \"connect\" | \"sessions\">\n> {\n readonly kind: \"remote\";\n readonly platform: string | undefined;\n readonly connectRetries: number;\n readonly connectBackoffMs: number;\n readonly connectTimeoutMs: number;\n}\n\n/** What a runner supports, which {@link defineRemote} checks the service against. */\nexport interface RemoteSupport {\n /** Engines the runner can drive. */\n engines: readonly BrowserName[];\n /** Protocols the runner can speak. */\n protocols: readonly RemoteProtocol[];\n /** Shown in errors, for example `remote()`. */\n label: string;\n}\n\n/** One target a remote service offers. */\nexport interface RemoteTarget {\n kind: \"remote\";\n target: CaptureTarget;\n engine: BrowserName;\n remote: RemoteBrowser;\n /** How the browser reaches the Storybook. */\n reach: TargetReach;\n}\n\nconst CDP_ENGINES = new Set<BrowserName>([\"chromium\", \"chrome\"]);\nconst SCHEMES: Record<RemoteProtocol, readonly string[]> = {\n playwright: [\"ws:\", \"wss:\"],\n cdp: [\"ws:\", \"wss:\", \"http:\", \"https:\"],\n};\n\n/**\n * Validate a remote service eagerly, so a mistake fails when the runner is created and not when the\n * first build runs: the name, the sessions, the engines against what the runner drives, and the\n * connection of every engine (protocol, endpoint scheme, CDP being Chromium only).\n */\nexport function defineRemote(options: RemoteOptions, support: RemoteSupport): RemoteBrowser {\n const { label } = support;\n if (!TARGET_NAME_PATTERN.test(options.name)) {\n throw new Error(\n `${label}: name \"${options.name}\" must be lowercase letters, digits and hyphens, start with a letter or digit and be at most 32 characters`,\n );\n }\n if (!Number.isInteger(options.sessions) || options.sessions < 1) {\n throw new Error(`${label} \"${options.name}\": sessions must be a positive integer`);\n }\n checkEngines(options, support);\n for (const engine of options.engines) {\n checkConnection(label, options, engine, support);\n }\n return {\n kind: \"remote\",\n name: options.name,\n engines: [...options.engines],\n connect: options.connect,\n sessions: options.sessions,\n platform: options.platform,\n connectRetries: options.connectRetries ?? 3,\n connectBackoffMs: options.connectBackoffMs ?? 500,\n connectTimeoutMs: options.connectTimeoutMs ?? 30_000,\n };\n}\n\n/** The targets a service offers, in the order of its `engines`. */\nexport function remoteTargetsOf(remote: RemoteBrowser): RemoteTarget[] {\n return remote.engines.map((engine) => ({\n kind: \"remote\",\n target: `${engine}@${remote.name}`,\n engine,\n remote,\n reach: reachOf(remote.connect(engine)),\n }));\n}\n\n/** `loopback` when the remote browser can route back to this host, else it needs a URL (decision 5). */\nexport function reachOf(connection: RemoteConnection): TargetReach {\n return connection.protocol === \"playwright\" && connection.exposeNetwork !== undefined\n ? \"loopback\"\n : \"url\";\n}\n\n/** Whether a value is a remote service entry. */\nexport function isRemoteBrowser(value: unknown): value is RemoteBrowser {\n return typeof value === \"object\" && value !== null && (value as RemoteBrowser).kind === \"remote\";\n}\n\n/**\n * Remove what identifies the connection from text surfaced to operators: the endpoint (it can carry\n * a key in its path or query), its host and path, its query values and every header value.\n */\nexport function scrubConnection(text: string, connection: RemoteConnection): string {\n const secrets = [connection.endpoint, ...Object.values(connection.headers ?? {})];\n try {\n const url = new URL(connection.endpoint);\n // Drivers echo the endpoint without its query; the host and a path that acts as a key stay hidden.\n secrets.push(\n url.password,\n ...url.searchParams.values(),\n decodeURIComponent(url.search),\n `${url.protocol}//${url.host}${url.pathname}`,\n url.host,\n url.pathname,\n );\n } catch {\n // An unparsable endpoint is scrubbed whole above.\n }\n let scrubbed = text;\n // Longest first: the endpoint goes before the fragments it contains.\n for (const secret of secrets\n .filter((value) => value.length >= 4)\n .toSorted((a, b) => b.length - a.length)) {\n scrubbed = scrubbed.replaceAll(secret, \"[redacted]\");\n }\n return scrubbed;\n}\n\nfunction checkEngines(options: RemoteOptions, support: RemoteSupport): void {\n const where = `${support.label} \"${options.name}\"`;\n if (options.engines.length === 0) {\n throw new Error(`${where}: engines must list at least one engine`);\n }\n for (const [index, engine] of options.engines.entries()) {\n if (!isBrowserName(engine)) {\n throw new Error(`${where}: unknown engine \"${String(engine)}\"`);\n }\n if (!support.engines.includes(engine)) {\n throw new Error(\n `${where}: this runner cannot drive \"${engine}\" (it drives ${support.engines.join(\", \")})`,\n );\n }\n if (options.engines.indexOf(engine) !== index) {\n throw new Error(`${where}: engine \"${engine}\" is listed twice`);\n }\n }\n}\n\nfunction checkConnection(\n label: string,\n options: RemoteOptions,\n engine: BrowserName,\n support: RemoteSupport,\n): void {\n const where = `${label} \"${options.name}\" (${engine})`;\n const connection = options.connect(engine);\n if (!support.protocols.includes(connection.protocol)) {\n throw new Error(\n `${where}: protocol \"${connection.protocol}\" is not supported by this runner (it speaks ${support.protocols.join(\", \")})`,\n );\n }\n if (connection.protocol === \"cdp\" && !CDP_ENGINES.has(engine)) {\n throw new Error(`${where}: the CDP protocol drives Chromium only, not \"${engine}\"`);\n }\n if (connection.protocol === \"cdp\" && connection.exposeNetwork !== undefined) {\n throw new Error(`${where}: exposeNetwork needs the \"playwright\" protocol`);\n }\n if (!SCHEMES[connection.protocol].some((scheme) => isScheme(connection.endpoint, scheme))) {\n throw new Error(\n `${where}: the endpoint must be a ${SCHEMES[connection.protocol].join(\" or \")} URL`,\n );\n }\n}\n\nfunction isScheme(endpoint: string, scheme: string): boolean {\n try {\n return new URL(endpoint).protocol === scheme;\n } catch {\n return false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import __tsdown_shims_path from 'node:path';
|
|
2
|
+
import __tsdown_shims_url from 'node:url';
|
|
3
|
+
//#region src/adapters/render-runs.d.ts
|
|
4
|
+
/** In-flight render calls of a capture runner, so `cancel` reaches exactly the runs it names. */
|
|
5
|
+
/**
|
|
6
|
+
* Every render call a runner has in flight, by build and run id.
|
|
7
|
+
*
|
|
8
|
+
* Several renders of one build can run at once in one process (the shards of a sharded build), and
|
|
9
|
+
* even two with the same run id (a redelivered shard). Each call registers its own entry and
|
|
10
|
+
* removes only that entry when it ends, so no render ever drops another's handle.
|
|
11
|
+
*/
|
|
12
|
+
declare class RenderRuns<T> {
|
|
13
|
+
#private;
|
|
14
|
+
/**
|
|
15
|
+
* Register a render call. Returns the function that removes it again (call it in `finally`).
|
|
16
|
+
*
|
|
17
|
+
* @param runId - The request's run id; a render without one is keyed by its build id.
|
|
18
|
+
*/
|
|
19
|
+
add(buildId: string, runId: string | undefined, run: T): () => void;
|
|
20
|
+
/** The runs `cancel(buildId, runId)` should stop: every run of the build without a run id. */
|
|
21
|
+
matching(buildId: string, runId?: string): T[];
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { RenderRuns };
|
|
25
|
+
//# sourceMappingURL=render-runs.d.mts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
//#region src/adapters/render-runs.ts
|
|
5
|
+
/** In-flight render calls of a capture runner, so `cancel` reaches exactly the runs it names. */
|
|
6
|
+
/**
|
|
7
|
+
* Every render call a runner has in flight, by build and run id.
|
|
8
|
+
*
|
|
9
|
+
* Several renders of one build can run at once in one process (the shards of a sharded build), and
|
|
10
|
+
* even two with the same run id (a redelivered shard). Each call registers its own entry and
|
|
11
|
+
* removes only that entry when it ends, so no render ever drops another's handle.
|
|
12
|
+
*/
|
|
13
|
+
var RenderRuns = class {
|
|
14
|
+
#byBuild = /* @__PURE__ */ new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Register a render call. Returns the function that removes it again (call it in `finally`).
|
|
17
|
+
*
|
|
18
|
+
* @param runId - The request's run id; a render without one is keyed by its build id.
|
|
19
|
+
*/
|
|
20
|
+
add(buildId, runId, run) {
|
|
21
|
+
const entry = {
|
|
22
|
+
runId: runId ?? buildId,
|
|
23
|
+
run
|
|
24
|
+
};
|
|
25
|
+
const runs = this.#byBuild.get(buildId) ?? /* @__PURE__ */ new Set();
|
|
26
|
+
runs.add(entry);
|
|
27
|
+
this.#byBuild.set(buildId, runs);
|
|
28
|
+
return () => {
|
|
29
|
+
runs.delete(entry);
|
|
30
|
+
if (runs.size === 0 && this.#byBuild.get(buildId) === runs) this.#byBuild.delete(buildId);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** The runs `cancel(buildId, runId)` should stop: every run of the build without a run id. */
|
|
34
|
+
matching(buildId, runId) {
|
|
35
|
+
return [...this.#byBuild.get(buildId) ?? []].filter((entry) => runId === void 0 || entry.runId === runId).map((e) => e.run);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { RenderRuns };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=render-runs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-runs.mjs","names":[],"sources":["../../src/adapters/render-runs.ts"],"sourcesContent":["/** In-flight render calls of a capture runner, so `cancel` reaches exactly the runs it names. */\n\n/**\n * Every render call a runner has in flight, by build and run id.\n *\n * Several renders of one build can run at once in one process (the shards of a sharded build), and\n * even two with the same run id (a redelivered shard). Each call registers its own entry and\n * removes only that entry when it ends, so no render ever drops another's handle.\n */\nexport class RenderRuns<T> {\n readonly #byBuild = new Map<string, Set<{ runId: string; run: T }>>();\n\n /**\n * Register a render call. Returns the function that removes it again (call it in `finally`).\n *\n * @param runId - The request's run id; a render without one is keyed by its build id.\n */\n add(buildId: string, runId: string | undefined, run: T): () => void {\n const entry = { runId: runId ?? buildId, run };\n const runs = this.#byBuild.get(buildId) ?? new Set();\n runs.add(entry);\n this.#byBuild.set(buildId, runs);\n return () => {\n runs.delete(entry);\n if (runs.size === 0 && this.#byBuild.get(buildId) === runs) {\n this.#byBuild.delete(buildId);\n }\n };\n }\n\n /** The runs `cancel(buildId, runId)` should stop: every run of the build without a run id. */\n matching(buildId: string, runId?: string): T[] {\n const runs = [...(this.#byBuild.get(buildId) ?? [])];\n return runs.filter((entry) => runId === undefined || entry.runId === runId).map((e) => e.run);\n }\n}\n"],"mappings":";;;;;;;;;;;;AASA,IAAa,aAAb,MAA2B;CACzB,2BAAoB,IAAI,IAA4C;;;;;;CAOpE,IAAI,SAAiB,OAA2B,KAAoB;EAClE,MAAM,QAAQ;GAAE,OAAO,SAAS;GAAS;EAAI;EAC7C,MAAM,OAAO,KAAK,SAAS,IAAI,OAAO,qBAAK,IAAI,IAAI;EACnD,KAAK,IAAI,KAAK;EACd,KAAK,SAAS,IAAI,SAAS,IAAI;EAC/B,aAAa;GACX,KAAK,OAAO,KAAK;GACjB,IAAI,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI,OAAO,MAAM,MACpD,KAAK,SAAS,OAAO,OAAO;EAEhC;CACF;;CAGA,SAAS,SAAiB,OAAqB;EAE7C,OAAO,CADO,GAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,CACvC,CAAC,CAAC,QAAQ,UAAU,UAAU,KAAA,KAAa,MAAM,UAAU,KAAK,CAAC,CAAC,KAAK,MAAM,EAAE,GAAG;CAC9F;AACF"}
|
|
@@ -26,8 +26,7 @@ function pushAll(entries, sources, hook) {
|
|
|
26
26
|
pushHook(entries, sources.database, hook);
|
|
27
27
|
pushHook(entries, sources.storage, hook);
|
|
28
28
|
pushHook(entries, sources.captureRunner, hook);
|
|
29
|
-
pushHook(entries,
|
|
30
|
-
for (const provider of sources.gitHosts ?? []) pushHook(entries, provider, hook);
|
|
29
|
+
for (const provider of sources.design ?? []) pushHook(entries, provider, hook);
|
|
31
30
|
for (const notifier of sources.notifiers ?? []) pushHook(entries, notifier, hook);
|
|
32
31
|
pushHook(entries, sources.emailSender, hook);
|
|
33
32
|
}
|
|
@@ -53,8 +52,7 @@ function bindAdapterLoggers(sources, logger) {
|
|
|
53
52
|
sources.database,
|
|
54
53
|
sources.storage,
|
|
55
54
|
sources.captureRunner,
|
|
56
|
-
sources.
|
|
57
|
-
...sources.gitHosts ?? [],
|
|
55
|
+
...sources.design ?? [],
|
|
58
56
|
...sources.notifiers ?? [],
|
|
59
57
|
sources.emailSender
|
|
60
58
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-runner.mjs","names":[],"sources":["../../src/adapters/setup-runner.ts"],"sourcesContent":["import type { Logger } from \"pino\";\nimport { sanitizeErrorText } from \"../utils/redact.ts\";\nimport type { AdapterLifecycle, AdapterMetadata, AdapterSetupContext } from \"./metadata.ts\";\nimport type {\n AdapterSetupFailure,\n AdapterSetupResult,\n AdapterSetupSources,\n HookEntry,\n} from \"./setup.ts\";\n\ninterface LifecycleCarrier {\n readonly metadata: AdapterMetadata;\n readonly lifecycle?: AdapterLifecycle;\n}\n\nfunction hookEntry(adapter: LifecycleCarrier, hook: \"setup\" | \"teardown\"): HookEntry | null {\n const lifecycle = adapter.lifecycle;\n if (!lifecycle) {\n return null;\n }\n const fn = lifecycle[hook];\n const { category, kind, name } = adapter.metadata;\n return {\n category,\n kind,\n name,\n run: async (ctx) => {\n await fn(ctx);\n },\n };\n}\n\nfunction pushHook(\n entries: HookEntry[],\n adapter: LifecycleCarrier | undefined,\n hook: \"setup\" | \"teardown\",\n): void {\n if (!adapter) {\n return;\n }\n const entry = hookEntry(adapter, hook);\n if (entry) {\n entries.push(entry);\n }\n}\n\nfunction pushAll(\n entries: HookEntry[],\n sources: AdapterSetupSources,\n hook: \"setup\" | \"teardown\",\n): void {\n pushHook(entries, sources.database, hook);\n pushHook(entries, sources.storage, hook);\n pushHook(entries, sources.captureRunner, hook);\n
|
|
1
|
+
{"version":3,"file":"setup-runner.mjs","names":[],"sources":["../../src/adapters/setup-runner.ts"],"sourcesContent":["import type { Logger } from \"pino\";\nimport { sanitizeErrorText } from \"../utils/redact.ts\";\nimport type { AdapterLifecycle, AdapterMetadata, AdapterSetupContext } from \"./metadata.ts\";\nimport type {\n AdapterSetupFailure,\n AdapterSetupResult,\n AdapterSetupSources,\n HookEntry,\n} from \"./setup.ts\";\n\ninterface LifecycleCarrier {\n readonly metadata: AdapterMetadata;\n readonly lifecycle?: AdapterLifecycle;\n}\n\nfunction hookEntry(adapter: LifecycleCarrier, hook: \"setup\" | \"teardown\"): HookEntry | null {\n const lifecycle = adapter.lifecycle;\n if (!lifecycle) {\n return null;\n }\n const fn = lifecycle[hook];\n const { category, kind, name } = adapter.metadata;\n return {\n category,\n kind,\n name,\n run: async (ctx) => {\n await fn(ctx);\n },\n };\n}\n\nfunction pushHook(\n entries: HookEntry[],\n adapter: LifecycleCarrier | undefined,\n hook: \"setup\" | \"teardown\",\n): void {\n if (!adapter) {\n return;\n }\n const entry = hookEntry(adapter, hook);\n if (entry) {\n entries.push(entry);\n }\n}\n\nfunction pushAll(\n entries: HookEntry[],\n sources: AdapterSetupSources,\n hook: \"setup\" | \"teardown\",\n): void {\n pushHook(entries, sources.database, hook);\n pushHook(entries, sources.storage, hook);\n pushHook(entries, sources.captureRunner, hook);\n for (const provider of sources.design ?? []) {\n pushHook(entries, provider, hook);\n }\n for (const notifier of sources.notifiers ?? []) {\n pushHook(entries, notifier, hook);\n }\n pushHook(entries, sources.emailSender, hook);\n}\n\n/** Collect every available `setup` hook in deterministic order. */\nexport function collectSetups(sources: AdapterSetupSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"setup\");\n return entries;\n}\n\n/** Collect every available `teardown` hook in deterministic order. */\nexport function collectTeardowns(sources: AdapterSetupSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"teardown\");\n return entries;\n}\n\ninterface LoggerCarrier {\n readonly metadata: AdapterMetadata;\n readonly setLogger?: (logger: Logger) => void;\n}\n\n/**\n * Bind the host logger on every adapter that accepts one, scoped by kind.\n * Adapters without `setLogger` keep today's behavior (silent when no\n * explicit `options.logger` was passed at construction).\n */\nexport function bindAdapterLoggers(sources: AdapterSetupSources, logger: Logger): void {\n const adapters: ReadonlyArray<LoggerCarrier | undefined> = [\n sources.database,\n sources.storage,\n sources.captureRunner,\n ...(sources.design ?? []),\n ...(sources.notifiers ?? []),\n sources.emailSender,\n ];\n for (const adapter of adapters) {\n adapter?.setLogger?.(logger.child({ component: adapter.metadata.kind }));\n }\n}\n\nfunction messageOf(reason: unknown): string {\n const text = reason instanceof Error ? reason.message : String(reason);\n return sanitizeErrorText(text, 500);\n}\n\n/** Budgets that trigger slow-hook warnings (observe only, never abort). */\nconst SLOW_SETUP_MS = 10_000;\nconst SLOW_TEARDOWN_MS = 5_000;\n\n/** Run one hook with start/done logging and a slow-hook warning. */\nasync function runHook(\n entry: HookEntry,\n ctx: AdapterSetupContext,\n logger: Logger,\n slowMs: number,\n): Promise<void> {\n const { category, kind, name } = entry;\n const started = Date.now();\n logger.info({ category, kind, name }, \"adapter hook start\");\n try {\n await entry.run(ctx);\n } finally {\n const durationMs = Date.now() - started;\n logger.info({ category, kind, name, durationMs }, \"adapter hook done\");\n if (durationMs > slowMs) {\n logger.warn({ category, kind, name, durationMs, slowMs }, \"slow adapter hook\");\n }\n }\n}\n\nfunction toFailure(entry: HookEntry, reason: unknown): AdapterSetupFailure {\n return { category: entry.category, kind: entry.kind, name: entry.name, error: messageOf(reason) };\n}\n\nfunction toResult(\n entries: HookEntry[],\n outcomes: PromiseSettledResult<void>[],\n logger: Logger,\n verb: string,\n): AdapterSetupResult {\n const failures: AdapterSetupFailure[] = [];\n for (const [index, entry] of entries.entries()) {\n const outcome: PromiseSettledResult<void> | undefined = outcomes[index];\n if (outcome?.status === \"rejected\") {\n failures.push(toFailure(entry, outcome.reason));\n }\n }\n if (failures.length > 0) {\n logger.error({ failures }, `adapter ${verb} failed`);\n } else {\n logger.info({ count: entries.length }, `adapters ${verb}d`);\n }\n return { ok: failures.length === 0, failures };\n}\n\n/** One run of collected hooks with start/done logging and hung visibility. */\nasync function runHooks(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n verb: string,\n slowMs: number,\n): Promise<AdapterSetupResult> {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n logger.warn({ count: entries.length, slowMs }, `adapters ${verb} still running`);\n }\n }, slowMs);\n timer.unref?.();\n try {\n const outcomes = await Promise.allSettled(\n entries.map(async (entry) => {\n await runHook(entry, ctx, logger, slowMs);\n }),\n );\n return toResult(entries, outcomes, logger, verb);\n } finally {\n settled = true;\n clearTimeout(timer);\n }\n}\n\n/** Run setup hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterSetups(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n): Promise<AdapterSetupResult> {\n return await runHooks(entries, ctx, logger, \"setup\", SLOW_SETUP_MS);\n}\n\n/** Run teardown hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterTeardowns(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n): Promise<AdapterSetupResult> {\n return await runHooks(entries, ctx, logger, \"teardown\", SLOW_TEARDOWN_MS);\n}\n"],"mappings":";;;;;AAeA,SAAS,UAAU,SAA2B,MAA8C;CAC1F,MAAM,YAAY,QAAQ;CAC1B,IAAI,CAAC,WACH,OAAO;CAET,MAAM,KAAK,UAAU;CACrB,MAAM,EAAE,UAAU,MAAM,SAAS,QAAQ;CACzC,OAAO;EACL;EACA;EACA;EACA,KAAK,OAAO,QAAQ;GAClB,MAAM,GAAG,GAAG;EACd;CACF;AACF;AAEA,SAAS,SACP,SACA,SACA,MACM;CACN,IAAI,CAAC,SACH;CAEF,MAAM,QAAQ,UAAU,SAAS,IAAI;CACrC,IAAI,OACF,QAAQ,KAAK,KAAK;AAEtB;AAEA,SAAS,QACP,SACA,SACA,MACM;CACN,SAAS,SAAS,QAAQ,UAAU,IAAI;CACxC,SAAS,SAAS,QAAQ,SAAS,IAAI;CACvC,SAAS,SAAS,QAAQ,eAAe,IAAI;CAC7C,KAAK,MAAM,YAAY,QAAQ,UAAU,CAAC,GACxC,SAAS,SAAS,UAAU,IAAI;CAElC,KAAK,MAAM,YAAY,QAAQ,aAAa,CAAC,GAC3C,SAAS,SAAS,UAAU,IAAI;CAElC,SAAS,SAAS,QAAQ,aAAa,IAAI;AAC7C;;AAGA,SAAgB,cAAc,SAA2C;CACvE,MAAM,UAAuB,CAAC;CAC9B,QAAQ,SAAS,SAAS,OAAO;CACjC,OAAO;AACT;;AAGA,SAAgB,iBAAiB,SAA2C;CAC1E,MAAM,UAAuB,CAAC;CAC9B,QAAQ,SAAS,SAAS,UAAU;CACpC,OAAO;AACT;;;;;;AAYA,SAAgB,mBAAmB,SAA8B,QAAsB;CACrF,MAAM,WAAqD;EACzD,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,GAAI,QAAQ,UAAU,CAAC;EACvB,GAAI,QAAQ,aAAa,CAAC;EAC1B,QAAQ;CACV;CACA,KAAK,MAAM,WAAW,UACpB,SAAS,YAAY,OAAO,MAAM,EAAE,WAAW,QAAQ,SAAS,KAAK,CAAC,CAAC;AAE3E;AAEA,SAAS,UAAU,QAAyB;CAC1C,MAAM,OAAO,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;CACrE,OAAO,kBAAkB,MAAM,GAAG;AACpC;;AAGA,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;;AAGzB,eAAe,QACb,OACA,KACA,QACA,QACe;CACf,MAAM,EAAE,UAAU,MAAM,SAAS;CACjC,MAAM,UAAU,KAAK,IAAI;CACzB,OAAO,KAAK;EAAE;EAAU;EAAM;CAAK,GAAG,oBAAoB;CAC1D,IAAI;EACF,MAAM,MAAM,IAAI,GAAG;CACrB,UAAU;EACR,MAAM,aAAa,KAAK,IAAI,IAAI;EAChC,OAAO,KAAK;GAAE;GAAU;GAAM;GAAM;EAAW,GAAG,mBAAmB;EACrE,IAAI,aAAa,QACf,OAAO,KAAK;GAAE;GAAU;GAAM;GAAM;GAAY;EAAO,GAAG,mBAAmB;CAEjF;AACF;AAEA,SAAS,UAAU,OAAkB,QAAsC;CACzE,OAAO;EAAE,UAAU,MAAM;EAAU,MAAM,MAAM;EAAM,MAAM,MAAM;EAAM,OAAO,UAAU,MAAM;CAAE;AAClG;AAEA,SAAS,SACP,SACA,UACA,QACA,MACoB;CACpB,MAAM,WAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,OAAO,UAAU,QAAQ,QAAQ,GAAG;EAC9C,MAAM,UAAkD,SAAS;EACjE,IAAI,SAAS,WAAW,YACtB,SAAS,KAAK,UAAU,OAAO,QAAQ,MAAM,CAAC;CAElD;CACA,IAAI,SAAS,SAAS,GACpB,OAAO,MAAM,EAAE,SAAS,GAAG,WAAW,KAAK,QAAQ;MAEnD,OAAO,KAAK,EAAE,OAAO,QAAQ,OAAO,GAAG,YAAY,KAAK,EAAE;CAE5D,OAAO;EAAE,IAAI,SAAS,WAAW;EAAG;CAAS;AAC/C;;AAGA,eAAe,SACb,SACA,KACA,QACA,MACA,QAC6B;CAC7B,IAAI,UAAU;CACd,MAAM,QAAQ,iBAAiB;EAC7B,IAAI,CAAC,SACH,OAAO,KAAK;GAAE,OAAO,QAAQ;GAAQ;EAAO,GAAG,YAAY,KAAK,eAAe;CAEnF,GAAG,MAAM;CACT,MAAM,QAAQ;CACd,IAAI;EAMF,OAAO,SAAS,SAAS,MALF,QAAQ,WAC7B,QAAQ,IAAI,OAAO,UAAU;GAC3B,MAAM,QAAQ,OAAO,KAAK,QAAQ,MAAM;EAC1C,CAAC,CACH,GACmC,QAAQ,IAAI;CACjD,UAAU;EACR,UAAU;EACV,aAAa,KAAK;CACpB;AACF;;AAGA,eAAsB,iBACpB,SACA,KACA,QAC6B;CAC7B,OAAO,MAAM,SAAS,SAAS,KAAK,QAAQ,SAAS,aAAa;AACpE;;AAGA,eAAsB,oBACpB,SACA,KACA,QAC6B;CAC7B,OAAO,MAAM,SAAS,SAAS,KAAK,QAAQ,YAAY,gBAAgB;AAC1E"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import __tsdown_shims_path from 'node:path';
|
|
2
|
+
import __tsdown_shims_url from 'node:url';
|
|
3
|
+
import { ShelfOptions } from "../config.mjs";
|
|
4
|
+
import { AdapterSetupSources } from "../adapter/setup.mjs";
|
|
5
|
+
//#region src/adapters/sources.d.ts
|
|
6
|
+
/** The adapter slots of `options`, with `auth` carried along for boot validation. */
|
|
7
|
+
declare function adapterSourcesOf(options: ShelfOptions): AdapterSetupSources & {
|
|
8
|
+
auth?: unknown;
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { adapterSourcesOf };
|
|
12
|
+
//# sourceMappingURL=sources.d.mts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
//#region src/adapters/sources.ts
|
|
5
|
+
/** The adapter slots of `options`, with `auth` carried along for boot validation. */
|
|
6
|
+
function adapterSourcesOf(options) {
|
|
7
|
+
return {
|
|
8
|
+
database: options.database,
|
|
9
|
+
storage: options.storage,
|
|
10
|
+
captureRunner: options.testing?.runner,
|
|
11
|
+
design: options.design,
|
|
12
|
+
notifiers: options.notifications?.notifiers,
|
|
13
|
+
emailSender: options.notifications?.emailSender,
|
|
14
|
+
auth: options.auth
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { adapterSourcesOf };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=sources.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.mjs","names":[],"sources":["../../src/adapters/sources.ts"],"sourcesContent":["/** Maps `ShelfOptions` to the flat adapter slots lifecycle, validation and health probing work on. */\nimport type { ShelfOptions } from \"../config.ts\";\nimport type { AdapterSetupSources } from \"./setup.ts\";\n\n/** The adapter slots of `options`, with `auth` carried along for boot validation. */\nexport function adapterSourcesOf(options: ShelfOptions): AdapterSetupSources & { auth?: unknown } {\n return {\n database: options.database,\n storage: options.storage,\n captureRunner: options.testing?.runner,\n design: options.design,\n notifiers: options.notifications?.notifiers,\n emailSender: options.notifications?.emailSender,\n auth: options.auth,\n };\n}\n"],"mappings":";;;;;AAKA,SAAgB,iBAAiB,SAAiE;CAChG,OAAO;EACL,UAAU,QAAQ;EAClB,SAAS,QAAQ;EACjB,eAAe,QAAQ,SAAS;EAChC,QAAQ,QAAQ;EAChB,WAAW,QAAQ,eAAe;EAClC,aAAa,QAAQ,eAAe;EACpC,MAAM,QAAQ;CAChB;AACF"}
|
|
@@ -119,13 +119,13 @@ function emailSenderReasons(sender) {
|
|
|
119
119
|
if (typeof record["send"] !== "function") reasons.push("missing methods: send");
|
|
120
120
|
return reasons;
|
|
121
121
|
}
|
|
122
|
-
/** Reasons a
|
|
123
|
-
function
|
|
122
|
+
/** Reasons a design provider lacks its descriptor shape. */
|
|
123
|
+
function designReasons(provider) {
|
|
124
124
|
const record = asRecord(provider);
|
|
125
|
-
if (!record) return ["
|
|
126
|
-
const reasons = metadataReasons(record, "
|
|
127
|
-
|
|
128
|
-
if (
|
|
125
|
+
if (!record) return ["design provider must be an object"];
|
|
126
|
+
const reasons = metadataReasons(record, "design");
|
|
127
|
+
const missing = ["parseUrl", "create"].filter((name) => typeof record[name] !== "function");
|
|
128
|
+
if (missing.length > 0) reasons.push(`missing methods: ${missing.join(", ")}`);
|
|
129
129
|
return reasons;
|
|
130
130
|
}
|
|
131
131
|
/** Required methods for a slot category. */
|
|
@@ -213,17 +213,29 @@ function checkAuth(auth) {
|
|
|
213
213
|
error: reasons.join("; ")
|
|
214
214
|
}];
|
|
215
215
|
}
|
|
216
|
-
|
|
216
|
+
const PROVIDER_KINDS = {
|
|
217
|
+
design: {
|
|
218
|
+
reasons: designReasons,
|
|
219
|
+
list: "design",
|
|
220
|
+
category: "design"
|
|
221
|
+
},
|
|
222
|
+
notifier: {
|
|
223
|
+
reasons: notifierReasons,
|
|
224
|
+
list: "notifiers",
|
|
225
|
+
category: "notifier"
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
/** Failures for design or notifier provider lists. */
|
|
217
229
|
function checkProviders(checks) {
|
|
218
230
|
const failures = [];
|
|
219
231
|
for (const check of checks) {
|
|
220
|
-
const
|
|
232
|
+
const kind = PROVIDER_KINDS[check.kinds];
|
|
233
|
+
const reasons = kind.reasons(check.provider);
|
|
221
234
|
if (reasons.length === 0) continue;
|
|
222
|
-
const slot =
|
|
223
|
-
const category = check.kinds === "git" ? "git-host" : "notifier";
|
|
235
|
+
const slot = `${kind.list}[${check.index}]`;
|
|
224
236
|
const metadata = asRecord(asRecord(check.provider)?.["metadata"]);
|
|
225
237
|
failures.push({
|
|
226
|
-
category,
|
|
238
|
+
category: kind.category,
|
|
227
239
|
kind: stringField(metadata, "kind") ?? "unknown",
|
|
228
240
|
name: stringField(metadata, "name") ?? slot,
|
|
229
241
|
error: reasons.map((reason) => `${slot}: ${reason}`).join("; ")
|
|
@@ -279,15 +291,10 @@ function validateAdapterSources(sources) {
|
|
|
279
291
|
category: "capture-runner",
|
|
280
292
|
slot: "captureRunner"
|
|
281
293
|
});
|
|
282
|
-
|
|
283
|
-
adapter: sources.captureQueue,
|
|
284
|
-
category: "capture-queue",
|
|
285
|
-
slot: "captureQueue"
|
|
286
|
-
});
|
|
287
|
-
const providers = [...(sources.gitHosts ?? []).map((provider, index) => ({
|
|
294
|
+
const providers = [...(sources.design ?? []).map((provider, index) => ({
|
|
288
295
|
provider,
|
|
289
296
|
index,
|
|
290
|
-
kinds: "
|
|
297
|
+
kinds: "design"
|
|
291
298
|
})), ...(sources.notifiers ?? []).map((provider, index) => ({
|
|
292
299
|
provider,
|
|
293
300
|
index,
|