@storyshelf/core 0.7.0 → 0.8.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/dist/adapter/capture-queue.d.mts +0 -2
- package/dist/adapter/capture-runner.d.mts +9 -4
- package/dist/adapter/capture-runner.mjs +6 -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 +112 -31
- package/dist/adapters/remote-browser.mjs +132 -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/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 +0 -2
- package/dist/capture/fingerprint.mjs +1 -2
- 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 +37 -6
- 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 +0 -2
- package/dist/models/design-health.mjs +1 -2
- package/dist/models/design-nodes.d.mts +2 -4
- package/dist/models/design-nodes.mjs +1 -2
- 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 +5 -2
- package/dist/models.mjs +5 -2
- 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 +0 -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 +5 -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 -6
package/dist/models/snapshot.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import "../adapters/capture-target.mjs";
|
|
|
5
5
|
import { ulid } from "../utils/ulid.mjs";
|
|
6
6
|
import { col } from "./columns.mjs";
|
|
7
7
|
import { and, eq, inArray } from "drizzle-orm";
|
|
8
|
-
|
|
8
|
+
// src/models/snapshot.ts
|
|
9
9
|
/** Snapshot records for captured stories within a build. */
|
|
10
10
|
/** Data operations for snapshot records. */
|
|
11
11
|
var SnapshotModel = class {
|
|
@@ -45,6 +45,9 @@ var SnapshotModel = class {
|
|
|
45
45
|
infraHash: input.infraHash ?? null,
|
|
46
46
|
envChange: input.envChange ?? null,
|
|
47
47
|
inherited: input.inherited ?? false,
|
|
48
|
+
sourceBuildId: input.inherited ? input.sourceBuildId ?? null : buildId,
|
|
49
|
+
comparisonImagePath: input.comparisonImagePath ?? null,
|
|
50
|
+
comparisonMetadata: input.comparisonMetadata ?? null,
|
|
48
51
|
baselineId: input.baselineId ?? null,
|
|
49
52
|
baselineVersion: input.baselineVersion ?? null,
|
|
50
53
|
mode: input.mode ?? null,
|
|
@@ -123,7 +126,6 @@ var SnapshotModel = class {
|
|
|
123
126
|
});
|
|
124
127
|
}
|
|
125
128
|
};
|
|
126
|
-
//#endregion
|
|
127
129
|
export { SnapshotModel };
|
|
128
130
|
|
|
129
131
|
//# sourceMappingURL=snapshot.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.mjs","names":[],"sources":["../../src/models/snapshot.ts"],"sourcesContent":["/** Snapshot records for captured stories within a build. */\nimport { and, eq, inArray } from \"drizzle-orm\";\nimport type { Table } from \"drizzle-orm\";\nimport { DEFAULT_BROWSER } from \"../adapters/capture-runner.ts\";\nimport type { DatabaseAdapter } from \"../adapters/database.ts\";\nimport type { Snapshot } from \"../schema/snapshot.ts\";\nimport type { SnapshotStatus } from \"../types.ts\";\nimport { ulid } from \"../utils/ulid.ts\";\nimport { col } from \"./columns.ts\";\n\n/** Tables required by {@link SnapshotModel}. */\nexport interface SnapshotTables {\n snapshots: Table;\n}\n\n/** Data operations for snapshot records. */\nexport class SnapshotModel {\n private readonly tables: SnapshotTables;\n private readonly db: DatabaseAdapter;\n\n /**\n * @param db - Database adapter.\n * @param tables - Table handles.\n */\n constructor(db: DatabaseAdapter, tables?: SnapshotTables) {\n this.db = db;\n this.tables = tables ?? { snapshots: db.tables.snapshots };\n }\n\n /**\n * Create a snapshot for a story within a build.\n *\n * @param projectId - Project ID.\n * @param buildId - Build ID.\n * @param input - Snapshot creation input.\n * @returns The created snapshot.\n */\n async create(projectId: string, buildId: string, input: SnapshotCreateInput): Promise<Snapshot> {\n const now = new Date().toISOString();\n return (await this.db.insert(this.tables.snapshots, {\n id: ulid(),\n projectId,\n buildId,\n storyId: input.storyId,\n storyName: input.storyName,\n storyTitle: input.storyTitle,\n storyImportPath: input.storyImportPath,\n designUrl: input.designUrl ?? null,\n viewportName: input.viewportName,\n viewportWidth: input.viewportWidth,\n viewportHeight: input.viewportHeight,\n screenshotPath: input.screenshotPath,\n infraHash: input.infraHash ?? null,\n envChange: input.envChange ?? null,\n inherited: input.inherited ?? false,\n baselineId: input.baselineId ?? null,\n baselineVersion: input.baselineVersion ?? null,\n mode: input.mode ?? null,\n browser: input.browser ?? DEFAULT_BROWSER,\n durationMs: input.durationMs ?? null,\n a11yViolations: input.a11yViolations ?? null,\n status: \"pending\",\n createdAt: now,\n updatedAt: now,\n })) as unknown as Snapshot;\n }\n\n /**\n * Delete the rendered snapshots a shard is about to write again: rows of `(story, engine)` pairs\n * in `work`, so a rerun starts from a clean slate instead of colliding with rows an earlier,\n * interrupted run left behind. Inherited rows are kept: the plan wrote them, for engines or\n * viewports this shard does not render.\n */\n async removeRendered(\n buildId: string,\n work: readonly { browser: string; storyIds: ReadonlySet<string> }[],\n ): Promise<number> {\n const doomed = (await this.listByBuild(buildId)).filter(\n (row) =>\n !row.inherited &&\n work.some(\n (engine) =>\n engine.browser === (row.browser ?? DEFAULT_BROWSER) && engine.storyIds.has(row.storyId),\n ),\n );\n await this.#removeAll(doomed);\n return doomed.length;\n }\n\n /** Delete every snapshot of a build: a new plan of it starts clean. */\n async removeForBuild(buildId: string): Promise<number> {\n const doomed = await this.listByBuild(buildId);\n await this.#removeAll(doomed);\n return doomed.length;\n }\n\n async #removeAll(rows: readonly Snapshot[]): Promise<void> {\n await Promise.all(\n rows.map(async (row) => {\n await this.db.remove(this.tables.snapshots, row.id);\n }),\n );\n }\n\n /**\n * Milliseconds each story cost on one build, summed over its viewports and engines. Stories the\n * renderer did not time are left out, so an empty map means this build carries no timings.\n */\n async durationsByStory(buildId: string): Promise<Map<string, number>> {\n const totals = new Map<string, number>();\n for (const row of await this.listByBuild(buildId)) {\n if (typeof row.durationMs === \"number\") {\n totals.set(row.storyId, (totals.get(row.storyId) ?? 0) + row.durationMs);\n }\n }\n return totals;\n }\n\n /** List all snapshots belonging to a build. */\n async listByBuild(buildId: string): Promise<Snapshot[]> {\n return (await this.db.list(this.tables.snapshots, {\n where: eq(col(this.tables.snapshots, \"buildId\"), buildId),\n })) as unknown as Snapshot[];\n }\n\n /**\n * Every snapshot of a story file across the project's builds. Index paths are\n * stored raw (`./src/A.stories.tsx`), so both spellings of `importPath` match.\n */\n async listByImportPath(projectId: string, importPath: string): Promise<Snapshot[]> {\n const bare = importPath.replace(/^(?:\\.\\/)+/u, \"\");\n return (await this.db.list(this.tables.snapshots, {\n where: and(\n eq(col(this.tables.snapshots, \"projectId\"), projectId),\n inArray(col(this.tables.snapshots, \"storyImportPath\"), [bare, `./${bare}`]),\n ),\n })) as unknown as Snapshot[];\n }\n\n /** Fetch a snapshot by id, or null if not found. */\n async get(id: string): Promise<Snapshot | null> {\n return (await this.db.get(this.tables.snapshots, id)) as unknown as Snapshot | null;\n }\n\n /** Update mutable fields of a snapshot. */\n async update(id: string, patch: Partial<Snapshot>): Promise<Snapshot> {\n return (await this.db.update(this.tables.snapshots, id, {\n ...patch,\n updatedAt: new Date().toISOString(),\n })) as unknown as Snapshot;\n }\n\n /** Set the status of a snapshot. */\n async setStatus(id: string, status: SnapshotStatus): Promise<Snapshot> {\n return await this.update(id, { status });\n }\n\n /** Record a reviewer's decision on a snapshot. */\n async review(id: string, status: SnapshotStatus, userId: string | null): Promise<Snapshot> {\n return await this.update(id, {\n status,\n reviewedBy: userId,\n reviewedAt: new Date().toISOString(),\n });\n }\n}\n\n/** Input for creating a snapshot. */\nexport interface SnapshotCreateInput {\n storyId: string;\n storyName: string;\n storyTitle: string;\n storyImportPath?: string;\n /** Figma URL declared by the story (`parameters.design` / `storyshelf.figma`). */\n designUrl?: string | null;\n viewportName: string;\n viewportWidth: number;\n viewportHeight: number;\n screenshotPath: string;\n infraHash?: string | null;\n /** JSON `EnvironmentChange` when accepted as an environment migration. */\n envChange?: string | null;\n inherited?: boolean;\n baselineId?: string | null;\n baselineVersion?: string | null;\n /** Resolved mode definition as JSON (display/capture only). */\n mode?: string | null;\n /** Engine the screenshot was captured with (default chromium). */\n browser?: string;\n /** Milliseconds the renderer spent on this capture, when it reported any. */\n durationMs?: number | null;\n /** JSON array of axe violation texts found on this capture; null when none. */\n a11yViolations?: string | null;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snapshot.mjs","names":[],"sources":["../../src/models/snapshot.ts"],"sourcesContent":["/** Snapshot records for captured stories within a build. */\nimport { and, eq, inArray } from \"drizzle-orm\";\nimport type { Table } from \"drizzle-orm\";\nimport { DEFAULT_BROWSER } from \"../adapters/capture-runner.ts\";\nimport type { DatabaseAdapter } from \"../adapters/database.ts\";\nimport type { Snapshot } from \"../schema/snapshot.ts\";\nimport type { SnapshotStatus } from \"../types.ts\";\nimport { ulid } from \"../utils/ulid.ts\";\nimport { col } from \"./columns.ts\";\n\n/** Tables required by {@link SnapshotModel}. */\nexport interface SnapshotTables {\n snapshots: Table;\n}\n\n/** Data operations for snapshot records. */\nexport class SnapshotModel {\n private readonly tables: SnapshotTables;\n private readonly db: DatabaseAdapter;\n\n /**\n * @param db - Database adapter.\n * @param tables - Table handles.\n */\n constructor(db: DatabaseAdapter, tables?: SnapshotTables) {\n this.db = db;\n this.tables = tables ?? { snapshots: db.tables.snapshots };\n }\n\n /**\n * Create a snapshot for a story within a build.\n *\n * @param projectId - Project ID.\n * @param buildId - Build ID.\n * @param input - Snapshot creation input.\n * @returns The created snapshot.\n */\n async create(projectId: string, buildId: string, input: SnapshotCreateInput): Promise<Snapshot> {\n const now = new Date().toISOString();\n return (await this.db.insert(this.tables.snapshots, {\n id: ulid(),\n projectId,\n buildId,\n storyId: input.storyId,\n storyName: input.storyName,\n storyTitle: input.storyTitle,\n storyImportPath: input.storyImportPath,\n designUrl: input.designUrl ?? null,\n viewportName: input.viewportName,\n viewportWidth: input.viewportWidth,\n viewportHeight: input.viewportHeight,\n screenshotPath: input.screenshotPath,\n infraHash: input.infraHash ?? null,\n envChange: input.envChange ?? null,\n inherited: input.inherited ?? false,\n sourceBuildId: input.inherited ? (input.sourceBuildId ?? null) : buildId,\n comparisonImagePath: input.comparisonImagePath ?? null,\n comparisonMetadata: input.comparisonMetadata ?? null,\n baselineId: input.baselineId ?? null,\n baselineVersion: input.baselineVersion ?? null,\n mode: input.mode ?? null,\n browser: input.browser ?? DEFAULT_BROWSER,\n durationMs: input.durationMs ?? null,\n a11yViolations: input.a11yViolations ?? null,\n status: \"pending\",\n createdAt: now,\n updatedAt: now,\n })) as unknown as Snapshot;\n }\n\n /**\n * Delete the rendered snapshots a shard is about to write again: rows of `(story, engine)` pairs\n * in `work`, so a rerun starts from a clean slate instead of colliding with rows an earlier,\n * interrupted run left behind. Inherited rows are kept: the plan wrote them, for engines or\n * viewports this shard does not render.\n */\n async removeRendered(\n buildId: string,\n work: readonly { browser: string; storyIds: ReadonlySet<string> }[],\n ): Promise<number> {\n const doomed = (await this.listByBuild(buildId)).filter(\n (row) =>\n !row.inherited &&\n work.some(\n (engine) =>\n engine.browser === (row.browser ?? DEFAULT_BROWSER) && engine.storyIds.has(row.storyId),\n ),\n );\n await this.#removeAll(doomed);\n return doomed.length;\n }\n\n /** Delete every snapshot of a build: a new plan of it starts clean. */\n async removeForBuild(buildId: string): Promise<number> {\n const doomed = await this.listByBuild(buildId);\n await this.#removeAll(doomed);\n return doomed.length;\n }\n\n async #removeAll(rows: readonly Snapshot[]): Promise<void> {\n await Promise.all(\n rows.map(async (row) => {\n await this.db.remove(this.tables.snapshots, row.id);\n }),\n );\n }\n\n /**\n * Milliseconds each story cost on one build, summed over its viewports and engines. Stories the\n * renderer did not time are left out, so an empty map means this build carries no timings.\n */\n async durationsByStory(buildId: string): Promise<Map<string, number>> {\n const totals = new Map<string, number>();\n for (const row of await this.listByBuild(buildId)) {\n if (typeof row.durationMs === \"number\") {\n totals.set(row.storyId, (totals.get(row.storyId) ?? 0) + row.durationMs);\n }\n }\n return totals;\n }\n\n /** List all snapshots belonging to a build. */\n async listByBuild(buildId: string): Promise<Snapshot[]> {\n return (await this.db.list(this.tables.snapshots, {\n where: eq(col(this.tables.snapshots, \"buildId\"), buildId),\n })) as unknown as Snapshot[];\n }\n\n /**\n * Every snapshot of a story file across the project's builds. Index paths are\n * stored raw (`./src/A.stories.tsx`), so both spellings of `importPath` match.\n */\n async listByImportPath(projectId: string, importPath: string): Promise<Snapshot[]> {\n const bare = importPath.replace(/^(?:\\.\\/)+/u, \"\");\n return (await this.db.list(this.tables.snapshots, {\n where: and(\n eq(col(this.tables.snapshots, \"projectId\"), projectId),\n inArray(col(this.tables.snapshots, \"storyImportPath\"), [bare, `./${bare}`]),\n ),\n })) as unknown as Snapshot[];\n }\n\n /** Fetch a snapshot by id, or null if not found. */\n async get(id: string): Promise<Snapshot | null> {\n return (await this.db.get(this.tables.snapshots, id)) as unknown as Snapshot | null;\n }\n\n /** Update mutable fields of a snapshot. */\n async update(id: string, patch: Partial<Snapshot>): Promise<Snapshot> {\n return (await this.db.update(this.tables.snapshots, id, {\n ...patch,\n updatedAt: new Date().toISOString(),\n })) as unknown as Snapshot;\n }\n\n /** Set the status of a snapshot. */\n async setStatus(id: string, status: SnapshotStatus): Promise<Snapshot> {\n return await this.update(id, { status });\n }\n\n /** Record a reviewer's decision on a snapshot. */\n async review(id: string, status: SnapshotStatus, userId: string | null): Promise<Snapshot> {\n return await this.update(id, {\n status,\n reviewedBy: userId,\n reviewedAt: new Date().toISOString(),\n });\n }\n}\n\n/** Input for creating a snapshot. */\nexport interface SnapshotCreateInput {\n storyId: string;\n storyName: string;\n storyTitle: string;\n storyImportPath?: string;\n /** Figma URL declared by the story (`parameters.design` / `storyshelf.figma`). */\n designUrl?: string | null;\n viewportName: string;\n viewportWidth: number;\n viewportHeight: number;\n screenshotPath: string;\n infraHash?: string | null;\n /** JSON `EnvironmentChange` when accepted as an environment migration. */\n envChange?: string | null;\n inherited?: boolean;\n sourceBuildId?: string | null;\n comparisonImagePath?: string | null;\n comparisonMetadata?: string | null;\n baselineId?: string | null;\n baselineVersion?: string | null;\n /** Resolved mode definition as JSON (display/capture only). */\n mode?: string | null;\n /** Engine the screenshot was captured with (default chromium). */\n browser?: string;\n /** Milliseconds the renderer spent on this capture, when it reported any. */\n durationMs?: number | null;\n /** JSON array of axe violation texts found on this capture; null when none. */\n a11yViolations?: string | null;\n}\n"],"mappings":"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"}
|
package/dist/models/token.d.mts
CHANGED
|
@@ -3,7 +3,6 @@ import __tsdown_shims_url from 'node:url';
|
|
|
3
3
|
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
4
|
import { Token } from "../schema/token.mjs";
|
|
5
5
|
import { Table } from "drizzle-orm";
|
|
6
|
-
//#region src/models/token.d.ts
|
|
7
6
|
/** Tables required by {@link TokenModel}. */
|
|
8
7
|
interface TokenTables {
|
|
9
8
|
tokens: Table;
|
|
@@ -51,6 +50,5 @@ declare class TokenModel {
|
|
|
51
50
|
/** Delete a token by id. */
|
|
52
51
|
remove(id: string): Promise<void>;
|
|
53
52
|
}
|
|
54
|
-
//#endregion
|
|
55
53
|
export { TokenModel, TokenTables };
|
|
56
54
|
//# sourceMappingURL=token.d.mts.map
|
package/dist/models/token.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { randomToken } from "../utils/hash.mjs";
|
|
|
5
5
|
import { ulid } from "../utils/ulid.mjs";
|
|
6
6
|
import { col } from "./columns.mjs";
|
|
7
7
|
import { and, eq } from "drizzle-orm";
|
|
8
|
-
|
|
8
|
+
// src/models/token.ts
|
|
9
9
|
/** CI tokens for project-scoped API access. */
|
|
10
10
|
/** Data operations for CI tokens. */
|
|
11
11
|
var TokenModel = class {
|
|
@@ -76,7 +76,6 @@ var TokenModel = class {
|
|
|
76
76
|
await this.db.remove(this.tables.tokens, id);
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
|
-
//#endregion
|
|
80
79
|
export { TokenModel };
|
|
81
80
|
|
|
82
81
|
//# sourceMappingURL=token.mjs.map
|
package/dist/models/usage.d.mts
CHANGED
|
@@ -3,7 +3,6 @@ import __tsdown_shims_url from 'node:url';
|
|
|
3
3
|
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
4
|
import { BuildPackageUsage, ProjectLink } from "../schema/usage.mjs";
|
|
5
5
|
import { Table } from "drizzle-orm";
|
|
6
|
-
//#region src/models/usage.d.ts
|
|
7
6
|
/** Tables required by {@link PackageUsageModel}. */
|
|
8
7
|
interface PackageUsageTables {
|
|
9
8
|
buildPackageUsage: Table;
|
|
@@ -71,6 +70,5 @@ declare class PackageUsageModel {
|
|
|
71
70
|
private atomic;
|
|
72
71
|
private buildWhere;
|
|
73
72
|
}
|
|
74
|
-
//#endregion
|
|
75
73
|
export { PackageUsageInput, PackageUsageModel, PackageUsageTables, UpstreamStory, matchUpstreamStory };
|
|
76
74
|
//# sourceMappingURL=usage.d.mts.map
|
package/dist/models/usage.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { ulid } from "../utils/ulid.mjs";
|
|
5
5
|
import { col } from "./columns.mjs";
|
|
6
6
|
import { and, eq } from "drizzle-orm";
|
|
7
|
-
|
|
7
|
+
// src/models/usage.ts
|
|
8
8
|
/** Per-build package usage and cross-project package links. */
|
|
9
9
|
/** `Button.stories.tsx` / `Button.js` / `Button/index.js` → `Button`. */
|
|
10
10
|
function componentStem(path) {
|
|
@@ -143,7 +143,6 @@ async function serialized(key, task) {
|
|
|
143
143
|
if (pending.get(key) === tail) pending.delete(key);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
|
-
//#endregion
|
|
147
146
|
export { PackageUsageModel, matchUpstreamStory };
|
|
148
147
|
|
|
149
148
|
//# sourceMappingURL=usage.mjs.map
|
package/dist/models/user.d.mts
CHANGED
|
@@ -3,7 +3,6 @@ import __tsdown_shims_url from 'node:url';
|
|
|
3
3
|
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
4
|
import { User } from "../schema/user.mjs";
|
|
5
5
|
import { Table } from "drizzle-orm";
|
|
6
|
-
//#region src/models/user.d.ts
|
|
7
6
|
/** Tables required by {@link UserModel}. */
|
|
8
7
|
interface UserTables {
|
|
9
8
|
users: Table;
|
|
@@ -37,6 +36,5 @@ declare class UserModel {
|
|
|
37
36
|
/** Update the display name override for a user (profile edit). */
|
|
38
37
|
setDisplayNameOverride(id: string, displayName: string | null): Promise<User>;
|
|
39
38
|
}
|
|
40
|
-
//#endregion
|
|
41
39
|
export { UserModel, UserTables };
|
|
42
40
|
//# sourceMappingURL=user.d.mts.map
|
package/dist/models/user.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { col } from "./columns.mjs";
|
|
5
5
|
import { eq } from "drizzle-orm";
|
|
6
|
-
|
|
6
|
+
// src/models/user.ts
|
|
7
7
|
/** User lookups for token and membership resolution. */
|
|
8
8
|
/** Data operations for users. */
|
|
9
9
|
var UserModel = class {
|
|
@@ -60,7 +60,6 @@ var UserModel = class {
|
|
|
60
60
|
return await this.db.update(this.tables.users, id, { displayNameOverride: displayName?.trim() ? displayName.trim() : null });
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
|
-
//#endregion
|
|
64
63
|
export { UserModel };
|
|
65
64
|
|
|
66
65
|
//# sourceMappingURL=user.mjs.map
|
|
@@ -4,7 +4,6 @@ import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
|
4
4
|
import { Webhook } from "../schema/webhook.mjs";
|
|
5
5
|
import { SecretInput } from "../utils/encrypt.mjs";
|
|
6
6
|
import { Table } from "drizzle-orm";
|
|
7
|
-
//#region src/models/webhook.d.ts
|
|
8
7
|
/** Tables required by {@link WebhookModel}. */
|
|
9
8
|
interface WebhookTables {
|
|
10
9
|
webhooks: Table;
|
|
@@ -59,6 +58,5 @@ interface WebhookCreateInput {
|
|
|
59
58
|
events?: string[];
|
|
60
59
|
secret: string;
|
|
61
60
|
}
|
|
62
|
-
//#endregion
|
|
63
61
|
export { WebhookCreateInput, WebhookModel, WebhookTables };
|
|
64
62
|
//# sourceMappingURL=webhook.d.mts.map
|
package/dist/models/webhook.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { decryptCredential, encrypt } from "../utils/encrypt.mjs";
|
|
|
6
6
|
import { ulid } from "../utils/ulid.mjs";
|
|
7
7
|
import { col } from "./columns.mjs";
|
|
8
8
|
import { eq } from "drizzle-orm";
|
|
9
|
-
|
|
9
|
+
// src/models/webhook.ts
|
|
10
10
|
/** Webhook subscriptions for project events. */
|
|
11
11
|
/** Data operations for webhook subscriptions. */
|
|
12
12
|
var WebhookModel = class {
|
|
@@ -101,7 +101,6 @@ var WebhookModel = class {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
|
-
//#endregion
|
|
105
104
|
export { WebhookModel };
|
|
106
105
|
|
|
107
106
|
//# sourceMappingURL=webhook.mjs.map
|
package/dist/models.d.mts
CHANGED
|
@@ -5,15 +5,18 @@ import { BuildCreateInput, BuildListFilter, BuildModel, isPublicBuild } from "./
|
|
|
5
5
|
import { AttemptLogRecorder, CaptureAttemptModel, CaptureAttemptTables, emitAttemptLog } from "./models/capture-attempt.mjs";
|
|
6
6
|
import { CaptureLogModel, CaptureLogTables } from "./models/capture-log.mjs";
|
|
7
7
|
import { ProjectCreateInput, ProjectModel } from "./models/project.mjs";
|
|
8
|
+
import { BaselineWriteConflict } from "./models/baseline-conflict.mjs";
|
|
9
|
+
import { BaselineStatus, NO_BASELINE, baselineStatus, isBaselineDrifted } from "./models/baseline-status.mjs";
|
|
10
|
+
import { BaselineApprovalConflict } from "./models/baseline-approval.mjs";
|
|
8
11
|
import { BaselineModel } from "./models/baseline.mjs";
|
|
9
12
|
import { SnapshotCreateInput, SnapshotModel } from "./models/snapshot.mjs";
|
|
10
13
|
import { AttemptClaim, CaptureJobModel, CaptureJobTables, NewCaptureJob, TERMINAL_JOB_STATUSES, attemptRowId, isTerminalJob, parseAttemptRowId } from "./models/capture-job.mjs";
|
|
11
14
|
import { BuildComponentInput, BuildComponentModel, BuildComponentTables } from "./models/build-component.mjs";
|
|
12
15
|
import { ComponentHistoryRow, ComponentPresence, componentHistory, componentPresence, worstStatus } from "./models/component.mjs";
|
|
16
|
+
import { BaselineOriginReader, resolveBaselineOrigin } from "./models/baseline-origin.mjs";
|
|
13
17
|
import { BASELINE_ARCHIVE_FORMAT, BASELINE_ARCHIVE_LIMITS, BASELINE_ARCHIVE_VERSION, BaselineArchiveError, BaselineManifest, BaselineManifestEntry } from "./models/baseline-archive.mjs";
|
|
14
18
|
import { BaselineExportOptions } from "./models/baseline-export.mjs";
|
|
15
19
|
import { BaselineImportResult, BaselineTransferModel } from "./models/baseline-transfer.mjs";
|
|
16
|
-
import { BaselineStatus, NO_BASELINE, baselineStatus, isBaselineDrifted } from "./models/baseline-status.mjs";
|
|
17
20
|
import { CaptureShardModel, CaptureShardTables } from "./models/capture-shard.mjs";
|
|
18
21
|
import { AiBudgetAlertModel, AiBudgetAlertTables } from "./models/ai-budget-alert.mjs";
|
|
19
22
|
import { AiUsageInput, AiUsageModel, AiUsageTables } from "./models/ai-usage.mjs";
|
|
@@ -42,4 +45,4 @@ import { ContentRefModel } from "./models/content-ref.mjs";
|
|
|
42
45
|
import { CredentialProbe, ReencryptResult, UnreadableCredential, probeCredentials, reencryptCredentials } from "./models/credentials.mjs";
|
|
43
46
|
import { SiteSettingsModel, SiteSettingsTables } from "./models/site-settings.mjs";
|
|
44
47
|
import { PUBLIC_ORIGIN_KEY, PublicOriginOptions, PublicOriginResolver, PublicOriginSource, ResolvedPublicOrigin, StoredPublicOrigin, createPublicOriginResolver } from "./models/public-origin.mjs";
|
|
45
|
-
export { AiBudgetAlertModel, type AiBudgetAlertTables, type AiUsageInput, AiUsageModel, type AiUsageTables, type AttemptClaim, type AttemptLogRecorder, BASELINE_ARCHIVE_FORMAT, BASELINE_ARCHIVE_LIMITS, BASELINE_ARCHIVE_VERSION, BaselineArchiveError, type BaselineExportOptions, type BaselineImportResult, type BaselineManifest, type BaselineManifestEntry, BaselineModel, type BaselineStatus, BaselineTransferModel, type BuildChangeset, type BuildComponentInput, BuildComponentModel, type BuildComponentTables, type BuildCreateInput, type BuildListFilter, BuildModel, BuildReviewModel, type BuildReviewTables, CaptureAttemptModel, type CaptureAttemptTables, CaptureJobModel, type CaptureJobTables, CaptureLogModel, type CaptureLogTables, CaptureShardModel, type CaptureShardTables, type ChangedComponent, type Changeset, type ChangesetComponent, type ChannelValidation, type CommentCreateInput, CommentModel, type ComponentHistoryRow, type ComponentPresence, ConnectionModel, type ConnectionTables, ContentRefModel, type CredentialProbe, DESIGN_TTL_MS, DesignCredentialModel, type DesignCredentialStatus, type DesignCredentialTables, DesignModel, DesignNodeModel, type DesignNodeTables, type DesignResolution, type DesignSource, type DesignTables, type InheritedRatio, InsightModel, type InsightResultInput, type InsightStartInput, type InsightStartResult, type InsightTables, LabelModel, MemberModel, NO_BASELINE, type NewCaptureJob, type NotificationChannelCreateInput, NotificationChannelModel, type NotificationChannelTables, type NotificationSubscriptionInput, NotificationSubscriptionModel, type NotificationSubscriptionTables, PROJECT_SCOPE, PUBLIC_ORIGIN_KEY, type PackageUsageInput, PackageUsageModel, type PackageUsageTables, type ProjectCreateInput, ProjectGroupMappingModel, ProjectModel, type PublicOriginOptions, type PublicOriginResolver, type PublicOriginSource, RECENT_BUILDS_FOR_INHERITED_RATIO, type ReencryptResult, type RefreshOptions, type ResolvedPublicOrigin, type ReviewStatusInput, SiteSettingsModel, type SiteSettingsTables, type SnapshotCreateInput, SnapshotModel, type StoredPublicOrigin, TERMINAL_JOB_STATUSES, TokenModel, type UnreadableCredential, type UpstreamStory, UserModel, type WebhookCreateInput, WebhookModel, acceptPendingWithoutWork, attemptRowId, averageInheritedRatio, baselineStatus, changesetOf, componentHistory, componentPresence, computeChangeset, createPublicOriginResolver, credentialDaysLeft, deriveReviewStatus, emitAttemptLog, findChangesetBaseline, isBaselineDrifted, isDesignStale, isPublicBuild, isTerminalJob, latestVerdicts, matchUpstreamStory, normalizeImportPath, parseAttemptRowId, probeCredentials, reencryptCredentials, resolveDesigns, worstStatus };
|
|
48
|
+
export { AiBudgetAlertModel, type AiBudgetAlertTables, type AiUsageInput, AiUsageModel, type AiUsageTables, type AttemptClaim, type AttemptLogRecorder, BASELINE_ARCHIVE_FORMAT, BASELINE_ARCHIVE_LIMITS, BASELINE_ARCHIVE_VERSION, BaselineApprovalConflict, BaselineArchiveError, type BaselineExportOptions, type BaselineImportResult, type BaselineManifest, type BaselineManifestEntry, BaselineModel, type BaselineOriginReader, type BaselineStatus, BaselineTransferModel, BaselineWriteConflict, type BuildChangeset, type BuildComponentInput, BuildComponentModel, type BuildComponentTables, type BuildCreateInput, type BuildListFilter, BuildModel, BuildReviewModel, type BuildReviewTables, CaptureAttemptModel, type CaptureAttemptTables, CaptureJobModel, type CaptureJobTables, CaptureLogModel, type CaptureLogTables, CaptureShardModel, type CaptureShardTables, type ChangedComponent, type Changeset, type ChangesetComponent, type ChannelValidation, type CommentCreateInput, CommentModel, type ComponentHistoryRow, type ComponentPresence, ConnectionModel, type ConnectionTables, ContentRefModel, type CredentialProbe, DESIGN_TTL_MS, DesignCredentialModel, type DesignCredentialStatus, type DesignCredentialTables, DesignModel, DesignNodeModel, type DesignNodeTables, type DesignResolution, type DesignSource, type DesignTables, type InheritedRatio, InsightModel, type InsightResultInput, type InsightStartInput, type InsightStartResult, type InsightTables, LabelModel, MemberModel, NO_BASELINE, type NewCaptureJob, type NotificationChannelCreateInput, NotificationChannelModel, type NotificationChannelTables, type NotificationSubscriptionInput, NotificationSubscriptionModel, type NotificationSubscriptionTables, PROJECT_SCOPE, PUBLIC_ORIGIN_KEY, type PackageUsageInput, PackageUsageModel, type PackageUsageTables, type ProjectCreateInput, ProjectGroupMappingModel, ProjectModel, type PublicOriginOptions, type PublicOriginResolver, type PublicOriginSource, RECENT_BUILDS_FOR_INHERITED_RATIO, type ReencryptResult, type RefreshOptions, type ResolvedPublicOrigin, type ReviewStatusInput, SiteSettingsModel, type SiteSettingsTables, type SnapshotCreateInput, SnapshotModel, type StoredPublicOrigin, TERMINAL_JOB_STATUSES, TokenModel, type UnreadableCredential, type UpstreamStory, UserModel, type WebhookCreateInput, WebhookModel, acceptPendingWithoutWork, attemptRowId, averageInheritedRatio, baselineStatus, changesetOf, componentHistory, componentPresence, computeChangeset, createPublicOriginResolver, credentialDaysLeft, deriveReviewStatus, emitAttemptLog, findChangesetBaseline, isBaselineDrifted, isDesignStale, isPublicBuild, isTerminalJob, latestVerdicts, matchUpstreamStory, normalizeImportPath, parseAttemptRowId, probeCredentials, reencryptCredentials, resolveBaselineOrigin, resolveDesigns, worstStatus };
|
package/dist/models.mjs
CHANGED
|
@@ -4,8 +4,10 @@ import.meta.url;
|
|
|
4
4
|
import { WebhookModel } from "./models/webhook.mjs";
|
|
5
5
|
import { CaptureAttemptModel, emitAttemptLog } from "./models/capture-attempt.mjs";
|
|
6
6
|
import { BuildModel, isPublicBuild } from "./models/build.mjs";
|
|
7
|
-
import {
|
|
7
|
+
import { BaselineWriteConflict } from "./models/baseline-conflict.mjs";
|
|
8
8
|
import { NO_BASELINE, baselineStatus, isBaselineDrifted } from "./models/baseline-status.mjs";
|
|
9
|
+
import { BaselineApprovalConflict } from "./models/baseline-approval.mjs";
|
|
10
|
+
import { BaselineModel } from "./models/baseline.mjs";
|
|
9
11
|
import { SnapshotModel } from "./models/snapshot.mjs";
|
|
10
12
|
import { CaptureShardModel } from "./models/capture-shard.mjs";
|
|
11
13
|
import { ProjectModel } from "./models/project.mjs";
|
|
@@ -18,6 +20,7 @@ import { PUBLIC_ORIGIN_KEY, createPublicOriginResolver } from "./models/public-o
|
|
|
18
20
|
import { CaptureLogModel } from "./models/capture-log.mjs";
|
|
19
21
|
import { BuildComponentModel } from "./models/build-component.mjs";
|
|
20
22
|
import { normalizeImportPath, resolveDesigns } from "./models/design-resolve.mjs";
|
|
23
|
+
import { resolveBaselineOrigin } from "./models/baseline-origin.mjs";
|
|
21
24
|
import { BASELINE_ARCHIVE_FORMAT, BASELINE_ARCHIVE_LIMITS, BASELINE_ARCHIVE_VERSION, BaselineArchiveError } from "./models/baseline-archive.mjs";
|
|
22
25
|
import { BaselineTransferModel } from "./models/baseline-transfer.mjs";
|
|
23
26
|
import { AiBudgetAlertModel } from "./models/ai-budget-alert.mjs";
|
|
@@ -42,4 +45,4 @@ import { TokenModel } from "./models/token.mjs";
|
|
|
42
45
|
import { UserModel } from "./models/user.mjs";
|
|
43
46
|
import { ContentRefModel } from "./models/content-ref.mjs";
|
|
44
47
|
import { probeCredentials, reencryptCredentials } from "./models/credentials.mjs";
|
|
45
|
-
export { AiBudgetAlertModel, AiUsageModel, BASELINE_ARCHIVE_FORMAT, BASELINE_ARCHIVE_LIMITS, BASELINE_ARCHIVE_VERSION, BaselineArchiveError, BaselineModel, BaselineTransferModel, BuildComponentModel, BuildModel, BuildReviewModel, CaptureAttemptModel, CaptureJobModel, CaptureLogModel, CaptureShardModel, CommentModel, ConnectionModel, ContentRefModel, DESIGN_TTL_MS, DesignCredentialModel, DesignModel, DesignNodeModel, InsightModel, LabelModel, MemberModel, NO_BASELINE, NotificationChannelModel, NotificationSubscriptionModel, PROJECT_SCOPE, PUBLIC_ORIGIN_KEY, PackageUsageModel, ProjectGroupMappingModel, ProjectModel, RECENT_BUILDS_FOR_INHERITED_RATIO, SiteSettingsModel, SnapshotModel, TERMINAL_JOB_STATUSES, TokenModel, UserModel, WebhookModel, acceptPendingWithoutWork, attemptRowId, averageInheritedRatio, baselineStatus, changesetOf, componentHistory, componentPresence, computeChangeset, createPublicOriginResolver, credentialDaysLeft, deriveReviewStatus, emitAttemptLog, findChangesetBaseline, isBaselineDrifted, isDesignStale, isPublicBuild, isTerminalJob, latestVerdicts, matchUpstreamStory, normalizeImportPath, parseAttemptRowId, probeCredentials, reencryptCredentials, resolveDesigns, worstStatus };
|
|
48
|
+
export { AiBudgetAlertModel, AiUsageModel, BASELINE_ARCHIVE_FORMAT, BASELINE_ARCHIVE_LIMITS, BASELINE_ARCHIVE_VERSION, BaselineApprovalConflict, BaselineArchiveError, BaselineModel, BaselineTransferModel, BaselineWriteConflict, BuildComponentModel, BuildModel, BuildReviewModel, CaptureAttemptModel, CaptureJobModel, CaptureLogModel, CaptureShardModel, CommentModel, ConnectionModel, ContentRefModel, DESIGN_TTL_MS, DesignCredentialModel, DesignModel, DesignNodeModel, InsightModel, LabelModel, MemberModel, NO_BASELINE, NotificationChannelModel, NotificationSubscriptionModel, PROJECT_SCOPE, PUBLIC_ORIGIN_KEY, PackageUsageModel, ProjectGroupMappingModel, ProjectModel, RECENT_BUILDS_FOR_INHERITED_RATIO, SiteSettingsModel, SnapshotModel, TERMINAL_JOB_STATUSES, TokenModel, UserModel, WebhookModel, acceptPendingWithoutWork, attemptRowId, averageInheritedRatio, baselineStatus, changesetOf, componentHistory, componentPresence, computeChangeset, createPublicOriginResolver, credentialDaysLeft, deriveReviewStatus, emitAttemptLog, findChangesetBaseline, isBaselineDrifted, isDesignStale, isPublicBuild, isTerminalJob, latestVerdicts, matchUpstreamStory, normalizeImportPath, parseAttemptRowId, probeCredentials, reencryptCredentials, resolveBaselineOrigin, resolveDesigns, worstStatus };
|
package/dist/options.d.mts
CHANGED
|
@@ -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 { ShelfOptions } from "./config.mjs";
|
|
4
|
-
//#region src/options.d.ts
|
|
5
4
|
/** Where capture scratch lives when `config.scratchDir` is not set. */
|
|
6
5
|
declare const DEFAULT_SCRATCH_DIR: string;
|
|
7
6
|
/**
|
|
@@ -13,6 +12,5 @@ declare const DEFAULT_SCRATCH_DIR: string;
|
|
|
13
12
|
* with or without `testing`.
|
|
14
13
|
*/
|
|
15
14
|
declare function resolveShelfOptions(options: ShelfOptions): ShelfOptions;
|
|
16
|
-
//#endregion
|
|
17
15
|
export { DEFAULT_SCRATCH_DIR, resolveShelfOptions };
|
|
18
16
|
//# sourceMappingURL=options.d.mts.map
|
package/dist/options.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import "node:path";
|
|
1
|
+
import { join } from "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { notificationsConfigSchema } from "./config.mjs";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
|
-
|
|
7
|
-
//#region src/options.ts
|
|
6
|
+
// src/options.ts
|
|
8
7
|
/** Resolves `ShelfOptions` once at boot: validates `testing.compare` and fills the scratch default. */
|
|
9
8
|
/** Where capture scratch lives when `config.scratchDir` is not set. */
|
|
10
9
|
const DEFAULT_SCRATCH_DIR = join(tmpdir(), "storyshelf");
|
|
@@ -84,7 +83,6 @@ function assertNotificationsConfig(config) {
|
|
|
84
83
|
throw new Error(`Invalid notifications.config: ${issues}`);
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
|
-
//#endregion
|
|
88
86
|
export { DEFAULT_SCRATCH_DIR, resolveShelfOptions };
|
|
89
87
|
|
|
90
88
|
//# sourceMappingURL=options.mjs.map
|
package/dist/options.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.mjs","names":[],"sources":["../src/options.ts"],"sourcesContent":["/** Resolves `ShelfOptions` once at boot: validates `testing.compare` and fills the scratch default. */\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { notificationsConfigSchema, type ShelfOptions } from \"./config.ts\";\n\n/** Where capture scratch lives when `config.scratchDir` is not set. */\nexport const DEFAULT_SCRATCH_DIR: string = join(tmpdir(), \"storyshelf\");\n\n/**\n * Validate and complete the options.\n *\n * - `testing.compare.threads` must be a non-negative integer.\n * - `notifications.config` must match its schema (it used to live in `ShelfConfig`, which validated it).\n * - `config.scratchDir` defaults to {@link DEFAULT_SCRATCH_DIR}: publishing extracts zips there,\n * with or without `testing`.\n */\nexport function resolveShelfOptions(options: ShelfOptions): ShelfOptions {\n assertThreads(options.testing?.compare?.threads);\n assertTestingProcess(options.testing);\n assertTestingBackable(options);\n assertNotificationsConfig(options.notifications?.config);\n if (options.config?.scratchDir !== undefined) {\n return options;\n }\n return { ...options, config: { ...options.config, scratchDir: DEFAULT_SCRATCH_DIR } };\n}\n\n/**\n * A `testing` instance renders here, so it needs a database a long-running server can keep.\n */\nfunction assertTestingBackable(options: ShelfOptions): void {\n if (options.testing === undefined) {\n return;\n }\n if (options.database.metadata.supportsTesting === false) {\n throw new Error(\n `The ${options.database.metadata.name} database cannot back testing: it is reachable only ` +\n `from a platform that ends the process after each request, so nothing would run capture ` +\n `jobs. Remove the testing option to host Storybooks only, or use a network database ` +\n `(Turso, Postgres, MySQL, SQLite on a volume).`,\n );\n }\n}\n\nfunction assertTestingProcess(testing: ShelfOptions[\"testing\"]): void {\n if (testing !== undefined && testing.runner === undefined) {\n throw new Error(\"testing requires testing.runner\");\n }\n if (testing?.workerEntry !== undefined && testing.runner === undefined) {\n throw new Error(\"testing.workerEntry requires testing.runner (it is the in-process fallback)\");\n }\n if (testing?.mode === \"fork\" && testing.workerEntry === undefined) {\n throw new Error('testing.mode \"fork\" requires testing.workerEntry');\n }\n assertShardSize(testing);\n assertTestingNumbers(testing);\n}\n\n/** Numeric `testing` options: concurrency, retries and the Storybook URL rate limit. */\nfunction assertTestingNumbers(testing: ShelfOptions[\"testing\"]): void {\n assertConcurrency(testing?.concurrency);\n assertRetries(testing?.retries);\n assertLeaseSeconds(testing?.leaseSeconds);\n assertStorybookUrlRateLimit(testing?.storybookUrlRateLimit);\n}\n\n/** A whole number of requests per minute; `0` would refuse every render. */\nfunction assertStorybookUrlRateLimit(limit: number | undefined): void {\n if (limit !== undefined && (!Number.isInteger(limit) || limit < 1)) {\n throw new Error(\n `testing.storybookUrlRateLimit must be a positive whole number of requests per minute, got ${String(limit)}`,\n );\n }\n}\n\n/** Retries are counted after the first attempt: `0` runs a job once. */\nfunction assertRetries(retries: number | undefined): void {\n if (retries !== undefined && (!Number.isInteger(retries) || retries < 0)) {\n throw new Error(`testing.retries must be a non-negative integer, got ${String(retries)}`);\n }\n}\n\n/** A lease must be a positive length: `0` would expire every job at once. */\nfunction assertLeaseSeconds(seconds: number | undefined): void {\n if (seconds !== undefined && (!Number.isFinite(seconds) || seconds <= 0)) {\n throw new Error(\n `testing.leaseSeconds must be a positive number of seconds, got ${String(seconds)}`,\n );\n }\n}\n\n/** `0` would deadlock the consumer. */\nfunction assertConcurrency(concurrency: number | undefined): void {\n if (concurrency !== undefined && (!Number.isInteger(concurrency) || concurrency < 1)) {\n throw new Error(`testing.concurrency must be a positive integer, got ${String(concurrency)}`);\n }\n}\n\nfunction assertShardSize(testing: ShelfOptions[\"testing\"]): void {\n const size = testing?.shardSize;\n if (size === undefined) {\n return;\n }\n if (!Number.isInteger(size) || size < 1) {\n throw new Error(`testing.shardSize must be a positive integer, got ${String(size)}`);\n }\n if (testing?.runner === undefined) {\n throw new Error(\"testing.shardSize requires testing.runner (workers set their own shardSize)\");\n }\n}\n\nfunction assertThreads(threads: number | undefined): void {\n if (threads !== undefined && (!Number.isInteger(threads) || threads < 0)) {\n throw new Error(\n `testing.compare.threads must be a non-negative integer, got ${String(threads)}`,\n );\n }\n}\n\nfunction assertNotificationsConfig(config: unknown): void {\n if (config === undefined) {\n return;\n }\n const result = notificationsConfigSchema.safeParse(config);\n if (!result.success) {\n const issues = result.error.issues.map((i) => `${i.path.join(\".\")}: ${i.message}`).join(\"; \");\n throw new Error(`Invalid notifications.config: ${issues}`);\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"options.mjs","names":[],"sources":["../src/options.ts"],"sourcesContent":["/** Resolves `ShelfOptions` once at boot: validates `testing.compare` and fills the scratch default. */\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { notificationsConfigSchema, type ShelfOptions } from \"./config.ts\";\n\n/** Where capture scratch lives when `config.scratchDir` is not set. */\nexport const DEFAULT_SCRATCH_DIR: string = join(tmpdir(), \"storyshelf\");\n\n/**\n * Validate and complete the options.\n *\n * - `testing.compare.threads` must be a non-negative integer.\n * - `notifications.config` must match its schema (it used to live in `ShelfConfig`, which validated it).\n * - `config.scratchDir` defaults to {@link DEFAULT_SCRATCH_DIR}: publishing extracts zips there,\n * with or without `testing`.\n */\nexport function resolveShelfOptions(options: ShelfOptions): ShelfOptions {\n assertThreads(options.testing?.compare?.threads);\n assertTestingProcess(options.testing);\n assertTestingBackable(options);\n assertNotificationsConfig(options.notifications?.config);\n if (options.config?.scratchDir !== undefined) {\n return options;\n }\n return { ...options, config: { ...options.config, scratchDir: DEFAULT_SCRATCH_DIR } };\n}\n\n/**\n * A `testing` instance renders here, so it needs a database a long-running server can keep.\n */\nfunction assertTestingBackable(options: ShelfOptions): void {\n if (options.testing === undefined) {\n return;\n }\n if (options.database.metadata.supportsTesting === false) {\n throw new Error(\n `The ${options.database.metadata.name} database cannot back testing: it is reachable only ` +\n `from a platform that ends the process after each request, so nothing would run capture ` +\n `jobs. Remove the testing option to host Storybooks only, or use a network database ` +\n `(Turso, Postgres, MySQL, SQLite on a volume).`,\n );\n }\n}\n\nfunction assertTestingProcess(testing: ShelfOptions[\"testing\"]): void {\n if (testing !== undefined && testing.runner === undefined) {\n throw new Error(\"testing requires testing.runner\");\n }\n if (testing?.workerEntry !== undefined && testing.runner === undefined) {\n throw new Error(\"testing.workerEntry requires testing.runner (it is the in-process fallback)\");\n }\n if (testing?.mode === \"fork\" && testing.workerEntry === undefined) {\n throw new Error('testing.mode \"fork\" requires testing.workerEntry');\n }\n assertShardSize(testing);\n assertTestingNumbers(testing);\n}\n\n/** Numeric `testing` options: concurrency, retries and the Storybook URL rate limit. */\nfunction assertTestingNumbers(testing: ShelfOptions[\"testing\"]): void {\n assertConcurrency(testing?.concurrency);\n assertRetries(testing?.retries);\n assertLeaseSeconds(testing?.leaseSeconds);\n assertStorybookUrlRateLimit(testing?.storybookUrlRateLimit);\n}\n\n/** A whole number of requests per minute; `0` would refuse every render. */\nfunction assertStorybookUrlRateLimit(limit: number | undefined): void {\n if (limit !== undefined && (!Number.isInteger(limit) || limit < 1)) {\n throw new Error(\n `testing.storybookUrlRateLimit must be a positive whole number of requests per minute, got ${String(limit)}`,\n );\n }\n}\n\n/** Retries are counted after the first attempt: `0` runs a job once. */\nfunction assertRetries(retries: number | undefined): void {\n if (retries !== undefined && (!Number.isInteger(retries) || retries < 0)) {\n throw new Error(`testing.retries must be a non-negative integer, got ${String(retries)}`);\n }\n}\n\n/** A lease must be a positive length: `0` would expire every job at once. */\nfunction assertLeaseSeconds(seconds: number | undefined): void {\n if (seconds !== undefined && (!Number.isFinite(seconds) || seconds <= 0)) {\n throw new Error(\n `testing.leaseSeconds must be a positive number of seconds, got ${String(seconds)}`,\n );\n }\n}\n\n/** `0` would deadlock the consumer. */\nfunction assertConcurrency(concurrency: number | undefined): void {\n if (concurrency !== undefined && (!Number.isInteger(concurrency) || concurrency < 1)) {\n throw new Error(`testing.concurrency must be a positive integer, got ${String(concurrency)}`);\n }\n}\n\nfunction assertShardSize(testing: ShelfOptions[\"testing\"]): void {\n const size = testing?.shardSize;\n if (size === undefined) {\n return;\n }\n if (!Number.isInteger(size) || size < 1) {\n throw new Error(`testing.shardSize must be a positive integer, got ${String(size)}`);\n }\n if (testing?.runner === undefined) {\n throw new Error(\"testing.shardSize requires testing.runner (workers set their own shardSize)\");\n }\n}\n\nfunction assertThreads(threads: number | undefined): void {\n if (threads !== undefined && (!Number.isInteger(threads) || threads < 0)) {\n throw new Error(\n `testing.compare.threads must be a non-negative integer, got ${String(threads)}`,\n );\n }\n}\n\nfunction assertNotificationsConfig(config: unknown): void {\n if (config === undefined) {\n return;\n }\n const result = notificationsConfigSchema.safeParse(config);\n if (!result.success) {\n const issues = result.error.issues.map((i) => `${i.path.join(\".\")}: ${i.message}`).join(\"; \");\n throw new Error(`Invalid notifications.config: ${issues}`);\n }\n}\n"],"mappings":";;;;;;;;AAMA,MAAa,sBAA8B,KAAK,OAAO,GAAG,YAAY;;;;;;;;;AAUtE,SAAgB,oBAAoB,SAAqC;CACvE,cAAc,QAAQ,SAAS,SAAS,OAAO;CAC/C,qBAAqB,QAAQ,OAAO;CACpC,sBAAsB,OAAO;CAC7B,0BAA0B,QAAQ,eAAe,MAAM;CACvD,IAAI,QAAQ,QAAQ,eAAe,KAAA,GACjC,OAAO;CAET,OAAO;EAAE,GAAG;EAAS,QAAQ;GAAE,GAAG,QAAQ;GAAQ,YAAY;EAAoB;CAAE;AACtF;;;;AAKA,SAAS,sBAAsB,SAA6B;CAC1D,IAAI,QAAQ,YAAY,KAAA,GACtB;CAEF,IAAI,QAAQ,SAAS,SAAS,oBAAoB,OAChD,MAAM,IAAI,MACR,OAAO,QAAQ,SAAS,SAAS,KAAK,4QAIxC;AAEJ;AAEA,SAAS,qBAAqB,SAAwC;CACpE,IAAI,YAAY,KAAA,KAAa,QAAQ,WAAW,KAAA,GAC9C,MAAM,IAAI,MAAM,iCAAiC;CAEnD,IAAI,SAAS,gBAAgB,KAAA,KAAa,QAAQ,WAAW,KAAA,GAC3D,MAAM,IAAI,MAAM,6EAA6E;CAE/F,IAAI,SAAS,SAAS,UAAU,QAAQ,gBAAgB,KAAA,GACtD,MAAM,IAAI,MAAM,oDAAkD;CAEpE,gBAAgB,OAAO;CACvB,qBAAqB,OAAO;AAC9B;;AAGA,SAAS,qBAAqB,SAAwC;CACpE,kBAAkB,SAAS,WAAW;CACtC,cAAc,SAAS,OAAO;CAC9B,mBAAmB,SAAS,YAAY;CACxC,4BAA4B,SAAS,qBAAqB;AAC5D;;AAGA,SAAS,4BAA4B,OAAiC;CACpE,IAAI,UAAU,KAAA,MAAc,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,IAC9D,MAAM,IAAI,MACR,6FAA6F,OAAO,KAAK,GAC3G;AAEJ;;AAGA,SAAS,cAAc,SAAmC;CACxD,IAAI,YAAY,KAAA,MAAc,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,IACpE,MAAM,IAAI,MAAM,uDAAuD,OAAO,OAAO,GAAG;AAE5F;;AAGA,SAAS,mBAAmB,SAAmC;CAC7D,IAAI,YAAY,KAAA,MAAc,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,IACpE,MAAM,IAAI,MACR,kEAAkE,OAAO,OAAO,GAClF;AAEJ;;AAGA,SAAS,kBAAkB,aAAuC;CAChE,IAAI,gBAAgB,KAAA,MAAc,CAAC,OAAO,UAAU,WAAW,KAAK,cAAc,IAChF,MAAM,IAAI,MAAM,uDAAuD,OAAO,WAAW,GAAG;AAEhG;AAEA,SAAS,gBAAgB,SAAwC;CAC/D,MAAM,OAAO,SAAS;CACtB,IAAI,SAAS,KAAA,GACX;CAEF,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,GACpC,MAAM,IAAI,MAAM,qDAAqD,OAAO,IAAI,GAAG;CAErF,IAAI,SAAS,WAAW,KAAA,GACtB,MAAM,IAAI,MAAM,6EAA6E;AAEjG;AAEA,SAAS,cAAc,SAAmC;CACxD,IAAI,YAAY,KAAA,MAAc,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,IACpE,MAAM,IAAI,MACR,+DAA+D,OAAO,OAAO,GAC/E;AAEJ;AAEA,SAAS,0BAA0B,QAAuB;CACxD,IAAI,WAAW,KAAA,GACb;CAEF,MAAM,SAAS,0BAA0B,UAAU,MAAM;CACzD,IAAI,CAAC,OAAO,SAAS;EACnB,MAAM,SAAS,OAAO,MAAM,OAAO,KAAK,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,IAAI;EAC5F,MAAM,IAAI,MAAM,iCAAiC,QAAQ;CAC3D;AACF"}
|
package/dist/paths.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/paths.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Path segment for a mode on a given engine. Chromium keeps the bare mode key
|
|
6
5
|
* so pre-multi-browser objects stay addressable; other engines get `~browser`.
|
|
@@ -22,10 +21,11 @@ declare function designRenderPath(projectId: string, provider: string, fileKey:
|
|
|
22
21
|
declare function baselinePath(projectId: string, branch: string, storyId: string, viewport: string, browser?: string): string;
|
|
23
22
|
/** Storage prefix for an extracted published Storybook. */
|
|
24
23
|
declare function storybookDir(projectId: string, buildId: string): string;
|
|
24
|
+
/** Disposable gzip representation of a content-addressed published file. */
|
|
25
|
+
declare function publishedGzipPath(hash: string): string;
|
|
25
26
|
/** Storage path for an uploaded Storybook zip. */
|
|
26
27
|
declare function storybookZipPath(projectId: string, buildId: string): string;
|
|
27
28
|
/** Storage path of a build's persisted catalog (ADR 0006, decision 9), next to its `storybook/` statics. */
|
|
28
29
|
declare function catalogPath(projectId: string, buildId: string): string;
|
|
29
|
-
|
|
30
|
-
export { baselinePath, catalogPath, contentDir, contentPath, designRenderPath, diffPath, isContentPath, modeSegment, screenshotPath, storybookDir, storybookZipPath };
|
|
30
|
+
export { baselinePath, catalogPath, contentDir, contentPath, designRenderPath, diffPath, isContentPath, modeSegment, publishedGzipPath, screenshotPath, storybookDir, storybookZipPath };
|
|
31
31
|
//# sourceMappingURL=paths.d.mts.map
|
package/dist/paths.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { isSafeSegment } from "./utils/path-security.mjs";
|
|
5
|
-
|
|
5
|
+
// src/utils/paths.ts
|
|
6
6
|
/** Storage path builders. Every segment is validated — a third-party
|
|
7
7
|
* capture runner echoing `story.id = "../../x"` must fail here, not in an
|
|
8
8
|
* adapter with its own key-jailing quirks. */
|
|
@@ -82,6 +82,11 @@ function storybookDir(projectId, buildId) {
|
|
|
82
82
|
assertSegments([projectId, buildId]);
|
|
83
83
|
return `${projectId}/builds/${buildId}/storybook`;
|
|
84
84
|
}
|
|
85
|
+
/** Disposable gzip representation of a content-addressed published file. */
|
|
86
|
+
function publishedGzipPath(hash) {
|
|
87
|
+
if (!/^[a-f0-9]{64}$/u.test(hash)) throw new Error("Invalid published content hash");
|
|
88
|
+
return `derived/published-gzip/${hash}.gz`;
|
|
89
|
+
}
|
|
85
90
|
/** Storage path for an uploaded Storybook zip. */
|
|
86
91
|
function storybookZipPath(projectId, buildId) {
|
|
87
92
|
assertSegments([projectId, buildId]);
|
|
@@ -92,7 +97,6 @@ function catalogPath(projectId, buildId) {
|
|
|
92
97
|
assertSegments([projectId, buildId]);
|
|
93
98
|
return `${projectId}/builds/${buildId}/catalog.json`;
|
|
94
99
|
}
|
|
95
|
-
|
|
96
|
-
export { baselinePath, catalogPath, contentDir, contentPath, designRenderPath, diffPath, isContentPath, modeSegment, screenshotPath, storybookDir, storybookZipPath };
|
|
100
|
+
export { baselinePath, catalogPath, contentDir, contentPath, designRenderPath, diffPath, isContentPath, modeSegment, publishedGzipPath, screenshotPath, storybookDir, storybookZipPath };
|
|
97
101
|
|
|
98
102
|
//# sourceMappingURL=paths.mjs.map
|
package/dist/paths.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.mjs","names":[],"sources":["../src/utils/paths.ts"],"sourcesContent":["/** Storage path builders. Every segment is validated — a third-party\n * capture runner echoing `story.id = \"../../x\"` must fail here, not in an\n * adapter with its own key-jailing quirks. */\nimport { isSafeSegment } from \"./path-security.ts\";\n\n/** Throw when any key segment could escape its storage prefix. */\nfunction assertSegments(segments: string[]): void {\n const bad = segments.filter((segment) => !isSafeSegment(segment) || segment.length === 0);\n if (bad.length > 0) {\n throw new Error(`Unsafe storage path segment: ${bad.join(\",\")}`);\n }\n}\n/**\n * Path segment for a mode on a given engine. Chromium keeps the bare mode key\n * so pre-multi-browser objects stay addressable; other engines get `~browser`.\n */\nexport function modeSegment(viewport: string, browser?: string): string {\n return browser && browser !== \"chromium\" ? `${viewport}~${browser}` : viewport;\n}\n\n/** Storage path for a captured snapshot screenshot. */\nexport function screenshotPath(\n projectId: string,\n buildId: string,\n storyId: string,\n viewport: string,\n browser?: string,\n): string {\n const segment = modeSegment(viewport, browser);\n assertSegments([projectId, buildId, storyId, segment]);\n return `${projectId}/builds/${buildId}/screenshots/${storyId}/${segment}.png`;\n}\n\n/** Storage prefix of a project's content-addressed screenshots. */\nexport function contentDir(projectId: string): string {\n assertSegments([projectId]);\n return `${projectId}/content`;\n}\n\n/** Storage path of a screenshot stored by the SHA-256 of its bytes (shared by builds and baselines). */\nexport function contentPath(projectId: string, hash: string): string {\n assertSegments([projectId, hash]);\n return `${contentDir(projectId)}/${hash}.png`;\n}\n\n/** Whether `path` is one of `projectId`'s content-addressed screenshots. */\nexport function isContentPath(projectId: string, path: string): boolean {\n return path.startsWith(`${contentDir(projectId)}/`) && path.endsWith(\".png\");\n}\n\n/** Storage path for a snapshot diff overlay image. */\nexport function diffPath(\n projectId: string,\n buildId: string,\n storyId: string,\n viewport: string,\n browser?: string,\n): string {\n const segment = modeSegment(viewport, browser);\n assertSegments([projectId, buildId, storyId, segment]);\n return `${projectId}/builds/${buildId}/diffs/${storyId}/${segment}.png`;\n}\n\n/** Storage path for a cached design node render (overwritten in place when the file version moves). */\nexport function designRenderPath(\n projectId: string,\n provider: string,\n fileKey: string,\n nodeId: string,\n viewerId = \"\",\n): string {\n const node = nodeId.replaceAll(\":\", \"-\");\n assertSegments([projectId, provider, fileKey, node, ...(viewerId ? [viewerId] : [])]);\n const owner = viewerId ? `user-${viewerId}/` : \"\";\n return `${projectId}/design/${provider}/${owner}${fileKey}/${node}.png`;\n}\n\n/** Storage path for a branch baseline screenshot. */\nexport function baselinePath(\n projectId: string,\n branch: string,\n storyId: string,\n viewport: string,\n browser?: string,\n): string {\n const segment = modeSegment(viewport, browser);\n assertSegments([projectId, branch, storyId, segment]);\n return `${projectId}/baselines/${branch}/${storyId}/${segment}.png`;\n}\n\n/** Storage prefix for an extracted published Storybook. */\nexport function storybookDir(projectId: string, buildId: string): string {\n assertSegments([projectId, buildId]);\n return `${projectId}/builds/${buildId}/storybook`;\n}\n\n/** Storage path for an uploaded Storybook zip. */\nexport function storybookZipPath(projectId: string, buildId: string): string {\n assertSegments([projectId, buildId]);\n return `${projectId}/builds/${buildId}/storybook.zip`;\n}\n\n/** Storage path of a build's persisted catalog (ADR 0006, decision 9), next to its `storybook/` statics. */\nexport function catalogPath(projectId: string, buildId: string): string {\n assertSegments([projectId, buildId]);\n return `${projectId}/builds/${buildId}/catalog.json`;\n}\n"],"mappings":";;;;;;;;;AAMA,SAAS,eAAe,UAA0B;CAChD,MAAM,MAAM,SAAS,QAAQ,YAAY,CAAC,cAAc,OAAO,KAAK,QAAQ,WAAW,CAAC;CACxF,IAAI,IAAI,SAAS,GACf,MAAM,IAAI,MAAM,gCAAgC,IAAI,KAAK,GAAG,GAAG;AAEnE;;;;;AAKA,SAAgB,YAAY,UAAkB,SAA0B;CACtE,OAAO,WAAW,YAAY,aAAa,GAAG,SAAS,GAAG,YAAY;AACxE;;AAGA,SAAgB,eACd,WACA,SACA,SACA,UACA,SACQ;CACR,MAAM,UAAU,YAAY,UAAU,OAAO;CAC7C,eAAe;EAAC;EAAW;EAAS;EAAS;CAAO,CAAC;CACrD,OAAO,GAAG,UAAU,UAAU,QAAQ,eAAe,QAAQ,GAAG,QAAQ;AAC1E;;AAGA,SAAgB,WAAW,WAA2B;CACpD,eAAe,CAAC,SAAS,CAAC;CAC1B,OAAO,GAAG,UAAU;AACtB;;AAGA,SAAgB,YAAY,WAAmB,MAAsB;CACnE,eAAe,CAAC,WAAW,IAAI,CAAC;CAChC,OAAO,GAAG,WAAW,SAAS,EAAE,GAAG,KAAK;AAC1C;;AAGA,SAAgB,cAAc,WAAmB,MAAuB;CACtE,OAAO,KAAK,WAAW,GAAG,WAAW,SAAS,EAAE,EAAE,KAAK,KAAK,SAAS,MAAM;AAC7E;;AAGA,SAAgB,SACd,WACA,SACA,SACA,UACA,SACQ;CACR,MAAM,UAAU,YAAY,UAAU,OAAO;CAC7C,eAAe;EAAC;EAAW;EAAS;EAAS;CAAO,CAAC;CACrD,OAAO,GAAG,UAAU,UAAU,QAAQ,SAAS,QAAQ,GAAG,QAAQ;AACpE;;AAGA,SAAgB,iBACd,WACA,UACA,SACA,QACA,WAAW,IACH;CACR,MAAM,OAAO,OAAO,WAAW,KAAK,GAAG;CACvC,eAAe;EAAC;EAAW;EAAU;EAAS;EAAM,GAAI,WAAW,CAAC,QAAQ,IAAI,CAAC;CAAE,CAAC;CAEpF,OAAO,GAAG,UAAU,UAAU,SAAS,GADzB,WAAW,QAAQ,SAAS,KAAK,KACG,QAAQ,GAAG,KAAK;AACpE;;AAGA,SAAgB,aACd,WACA,QACA,SACA,UACA,SACQ;CACR,MAAM,UAAU,YAAY,UAAU,OAAO;CAC7C,eAAe;EAAC;EAAW;EAAQ;EAAS;CAAO,CAAC;CACpD,OAAO,GAAG,UAAU,aAAa,OAAO,GAAG,QAAQ,GAAG,QAAQ;AAChE;;AAGA,SAAgB,aAAa,WAAmB,SAAyB;CACvE,eAAe,CAAC,WAAW,OAAO,CAAC;CACnC,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC;;AAGA,SAAgB,iBAAiB,WAAmB,SAAyB;CAC3E,eAAe,CAAC,WAAW,OAAO,CAAC;CACnC,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC;;AAGA,SAAgB,YAAY,WAAmB,SAAyB;CACtE,eAAe,CAAC,WAAW,OAAO,CAAC;CACnC,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC"}
|
|
1
|
+
{"version":3,"file":"paths.mjs","names":[],"sources":["../src/utils/paths.ts"],"sourcesContent":["/** Storage path builders. Every segment is validated — a third-party\n * capture runner echoing `story.id = \"../../x\"` must fail here, not in an\n * adapter with its own key-jailing quirks. */\nimport { isSafeSegment } from \"./path-security.ts\";\n\n/** Throw when any key segment could escape its storage prefix. */\nfunction assertSegments(segments: string[]): void {\n const bad = segments.filter((segment) => !isSafeSegment(segment) || segment.length === 0);\n if (bad.length > 0) {\n throw new Error(`Unsafe storage path segment: ${bad.join(\",\")}`);\n }\n}\n/**\n * Path segment for a mode on a given engine. Chromium keeps the bare mode key\n * so pre-multi-browser objects stay addressable; other engines get `~browser`.\n */\nexport function modeSegment(viewport: string, browser?: string): string {\n return browser && browser !== \"chromium\" ? `${viewport}~${browser}` : viewport;\n}\n\n/** Storage path for a captured snapshot screenshot. */\nexport function screenshotPath(\n projectId: string,\n buildId: string,\n storyId: string,\n viewport: string,\n browser?: string,\n): string {\n const segment = modeSegment(viewport, browser);\n assertSegments([projectId, buildId, storyId, segment]);\n return `${projectId}/builds/${buildId}/screenshots/${storyId}/${segment}.png`;\n}\n\n/** Storage prefix of a project's content-addressed screenshots. */\nexport function contentDir(projectId: string): string {\n assertSegments([projectId]);\n return `${projectId}/content`;\n}\n\n/** Storage path of a screenshot stored by the SHA-256 of its bytes (shared by builds and baselines). */\nexport function contentPath(projectId: string, hash: string): string {\n assertSegments([projectId, hash]);\n return `${contentDir(projectId)}/${hash}.png`;\n}\n\n/** Whether `path` is one of `projectId`'s content-addressed screenshots. */\nexport function isContentPath(projectId: string, path: string): boolean {\n return path.startsWith(`${contentDir(projectId)}/`) && path.endsWith(\".png\");\n}\n\n/** Storage path for a snapshot diff overlay image. */\nexport function diffPath(\n projectId: string,\n buildId: string,\n storyId: string,\n viewport: string,\n browser?: string,\n): string {\n const segment = modeSegment(viewport, browser);\n assertSegments([projectId, buildId, storyId, segment]);\n return `${projectId}/builds/${buildId}/diffs/${storyId}/${segment}.png`;\n}\n\n/** Storage path for a cached design node render (overwritten in place when the file version moves). */\nexport function designRenderPath(\n projectId: string,\n provider: string,\n fileKey: string,\n nodeId: string,\n viewerId = \"\",\n): string {\n const node = nodeId.replaceAll(\":\", \"-\");\n assertSegments([projectId, provider, fileKey, node, ...(viewerId ? [viewerId] : [])]);\n const owner = viewerId ? `user-${viewerId}/` : \"\";\n return `${projectId}/design/${provider}/${owner}${fileKey}/${node}.png`;\n}\n\n/** Storage path for a branch baseline screenshot. */\nexport function baselinePath(\n projectId: string,\n branch: string,\n storyId: string,\n viewport: string,\n browser?: string,\n): string {\n const segment = modeSegment(viewport, browser);\n assertSegments([projectId, branch, storyId, segment]);\n return `${projectId}/baselines/${branch}/${storyId}/${segment}.png`;\n}\n\n/** Storage prefix for an extracted published Storybook. */\nexport function storybookDir(projectId: string, buildId: string): string {\n assertSegments([projectId, buildId]);\n return `${projectId}/builds/${buildId}/storybook`;\n}\n\n/** Disposable gzip representation of a content-addressed published file. */\nexport function publishedGzipPath(hash: string): string {\n if (!/^[a-f0-9]{64}$/u.test(hash)) throw new Error(\"Invalid published content hash\");\n return `derived/published-gzip/${hash}.gz`;\n}\n\n/** Storage path for an uploaded Storybook zip. */\nexport function storybookZipPath(projectId: string, buildId: string): string {\n assertSegments([projectId, buildId]);\n return `${projectId}/builds/${buildId}/storybook.zip`;\n}\n\n/** Storage path of a build's persisted catalog (ADR 0006, decision 9), next to its `storybook/` statics. */\nexport function catalogPath(projectId: string, buildId: string): string {\n assertSegments([projectId, buildId]);\n return `${projectId}/builds/${buildId}/catalog.json`;\n}\n"],"mappings":";;;;;;;;;AAMA,SAAS,eAAe,UAA0B;CAChD,MAAM,MAAM,SAAS,QAAQ,YAAY,CAAC,cAAc,OAAO,KAAK,QAAQ,WAAW,CAAC;CACxF,IAAI,IAAI,SAAS,GACf,MAAM,IAAI,MAAM,gCAAgC,IAAI,KAAK,GAAG,GAAG;AAEnE;;;;;AAKA,SAAgB,YAAY,UAAkB,SAA0B;CACtE,OAAO,WAAW,YAAY,aAAa,GAAG,SAAS,GAAG,YAAY;AACxE;;AAGA,SAAgB,eACd,WACA,SACA,SACA,UACA,SACQ;CACR,MAAM,UAAU,YAAY,UAAU,OAAO;CAC7C,eAAe;EAAC;EAAW;EAAS;EAAS;CAAO,CAAC;CACrD,OAAO,GAAG,UAAU,UAAU,QAAQ,eAAe,QAAQ,GAAG,QAAQ;AAC1E;;AAGA,SAAgB,WAAW,WAA2B;CACpD,eAAe,CAAC,SAAS,CAAC;CAC1B,OAAO,GAAG,UAAU;AACtB;;AAGA,SAAgB,YAAY,WAAmB,MAAsB;CACnE,eAAe,CAAC,WAAW,IAAI,CAAC;CAChC,OAAO,GAAG,WAAW,SAAS,EAAE,GAAG,KAAK;AAC1C;;AAGA,SAAgB,cAAc,WAAmB,MAAuB;CACtE,OAAO,KAAK,WAAW,GAAG,WAAW,SAAS,EAAE,EAAE,KAAK,KAAK,SAAS,MAAM;AAC7E;;AAGA,SAAgB,SACd,WACA,SACA,SACA,UACA,SACQ;CACR,MAAM,UAAU,YAAY,UAAU,OAAO;CAC7C,eAAe;EAAC;EAAW;EAAS;EAAS;CAAO,CAAC;CACrD,OAAO,GAAG,UAAU,UAAU,QAAQ,SAAS,QAAQ,GAAG,QAAQ;AACpE;;AAGA,SAAgB,iBACd,WACA,UACA,SACA,QACA,WAAW,IACH;CACR,MAAM,OAAO,OAAO,WAAW,KAAK,GAAG;CACvC,eAAe;EAAC;EAAW;EAAU;EAAS;EAAM,GAAI,WAAW,CAAC,QAAQ,IAAI,CAAC;CAAE,CAAC;CAEpF,OAAO,GAAG,UAAU,UAAU,SAAS,GADzB,WAAW,QAAQ,SAAS,KAAK,KACG,QAAQ,GAAG,KAAK;AACpE;;AAGA,SAAgB,aACd,WACA,QACA,SACA,UACA,SACQ;CACR,MAAM,UAAU,YAAY,UAAU,OAAO;CAC7C,eAAe;EAAC;EAAW;EAAQ;EAAS;CAAO,CAAC;CACpD,OAAO,GAAG,UAAU,aAAa,OAAO,GAAG,QAAQ,GAAG,QAAQ;AAChE;;AAGA,SAAgB,aAAa,WAAmB,SAAyB;CACvE,eAAe,CAAC,WAAW,OAAO,CAAC;CACnC,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC;;AAGA,SAAgB,kBAAkB,MAAsB;CACtD,IAAI,CAAC,kBAAkB,KAAK,IAAI,GAAG,MAAM,IAAI,MAAM,gCAAgC;CACnF,OAAO,0BAA0B,KAAK;AACxC;;AAGA,SAAgB,iBAAiB,WAAmB,SAAyB;CAC3E,eAAe,CAAC,WAAW,OAAO,CAAC;CACnC,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC;;AAGA,SAAgB,YAAY,WAAmB,SAAyB;CACtE,eAAe,CAAC,WAAW,OAAO,CAAC;CACnC,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC"}
|
package/dist/retention/ai.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
3
|
import { Logger } from "../logger.mjs";
|
|
5
|
-
|
|
4
|
+
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
6
5
|
/** Pending/running rows older than this are marked `interrupted`. */
|
|
7
6
|
declare const STALE_RUN_MS: number;
|
|
8
7
|
/** What one AI retention pass removed. */
|
|
@@ -13,6 +12,5 @@ interface AiPurgeResult {
|
|
|
13
12
|
}
|
|
14
13
|
/** Run one AI retention pass (safe to call from any instance, any time). */
|
|
15
14
|
declare function purgeAiData(db: DatabaseAdapter, now?: Date, logger?: Logger): Promise<AiPurgeResult>;
|
|
16
|
-
//#endregion
|
|
17
15
|
export { AiPurgeResult, STALE_RUN_MS, purgeAiData };
|
|
18
16
|
//# sourceMappingURL=ai.d.mts.map
|
package/dist/retention/ai.mjs
CHANGED
|
@@ -17,7 +17,6 @@ async function purgeAiData(db, now = /* @__PURE__ */ new Date(), logger) {
|
|
|
17
17
|
if (result.health > 0 || result.usage > 0 || result.interrupted > 0) logger?.info(result, "ai data retention pass complete");
|
|
18
18
|
return result;
|
|
19
19
|
}
|
|
20
|
-
//#endregion
|
|
21
20
|
export { STALE_RUN_MS, purgeAiData };
|
|
22
21
|
|
|
23
22
|
//# sourceMappingURL=ai.mjs.map
|
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { BuildModel } from "../models/build.mjs";
|
|
5
5
|
import { BuildReviewModel } from "../models/build-review.mjs";
|
|
6
6
|
import { CommentModel } from "../models/comment.mjs";
|
|
7
|
-
|
|
7
|
+
// src/retention/pending.ts
|
|
8
8
|
/**
|
|
9
9
|
* The project's pending builds whose last activity (upload, comment or verdict) is before
|
|
10
10
|
* `cutoff`. `capture_attempts` need no check: a build capture worked on leaves `pending`.
|
|
@@ -41,7 +41,6 @@ function stampOf(item) {
|
|
|
41
41
|
function hasNewerOnBranch(all, build) {
|
|
42
42
|
return all.some((other) => other.id !== build.id && other.gitBranch === build.gitBranch && other.createdAt > build.createdAt);
|
|
43
43
|
}
|
|
44
|
-
//#endregion
|
|
45
44
|
export { pendingCandidates };
|
|
46
45
|
|
|
47
46
|
//# sourceMappingURL=pending.mjs.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
// src/retention/published-gzip-sweep.ts
|
|
5
|
+
const PREFIX = "derived/published-gzip/";
|
|
6
|
+
const MAX_PER_SWEEP = 128;
|
|
7
|
+
const cursors = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
/** Reclaim disposable orphan variants; never delete content or other storage keys. */
|
|
9
|
+
async function sweepPublishedGzip(storage) {
|
|
10
|
+
const keys = (await storage.list(PREFIX)).filter((key) => /^derived\/published-gzip\/[a-f0-9]{64}\.gz$/u.test(key)).toSorted();
|
|
11
|
+
if (keys.length === 0) return;
|
|
12
|
+
const cursor = cursors.get(storage);
|
|
13
|
+
const next = cursor ? keys.findIndex((key) => key > cursor) : 0;
|
|
14
|
+
const start = Math.max(0, next);
|
|
15
|
+
const batch = [...keys.slice(start), ...keys.slice(0, start)].slice(0, MAX_PER_SWEEP);
|
|
16
|
+
for (const key of batch) await removeOrphan(storage, key);
|
|
17
|
+
const last = batch.at(-1);
|
|
18
|
+
if (last) cursors.set(storage, last);
|
|
19
|
+
}
|
|
20
|
+
async function removeOrphan(storage, key) {
|
|
21
|
+
const hash = key.slice(23, -3);
|
|
22
|
+
try {
|
|
23
|
+
if (!await storage.exists(`content/${hash}`)) await storage.delete(key);
|
|
24
|
+
} catch {}
|
|
25
|
+
}
|
|
26
|
+
export { sweepPublishedGzip };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=published-gzip-sweep.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"published-gzip-sweep.mjs","names":[],"sources":["../../src/retention/published-gzip-sweep.ts"],"sourcesContent":["import type { StorageAdapter } from \"../adapters/storage.ts\";\n\nconst PREFIX = \"derived/published-gzip/\";\nconst MAX_PER_SWEEP = 128;\nconst cursors = new WeakMap<StorageAdapter, string>();\n\n/** Reclaim disposable orphan variants; never delete content or other storage keys. */\nexport async function sweepPublishedGzip(storage: StorageAdapter): Promise<void> {\n const keys = (await storage.list(PREFIX))\n .filter((key) => /^derived\\/published-gzip\\/[a-f0-9]{64}\\.gz$/u.test(key))\n .toSorted();\n if (keys.length === 0) return;\n const cursor = cursors.get(storage);\n const next = cursor ? keys.findIndex((key) => key > cursor) : 0;\n const start = Math.max(0, next);\n const batch = [...keys.slice(start), ...keys.slice(0, start)].slice(0, MAX_PER_SWEEP);\n for (const key of batch) {\n // oxlint-disable-next-line eslint/no-await-in-loop -- bounded, sequential storage work\n await removeOrphan(storage, key);\n }\n const last = batch.at(-1);\n if (last) cursors.set(storage, last);\n}\n\nasync function removeOrphan(storage: StorageAdapter, key: string): Promise<void> {\n const hash = key.slice(PREFIX.length, -3);\n try {\n if (!(await storage.exists(`content/${hash}`))) await storage.delete(key);\n } catch {\n // Retention is best effort; a missing variant can always be regenerated.\n }\n}\n"],"mappings":";;;;AAEA,MAAM,SAAS;AACf,MAAM,gBAAgB;AACtB,MAAM,0BAAU,IAAI,QAAgC;;AAGpD,eAAsB,mBAAmB,SAAwC;CAC/E,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,EAAA,CACpC,QAAQ,QAAQ,+CAA+C,KAAK,GAAG,CAAC,CAAC,CACzE,SAAS;CACZ,IAAI,KAAK,WAAW,GAAG;CACvB,MAAM,SAAS,QAAQ,IAAI,OAAO;CAClC,MAAM,OAAO,SAAS,KAAK,WAAW,QAAQ,MAAM,MAAM,IAAI;CAC9D,MAAM,QAAQ,KAAK,IAAI,GAAG,IAAI;CAC9B,MAAM,QAAQ,CAAC,GAAG,KAAK,MAAM,KAAK,GAAG,GAAG,KAAK,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,aAAa;CACpF,KAAK,MAAM,OAAO,OAEhB,MAAM,aAAa,SAAS,GAAG;CAEjC,MAAM,OAAO,MAAM,GAAG,EAAE;CACxB,IAAI,MAAM,QAAQ,IAAI,SAAS,IAAI;AACrC;AAEA,eAAe,aAAa,SAAyB,KAA4B;CAC/E,MAAM,OAAO,IAAI,MAAM,IAAe,EAAE;CACxC,IAAI;EACF,IAAI,CAAE,MAAM,QAAQ,OAAO,WAAW,MAAM,GAAI,MAAM,QAAQ,OAAO,GAAG;CAC1E,QAAQ,CAER;AACF"}
|
|
@@ -4,7 +4,6 @@ import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
|
4
4
|
import { StorageAdapter } from "../adapter/storage.mjs";
|
|
5
5
|
import { Logger } from "pino";
|
|
6
6
|
import { Table } from "drizzle-orm";
|
|
7
|
-
//#region src/retention/screenshot-sweep.d.ts
|
|
8
7
|
/** Longest an unreferenced screenshot is kept after the sweep first sees it (default 24 h). */
|
|
9
8
|
declare const SWEEP_GRACE_MS: number;
|
|
10
9
|
/** Tables the sweep reads references and in-flight builds from. */
|
|
@@ -46,6 +45,5 @@ declare function sweepScreenshotContent(deps: SweepDeps, projectId: string, opti
|
|
|
46
45
|
now?: number;
|
|
47
46
|
graceMs?: number;
|
|
48
47
|
}): Promise<SweepResult>;
|
|
49
|
-
//#endregion
|
|
50
48
|
export { SWEEP_GRACE_MS, SweepDeps, SweepResult, SweepTables, sweepScreenshotContent };
|
|
51
49
|
//# sourceMappingURL=screenshot-sweep.d.mts.map
|
|
@@ -5,7 +5,7 @@ import { col } from "../models/columns.mjs";
|
|
|
5
5
|
import { contentDir } from "../paths.mjs";
|
|
6
6
|
import { CLAIMS_DIR } from "../utils/screenshot-store.mjs";
|
|
7
7
|
import { and, eq, gte, inArray, like } from "drizzle-orm";
|
|
8
|
-
|
|
8
|
+
// src/retention/screenshot-sweep.ts
|
|
9
9
|
/** Mark-and-sweep for a project's content-addressed screenshots. */
|
|
10
10
|
/** Longest an unreferenced screenshot is kept after the sweep first sees it (default 24 h). */
|
|
11
11
|
const SWEEP_GRACE_MS = 864e5;
|
|
@@ -122,7 +122,6 @@ async function readMarker(storage, dir) {
|
|
|
122
122
|
async function writeMarker(storage, dir, next, previous) {
|
|
123
123
|
if (JSON.stringify(next) !== JSON.stringify(previous)) await storage.write(`${dir}${MARKER}`, Buffer.from(JSON.stringify(next)));
|
|
124
124
|
}
|
|
125
|
-
//#endregion
|
|
126
125
|
export { SWEEP_GRACE_MS, sweepScreenshotContent };
|
|
127
126
|
|
|
128
127
|
//# sourceMappingURL=screenshot-sweep.mjs.map
|
package/dist/retention.d.mts
CHANGED
|
@@ -7,7 +7,6 @@ import { SWEEP_GRACE_MS, SweepDeps, SweepResult, SweepTables, sweepScreenshotCon
|
|
|
7
7
|
import { AiPurgeResult, STALE_RUN_MS, purgeAiData } from "./retention/ai.mjs";
|
|
8
8
|
import { Logger } from "pino";
|
|
9
9
|
import { Table } from "drizzle-orm";
|
|
10
|
-
//#region src/retention/purge.d.ts
|
|
11
10
|
/** Table handles for retention queries. */
|
|
12
11
|
interface RetentionTables {
|
|
13
12
|
builds: Table;
|
|
@@ -54,6 +53,5 @@ interface BranchGcResult {
|
|
|
54
53
|
removedBranches: number;
|
|
55
54
|
removedBaselines: number;
|
|
56
55
|
}
|
|
57
|
-
//#endregion
|
|
58
56
|
export { type AiPurgeResult, BranchGcResult, PurgeOptions, PurgeResult, Retention, RetentionTables, STALE_RUN_MS, SWEEP_GRACE_MS, type SweepDeps, type SweepResult, type SweepTables, purgeAiData, sweepScreenshotContent };
|
|
59
57
|
//# sourceMappingURL=retention.d.mts.map
|
package/dist/retention.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { TERMINAL_BUILD_STATUSES } from "./types.mjs";
|
|
5
5
|
import { col } from "./models/columns.mjs";
|
|
6
6
|
import { BuildModel } from "./models/build.mjs";
|
|
7
|
+
import { publishedGzipPath } from "./paths.mjs";
|
|
7
8
|
import { BaselineModel } from "./models/baseline.mjs";
|
|
8
9
|
import { CaptureJobModel } from "./models/capture-job.mjs";
|
|
9
10
|
import { BuildComponentModel } from "./models/build-component.mjs";
|
|
@@ -11,10 +12,11 @@ import { InsightModel } from "./models/insight.mjs";
|
|
|
11
12
|
import { LabelModel } from "./models/label.mjs";
|
|
12
13
|
import { PackageUsageModel } from "./models/usage.mjs";
|
|
13
14
|
import { pendingCandidates } from "./retention/pending.mjs";
|
|
15
|
+
import { sweepPublishedGzip } from "./retention/published-gzip-sweep.mjs";
|
|
14
16
|
import { SWEEP_GRACE_MS, sweepScreenshotContent } from "./retention/screenshot-sweep.mjs";
|
|
15
17
|
import { STALE_RUN_MS, purgeAiData } from "./retention/ai.mjs";
|
|
16
18
|
import { and, desc, eq, inArray, lt } from "drizzle-orm";
|
|
17
|
-
|
|
19
|
+
// src/retention/purge.ts
|
|
18
20
|
/** Removes expired transient builds while keeping baselines and persistent builds. */
|
|
19
21
|
var Retention = class {
|
|
20
22
|
db;
|
|
@@ -153,9 +155,11 @@ var Retention = class {
|
|
|
153
155
|
const all = await this.db.list(contentRefs);
|
|
154
156
|
for (const row of all) if (row.refCount === 0 && row.lastSeenAt < cutoff) {
|
|
155
157
|
await this.storage.delete(`content/${row.hash}`).catch(() => {});
|
|
158
|
+
if (/^[a-f0-9]{64}$/u.test(row.hash)) await this.storage.delete(publishedGzipPath(row.hash)).catch(() => {});
|
|
156
159
|
await this.db.remove(contentRefs, row.hash);
|
|
157
160
|
}
|
|
158
161
|
} catch {}
|
|
162
|
+
await sweepPublishedGzip(this.storage).catch(() => {});
|
|
159
163
|
return files.length;
|
|
160
164
|
}
|
|
161
165
|
async purgeStaleBranches(project, ttlDays) {
|
|
@@ -196,7 +200,6 @@ function branchLatestAt(rows) {
|
|
|
196
200
|
}
|
|
197
201
|
return latestAt;
|
|
198
202
|
}
|
|
199
|
-
//#endregion
|
|
200
203
|
export { Retention, STALE_RUN_MS, SWEEP_GRACE_MS, purgeAiData, sweepScreenshotContent };
|
|
201
204
|
|
|
202
205
|
//# sourceMappingURL=retention.mjs.map
|