@storyshelf/core 0.3.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -31
- package/dist/adapter/capture-queue.d.mts +29 -1
- package/dist/adapter/capture-runner.d.mts +18 -2
- package/dist/adapter/capture-runner.mjs +12 -1
- package/dist/adapter/capture-runner.mjs.map +1 -0
- package/dist/adapter/database.d.mts +67 -17
- package/dist/adapter/database.mjs +22 -55
- package/dist/adapter/database.mjs.map +1 -1
- package/dist/adapter/email-sender.d.mts +27 -0
- package/dist/adapter/email-sender.mjs +4 -0
- package/dist/adapter/metadata.d.mts +21 -15
- package/dist/adapter/notifier.d.mts +7 -0
- package/dist/adapter/notifier.mjs +6 -0
- package/dist/adapter/setup.d.mts +61 -0
- package/dist/adapter/setup.mjs +29 -0
- package/dist/adapter/setup.mjs.map +1 -0
- package/dist/adapter/webhook-events.d.mts +29 -0
- package/dist/adapter/webhook-events.mjs +83 -0
- package/dist/adapter/webhook-events.mjs.map +1 -0
- package/dist/adapters/notifier/events.d.mts +26 -0
- package/dist/adapters/notifier/events.mjs +66 -0
- package/dist/adapters/notifier/events.mjs.map +1 -0
- package/dist/adapters/notifier/format.d.mts +14 -0
- package/dist/adapters/notifier/format.mjs +96 -0
- package/dist/adapters/notifier/format.mjs.map +1 -0
- package/dist/adapters/notifier/provider.d.mts +32 -0
- package/dist/adapters/notifier/types.d.mts +56 -0
- package/dist/adapters/setup-runner.d.mts +23 -0
- package/dist/adapters/setup-runner.mjs +149 -0
- package/dist/adapters/setup-runner.mjs.map +1 -0
- package/dist/adapters/validate.d.mts +30 -0
- package/dist/adapters/validate.mjs +313 -0
- package/dist/adapters/validate.mjs.map +1 -0
- package/dist/auth.d.mts +94 -0
- package/dist/auth.mjs +4 -0
- package/dist/brand-packs.d.mts +16 -0
- package/dist/brand-packs.mjs +130 -0
- package/dist/brand-packs.mjs.map +1 -0
- package/dist/capture/adapter.d.mts +51 -1
- package/dist/capture/adapter.mjs.map +1 -1
- package/dist/capture/affected.d.mts +16 -0
- package/dist/capture/affected.mjs +64 -0
- package/dist/capture/affected.mjs.map +1 -0
- package/dist/capture/diff-record.mjs +30 -0
- package/dist/capture/diff-record.mjs.map +1 -0
- package/dist/capture/dispatch.d.mts +36 -0
- package/dist/capture/dispatch.mjs +88 -31
- package/dist/capture/dispatch.mjs.map +1 -1
- package/dist/capture/guards.mjs +31 -0
- package/dist/capture/guards.mjs.map +1 -0
- package/dist/capture/orchestrator.d.mts +41 -6
- package/dist/capture/orchestrator.mjs +151 -28
- package/dist/capture/orchestrator.mjs.map +1 -1
- package/dist/capture/pipeline.d.mts +30 -16
- package/dist/capture/pipeline.mjs +143 -39
- package/dist/capture/pipeline.mjs.map +1 -1
- package/dist/capture/recovery.d.mts +21 -0
- package/dist/capture/recovery.mjs +83 -0
- package/dist/capture/recovery.mjs.map +1 -0
- package/dist/capture/rediff.d.mts +35 -0
- package/dist/capture/rediff.mjs +77 -0
- package/dist/capture/rediff.mjs.map +1 -0
- package/dist/capture/sizing.d.mts +58 -0
- package/dist/capture/sizing.mjs +119 -0
- package/dist/capture/sizing.mjs.map +1 -0
- package/dist/capture/skip-checks.mjs +3 -3
- package/dist/capture/skip-checks.mjs.map +1 -1
- package/dist/capture/statics.d.mts +38 -0
- package/dist/capture/statics.mjs +38 -4
- package/dist/capture/statics.mjs.map +1 -1
- package/dist/capture/status-fanout.mjs +7 -2
- package/dist/capture/status-fanout.mjs.map +1 -1
- package/dist/capture/storybook.d.mts +31 -2
- package/dist/capture/storybook.mjs +77 -2
- package/dist/capture/storybook.mjs.map +1 -1
- package/dist/capture.d.mts +10 -4
- package/dist/capture.mjs +7 -2
- package/dist/config.d.mts +121 -4
- package/dist/config.mjs +55 -8
- package/dist/config.mjs.map +1 -1
- package/dist/index.d.mts +5 -56
- package/dist/index.mjs +4 -284
- package/dist/logger.d.mts +26 -17
- package/dist/logger.mjs +10 -5
- package/dist/logger.mjs.map +1 -1
- package/dist/models/baseline-status.d.mts +29 -0
- package/dist/models/baseline-status.mjs +26 -0
- package/dist/models/baseline-status.mjs.map +1 -0
- package/dist/models/baseline.d.mts +33 -0
- package/dist/models/baseline.mjs +35 -13
- package/dist/models/baseline.mjs.map +1 -1
- package/dist/models/build.d.mts +87 -0
- package/dist/models/build.mjs +83 -35
- package/dist/models/build.mjs.map +1 -1
- package/dist/models/capture-attempt.d.mts +40 -0
- package/dist/models/capture-attempt.mjs +85 -0
- package/dist/models/capture-attempt.mjs.map +1 -0
- package/dist/models/capture-log.d.mts +21 -0
- package/dist/models/capture-log.mjs +44 -0
- package/dist/models/capture-log.mjs.map +1 -0
- package/dist/models/comment.d.mts +29 -0
- package/dist/models/comment.mjs +11 -8
- package/dist/models/comment.mjs.map +1 -1
- package/dist/models/content-ref.d.mts +21 -0
- package/dist/models/content-ref.mjs +49 -0
- package/dist/models/content-ref.mjs.map +1 -0
- package/dist/models/credentials.d.mts +36 -0
- package/dist/models/credentials.mjs +103 -0
- package/dist/models/credentials.mjs.map +1 -0
- package/dist/models/label.d.mts +58 -0
- package/dist/models/label.mjs +32 -27
- package/dist/models/label.mjs.map +1 -1
- package/dist/models/member.d.mts +34 -0
- package/dist/models/member.mjs +20 -11
- package/dist/models/member.mjs.map +1 -1
- package/dist/models/notification-channel.d.mts +52 -0
- package/dist/models/notification-channel.mjs +93 -0
- package/dist/models/notification-channel.mjs.map +1 -0
- package/dist/models/notification-subscription.d.mts +44 -0
- package/dist/models/notification-subscription.mjs +89 -0
- package/dist/models/notification-subscription.mjs.map +1 -0
- package/dist/models/project-group-mapping.d.mts +30 -0
- package/dist/models/project-group-mapping.mjs +46 -0
- package/dist/models/project-group-mapping.mjs.map +1 -0
- package/dist/models/project.d.mts +54 -0
- package/dist/models/project.mjs +15 -11
- package/dist/models/project.mjs.map +1 -1
- package/dist/models/snapshot.d.mts +58 -0
- package/dist/models/snapshot.mjs +13 -7
- package/dist/models/snapshot.mjs.map +1 -1
- package/dist/models/status-config.d.mts +38 -0
- package/dist/models/status-config.mjs +12 -11
- package/dist/models/status-config.mjs.map +1 -1
- package/dist/models/token.d.mts +44 -0
- package/dist/models/token.mjs +18 -15
- package/dist/models/token.mjs.map +1 -1
- package/dist/models/user.d.mts +42 -0
- package/dist/models/user.mjs +65 -0
- package/dist/models/user.mjs.map +1 -0
- package/dist/models/webhook.d.mts +50 -0
- package/dist/models/webhook.mjs +12 -10
- package/dist/models/webhook.mjs.map +1 -1
- package/dist/models.d.mts +22 -0
- package/dist/models.mjs +23 -0
- package/dist/paths.mjs +29 -0
- package/dist/paths.mjs.map +1 -1
- package/dist/retention.d.mts +45 -0
- package/dist/retention.mjs +145 -0
- package/dist/retention.mjs.map +1 -0
- package/dist/schema/baseline.d.mts +1 -0
- package/dist/schema/build.d.mts +8 -0
- package/dist/schema/capture-attempt.d.mts +38 -0
- package/dist/schema/comment.d.mts +1 -1
- package/dist/schema/content-ref.d.mts +13 -0
- package/dist/schema/member.d.mts +2 -0
- package/dist/schema/notification.d.mts +35 -0
- package/dist/schema/project-group-mapping.d.mts +15 -0
- package/dist/schema/project.d.mts +4 -0
- package/dist/schema/snapshot.d.mts +7 -0
- package/dist/schema/token.d.mts +2 -0
- package/dist/schema/user.d.mts +11 -1
- package/dist/schema.d.mts +9 -46
- package/dist/schema.mjs +1 -55
- package/dist/test-helpers/create-project.d.mts +15 -0
- package/dist/test-helpers/create-project.mjs +28 -0
- package/dist/test-helpers/create-project.mjs.map +1 -0
- package/dist/test-helpers/database-contract.d.mts +13 -0
- package/dist/test-helpers/database-contract.mjs +58 -0
- package/dist/test-helpers/database-contract.mjs.map +1 -0
- package/dist/test-helpers/fake-adapters.d.mts +14 -0
- package/dist/test-helpers/fake-adapters.mjs +20 -0
- package/dist/test-helpers/fake-adapters.mjs.map +1 -0
- package/dist/test-helpers/fake-database.d.mts +11 -0
- package/dist/test-helpers/fake-database.mjs +104 -0
- package/dist/test-helpers/fake-database.mjs.map +1 -0
- package/dist/test-helpers/fake-storage.d.mts +14 -0
- package/dist/test-helpers/fake-storage.mjs +49 -0
- package/dist/test-helpers/fake-storage.mjs.map +1 -0
- package/dist/test-helpers/fake-tables.mjs +276 -0
- package/dist/test-helpers/fake-tables.mjs.map +1 -0
- package/dist/test-helpers/git-contract.d.mts +11 -0
- package/dist/test-helpers/git-contract.mjs +34 -0
- package/dist/test-helpers/git-contract.mjs.map +1 -0
- package/dist/test-helpers/notifier-contract.d.mts +11 -0
- package/dist/test-helpers/notifier-contract.mjs +34 -0
- package/dist/test-helpers/notifier-contract.mjs.map +1 -0
- package/dist/test-helpers/queue-contract.d.mts +11 -0
- package/dist/test-helpers/queue-contract.mjs +64 -0
- package/dist/test-helpers/queue-contract.mjs.map +1 -0
- package/dist/test-helpers/runner-contract.d.mts +11 -0
- package/dist/test-helpers/runner-contract.mjs +32 -0
- package/dist/test-helpers/runner-contract.mjs.map +1 -0
- package/dist/test-helpers/sql-chunks.mjs +138 -0
- package/dist/test-helpers/sql-chunks.mjs.map +1 -0
- package/dist/test-helpers/storage-contract.d.mts +11 -0
- package/dist/test-helpers/storage-contract.mjs +87 -0
- package/dist/test-helpers/storage-contract.mjs.map +1 -0
- package/dist/test-helpers.d.mts +13 -0
- package/dist/test-helpers.mjs +14 -0
- package/dist/tracing.mjs +63 -0
- package/dist/tracing.mjs.map +1 -0
- package/dist/types.d.mts +38 -5
- package/dist/types.mjs +18 -5
- package/dist/types.mjs.map +1 -1
- package/dist/urls.d.mts +12 -1
- package/dist/urls.mjs +22 -3
- package/dist/urls.mjs.map +1 -1
- package/dist/utils/encrypt.d.mts +48 -0
- package/dist/utils/encrypt.mjs +67 -13
- package/dist/utils/encrypt.mjs.map +1 -1
- package/dist/utils/hash.d.mts +17 -0
- package/dist/utils/hash.mjs +8 -2
- package/dist/utils/hash.mjs.map +1 -1
- package/dist/utils/http.d.mts +58 -0
- package/dist/utils/http.mjs +147 -0
- package/dist/utils/http.mjs.map +1 -0
- package/dist/utils/mime.d.mts +9 -0
- package/dist/utils/mime.mjs +33 -0
- package/dist/utils/mime.mjs.map +1 -0
- package/dist/utils/path-security.d.mts +12 -0
- package/dist/utils/path-security.mjs +24 -0
- package/dist/utils/path-security.mjs.map +1 -0
- package/dist/utils/redact.d.mts +17 -0
- package/dist/utils/redact.mjs +42 -0
- package/dist/utils/redact.mjs.map +1 -0
- package/dist/utils/timing.d.mts +19 -0
- package/dist/utils/timing.mjs +46 -0
- package/dist/utils/timing.mjs.map +1 -0
- package/dist/utils/ulid.d.mts +10 -0
- package/dist/utils/ulid.mjs +8 -8
- package/dist/utils/ulid.mjs.map +1 -1
- package/dist/utils.d.mts +12 -0
- package/dist/utils.mjs +13 -0
- package/package.json +69 -28
- package/dist/adapter/auth.d.mts +0 -50
- package/dist/adapter/auth.mjs +0 -10
- package/dist/adapter/auth.mjs.map +0 -1
- package/dist/adapter/init.d.mts +0 -58
- package/dist/adapter/init.mjs +0 -93
- package/dist/adapter/init.mjs.map +0 -1
- package/dist/adapters/webhook-events.mjs +0 -55
- package/dist/adapters/webhook-events.mjs.map +0 -1
- package/dist/ddl.d.mts +0 -8
- package/dist/ddl.mjs +0 -158
- package/dist/ddl.mjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/middleware/auth-gate.mjs +0 -36
- package/dist/middleware/auth-gate.mjs.map +0 -1
- package/dist/middleware/csrf.mjs +0 -40
- package/dist/middleware/csrf.mjs.map +0 -1
- package/dist/middleware/rate-limit.mjs +0 -39
- package/dist/middleware/rate-limit.mjs.map +0 -1
- package/dist/middleware/request-log.mjs +0 -28
- package/dist/middleware/request-log.mjs.map +0 -1
- package/dist/middleware/store-scope.mjs +0 -29
- package/dist/middleware/store-scope.mjs.map +0 -1
- package/dist/pages/build-detail.mjs +0 -339
- package/dist/pages/build-detail.mjs.map +0 -1
- package/dist/pages/build-diff-comments.mjs +0 -113
- package/dist/pages/build-diff-comments.mjs.map +0 -1
- package/dist/pages/build-diff-header.mjs +0 -163
- package/dist/pages/build-diff-header.mjs.map +0 -1
- package/dist/pages/build-diff-nav.mjs +0 -66
- package/dist/pages/build-diff-nav.mjs.map +0 -1
- package/dist/pages/build-diff-viewer.mjs +0 -197
- package/dist/pages/build-diff-viewer.mjs.map +0 -1
- package/dist/pages/build-diff.mjs +0 -90
- package/dist/pages/build-diff.mjs.map +0 -1
- package/dist/pages/compute-jobs.mjs +0 -198
- package/dist/pages/compute-jobs.mjs.map +0 -1
- package/dist/pages/label-detail.mjs +0 -228
- package/dist/pages/label-detail.mjs.map +0 -1
- package/dist/pages/login.mjs +0 -78
- package/dist/pages/login.mjs.map +0 -1
- package/dist/pages/project-builds.mjs +0 -231
- package/dist/pages/project-builds.mjs.map +0 -1
- package/dist/pages/project-create.mjs +0 -169
- package/dist/pages/project-create.mjs.map +0 -1
- package/dist/pages/project-settings.mjs +0 -102
- package/dist/pages/project-settings.mjs.map +0 -1
- package/dist/pages/projects.mjs +0 -184
- package/dist/pages/projects.mjs.map +0 -1
- package/dist/pages/root.mjs +0 -94
- package/dist/pages/root.mjs.map +0 -1
- package/dist/pages/settings-general.mjs +0 -192
- package/dist/pages/settings-general.mjs.map +0 -1
- package/dist/pages/settings-labels.mjs +0 -150
- package/dist/pages/settings-labels.mjs.map +0 -1
- package/dist/pages/settings-members.mjs +0 -125
- package/dist/pages/settings-members.mjs.map +0 -1
- package/dist/pages/settings-status.mjs +0 -152
- package/dist/pages/settings-status.mjs.map +0 -1
- package/dist/pages/settings-tests.mjs +0 -149
- package/dist/pages/settings-tests.mjs.map +0 -1
- package/dist/pages/settings-tokens.mjs +0 -96
- package/dist/pages/settings-tokens.mjs.map +0 -1
- package/dist/pages/settings-webhooks.mjs +0 -150
- package/dist/pages/settings-webhooks.mjs.map +0 -1
- package/dist/pages/storybook.mjs +0 -96
- package/dist/pages/storybook.mjs.map +0 -1
- package/dist/retention/purge.mjs +0 -67
- package/dist/retention/purge.mjs.map +0 -1
- package/dist/routers/admin.mjs +0 -42
- package/dist/routers/admin.mjs.map +0 -1
- package/dist/routers/assets.mjs +0 -25
- package/dist/routers/assets.mjs.map +0 -1
- package/dist/routers/auth.mjs +0 -78
- package/dist/routers/auth.mjs.map +0 -1
- package/dist/routers/builds.handlers.mjs +0 -184
- package/dist/routers/builds.handlers.mjs.map +0 -1
- package/dist/routers/builds.mjs +0 -185
- package/dist/routers/builds.mjs.map +0 -1
- package/dist/routers/comments.mjs +0 -90
- package/dist/routers/comments.mjs.map +0 -1
- package/dist/routers/health.mjs +0 -137
- package/dist/routers/health.mjs.map +0 -1
- package/dist/routers/helpers.mjs +0 -82
- package/dist/routers/helpers.mjs.map +0 -1
- package/dist/routers/htmx.mjs +0 -20
- package/dist/routers/htmx.mjs.map +0 -1
- package/dist/routers/labels.mjs +0 -110
- package/dist/routers/labels.mjs.map +0 -1
- package/dist/routers/media.mjs +0 -55
- package/dist/routers/media.mjs.map +0 -1
- package/dist/routers/members.mjs +0 -102
- package/dist/routers/members.mjs.map +0 -1
- package/dist/routers/projects.mjs +0 -122
- package/dist/routers/projects.mjs.map +0 -1
- package/dist/routers/schemas.mjs +0 -224
- package/dist/routers/schemas.mjs.map +0 -1
- package/dist/routers/settings-general.mjs +0 -95
- package/dist/routers/settings-general.mjs.map +0 -1
- package/dist/routers/settings-labels.mjs +0 -49
- package/dist/routers/settings-labels.mjs.map +0 -1
- package/dist/routers/settings-members.mjs +0 -30
- package/dist/routers/settings-members.mjs.map +0 -1
- package/dist/routers/settings-status.mjs +0 -73
- package/dist/routers/settings-status.mjs.map +0 -1
- package/dist/routers/settings-tokens.mjs +0 -40
- package/dist/routers/settings-tokens.mjs.map +0 -1
- package/dist/routers/settings-webhooks.mjs +0 -63
- package/dist/routers/settings-webhooks.mjs.map +0 -1
- package/dist/routers/settings.handlers.mjs +0 -93
- package/dist/routers/settings.handlers.mjs.map +0 -1
- package/dist/routers/settings.mjs +0 -23
- package/dist/routers/settings.mjs.map +0 -1
- package/dist/routers/snapshots.mjs +0 -144
- package/dist/routers/snapshots.mjs.map +0 -1
- package/dist/routers/status-configs.mjs +0 -101
- package/dist/routers/status-configs.mjs.map +0 -1
- package/dist/routers/storybook.mjs +0 -120
- package/dist/routers/storybook.mjs.map +0 -1
- package/dist/routers/tokens.mjs +0 -81
- package/dist/routers/tokens.mjs.map +0 -1
- package/dist/routers/ui.mjs +0 -165
- package/dist/routers/ui.mjs.map +0 -1
- package/dist/routers/webhooks.mjs +0 -90
- package/dist/routers/webhooks.mjs.map +0 -1
- package/dist/schema/baseline.mjs +0 -22
- package/dist/schema/baseline.mjs.map +0 -1
- package/dist/schema/build.mjs +0 -29
- package/dist/schema/build.mjs.map +0 -1
- package/dist/schema/comment.mjs +0 -26
- package/dist/schema/comment.mjs.map +0 -1
- package/dist/schema/label.mjs +0 -30
- package/dist/schema/label.mjs.map +0 -1
- package/dist/schema/member.mjs +0 -19
- package/dist/schema/member.mjs.map +0 -1
- package/dist/schema/project.mjs +0 -25
- package/dist/schema/project.mjs.map +0 -1
- package/dist/schema/snapshot.mjs +0 -34
- package/dist/schema/snapshot.mjs.map +0 -1
- package/dist/schema/status-config.mjs +0 -20
- package/dist/schema/status-config.mjs.map +0 -1
- package/dist/schema/token.mjs +0 -19
- package/dist/schema/token.mjs.map +0 -1
- package/dist/schema/user.mjs +0 -19
- package/dist/schema/user.mjs.map +0 -1
- package/dist/schema/webhook.mjs +0 -20
- package/dist/schema/webhook.mjs.map +0 -1
- package/dist/schema.mjs.map +0 -1
- package/dist/store.mjs +0 -20
- package/dist/store.mjs.map +0 -1
- package/dist/ui/document.mjs +0 -348
- package/dist/ui/document.mjs.map +0 -1
- package/dist/ui/feedback.mjs +0 -24
- package/dist/ui/feedback.mjs.map +0 -1
- package/dist/ui/forms.mjs +0 -117
- package/dist/ui/forms.mjs.map +0 -1
- package/dist/ui/styles.mjs +0 -174
- package/dist/ui/styles.mjs.map +0 -1
- package/dist/ui/theme.mjs +0 -44
- package/dist/ui/theme.mjs.map +0 -1
|
@@ -1,16 +1,83 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
import {
|
|
4
|
+
import { STATS_FILENAME, loadDepGraph } from "@storyshelf/affected";
|
|
5
5
|
import { join } from "node:path";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
6
7
|
//#region src/capture/storybook.ts
|
|
8
|
+
/** Merge the `chromatic` and `storyshelf` parameter layers (`storyshelf` wins). */
|
|
7
9
|
function mergeParameters(entry) {
|
|
8
10
|
const merged = {
|
|
9
11
|
...entry.parameters?.chromatic,
|
|
10
12
|
...entry.parameters?.storyshelf
|
|
11
13
|
};
|
|
14
|
+
if (entry.parameters?.viewport) merged.viewport = entry.parameters.viewport;
|
|
12
15
|
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
13
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* The Storybook `MINIMAL_VIEWPORTS` snapshot used to resolve a story's
|
|
19
|
+
* `defaultViewport` name at capture time. Dimensions are the documented
|
|
20
|
+
* stable set; inline `parameters.viewport.viewports` always win over these.
|
|
21
|
+
*/
|
|
22
|
+
const STORYBOOK_BUILTIN_VIEWPORTS = {
|
|
23
|
+
mobile1: {
|
|
24
|
+
name: "mobile1",
|
|
25
|
+
width: 320,
|
|
26
|
+
height: 568
|
|
27
|
+
},
|
|
28
|
+
mobile2: {
|
|
29
|
+
name: "mobile2",
|
|
30
|
+
width: 414,
|
|
31
|
+
height: 896
|
|
32
|
+
},
|
|
33
|
+
tablet: {
|
|
34
|
+
name: "tablet",
|
|
35
|
+
width: 834,
|
|
36
|
+
height: 1112
|
|
37
|
+
},
|
|
38
|
+
desktop: {
|
|
39
|
+
name: "desktop",
|
|
40
|
+
width: 1024,
|
|
41
|
+
height: 1280
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Resolve the viewports a story should be captured at: the project's global
|
|
46
|
+
* list plus the story's Storybook default viewport (union), deduplicated by
|
|
47
|
+
* name. An unresolvable or duplicate default contributes nothing extra.
|
|
48
|
+
*/
|
|
49
|
+
function resolveStoryViewports(entry, globalViewports) {
|
|
50
|
+
const resolved = storyViewport(entry);
|
|
51
|
+
if (resolved && !globalViewports.some((v) => v.name === resolved.name)) return [...globalViewports, resolved];
|
|
52
|
+
return [...globalViewports];
|
|
53
|
+
}
|
|
54
|
+
function storyViewport(entry) {
|
|
55
|
+
const config = entry.parameters?.viewport;
|
|
56
|
+
const name = config?.defaultViewport;
|
|
57
|
+
const inline = name ? config?.viewports?.[name] : void 0;
|
|
58
|
+
return name && inline ? viewportFromInline(name, inline) : name ? STORYBOOK_BUILTIN_VIEWPORTS[name] : void 0;
|
|
59
|
+
}
|
|
60
|
+
function viewportFromInline(defaultName, inline) {
|
|
61
|
+
const dims = viewportDims(inline.styles);
|
|
62
|
+
return dims ? {
|
|
63
|
+
name: inline.name ?? defaultName,
|
|
64
|
+
...dims
|
|
65
|
+
} : void 0;
|
|
66
|
+
}
|
|
67
|
+
function viewportDims(styles) {
|
|
68
|
+
const width = pxOf(styles?.width);
|
|
69
|
+
const height = pxOf(styles?.height);
|
|
70
|
+
return width !== void 0 && height !== void 0 ? {
|
|
71
|
+
width,
|
|
72
|
+
height
|
|
73
|
+
} : void 0;
|
|
74
|
+
}
|
|
75
|
+
function pxOf(value) {
|
|
76
|
+
if (typeof value === "number") return Math.round(value);
|
|
77
|
+
const bare = typeof value === "string" ? value.trim() : "";
|
|
78
|
+
const match = /^(\d+(?:\.\d+)?)px$/u.exec(bare);
|
|
79
|
+
return match ? Number(match[1]) : void 0;
|
|
80
|
+
}
|
|
14
81
|
/** Discovers stories from a built Storybook via its index file. */
|
|
15
82
|
var StorybookAdapter = class {
|
|
16
83
|
name = "storybook";
|
|
@@ -30,6 +97,14 @@ var StorybookAdapter = class {
|
|
|
30
97
|
buildUrl(baseUrl, storyId) {
|
|
31
98
|
return `${baseUrl}/iframe.html?id=${encodeURIComponent(storyId)}&viewMode=story`;
|
|
32
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Load the Vite stats dependency graph of an extracted build for affected
|
|
102
|
+
* capture. Resolves `null` when the build ships no usable stats, in which
|
|
103
|
+
* case the orchestrator renders every story.
|
|
104
|
+
*/
|
|
105
|
+
async loadDependencyGraph(source) {
|
|
106
|
+
return await loadDepGraph(join(source, STATS_FILENAME));
|
|
107
|
+
}
|
|
33
108
|
async readIndex(source) {
|
|
34
109
|
const found = (await Promise.all(["stories.json", "index.json"].map(async (name) => {
|
|
35
110
|
try {
|
|
@@ -44,6 +119,6 @@ var StorybookAdapter = class {
|
|
|
44
119
|
}
|
|
45
120
|
};
|
|
46
121
|
//#endregion
|
|
47
|
-
export { StorybookAdapter };
|
|
122
|
+
export { STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, mergeParameters, resolveStoryViewports };
|
|
48
123
|
|
|
49
124
|
//# sourceMappingURL=storybook.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storybook.mjs","names":[],"sources":["../../src/capture/storybook.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {
|
|
1
|
+
{"version":3,"file":"storybook.mjs","names":[],"sources":["../../src/capture/storybook.ts"],"sourcesContent":["import { loadDepGraph, STATS_FILENAME, type DepGraph } from \"@storyshelf/affected\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n StoryEntry,\n StoryParameters,\n StorySourceAdapter,\n StoryViewportConfig,\n StoryViewportDefinition,\n Viewport,\n} from \"./adapter.ts\";\n\ninterface StorybookIndex {\n v: number;\n entries: Record<\n string,\n {\n id: string;\n name: string;\n title: string;\n importPath?: string;\n tags?: string[];\n type: string;\n subtype?: string;\n parameters?: StorybookParameters;\n }\n >;\n}\n\n/** Story parameters as serialized by the Storybook index. */\ninterface StorybookParameters {\n chromatic?: StoryParameters;\n storyshelf?: StoryParameters;\n viewport?: StoryViewportConfig;\n}\n\n/** Merge the `chromatic` and `storyshelf` parameter layers (`storyshelf` wins). */\nexport function mergeParameters(entry: {\n parameters?: StorybookParameters;\n}): StoryParameters | undefined {\n const merged: StoryParameters = {\n ...entry.parameters?.chromatic,\n ...entry.parameters?.storyshelf,\n };\n if (entry.parameters?.viewport) merged.viewport = entry.parameters.viewport;\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\n/**\n * The Storybook `MINIMAL_VIEWPORTS` snapshot used to resolve a story's\n * `defaultViewport` name at capture time. Dimensions are the documented\n * stable set; inline `parameters.viewport.viewports` always win over these.\n */\nexport const STORYBOOK_BUILTIN_VIEWPORTS: Readonly<Record<string, Viewport>> = {\n mobile1: { name: \"mobile1\", width: 320, height: 568 },\n mobile2: { name: \"mobile2\", width: 414, height: 896 },\n tablet: { name: \"tablet\", width: 834, height: 1112 },\n desktop: { name: \"desktop\", width: 1024, height: 1280 },\n};\n\n/**\n * Resolve the viewports a story should be captured at: the project's global\n * list plus the story's Storybook default viewport (union), deduplicated by\n * name. An unresolvable or duplicate default contributes nothing extra.\n */\nexport function resolveStoryViewports(\n entry: Pick<StoryEntry, \"parameters\">,\n globalViewports: Viewport[],\n): Viewport[] {\n const resolved = storyViewport(entry);\n if (resolved && !globalViewports.some((v) => v.name === resolved.name)) {\n return [...globalViewports, resolved];\n }\n return [...globalViewports];\n}\n\nfunction storyViewport(entry: Pick<StoryEntry, \"parameters\">): Viewport | undefined {\n const config = entry.parameters?.viewport;\n const name = config?.defaultViewport;\n const inline = name ? config?.viewports?.[name] : undefined;\n const resolved =\n name && inline\n ? viewportFromInline(name, inline)\n : name\n ? STORYBOOK_BUILTIN_VIEWPORTS[name]\n : undefined;\n return resolved;\n}\n\nfunction viewportFromInline(\n defaultName: string,\n inline: StoryViewportDefinition,\n): Viewport | undefined {\n const dims = viewportDims(inline.styles);\n return dims ? { name: inline.name ?? defaultName, ...dims } : undefined;\n}\n\nfunction viewportDims(\n styles: StoryViewportDefinition[\"styles\"] | undefined,\n): { width: number; height: number } | undefined {\n const width = pxOf(styles?.width);\n const height = pxOf(styles?.height);\n return width !== undefined && height !== undefined ? { width, height } : undefined;\n}\n\nfunction pxOf(value: string | number | undefined): number | undefined {\n if (typeof value === \"number\") return Math.round(value);\n const bare = typeof value === \"string\" ? value.trim() : \"\";\n const match = /^(\\d+(?:\\.\\d+)?)px$/u.exec(bare);\n return match ? Number(match[1]) : undefined;\n}\n\n/** Discovers stories from a built Storybook via its index file. */\nexport class StorybookAdapter implements StorySourceAdapter {\n readonly name = \"storybook\";\n readonly screenshotSelector = \"#storybook-root\";\n\n async discover(source: string): Promise<StoryEntry[]> {\n const index = await this.readIndex(source);\n return Object.values(index.entries)\n .filter((entry) => entry.type !== \"docs\" && entry.subtype !== \"test\")\n .map((entry) => ({\n id: entry.id,\n title: entry.title,\n name: entry.name,\n importPath: entry.importPath,\n tags: entry.tags,\n type: entry.type === \"docs\" ? \"docs\" : \"story\",\n parameters: mergeParameters(entry),\n }));\n }\n\n // eslint-disable-next-line class-methods-use-this\n buildUrl(baseUrl: string, storyId: string): string {\n return `${baseUrl}/iframe.html?id=${encodeURIComponent(storyId)}&viewMode=story`;\n }\n\n /**\n * Load the Vite stats dependency graph of an extracted build for affected\n * capture. Resolves `null` when the build ships no usable stats, in which\n * case the orchestrator renders every story.\n */\n // eslint-disable-next-line class-methods-use-this\n async loadDependencyGraph(source: string): Promise<DepGraph | null> {\n return await loadDepGraph(join(source, STATS_FILENAME));\n }\n\n // eslint-disable-next-line class-methods-use-this\n private async readIndex(source: string): Promise<StorybookIndex> {\n const candidates: string[] = [\"stories.json\", \"index.json\"];\n const results = await Promise.all(\n candidates.map(async (name) => {\n try {\n const raw = await readFile(join(source, name), \"utf8\");\n return JSON.parse(raw) as StorybookIndex;\n } catch {\n return null;\n }\n }),\n );\n const found = results.find((index) => index !== null);\n if (found) {\n return found;\n }\n throw new Error(`No Storybook index found in ${source}`);\n }\n}\n"],"mappings":";;;;;;;;AAqCA,SAAgB,gBAAgB,OAEA;CAC9B,MAAM,SAA0B;EAC9B,GAAG,MAAM,YAAY;EACrB,GAAG,MAAM,YAAY;CACvB;CACA,IAAI,MAAM,YAAY,UAAU,OAAO,WAAW,MAAM,WAAW;CACnE,OAAO,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,IAAI,SAAS,KAAA;AACnD;;;;;;AAOA,MAAa,8BAAkE;CAC7E,SAAS;EAAE,MAAM;EAAW,OAAO;EAAK,QAAQ;CAAI;CACpD,SAAS;EAAE,MAAM;EAAW,OAAO;EAAK,QAAQ;CAAI;CACpD,QAAQ;EAAE,MAAM;EAAU,OAAO;EAAK,QAAQ;CAAK;CACnD,SAAS;EAAE,MAAM;EAAW,OAAO;EAAM,QAAQ;CAAK;AACxD;;;;;;AAOA,SAAgB,sBACd,OACA,iBACY;CACZ,MAAM,WAAW,cAAc,KAAK;CACpC,IAAI,YAAY,CAAC,gBAAgB,MAAM,MAAM,EAAE,SAAS,SAAS,IAAI,GACnE,OAAO,CAAC,GAAG,iBAAiB,QAAQ;CAEtC,OAAO,CAAC,GAAG,eAAe;AAC5B;AAEA,SAAS,cAAc,OAA6D;CAClF,MAAM,SAAS,MAAM,YAAY;CACjC,MAAM,OAAO,QAAQ;CACrB,MAAM,SAAS,OAAO,QAAQ,YAAY,QAAQ,KAAA;CAOlD,OALE,QAAQ,SACJ,mBAAmB,MAAM,MAAM,IAC/B,OACE,4BAA4B,QAC5B,KAAA;AAEV;AAEA,SAAS,mBACP,aACA,QACsB;CACtB,MAAM,OAAO,aAAa,OAAO,MAAM;CACvC,OAAO,OAAO;EAAE,MAAM,OAAO,QAAQ;EAAa,GAAG;CAAK,IAAI,KAAA;AAChE;AAEA,SAAS,aACP,QAC+C;CAC/C,MAAM,QAAQ,KAAK,QAAQ,KAAK;CAChC,MAAM,SAAS,KAAK,QAAQ,MAAM;CAClC,OAAO,UAAU,KAAA,KAAa,WAAW,KAAA,IAAY;EAAE;EAAO;CAAO,IAAI,KAAA;AAC3E;AAEA,SAAS,KAAK,OAAwD;CACpE,IAAI,OAAO,UAAU,UAAU,OAAO,KAAK,MAAM,KAAK;CACtD,MAAM,OAAO,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;CACxD,MAAM,QAAQ,uBAAuB,KAAK,IAAI;CAC9C,OAAO,QAAQ,OAAO,MAAM,EAAE,IAAI,KAAA;AACpC;;AAGA,IAAa,mBAAb,MAA4D;CAC1D,OAAgB;CAChB,qBAA8B;CAE9B,MAAM,SAAS,QAAuC;EACpD,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM;EACzC,OAAO,OAAO,OAAO,MAAM,OAAO,CAAC,CAChC,QAAQ,UAAU,MAAM,SAAS,UAAU,MAAM,YAAY,MAAM,CAAC,CACpE,KAAK,WAAW;GACf,IAAI,MAAM;GACV,OAAO,MAAM;GACb,MAAM,MAAM;GACZ,YAAY,MAAM;GAClB,MAAM,MAAM;GACZ,MAAM,MAAM,SAAS,SAAS,SAAS;GACvC,YAAY,gBAAgB,KAAK;EACnC,EAAE;CACN;CAGA,SAAS,SAAiB,SAAyB;EACjD,OAAO,GAAG,QAAQ,kBAAkB,mBAAmB,OAAO,EAAE;CAClE;;;;;;CAQA,MAAM,oBAAoB,QAA0C;EAClE,OAAO,MAAM,aAAa,KAAK,QAAQ,cAAc,CAAC;CACxD;CAGA,MAAc,UAAU,QAAyC;EAY/D,MAAM,SAAQ,MAVQ,QAAQ,IAC5B,CAF4B,gBAAgB,YAEnC,CAAC,CAAC,IAAI,OAAO,SAAS;GAC7B,IAAI;IACF,MAAM,MAAM,MAAM,SAAS,KAAK,QAAQ,IAAI,GAAG,MAAM;IACrD,OAAO,KAAK,MAAM,GAAG;GACvB,QAAQ;IACN,OAAO;GACT;EACF,CAAC,CACH,EAAA,CACsB,MAAM,UAAU,UAAU,IAAI;EACpD,IAAI,OACF,OAAO;EAET,MAAM,IAAI,MAAM,+BAA+B,QAAQ;CACzD;AACF"}
|
package/dist/capture.d.mts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { DEFAULT_VIEWPORTS, StoryEntry, StoryParameters, StorySourceAdapter, Viewport, isDisabledStory, isFlakyStory } from "./capture/adapter.mjs";
|
|
4
|
-
import {
|
|
3
|
+
import { DEFAULT_VIEWPORTS, StoryEntry, StoryParameters, StorySourceAdapter, StoryViewportConfig, StoryViewportDefinition, Viewport, isDisabledStory, isFlakyStory } from "./capture/adapter.mjs";
|
|
4
|
+
import { PollableCaptureQueue, PollableJob } from "./adapter/capture-queue.mjs";
|
|
5
5
|
import { CaptureContext, persistCapture } from "./capture/pipeline.mjs";
|
|
6
|
+
import { CaptureAttemptRef, CaptureJobInput, CaptureJobOptions, executeCaptureJob } from "./capture/orchestrator.mjs";
|
|
7
|
+
import { REDIFFABLE_BUILD_STATUSES, RediffDeps, RediffResult, rediffBuild } from "./capture/rediff.mjs";
|
|
8
|
+
import { CaptureDispatchJob, DispatchDeps, createDispatchJob } from "./capture/dispatch.mjs";
|
|
9
|
+
import { INTERRUPTED_ERROR, RecoveryDeps, RecoveryResult, recoverStuckCaptures } from "./capture/recovery.mjs";
|
|
6
10
|
import { InMemoryCaptureQueue, InMemoryCaptureQueueOptions } from "./capture/queue.mjs";
|
|
7
|
-
import { StorybookAdapter } from "./capture/storybook.mjs";
|
|
8
|
-
|
|
11
|
+
import { STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, mergeParameters, resolveStoryViewports } from "./capture/storybook.mjs";
|
|
12
|
+
import { extractStorybookToScratch, persistStorybookStatics } from "./capture/statics.mjs";
|
|
13
|
+
import { BoundingBox, SIZING_DEFAULTS, ScreenshotPlan, SizingOptions, getScreenshotPlan, resolveViewports } from "./capture/sizing.mjs";
|
|
14
|
+
export { type BoundingBox, type CaptureAttemptRef, type CaptureContext, type CaptureDispatchJob, type CaptureJobInput, type CaptureJobOptions, DEFAULT_VIEWPORTS, type DispatchDeps, INTERRUPTED_ERROR, InMemoryCaptureQueue, type InMemoryCaptureQueueOptions, type PollableCaptureQueue, type PollableJob, REDIFFABLE_BUILD_STATUSES, type RecoveryDeps, type RecoveryResult, type RediffDeps, type RediffResult, SIZING_DEFAULTS, STORYBOOK_BUILTIN_VIEWPORTS, type ScreenshotPlan, type SizingOptions, type StoryEntry, type StoryParameters, type StorySourceAdapter, type StoryViewportConfig, type StoryViewportDefinition, StorybookAdapter, type Viewport, createDispatchJob, executeCaptureJob, extractStorybookToScratch, getScreenshotPlan, isDisabledStory, isFlakyStory, mergeParameters, persistCapture, persistStorybookStatics, recoverStuckCaptures, rediffBuild, resolveViewports as resolveCaptureViewports, resolveStoryViewports };
|
package/dist/capture.mjs
CHANGED
|
@@ -2,8 +2,13 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { DEFAULT_VIEWPORTS, isDisabledStory, isFlakyStory } from "./capture/adapter.mjs";
|
|
5
|
+
import { STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, mergeParameters, resolveStoryViewports } from "./capture/storybook.mjs";
|
|
6
|
+
import { SIZING_DEFAULTS, getScreenshotPlan, resolveViewports } from "./capture/sizing.mjs";
|
|
5
7
|
import { persistCapture } from "./capture/pipeline.mjs";
|
|
6
|
-
import {
|
|
8
|
+
import { extractStorybookToScratch, persistStorybookStatics } from "./capture/statics.mjs";
|
|
7
9
|
import { executeCaptureJob } from "./capture/orchestrator.mjs";
|
|
10
|
+
import { REDIFFABLE_BUILD_STATUSES, rediffBuild } from "./capture/rediff.mjs";
|
|
11
|
+
import { INTERRUPTED_ERROR, recoverStuckCaptures } from "./capture/recovery.mjs";
|
|
8
12
|
import { InMemoryCaptureQueue } from "./capture/queue.mjs";
|
|
9
|
-
|
|
13
|
+
import { createDispatchJob } from "./capture/dispatch.mjs";
|
|
14
|
+
export { DEFAULT_VIEWPORTS, INTERRUPTED_ERROR, InMemoryCaptureQueue, REDIFFABLE_BUILD_STATUSES, SIZING_DEFAULTS, STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, createDispatchJob, executeCaptureJob, extractStorybookToScratch, getScreenshotPlan, isDisabledStory, isFlakyStory, mergeParameters, persistCapture, persistStorybookStatics, recoverStuckCaptures, rediffBuild, resolveViewports as resolveCaptureViewports, resolveStoryViewports };
|
package/dist/config.d.mts
CHANGED
|
@@ -1,41 +1,83 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { CaptureQueue } from "./adapter/capture-queue.mjs";
|
|
4
3
|
import { CaptureRunner } from "./adapter/capture-runner.mjs";
|
|
5
4
|
import { DatabaseAdapter } from "./adapter/database.mjs";
|
|
5
|
+
import { EmailSender } from "./adapter/email-sender.mjs";
|
|
6
6
|
import { GitHostProvider } from "./adapter/git-host.mjs";
|
|
7
|
+
import { NotifierProvider } from "./adapters/notifier/provider.mjs";
|
|
7
8
|
import { StorageAdapter } from "./adapter/storage.mjs";
|
|
9
|
+
import { Auth } from "./auth.mjs";
|
|
8
10
|
import { AdapterCategory } from "./adapter/metadata.mjs";
|
|
9
|
-
import {
|
|
11
|
+
import { CaptureQueue } from "./adapter/capture-queue.mjs";
|
|
10
12
|
import { z } from "zod";
|
|
11
13
|
import { Logger } from "pino";
|
|
12
14
|
//#region src/config.d.ts
|
|
13
15
|
/** Brand color theme for the server-rendered UI. */
|
|
14
16
|
interface BrandTheme {
|
|
15
17
|
accent: string;
|
|
18
|
+
accentContrast?: string;
|
|
19
|
+
ring?: string;
|
|
16
20
|
surface: {
|
|
17
21
|
base: string;
|
|
18
22
|
card: string;
|
|
23
|
+
muted?: string;
|
|
24
|
+
subtle?: string;
|
|
19
25
|
};
|
|
20
26
|
text: {
|
|
21
27
|
primary: string;
|
|
22
28
|
secondary: string;
|
|
29
|
+
muted?: string;
|
|
23
30
|
};
|
|
24
31
|
border: string;
|
|
32
|
+
borderSubtle?: string;
|
|
25
33
|
status: {
|
|
26
34
|
approved: string;
|
|
27
35
|
new: string;
|
|
28
36
|
rejected: string;
|
|
29
37
|
};
|
|
38
|
+
sidebarBg?: string;
|
|
39
|
+
topbarBg?: string;
|
|
40
|
+
radius?: string;
|
|
41
|
+
radiusSm?: string;
|
|
42
|
+
shadow?: string;
|
|
43
|
+
}
|
|
44
|
+
/** Text overrides for the auth (login) UI. */
|
|
45
|
+
interface AuthUiConfig {
|
|
46
|
+
/** Page title, default "Sign in". */
|
|
47
|
+
title?: string;
|
|
48
|
+
/** Optional subtitle under the title. */
|
|
49
|
+
subtitle?: string;
|
|
50
|
+
/** Password field label, default "Password". */
|
|
51
|
+
passwordLabel?: string;
|
|
52
|
+
/** Password field placeholder. */
|
|
53
|
+
passwordPlaceholder?: string;
|
|
54
|
+
/** Submit button label, default "Sign in". */
|
|
55
|
+
submitLabel?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Template for SSO buttons, default "Sign in with {label}".
|
|
58
|
+
* Must contain "{label}" which is replaced with the provider label.
|
|
59
|
+
*/
|
|
60
|
+
ssoLabelTemplate?: string;
|
|
61
|
+
/** Help text shown under the form. */
|
|
62
|
+
helpText?: string;
|
|
63
|
+
/** Footer text shown at the bottom of the card. */
|
|
64
|
+
footerText?: string;
|
|
30
65
|
}
|
|
31
66
|
/** Branding overrides for the server-rendered UI. */
|
|
32
67
|
interface UIConfig {
|
|
33
68
|
name?: string;
|
|
34
69
|
logo?: string;
|
|
70
|
+
/**
|
|
71
|
+
* @deprecated Ignored. The favicon is the product's own mark, served by the
|
|
72
|
+
* app itself; set `logo` to rebrand the sidebar instead.
|
|
73
|
+
*/
|
|
35
74
|
favicon?: string;
|
|
36
75
|
lightTheme?: BrandTheme;
|
|
37
76
|
darkTheme?: BrandTheme;
|
|
77
|
+
auth?: AuthUiConfig;
|
|
38
78
|
}
|
|
79
|
+
/** Default cap for a single Storybook zip upload (1 GiB). */
|
|
80
|
+
declare const DEFAULT_MAX_UPLOAD_BYTES: number;
|
|
39
81
|
/** A viewport in which stories are captured. */
|
|
40
82
|
interface ShelfViewport {
|
|
41
83
|
name: string;
|
|
@@ -50,14 +92,54 @@ interface AdapterSnapshot {
|
|
|
50
92
|
kind: string;
|
|
51
93
|
category: AdapterCategory;
|
|
52
94
|
}
|
|
95
|
+
/** Site-wide notification defaults (brand + sender identity for admin alerts). */
|
|
96
|
+
interface NotificationsConfig {
|
|
97
|
+
fromEmail?: string;
|
|
98
|
+
fromName?: string;
|
|
99
|
+
footerText?: string;
|
|
100
|
+
slackUsername?: string;
|
|
101
|
+
}
|
|
53
102
|
/** Shelf-level configuration (validated by {@link shelfConfigSchema}). */
|
|
54
103
|
interface ShelfConfig {
|
|
55
104
|
secret?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The secret `secret` replaced. Used only to decrypt stored credentials
|
|
107
|
+
* (webhook, git-token, and notification secrets) written before a rotation;
|
|
108
|
+
* new writes always use `secret`. Remove once credentials are re-encrypted.
|
|
109
|
+
*/
|
|
110
|
+
previousSecret?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Re-encrypt credentials still under `previousSecret` at boot. Default false:
|
|
113
|
+
* site admins can run it from the System page instead. No effect without
|
|
114
|
+
* `previousSecret`.
|
|
115
|
+
*/
|
|
116
|
+
migrateCredentialsOnBoot?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Bootstrap site-admin bearer token (`STORYSHELF_ADMIN_TOKEN`/`ADMIN_TOKEN`).
|
|
119
|
+
* Grants site-admin API access when no admin user exists yet; never
|
|
120
|
+
* mint sessions from it. Distinct from `secret` (session signing).
|
|
121
|
+
*/
|
|
122
|
+
adminToken?: string;
|
|
56
123
|
publishedBaseDomain?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Public base URL of this deployment (e.g. `https://shelf.example.com`).
|
|
126
|
+
* Used as the issuer in the `/.well-known/openid-configuration` relying-party
|
|
127
|
+
* helper document; falls back to the request origin when unset.
|
|
128
|
+
*/
|
|
129
|
+
publicBaseUrl?: string;
|
|
57
130
|
captureConcurrency?: number;
|
|
58
131
|
scratchDir?: string;
|
|
59
132
|
purgeTtlDays?: number;
|
|
133
|
+
/** Branch baseline TTL, days; null disables branch GC (default 30). */
|
|
134
|
+
branchTtlDays?: number | null;
|
|
135
|
+
/** Branch GC interval, ms; daily sweep via interval clock (default 86_400_000). */
|
|
136
|
+
branchGcIntervalMs?: number;
|
|
60
137
|
maxUploadBytes?: number;
|
|
138
|
+
/**
|
|
139
|
+
* Emit `Server-Timing` response headers (total + db/storage roll-ups).
|
|
140
|
+
* Opt-in, off by default — some deployments prefer no timing headers.
|
|
141
|
+
*/
|
|
142
|
+
serverTiming?: boolean;
|
|
61
143
|
/**
|
|
62
144
|
* Max zip size (bytes) eligible for inline statics extraction at upload.
|
|
63
145
|
* Unset (or 0) disables inline extraction — statics land via capture.
|
|
@@ -65,19 +147,54 @@ interface ShelfConfig {
|
|
|
65
147
|
maxInlineUnzipSize?: number;
|
|
66
148
|
viewports?: ShelfViewport[];
|
|
67
149
|
adapters?: Record<string, AdapterSnapshot>;
|
|
150
|
+
notifications?: NotificationsConfig;
|
|
68
151
|
}
|
|
152
|
+
/** Zod schema validating the shelf-level configuration. */
|
|
153
|
+
declare const shelfConfigSchema: z.ZodType<ShelfConfig>;
|
|
154
|
+
/** Zod schema validating the UI branding configuration. */
|
|
155
|
+
declare const uiConfigSchema: z.ZodType<UIConfig>;
|
|
156
|
+
/**
|
|
157
|
+
* Parse and validate a raw shelf-level configuration object.
|
|
158
|
+
*
|
|
159
|
+
* @param config - Unvalidated configuration record.
|
|
160
|
+
* @returns The validated shelf configuration.
|
|
161
|
+
*/
|
|
162
|
+
declare function validateConfig(config: Record<string, unknown>): ShelfConfig;
|
|
163
|
+
/**
|
|
164
|
+
* Parse and validate a raw UI branding configuration object.
|
|
165
|
+
*
|
|
166
|
+
* @param config - Unvalidated UI configuration record.
|
|
167
|
+
* @returns The validated UI configuration.
|
|
168
|
+
*/
|
|
169
|
+
declare function validateUiConfig(config: Record<string, unknown>): UIConfig;
|
|
69
170
|
/** Adapter and configuration options for creating the shelf router. */
|
|
70
171
|
interface ShelfOptions {
|
|
71
172
|
database: DatabaseAdapter;
|
|
72
173
|
storage: StorageAdapter;
|
|
73
174
|
captureRunner?: CaptureRunner;
|
|
74
175
|
captureQueue?: CaptureQueue;
|
|
75
|
-
auth?:
|
|
176
|
+
auth?: Auth;
|
|
76
177
|
gitHosts?: GitHostProvider[];
|
|
178
|
+
notifiers?: NotifierProvider[];
|
|
179
|
+
emailSender?: EmailSender;
|
|
77
180
|
logger?: Logger;
|
|
78
181
|
ui?: UIConfig;
|
|
79
182
|
config?: ShelfConfig;
|
|
183
|
+
/**
|
|
184
|
+
* Externally-managed observability SDK handle (e.g. from
|
|
185
|
+
* `initObservabilityFromEnv`). Structural — core never imports the
|
|
186
|
+
* observability package. Flushed on `app.lifecycle.teardown()`.
|
|
187
|
+
*/
|
|
188
|
+
observability?: ObservabilityHandle;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Shutdown hook for an externally-managed observability SDK.
|
|
192
|
+
* Structural so core stays dependency-free.
|
|
193
|
+
*/
|
|
194
|
+
interface ObservabilityHandle {
|
|
195
|
+
/** Flush exporters and release SDK resources. Must be idempotent. */
|
|
196
|
+
shutdown(): Promise<void>;
|
|
80
197
|
}
|
|
81
198
|
//#endregion
|
|
82
|
-
export { AdapterSnapshot, BrandTheme, ShelfConfig, ShelfOptions, ShelfViewport, UIConfig };
|
|
199
|
+
export { AdapterSnapshot, AuthUiConfig, BrandTheme, DEFAULT_MAX_UPLOAD_BYTES, NotificationsConfig, ObservabilityHandle, ShelfConfig, ShelfOptions, ShelfViewport, UIConfig, shelfConfigSchema, uiConfigSchema, validateConfig, validateUiConfig };
|
|
83
200
|
//# sourceMappingURL=config.d.mts.map
|
package/dist/config.mjs
CHANGED
|
@@ -12,20 +12,31 @@ const viewportSchema = z.object({
|
|
|
12
12
|
});
|
|
13
13
|
const brandThemeSchema = z.object({
|
|
14
14
|
accent: z.string(),
|
|
15
|
+
accentContrast: z.string().optional(),
|
|
16
|
+
ring: z.string().optional(),
|
|
15
17
|
surface: z.object({
|
|
16
18
|
base: z.string(),
|
|
17
|
-
card: z.string()
|
|
19
|
+
card: z.string(),
|
|
20
|
+
muted: z.string().optional(),
|
|
21
|
+
subtle: z.string().optional()
|
|
18
22
|
}),
|
|
19
23
|
text: z.object({
|
|
20
24
|
primary: z.string(),
|
|
21
|
-
secondary: z.string()
|
|
25
|
+
secondary: z.string(),
|
|
26
|
+
muted: z.string().optional()
|
|
22
27
|
}),
|
|
23
28
|
border: z.string(),
|
|
29
|
+
borderSubtle: z.string().optional(),
|
|
24
30
|
status: z.object({
|
|
25
31
|
approved: z.string(),
|
|
26
32
|
new: z.string(),
|
|
27
33
|
rejected: z.string()
|
|
28
|
-
})
|
|
34
|
+
}),
|
|
35
|
+
sidebarBg: z.string().optional(),
|
|
36
|
+
topbarBg: z.string().optional(),
|
|
37
|
+
radius: z.string().optional(),
|
|
38
|
+
radiusSm: z.string().optional(),
|
|
39
|
+
shadow: z.string().optional()
|
|
29
40
|
});
|
|
30
41
|
const adapterSnapshotSchema = z.object({
|
|
31
42
|
name: z.string(),
|
|
@@ -35,31 +46,67 @@ const adapterSnapshotSchema = z.object({
|
|
|
35
46
|
category: z.enum([
|
|
36
47
|
"database",
|
|
37
48
|
"storage",
|
|
38
|
-
"auth",
|
|
39
49
|
"capture-runner",
|
|
40
50
|
"capture-queue",
|
|
41
|
-
"git-host"
|
|
51
|
+
"git-host",
|
|
52
|
+
"notifier"
|
|
42
53
|
])
|
|
43
54
|
});
|
|
55
|
+
const authUiConfigSchema = z.object({
|
|
56
|
+
title: z.string().min(1).optional(),
|
|
57
|
+
subtitle: z.string().optional(),
|
|
58
|
+
passwordLabel: z.string().min(1).optional(),
|
|
59
|
+
passwordPlaceholder: z.string().optional(),
|
|
60
|
+
submitLabel: z.string().min(1).optional(),
|
|
61
|
+
ssoLabelTemplate: z.string().min(1).optional(),
|
|
62
|
+
helpText: z.string().optional(),
|
|
63
|
+
footerText: z.string().optional()
|
|
64
|
+
});
|
|
65
|
+
const notificationsConfigSchema = z.object({
|
|
66
|
+
fromEmail: z.string().min(1).optional(),
|
|
67
|
+
fromName: z.string().min(1).optional(),
|
|
68
|
+
footerText: z.string().min(1).optional(),
|
|
69
|
+
slackUsername: z.string().min(1).optional()
|
|
70
|
+
});
|
|
44
71
|
/** Zod schema validating the shelf-level configuration. */
|
|
45
72
|
const shelfConfigSchema = z.object({
|
|
46
73
|
secret: z.string().min(1).optional(),
|
|
74
|
+
previousSecret: z.string().min(1).optional(),
|
|
75
|
+
migrateCredentialsOnBoot: z.boolean().optional(),
|
|
76
|
+
adminToken: z.string().min(1).optional(),
|
|
47
77
|
publishedBaseDomain: z.string().optional(),
|
|
78
|
+
publicBaseUrl: z.string().url().optional(),
|
|
48
79
|
captureConcurrency: z.number().int().positive().optional(),
|
|
49
80
|
scratchDir: z.string().optional(),
|
|
50
81
|
purgeTtlDays: z.number().int().positive().optional(),
|
|
82
|
+
branchTtlDays: z.number().int().positive().nullable().optional(),
|
|
83
|
+
branchGcIntervalMs: z.number().int().positive().optional(),
|
|
51
84
|
maxUploadBytes: z.number().int().positive().optional(),
|
|
85
|
+
serverTiming: z.boolean().optional(),
|
|
52
86
|
maxInlineUnzipSize: z.number().int().positive().optional(),
|
|
53
87
|
viewports: z.array(viewportSchema).min(1, "at least one viewport required").optional(),
|
|
54
|
-
adapters: z.record(z.string(), adapterSnapshotSchema).optional()
|
|
55
|
-
|
|
88
|
+
adapters: z.record(z.string(), adapterSnapshotSchema).optional(),
|
|
89
|
+
notifications: notificationsConfigSchema.optional()
|
|
90
|
+
}).strict().superRefine((config, ctx) => {
|
|
91
|
+
if (config.previousSecret !== void 0 && config.secret === void 0) ctx.addIssue({
|
|
92
|
+
code: "custom",
|
|
93
|
+
path: ["previousSecret"],
|
|
94
|
+
message: "previousSecret requires secret"
|
|
95
|
+
});
|
|
96
|
+
if (config.previousSecret !== void 0 && config.previousSecret === config.secret) ctx.addIssue({
|
|
97
|
+
code: "custom",
|
|
98
|
+
path: ["previousSecret"],
|
|
99
|
+
message: "previousSecret must differ from secret"
|
|
100
|
+
});
|
|
101
|
+
});
|
|
56
102
|
/** Zod schema validating the UI branding configuration. */
|
|
57
103
|
const uiConfigSchema = z.object({
|
|
58
104
|
name: z.string().optional(),
|
|
59
105
|
logo: z.string().url().optional(),
|
|
60
106
|
favicon: z.string().url().optional(),
|
|
61
107
|
lightTheme: brandThemeSchema.optional(),
|
|
62
|
-
darkTheme: brandThemeSchema.optional()
|
|
108
|
+
darkTheme: brandThemeSchema.optional(),
|
|
109
|
+
auth: authUiConfigSchema.optional()
|
|
63
110
|
}).strict();
|
|
64
111
|
/**
|
|
65
112
|
* Parse and validate a raw shelf-level configuration object.
|
package/dist/config.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import type { Logger } from \"pino\";\nimport { z } from \"zod\";\nimport type { AuthAdapter } from \"./adapters/auth.ts\";\nimport type { CaptureQueue } from \"./adapters/capture-queue.ts\";\nimport type { CaptureRunner } from \"./adapters/capture-runner.ts\";\nimport type { DatabaseAdapter } from \"./adapters/database.ts\";\nimport type { GitHostProvider } from \"./adapters/git-host/index.ts\";\nimport type { AdapterCategory } from \"./adapters/metadata.ts\";\nimport type { StorageAdapter } from \"./adapters/storage.ts\";\n\n/** Brand color theme for the server-rendered UI. */\nexport interface BrandTheme {\n accent: string;\n surface: { base: string; card: string };\n text: { primary: string; secondary: string };\n border: string;\n status: { approved: string; new: string; rejected: string };\n}\n\n/** Branding overrides for the server-rendered UI. */\nexport interface UIConfig {\n name?: string;\n logo?: string;\n favicon?: string;\n lightTheme?: BrandTheme;\n darkTheme?: BrandTheme;\n}\n\n/** Default cap for a single Storybook zip upload (1 GiB). */\nexport const DEFAULT_MAX_UPLOAD_BYTES = 1024 * 1024 * 1024;\n\n/** A viewport in which stories are captured. */\nexport interface ShelfViewport {\n name: string;\n width: number;\n height: number;\n}\n\n/** Metadata snapshot of a configured adapter. */\nexport interface AdapterSnapshot {\n name: string;\n version: string;\n description?: string;\n kind: string;\n category: AdapterCategory;\n}\n\n/** Shelf-level configuration (validated by {@link shelfConfigSchema}). */\nexport interface ShelfConfig {\n secret?: string;\n publishedBaseDomain?: string;\n captureConcurrency?: number;\n scratchDir?: string;\n purgeTtlDays?: number;\n maxUploadBytes?: number;\n /**\n * Max zip size (bytes) eligible for inline statics extraction at upload.\n * Unset (or 0) disables inline extraction — statics land via capture.\n */\n maxInlineUnzipSize?: number;\n viewports?: ShelfViewport[];\n adapters?: Record<string, AdapterSnapshot>;\n}\n\nconst viewportSchema: z.ZodType<ShelfViewport> = z.object({\n name: z.string().min(1),\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n});\n\nconst brandThemeSchema = z.object({\n accent: z.string(),\n surface: z.object({ base: z.string(), card: z.string() }),\n text: z.object({ primary: z.string(), secondary: z.string() }),\n border: z.string(),\n status: z.object({ approved: z.string(), new: z.string(), rejected: z.string() }),\n});\n\nconst adapterSnapshotSchema: z.ZodType<AdapterSnapshot> = z.object({\n name: z.string(),\n version: z.string(),\n description: z.string().optional(),\n kind: z.string(),\n category: z.enum([\"database\", \"storage\", \"auth\", \"capture-runner\", \"capture-queue\", \"git-host\"]),\n});\n\n/** Zod schema validating the shelf-level configuration. */\nexport const shelfConfigSchema: z.ZodType<ShelfConfig> = z\n .object({\n secret: z.string().min(1).optional(),\n publishedBaseDomain: z.string().optional(),\n captureConcurrency: z.number().int().positive().optional(),\n scratchDir: z.string().optional(),\n purgeTtlDays: z.number().int().positive().optional(),\n maxUploadBytes: z.number().int().positive().optional(),\n maxInlineUnzipSize: z.number().int().positive().optional(),\n viewports: z.array(viewportSchema).min(1, \"at least one viewport required\").optional(),\n adapters: z.record(z.string(), adapterSnapshotSchema).optional(),\n })\n .strict();\n\n/** Zod schema validating the UI branding configuration. */\nexport const uiConfigSchema = z\n .object({\n name: z.string().optional(),\n // oxlint-disable-next-line typescript/no-deprecated -- z.string().url() kept for zod v3 API compat\n logo: z.string().url().optional(),\n // oxlint-disable-next-line typescript/no-deprecated -- z.string().url() kept for zod v3 API compat\n favicon: z.string().url().optional(),\n lightTheme: brandThemeSchema.optional(),\n darkTheme: brandThemeSchema.optional(),\n })\n .strict();\n\n/**\n * Parse and validate a raw shelf-level configuration object.\n *\n * @param config - Unvalidated configuration record.\n * @returns The validated shelf configuration.\n */\nexport function validateConfig(config: Record<string, unknown>): ShelfConfig {\n const result = shelfConfigSchema.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 ShelfConfig: ${issues}`);\n }\n return result.data;\n}\n\n/**\n * Parse and validate a raw UI branding configuration object.\n *\n * @param config - Unvalidated UI configuration record.\n * @returns The validated UI configuration.\n */\nexport function validateUiConfig(config: Record<string, unknown>): UIConfig {\n const result = uiConfigSchema.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 UIConfig: ${issues}`);\n }\n return result.data;\n}\n\n/** Adapter and configuration options for creating the shelf router. */\nexport interface ShelfOptions {\n database: DatabaseAdapter;\n storage: StorageAdapter;\n captureRunner?: CaptureRunner;\n captureQueue?: CaptureQueue;\n auth?: AuthAdapter;\n gitHosts?: GitHostProvider[];\n logger?: Logger;\n ui?: UIConfig;\n config?: ShelfConfig;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import type { Logger } from \"pino\";\nimport { z } from \"zod\";\nimport type { CaptureQueue } from \"./adapters/capture-queue.ts\";\nimport type { CaptureRunner } from \"./adapters/capture-runner.ts\";\nimport type { DatabaseAdapter } from \"./adapters/database.ts\";\nimport type { EmailSender } from \"./adapters/email-sender.ts\";\nimport type { GitHostProvider } from \"./adapters/git-host/index.ts\";\nimport type { AdapterCategory } from \"./adapters/metadata.ts\";\nimport type { NotifierProvider } from \"./adapters/notifier/provider.ts\";\nimport type { StorageAdapter } from \"./adapters/storage.ts\";\nimport type { Auth } from \"./auth.ts\";\n\n/** Brand color theme for the server-rendered UI. */\nexport interface BrandTheme {\n accent: string;\n accentContrast?: string;\n ring?: string;\n surface: { base: string; card: string; muted?: string; subtle?: string };\n text: { primary: string; secondary: string; muted?: string };\n border: string;\n borderSubtle?: string;\n status: { approved: string; new: string; rejected: string };\n sidebarBg?: string;\n topbarBg?: string;\n radius?: string;\n radiusSm?: string;\n shadow?: string;\n}\n\n/** Text overrides for the auth (login) UI. */\nexport interface AuthUiConfig {\n /** Page title, default \"Sign in\". */\n title?: string;\n /** Optional subtitle under the title. */\n subtitle?: string;\n /** Password field label, default \"Password\". */\n passwordLabel?: string;\n /** Password field placeholder. */\n passwordPlaceholder?: string;\n /** Submit button label, default \"Sign in\". */\n submitLabel?: string;\n /**\n * Template for SSO buttons, default \"Sign in with {label}\".\n * Must contain \"{label}\" which is replaced with the provider label.\n */\n ssoLabelTemplate?: string;\n /** Help text shown under the form. */\n helpText?: string;\n /** Footer text shown at the bottom of the card. */\n footerText?: string;\n}\n\n/** Branding overrides for the server-rendered UI. */\nexport interface UIConfig {\n name?: string;\n logo?: string;\n /**\n * @deprecated Ignored. The favicon is the product's own mark, served by the\n * app itself; set `logo` to rebrand the sidebar instead.\n */\n favicon?: string;\n lightTheme?: BrandTheme;\n darkTheme?: BrandTheme;\n auth?: AuthUiConfig;\n}\n\n/** Default cap for a single Storybook zip upload (1 GiB). */\nexport const DEFAULT_MAX_UPLOAD_BYTES = 1024 * 1024 * 1024;\n\n/** A viewport in which stories are captured. */\nexport interface ShelfViewport {\n name: string;\n width: number;\n height: number;\n}\n\n/** Metadata snapshot of a configured adapter. */\nexport interface AdapterSnapshot {\n name: string;\n version: string;\n description?: string;\n kind: string;\n category: AdapterCategory;\n}\n\n/** Site-wide notification defaults (brand + sender identity for admin alerts). */\nexport interface NotificationsConfig {\n fromEmail?: string;\n fromName?: string;\n footerText?: string;\n slackUsername?: string;\n}\n/** Shelf-level configuration (validated by {@link shelfConfigSchema}). */\nexport interface ShelfConfig {\n secret?: string;\n /**\n * The secret `secret` replaced. Used only to decrypt stored credentials\n * (webhook, git-token, and notification secrets) written before a rotation;\n * new writes always use `secret`. Remove once credentials are re-encrypted.\n */\n previousSecret?: string;\n /**\n * Re-encrypt credentials still under `previousSecret` at boot. Default false:\n * site admins can run it from the System page instead. No effect without\n * `previousSecret`.\n */\n migrateCredentialsOnBoot?: boolean;\n /**\n * Bootstrap site-admin bearer token (`STORYSHELF_ADMIN_TOKEN`/`ADMIN_TOKEN`).\n * Grants site-admin API access when no admin user exists yet; never\n * mint sessions from it. Distinct from `secret` (session signing).\n */\n adminToken?: string;\n publishedBaseDomain?: string;\n /**\n * Public base URL of this deployment (e.g. `https://shelf.example.com`).\n * Used as the issuer in the `/.well-known/openid-configuration` relying-party\n * helper document; falls back to the request origin when unset.\n */\n publicBaseUrl?: string;\n captureConcurrency?: number;\n scratchDir?: string;\n purgeTtlDays?: number;\n /** Branch baseline TTL, days; null disables branch GC (default 30). */\n branchTtlDays?: number | null;\n /** Branch GC interval, ms; daily sweep via interval clock (default 86_400_000). */\n branchGcIntervalMs?: number;\n maxUploadBytes?: number;\n /**\n * Emit `Server-Timing` response headers (total + db/storage roll-ups).\n * Opt-in, off by default — some deployments prefer no timing headers.\n */\n serverTiming?: boolean;\n /**\n * Max zip size (bytes) eligible for inline statics extraction at upload.\n * Unset (or 0) disables inline extraction — statics land via capture.\n */\n maxInlineUnzipSize?: number;\n viewports?: ShelfViewport[];\n adapters?: Record<string, AdapterSnapshot>;\n notifications?: NotificationsConfig;\n}\n\nconst viewportSchema: z.ZodType<ShelfViewport> = z.object({\n name: z.string().min(1),\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n});\n\nconst brandThemeSchema: z.ZodType<BrandTheme> = z.object({\n accent: z.string(),\n accentContrast: z.string().optional(),\n ring: z.string().optional(),\n surface: z.object({\n base: z.string(),\n card: z.string(),\n muted: z.string().optional(),\n subtle: z.string().optional(),\n }),\n text: z.object({ primary: z.string(), secondary: z.string(), muted: z.string().optional() }),\n border: z.string(),\n borderSubtle: z.string().optional(),\n status: z.object({ approved: z.string(), new: z.string(), rejected: z.string() }),\n sidebarBg: z.string().optional(),\n topbarBg: z.string().optional(),\n radius: z.string().optional(),\n radiusSm: z.string().optional(),\n shadow: z.string().optional(),\n});\n\nconst adapterSnapshotSchema: z.ZodType<AdapterSnapshot> = z.object({\n name: z.string(),\n version: z.string(),\n description: z.string().optional(),\n kind: z.string(),\n category: z.enum([\n \"database\",\n \"storage\",\n \"capture-runner\",\n \"capture-queue\",\n \"git-host\",\n \"notifier\",\n ]),\n});\n\nconst authUiConfigSchema: z.ZodType<AuthUiConfig> = z.object({\n title: z.string().min(1).optional(),\n subtitle: z.string().optional(),\n passwordLabel: z.string().min(1).optional(),\n passwordPlaceholder: z.string().optional(),\n submitLabel: z.string().min(1).optional(),\n ssoLabelTemplate: z.string().min(1).optional(),\n helpText: z.string().optional(),\n footerText: z.string().optional(),\n});\n\nconst notificationsConfigSchema: z.ZodType<NotificationsConfig> = z.object({\n fromEmail: z.string().min(1).optional(),\n fromName: z.string().min(1).optional(),\n footerText: z.string().min(1).optional(),\n slackUsername: z.string().min(1).optional(),\n});\n\n/** Zod schema validating the shelf-level configuration. */\nexport const shelfConfigSchema: z.ZodType<ShelfConfig> = z\n .object({\n secret: z.string().min(1).optional(),\n previousSecret: z.string().min(1).optional(),\n migrateCredentialsOnBoot: z.boolean().optional(),\n adminToken: z.string().min(1).optional(),\n publishedBaseDomain: z.string().optional(),\n // oxlint-disable-next-line typescript/no-deprecated -- z.string().url() kept for zod v3 API compat\n publicBaseUrl: z.string().url().optional(),\n captureConcurrency: z.number().int().positive().optional(),\n scratchDir: z.string().optional(),\n purgeTtlDays: z.number().int().positive().optional(),\n branchTtlDays: z.number().int().positive().nullable().optional(),\n branchGcIntervalMs: z.number().int().positive().optional(),\n maxUploadBytes: z.number().int().positive().optional(),\n serverTiming: z.boolean().optional(),\n maxInlineUnzipSize: z.number().int().positive().optional(),\n viewports: z.array(viewportSchema).min(1, \"at least one viewport required\").optional(),\n adapters: z.record(z.string(), adapterSnapshotSchema).optional(),\n notifications: notificationsConfigSchema.optional(),\n })\n .strict()\n .superRefine((config, ctx) => {\n if (config.previousSecret !== undefined && config.secret === undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"previousSecret\"],\n message: \"previousSecret requires secret\",\n });\n }\n if (config.previousSecret !== undefined && config.previousSecret === config.secret) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"previousSecret\"],\n message: \"previousSecret must differ from secret\",\n });\n }\n });\n\n/** Zod schema validating the UI branding configuration. */\nexport const uiConfigSchema: z.ZodType<UIConfig> = z\n .object({\n name: z.string().optional(),\n // oxlint-disable-next-line typescript/no-deprecated -- z.string().url() kept for zod v3 API compat\n logo: z.string().url().optional(),\n // Accepted but ignored (see UIConfig.favicon) so existing configs keep\n // validating under .strict().\n // oxlint-disable-next-line typescript/no-deprecated -- z.string().url() kept for zod v3 API compat\n favicon: z.string().url().optional(),\n lightTheme: brandThemeSchema.optional(),\n darkTheme: brandThemeSchema.optional(),\n auth: authUiConfigSchema.optional(),\n })\n .strict();\n\n/**\n * Parse and validate a raw shelf-level configuration object.\n *\n * @param config - Unvalidated configuration record.\n * @returns The validated shelf configuration.\n */\nexport function validateConfig(config: Record<string, unknown>): ShelfConfig {\n const result = shelfConfigSchema.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 ShelfConfig: ${issues}`);\n }\n return result.data;\n}\n\n/**\n * Parse and validate a raw UI branding configuration object.\n *\n * @param config - Unvalidated UI configuration record.\n * @returns The validated UI configuration.\n */\nexport function validateUiConfig(config: Record<string, unknown>): UIConfig {\n const result = uiConfigSchema.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 UIConfig: ${issues}`);\n }\n return result.data;\n}\n\n/** Adapter and configuration options for creating the shelf router. */\nexport interface ShelfOptions {\n database: DatabaseAdapter;\n storage: StorageAdapter;\n captureRunner?: CaptureRunner;\n captureQueue?: CaptureQueue;\n auth?: Auth;\n gitHosts?: GitHostProvider[];\n notifiers?: NotifierProvider[];\n emailSender?: EmailSender;\n logger?: Logger;\n ui?: UIConfig;\n config?: ShelfConfig;\n /**\n * Externally-managed observability SDK handle (e.g. from\n * `initObservabilityFromEnv`). Structural — core never imports the\n * observability package. Flushed on `app.lifecycle.teardown()`.\n */\n observability?: ObservabilityHandle;\n}\n\n/**\n * Shutdown hook for an externally-managed observability SDK.\n * Structural so core stays dependency-free.\n */\nexport interface ObservabilityHandle {\n /** Flush exporters and release SDK resources. Must be idempotent. */\n shutdown(): Promise<void>;\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,58 +1,7 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
import { createShelfLogger } from "./logger.mjs";
|
|
9
|
-
import { AuthUser } from "./adapter/auth.mjs";
|
|
10
|
-
import { AdapterInitResult } from "./adapter/init.mjs";
|
|
11
|
-
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
12
|
-
//#region src/index.d.ts
|
|
13
|
-
/** Per-request shelf context (adapters, config, user, capture queue). */
|
|
14
|
-
interface ShelfContext {
|
|
15
|
-
requestId?: string;
|
|
16
|
-
db: DatabaseAdapter;
|
|
17
|
-
storage: StorageAdapter;
|
|
18
|
-
config: ShelfConfig;
|
|
19
|
-
ui: UIConfig;
|
|
20
|
-
logger: ReturnType<typeof createShelfLogger>;
|
|
21
|
-
user: AuthUser | null;
|
|
22
|
-
authEnabled: boolean;
|
|
23
|
-
enqueueCapture?: (buildId: string, reqId?: string) => Promise<void>;
|
|
24
|
-
captureQueue: CaptureQueue | null;
|
|
25
|
-
gitHosts: GitHostProvider[];
|
|
26
|
-
}
|
|
27
|
-
/** Hono application type carrying the shelf context variables. */
|
|
28
|
-
type ShelfApp = OpenAPIHono<{
|
|
29
|
-
Variables: ShelfContext;
|
|
30
|
-
}>;
|
|
31
|
-
/** App-scoped adapter lifecycle namespace (single `lifecycle` prop avoids Hono collisions). */
|
|
32
|
-
interface ShelfLifecycle {
|
|
33
|
-
/** Settled summary of the eager background init run; never rejects. */
|
|
34
|
-
readonly ready: Promise<AdapterInitResult>;
|
|
35
|
-
/**
|
|
36
|
-
* Fail-fast await for server startup (`await app.lifecycle.init()`).
|
|
37
|
-
* Re-runs init so transient failures are retryable; throws AdapterLifecycleError.
|
|
38
|
-
* Optional — when skipped, the first request gates on `ready` instead.
|
|
39
|
-
*/
|
|
40
|
-
init(): Promise<void>;
|
|
41
|
-
/** Graceful teardown for SIGTERM/SIGINT (`await app.lifecycle.close()`). Idempotent. */
|
|
42
|
-
close(): Promise<void>;
|
|
43
|
-
}
|
|
44
|
-
/** Hono app with the shelf lifecycle namespace attached. */
|
|
45
|
-
type ShelfRouter = ShelfApp & {
|
|
46
|
-
readonly lifecycle: ShelfLifecycle;
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* Create the StoryShelf Hono router with all API routes and HTML pages.
|
|
50
|
-
*
|
|
51
|
-
* Adapter `init` hooks kick off eagerly in the background (the constructor
|
|
52
|
-
* stays synchronous). Await `app.lifecycle.init()` before serving for
|
|
53
|
-
* fail-fast startup, or let the first request gate on settlement.
|
|
54
|
-
*/
|
|
55
|
-
declare function createShelfRouter(options: ShelfOptions): ShelfRouter;
|
|
56
|
-
//#endregion
|
|
57
|
-
export { type BrandTheme, ShelfApp, type ShelfConfig, ShelfContext, ShelfLifecycle, type ShelfOptions, ShelfRouter, type UIConfig, createShelfRouter };
|
|
58
|
-
//# sourceMappingURL=index.d.mts.map
|
|
3
|
+
import { BUILD_STATUSES, BuildStatus, ProjectRole, SNAPSHOT_STATUSES, SiteRole, SnapshotStatus, TERMINAL_BUILD_STATUSES } from "./types.mjs";
|
|
4
|
+
import { AdapterSnapshot, BrandTheme, DEFAULT_MAX_UPLOAD_BYTES, ShelfConfig, ShelfOptions, ShelfViewport, UIConfig, shelfConfigSchema, uiConfigSchema, validateConfig, validateUiConfig } from "./config.mjs";
|
|
5
|
+
import { Logger, LoggerOptions, PinoTransport, createShelfLogger } from "./logger.mjs";
|
|
6
|
+
import { BrandPack, brandPack, brandPacks } from "./brand-packs.mjs";
|
|
7
|
+
export { type AdapterSnapshot, BUILD_STATUSES, type BrandPack, type BrandTheme, type BuildStatus, DEFAULT_MAX_UPLOAD_BYTES, type Logger, type LoggerOptions, type PinoTransport, type ProjectRole, SNAPSHOT_STATUSES, type ShelfConfig, type ShelfOptions, type ShelfViewport, type SiteRole, type SnapshotStatus, TERMINAL_BUILD_STATUSES, type UIConfig, brandPack, brandPacks, createShelfLogger, shelfConfigSchema, uiConfigSchema, validateConfig, validateUiConfig };
|