@storyshelf/core 0.1.2 → 0.3.1
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 +50 -46
- package/dist/adapter/auth.d.mts +4 -4
- package/dist/adapter/auth.mjs.map +1 -1
- package/dist/{adapters → adapter}/capture-queue.d.mts +6 -4
- package/dist/adapter/capture-queue.mjs +4 -0
- package/dist/adapter/capture-runner.d.mts +7 -7
- package/dist/adapter/database.d.mts +20 -9
- package/dist/adapter/database.mjs +60 -1
- package/dist/adapter/database.mjs.map +1 -0
- package/dist/adapter/git-host/comments.d.mts +41 -0
- package/dist/adapter/git-host/comments.mjs +54 -0
- package/dist/adapter/git-host/comments.mjs.map +1 -0
- package/dist/adapter/git-host/helpers.d.mts +1 -0
- package/dist/adapter/git-host/helpers.mjs +1 -0
- package/dist/adapter/git-host/helpers.mjs.map +1 -1
- package/dist/adapter/git-host.d.mts +3 -7
- package/dist/adapter/init.d.mts +58 -0
- package/dist/adapter/init.mjs +93 -0
- package/dist/adapter/init.mjs.map +1 -0
- package/dist/adapter/metadata.d.mts +83 -0
- package/dist/adapter/metadata.mjs +4 -0
- package/dist/adapter/storage.d.mts +15 -4
- package/dist/adapters/webhook-events.mjs +20 -4
- package/dist/adapters/webhook-events.mjs.map +1 -1
- package/dist/capture/adapter.d.mts +7 -1
- package/dist/capture/adapter.mjs +3 -0
- package/dist/capture/adapter.mjs.map +1 -1
- package/dist/capture/dispatch.mjs +150 -0
- package/dist/capture/dispatch.mjs.map +1 -0
- package/dist/capture/orchestrator.d.mts +9 -0
- package/dist/capture/orchestrator.mjs +11 -44
- package/dist/capture/orchestrator.mjs.map +1 -1
- package/dist/capture/pipeline.d.mts +4 -1
- package/dist/capture/pipeline.mjs +6 -6
- package/dist/capture/pipeline.mjs.map +1 -1
- package/dist/capture/queue.d.mts +4 -1
- package/dist/capture/queue.mjs +3 -1
- package/dist/capture/queue.mjs.map +1 -1
- package/dist/capture/skip-checks.mjs +76 -0
- package/dist/capture/skip-checks.mjs.map +1 -0
- package/dist/capture/statics.mjs +124 -0
- package/dist/capture/statics.mjs.map +1 -0
- package/dist/capture/status-fanout.mjs +1 -0
- package/dist/capture/status-fanout.mjs.map +1 -1
- package/dist/capture/storybook.d.mts +1 -0
- package/dist/capture/storybook.mjs +1 -0
- package/dist/capture/storybook.mjs.map +1 -1
- package/dist/capture.d.mts +8 -0
- package/dist/capture.mjs +9 -0
- package/dist/config.d.mts +37 -22
- package/dist/config.mjs +28 -2
- package/dist/config.mjs.map +1 -1
- package/dist/ddl.d.mts +2 -1
- package/dist/ddl.mjs +2 -1
- package/dist/ddl.mjs.map +1 -1
- package/dist/diff/engine.d.mts +8 -0
- package/dist/diff/engine.mjs +8 -0
- package/dist/diff/engine.mjs.map +1 -1
- package/dist/diff/options.d.mts +3 -1
- package/dist/diff.d.mts +5 -0
- package/dist/diff.mjs +6 -0
- package/dist/index.d.mts +34 -24
- package/dist/index.mjs +211 -252
- package/dist/index.mjs.map +1 -1
- package/dist/logger.d.mts +3 -3
- package/dist/logger.mjs.map +1 -1
- package/dist/middleware/auth-gate.mjs +36 -0
- package/dist/middleware/auth-gate.mjs.map +1 -0
- package/dist/middleware/csrf.mjs +1 -0
- package/dist/middleware/csrf.mjs.map +1 -1
- package/dist/middleware/rate-limit.mjs +1 -0
- package/dist/middleware/rate-limit.mjs.map +1 -1
- package/dist/middleware/request-log.mjs +28 -0
- package/dist/middleware/request-log.mjs.map +1 -0
- package/dist/middleware/store-scope.mjs +29 -0
- package/dist/middleware/store-scope.mjs.map +1 -0
- package/dist/models/baseline.mjs +9 -5
- package/dist/models/baseline.mjs.map +1 -1
- package/dist/models/build.mjs +5 -1
- package/dist/models/build.mjs.map +1 -1
- package/dist/models/comment.mjs +4 -1
- package/dist/models/comment.mjs.map +1 -1
- package/dist/models/label.mjs +3 -1
- package/dist/models/label.mjs.map +1 -1
- package/dist/models/member.mjs +2 -1
- package/dist/models/member.mjs.map +1 -1
- package/dist/models/project.mjs +2 -1
- package/dist/models/project.mjs.map +1 -1
- package/dist/models/snapshot.mjs +2 -1
- package/dist/models/snapshot.mjs.map +1 -1
- package/dist/models/status-config.mjs +2 -1
- package/dist/models/status-config.mjs.map +1 -1
- package/dist/models/token.mjs +2 -1
- package/dist/models/token.mjs.map +1 -1
- package/dist/models/webhook.mjs +12 -3
- package/dist/models/webhook.mjs.map +1 -1
- package/dist/pages/build-detail.mjs +10 -4
- package/dist/pages/build-detail.mjs.map +1 -1
- package/dist/pages/build-diff-comments.mjs +113 -0
- package/dist/pages/build-diff-comments.mjs.map +1 -0
- package/dist/pages/build-diff-header.mjs +163 -0
- package/dist/pages/build-diff-header.mjs.map +1 -0
- package/dist/pages/build-diff-nav.mjs +66 -0
- package/dist/pages/build-diff-nav.mjs.map +1 -0
- package/dist/pages/build-diff-viewer.mjs +197 -0
- package/dist/pages/build-diff-viewer.mjs.map +1 -0
- package/dist/pages/build-diff.mjs +66 -413
- package/dist/pages/build-diff.mjs.map +1 -1
- package/dist/pages/compute-jobs.mjs +3 -1
- package/dist/pages/compute-jobs.mjs.map +1 -1
- package/dist/pages/label-detail.mjs +4 -3
- package/dist/pages/label-detail.mjs.map +1 -1
- package/dist/pages/login.mjs +1 -0
- package/dist/pages/login.mjs.map +1 -1
- package/dist/pages/project-builds.mjs +6 -3
- package/dist/pages/project-builds.mjs.map +1 -1
- package/dist/pages/project-create.mjs +1 -0
- package/dist/pages/project-create.mjs.map +1 -1
- package/dist/pages/project-settings.mjs +1 -0
- package/dist/pages/project-settings.mjs.map +1 -1
- package/dist/pages/projects.mjs +12 -6
- package/dist/pages/projects.mjs.map +1 -1
- package/dist/pages/root.mjs +7 -3
- package/dist/pages/root.mjs.map +1 -1
- package/dist/pages/settings-general.mjs +1 -0
- package/dist/pages/settings-general.mjs.map +1 -1
- package/dist/pages/settings-labels.mjs +2 -1
- package/dist/pages/settings-labels.mjs.map +1 -1
- package/dist/pages/settings-members.mjs +2 -1
- package/dist/pages/settings-members.mjs.map +1 -1
- package/dist/pages/settings-status.mjs +3 -1
- package/dist/pages/settings-status.mjs.map +1 -1
- package/dist/pages/settings-tests.mjs +4 -3
- package/dist/pages/settings-tests.mjs.map +1 -1
- package/dist/pages/settings-tokens.mjs +1 -0
- package/dist/pages/settings-tokens.mjs.map +1 -1
- package/dist/pages/settings-webhooks.mjs +1 -0
- package/dist/pages/settings-webhooks.mjs.map +1 -1
- package/dist/pages/storybook.mjs +38 -1
- package/dist/pages/storybook.mjs.map +1 -1
- package/dist/{utils/paths.d.mts → paths.d.mts} +5 -0
- package/dist/{utils/paths.mjs → paths.mjs} +5 -0
- package/dist/paths.mjs.map +1 -0
- package/dist/retention/purge.mjs +2 -1
- package/dist/retention/purge.mjs.map +1 -1
- package/dist/routers/admin.mjs +2 -1
- package/dist/routers/admin.mjs.map +1 -1
- package/dist/routers/assets.mjs +1 -0
- package/dist/routers/assets.mjs.map +1 -1
- package/dist/routers/auth.mjs +1 -0
- package/dist/routers/auth.mjs.map +1 -1
- package/dist/routers/builds.handlers.mjs +114 -19
- package/dist/routers/builds.handlers.mjs.map +1 -1
- package/dist/routers/builds.mjs +55 -34
- package/dist/routers/builds.mjs.map +1 -1
- package/dist/routers/comments.mjs +1 -0
- package/dist/routers/comments.mjs.map +1 -1
- package/dist/routers/health.mjs +137 -0
- package/dist/routers/health.mjs.map +1 -0
- package/dist/routers/helpers.mjs +8 -2
- package/dist/routers/helpers.mjs.map +1 -1
- package/dist/routers/htmx.mjs +2 -0
- package/dist/routers/htmx.mjs.map +1 -1
- package/dist/routers/labels.mjs +2 -1
- package/dist/routers/labels.mjs.map +1 -1
- package/dist/routers/media.mjs +3 -2
- package/dist/routers/media.mjs.map +1 -1
- package/dist/routers/members.mjs +1 -0
- package/dist/routers/members.mjs.map +1 -1
- package/dist/routers/projects.mjs +2 -1
- package/dist/routers/projects.mjs.map +1 -1
- package/dist/routers/schemas.mjs +25 -0
- package/dist/routers/schemas.mjs.map +1 -1
- package/dist/routers/settings-general.mjs +95 -0
- package/dist/routers/settings-general.mjs.map +1 -0
- package/dist/routers/settings-labels.mjs +49 -0
- package/dist/routers/settings-labels.mjs.map +1 -0
- package/dist/routers/settings-members.mjs +30 -0
- package/dist/routers/settings-members.mjs.map +1 -0
- package/dist/routers/settings-status.mjs +73 -0
- package/dist/routers/settings-status.mjs.map +1 -0
- package/dist/routers/settings-tokens.mjs +40 -0
- package/dist/routers/settings-tokens.mjs.map +1 -0
- package/dist/routers/settings-webhooks.mjs +63 -0
- package/dist/routers/settings-webhooks.mjs.map +1 -0
- package/dist/routers/settings.handlers.mjs +93 -0
- package/dist/routers/settings.handlers.mjs.map +1 -0
- package/dist/routers/settings.mjs +14 -246
- package/dist/routers/settings.mjs.map +1 -1
- package/dist/routers/snapshots.mjs +2 -1
- package/dist/routers/snapshots.mjs.map +1 -1
- package/dist/routers/status-configs.mjs +2 -1
- package/dist/routers/status-configs.mjs.map +1 -1
- package/dist/routers/storybook.mjs +12 -4
- package/dist/routers/storybook.mjs.map +1 -1
- package/dist/routers/tokens.mjs +2 -1
- package/dist/routers/tokens.mjs.map +1 -1
- package/dist/routers/ui.mjs +5 -4
- package/dist/routers/ui.mjs.map +1 -1
- package/dist/routers/webhooks.mjs +7 -6
- package/dist/routers/webhooks.mjs.map +1 -1
- package/dist/schema/baseline.d.mts +18 -0
- package/dist/schema/baseline.mjs +22 -0
- package/dist/schema/baseline.mjs.map +1 -0
- package/dist/schema/build.d.mts +26 -0
- package/dist/schema/build.mjs +29 -0
- package/dist/schema/build.mjs.map +1 -0
- package/dist/schema/comment.d.mts +19 -0
- package/dist/schema/comment.mjs +26 -0
- package/dist/schema/comment.mjs.map +1 -0
- package/dist/schema/label.d.mts +25 -0
- package/dist/schema/label.mjs +30 -0
- package/dist/schema/label.mjs.map +1 -0
- package/dist/schema/member.d.mts +15 -0
- package/dist/schema/member.mjs +19 -0
- package/dist/schema/member.mjs.map +1 -0
- package/dist/schema/project.d.mts +34 -0
- package/dist/schema/project.mjs +25 -0
- package/dist/schema/project.mjs.map +1 -0
- package/dist/schema/snapshot.d.mts +30 -0
- package/dist/schema/snapshot.mjs +34 -0
- package/dist/schema/snapshot.mjs.map +1 -0
- package/dist/schema/status-config.d.mts +16 -0
- package/dist/schema/status-config.mjs +20 -0
- package/dist/schema/status-config.mjs.map +1 -0
- package/dist/schema/token.d.mts +15 -0
- package/dist/schema/token.mjs +19 -0
- package/dist/schema/token.mjs.map +1 -0
- package/dist/schema/user.d.mts +17 -0
- package/dist/schema/user.mjs +19 -0
- package/dist/schema/user.mjs.map +1 -0
- package/dist/schema/webhook.d.mts +16 -0
- package/dist/schema/webhook.mjs +20 -0
- package/dist/schema/webhook.mjs.map +1 -0
- package/dist/schema.d.mts +52 -4433
- package/dist/schema.mjs +37 -139
- package/dist/schema.mjs.map +1 -1
- package/dist/store.mjs +2 -0
- package/dist/store.mjs.map +1 -1
- package/dist/types.d.mts +13 -2
- package/dist/types.mjs +8 -0
- package/dist/types.mjs.map +1 -1
- package/dist/ui/document.mjs +1 -0
- package/dist/ui/document.mjs.map +1 -1
- package/dist/ui/feedback.mjs +24 -0
- package/dist/ui/feedback.mjs.map +1 -0
- package/dist/ui/{components.mjs → forms.mjs} +6 -16
- package/dist/ui/forms.mjs.map +1 -0
- package/dist/ui/styles.mjs +1 -0
- package/dist/ui/styles.mjs.map +1 -1
- package/dist/ui/theme.mjs +2 -0
- package/dist/ui/theme.mjs.map +1 -1
- package/dist/urls.d.mts +8 -0
- package/dist/urls.mjs +7 -0
- package/dist/urls.mjs.map +1 -1
- package/dist/utils/hash.mjs +3 -0
- package/dist/utils/hash.mjs.map +1 -1
- package/dist/utils/ulid.mjs +2 -0
- package/dist/utils/ulid.mjs.map +1 -1
- package/package.json +47 -45
- package/dist/adapters/metadata.d.mts +0 -24
- package/dist/models/baseline.d.mts +0 -20
- package/dist/models/build.d.mts +0 -50
- package/dist/models/comment.d.mts +0 -20
- package/dist/models/label.d.mts +0 -49
- package/dist/models/member.d.mts +0 -27
- package/dist/models/project.d.mts +0 -42
- package/dist/models/snapshot.d.mts +0 -46
- package/dist/models/token.d.mts +0 -33
- package/dist/models/webhook.d.mts +0 -37
- package/dist/retention/purge.d.mts +0 -28
- package/dist/ui/components.mjs.map +0 -1
- package/dist/ui/document.d.mts +0 -8
- package/dist/utils/paths.mjs.map +0 -1
- package/dist/utils/ulid.d.mts +0 -8
package/dist/config.d.mts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import {
|
|
4
|
-
import { CaptureQueue } from "./adapters/capture-queue.mjs";
|
|
3
|
+
import { CaptureQueue } from "./adapter/capture-queue.mjs";
|
|
5
4
|
import { CaptureRunner } from "./adapter/capture-runner.mjs";
|
|
6
5
|
import { DatabaseAdapter } from "./adapter/database.mjs";
|
|
7
6
|
import { GitHostProvider } from "./adapter/git-host.mjs";
|
|
8
7
|
import { StorageAdapter } from "./adapter/storage.mjs";
|
|
8
|
+
import { AdapterCategory } from "./adapter/metadata.mjs";
|
|
9
|
+
import { AuthAdapter } from "./adapter/auth.mjs";
|
|
9
10
|
import { z } from "zod";
|
|
10
11
|
import { Logger } from "pino";
|
|
11
12
|
//#region src/config.d.ts
|
|
13
|
+
/** Brand color theme for the server-rendered UI. */
|
|
12
14
|
interface BrandTheme {
|
|
13
15
|
accent: string;
|
|
14
16
|
surface: {
|
|
@@ -26,6 +28,7 @@ interface BrandTheme {
|
|
|
26
28
|
rejected: string;
|
|
27
29
|
};
|
|
28
30
|
}
|
|
31
|
+
/** Branding overrides for the server-rendered UI. */
|
|
29
32
|
interface UIConfig {
|
|
30
33
|
name?: string;
|
|
31
34
|
logo?: string;
|
|
@@ -33,25 +36,37 @@ interface UIConfig {
|
|
|
33
36
|
lightTheme?: BrandTheme;
|
|
34
37
|
darkTheme?: BrandTheme;
|
|
35
38
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
/** A viewport in which stories are captured. */
|
|
40
|
+
interface ShelfViewport {
|
|
41
|
+
name: string;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
}
|
|
45
|
+
/** Metadata snapshot of a configured adapter. */
|
|
46
|
+
interface AdapterSnapshot {
|
|
47
|
+
name: string;
|
|
48
|
+
version: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
kind: string;
|
|
51
|
+
category: AdapterCategory;
|
|
52
|
+
}
|
|
53
|
+
/** Shelf-level configuration (validated by {@link shelfConfigSchema}). */
|
|
54
|
+
interface ShelfConfig {
|
|
55
|
+
secret?: string;
|
|
56
|
+
publishedBaseDomain?: string;
|
|
57
|
+
captureConcurrency?: number;
|
|
58
|
+
scratchDir?: string;
|
|
59
|
+
purgeTtlDays?: number;
|
|
60
|
+
maxUploadBytes?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Max zip size (bytes) eligible for inline statics extraction at upload.
|
|
63
|
+
* Unset (or 0) disables inline extraction — statics land via capture.
|
|
64
|
+
*/
|
|
65
|
+
maxInlineUnzipSize?: number;
|
|
66
|
+
viewports?: ShelfViewport[];
|
|
67
|
+
adapters?: Record<string, AdapterSnapshot>;
|
|
68
|
+
}
|
|
69
|
+
/** Adapter and configuration options for creating the shelf router. */
|
|
55
70
|
interface ShelfOptions {
|
|
56
71
|
database: DatabaseAdapter;
|
|
57
72
|
storage: StorageAdapter;
|
|
@@ -64,5 +79,5 @@ interface ShelfOptions {
|
|
|
64
79
|
config?: ShelfConfig;
|
|
65
80
|
}
|
|
66
81
|
//#endregion
|
|
67
|
-
export { BrandTheme, ShelfConfig, ShelfOptions,
|
|
82
|
+
export { AdapterSnapshot, BrandTheme, ShelfConfig, ShelfOptions, ShelfViewport, UIConfig };
|
|
68
83
|
//# sourceMappingURL=config.d.mts.map
|
package/dist/config.mjs
CHANGED
|
@@ -3,6 +3,8 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/config.ts
|
|
6
|
+
/** Default cap for a single Storybook zip upload (1 GiB). */
|
|
7
|
+
const DEFAULT_MAX_UPLOAD_BYTES = 1073741824;
|
|
6
8
|
const viewportSchema = z.object({
|
|
7
9
|
name: z.string().min(1),
|
|
8
10
|
width: z.number().int().positive(),
|
|
@@ -29,17 +31,29 @@ const adapterSnapshotSchema = z.object({
|
|
|
29
31
|
name: z.string(),
|
|
30
32
|
version: z.string(),
|
|
31
33
|
description: z.string().optional(),
|
|
32
|
-
kind: z.string()
|
|
34
|
+
kind: z.string(),
|
|
35
|
+
category: z.enum([
|
|
36
|
+
"database",
|
|
37
|
+
"storage",
|
|
38
|
+
"auth",
|
|
39
|
+
"capture-runner",
|
|
40
|
+
"capture-queue",
|
|
41
|
+
"git-host"
|
|
42
|
+
])
|
|
33
43
|
});
|
|
44
|
+
/** Zod schema validating the shelf-level configuration. */
|
|
34
45
|
const shelfConfigSchema = z.object({
|
|
35
46
|
secret: z.string().min(1).optional(),
|
|
36
47
|
publishedBaseDomain: z.string().optional(),
|
|
37
48
|
captureConcurrency: z.number().int().positive().optional(),
|
|
38
49
|
scratchDir: z.string().optional(),
|
|
39
50
|
purgeTtlDays: z.number().int().positive().optional(),
|
|
51
|
+
maxUploadBytes: z.number().int().positive().optional(),
|
|
52
|
+
maxInlineUnzipSize: z.number().int().positive().optional(),
|
|
40
53
|
viewports: z.array(viewportSchema).min(1, "at least one viewport required").optional(),
|
|
41
54
|
adapters: z.record(z.string(), adapterSnapshotSchema).optional()
|
|
42
55
|
}).strict();
|
|
56
|
+
/** Zod schema validating the UI branding configuration. */
|
|
43
57
|
const uiConfigSchema = z.object({
|
|
44
58
|
name: z.string().optional(),
|
|
45
59
|
logo: z.string().url().optional(),
|
|
@@ -47,6 +61,12 @@ const uiConfigSchema = z.object({
|
|
|
47
61
|
lightTheme: brandThemeSchema.optional(),
|
|
48
62
|
darkTheme: brandThemeSchema.optional()
|
|
49
63
|
}).strict();
|
|
64
|
+
/**
|
|
65
|
+
* Parse and validate a raw shelf-level configuration object.
|
|
66
|
+
*
|
|
67
|
+
* @param config - Unvalidated configuration record.
|
|
68
|
+
* @returns The validated shelf configuration.
|
|
69
|
+
*/
|
|
50
70
|
function validateConfig(config) {
|
|
51
71
|
const result = shelfConfigSchema.safeParse(config);
|
|
52
72
|
if (!result.success) {
|
|
@@ -55,6 +75,12 @@ function validateConfig(config) {
|
|
|
55
75
|
}
|
|
56
76
|
return result.data;
|
|
57
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Parse and validate a raw UI branding configuration object.
|
|
80
|
+
*
|
|
81
|
+
* @param config - Unvalidated UI configuration record.
|
|
82
|
+
* @returns The validated UI configuration.
|
|
83
|
+
*/
|
|
58
84
|
function validateUiConfig(config) {
|
|
59
85
|
const result = uiConfigSchema.safeParse(config);
|
|
60
86
|
if (!result.success) {
|
|
@@ -64,6 +90,6 @@ function validateUiConfig(config) {
|
|
|
64
90
|
return result.data;
|
|
65
91
|
}
|
|
66
92
|
//#endregion
|
|
67
|
-
export { shelfConfigSchema, uiConfigSchema, validateConfig, validateUiConfig };
|
|
93
|
+
export { DEFAULT_MAX_UPLOAD_BYTES, shelfConfigSchema, uiConfigSchema, validateConfig, validateUiConfig };
|
|
68
94
|
|
|
69
95
|
//# sourceMappingURL=config.mjs.map
|
package/dist/config.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import {
|
|
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":";;;;;;AA6BA,MAAa,2BAA2B;AAmCxC,MAAM,iBAA2C,EAAE,OAAO;CACxD,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;CACjC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;AACpC,CAAC;AAED,MAAM,mBAAmB,EAAE,OAAO;CAChC,QAAQ,EAAE,OAAO;CACjB,SAAS,EAAE,OAAO;EAAE,MAAM,EAAE,OAAO;EAAG,MAAM,EAAE,OAAO;CAAE,CAAC;CACxD,MAAM,EAAE,OAAO;EAAE,SAAS,EAAE,OAAO;EAAG,WAAW,EAAE,OAAO;CAAE,CAAC;CAC7D,QAAQ,EAAE,OAAO;CACjB,QAAQ,EAAE,OAAO;EAAE,UAAU,EAAE,OAAO;EAAG,KAAK,EAAE,OAAO;EAAG,UAAU,EAAE,OAAO;CAAE,CAAC;AAClF,CAAC;AAED,MAAM,wBAAoD,EAAE,OAAO;CACjE,MAAM,EAAE,OAAO;CACf,SAAS,EAAE,OAAO;CAClB,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS;CACjC,MAAM,EAAE,OAAO;CACf,UAAU,EAAE,KAAK;EAAC;EAAY;EAAW;EAAQ;EAAkB;EAAiB;CAAU,CAAC;AACjG,CAAC;;AAGD,MAAa,oBAA4C,EACtD,OAAO;CACN,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CACnC,qBAAqB,EAAE,OAAO,CAAC,CAAC,SAAS;CACzC,oBAAoB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACzD,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACnD,gBAAgB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACrD,oBAAoB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACzD,WAAW,EAAE,MAAM,cAAc,CAAC,CAAC,IAAI,GAAG,gCAAgC,CAAC,CAAC,SAAS;CACrF,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,qBAAqB,CAAC,CAAC,SAAS;AACjE,CAAC,CAAC,CACD,OAAO;;AAGV,MAAa,iBAAiB,EAC3B,OAAO;CACN,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAE1B,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;CAEhC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;CACnC,YAAY,iBAAiB,SAAS;CACtC,WAAW,iBAAiB,SAAS;AACvC,CAAC,CAAC,CACD,OAAO;;;;;;;AAQV,SAAgB,eAAe,QAA8C;CAC3E,MAAM,SAAS,kBAAkB,UAAU,MAAM;CACjD,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,wBAAwB,QAAQ;CAClD;CACA,OAAO,OAAO;AAChB;;;;;;;AAQA,SAAgB,iBAAiB,QAA2C;CAC1E,MAAM,SAAS,eAAe,UAAU,MAAM;CAC9C,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,qBAAqB,QAAQ;CAC/C;CACA,OAAO,OAAO;AAChB"}
|
package/dist/ddl.d.mts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
//#region src/ddl.d.ts
|
|
4
|
-
|
|
4
|
+
/** Canonical SQLite DDL for all StoryShelf tables and indexes. */
|
|
5
|
+
declare const DDL = "\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n git_repository TEXT,\n git_default_branch TEXT NOT NULL DEFAULT 'main',\n pixel_threshold REAL NOT NULL DEFAULT 0.1,\n max_diff_ratio REAL NOT NULL DEFAULT 0.01,\n public_branch_regex TEXT,\n storybook_meta TEXT,\n execute_play INTEGER NOT NULL DEFAULT 0,\n play_timeout_ms INTEGER NOT NULL DEFAULT 10000,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_status_configs (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n config TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS builds (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n git_sha TEXT NOT NULL,\n git_branch TEXT NOT NULL,\n is_default INTEGER NOT NULL DEFAULT 0,\n author_email TEXT,\n author_name TEXT,\n message TEXT,\n public INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'pending',\n snapshot_count INTEGER NOT NULL DEFAULT 0,\n changed_count INTEGER NOT NULL DEFAULT 0,\n approved_count INTEGER NOT NULL DEFAULT 0,\n rejected_count INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha);\nCREATE INDEX IF NOT EXISTS builds_git_branch_idx ON builds (git_branch);\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n story_name TEXT NOT NULL,\n story_title TEXT NOT NULL,\n story_import_path TEXT,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n viewport_width INTEGER NOT NULL DEFAULT 1280,\n viewport_height INTEGER NOT NULL DEFAULT 720,\n screenshot_path TEXT NOT NULL,\n diff_path TEXT,\n diff_pixels INTEGER,\n diff_ratio REAL,\n diff_passed INTEGER,\n status TEXT NOT NULL DEFAULT 'pending',\n reviewed_by TEXT,\n reviewed_at TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS snapshots_build_story_viewport_idx ON snapshots (build_id, story_id, viewport_name);\nCREATE INDEX IF NOT EXISTS snapshots_build_id_idx ON snapshots (build_id);\nCREATE TABLE IF NOT EXISTS baselines (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n branch TEXT NOT NULL,\n snapshot_id TEXT,\n screenshot_path TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS baselines_project_story_viewport_branch_idx ON baselines (project_id, story_id, viewport_name, branch);\nCREATE INDEX IF NOT EXISTS baselines_project_story_idx ON baselines (project_id, story_id);\nCREATE TABLE IF NOT EXISTS comments (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n snapshot_id TEXT REFERENCES snapshots(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n body TEXT NOT NULL,\n parent_id TEXT,\n resolved INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS comments_build_id_idx ON comments (build_id);\nCREATE TABLE IF NOT EXISTS label_types (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n name TEXT NOT NULL,\n link_template TEXT,\n color TEXT,\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS label_types_project_key_idx ON label_types (project_id, key);\nCREATE TABLE IF NOT EXISTS build_labels (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n type_key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS build_labels_build_type_value_idx ON build_labels (build_id, type_key, value);\nCREATE TABLE IF NOT EXISTS tokens (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n hash TEXT NOT NULL UNIQUE,\n last_used_at TEXT,\n created_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS webhooks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n url TEXT NOT NULL,\n secret_encrypted TEXT NOT NULL,\n events TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n avatar_url TEXT,\n role TEXT NOT NULL DEFAULT 'member',\n last_login_at TEXT,\n created_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_members (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_members_project_user_idx ON project_members (project_id, user_id);\n";
|
|
5
6
|
//#endregion
|
|
6
7
|
export { DDL };
|
|
7
8
|
//# sourceMappingURL=ddl.d.mts.map
|
package/dist/ddl.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
//#region src/ddl.ts
|
|
5
|
+
/** Canonical SQLite DDL for all StoryShelf tables and indexes. */
|
|
5
6
|
const DDL = `
|
|
6
7
|
CREATE TABLE IF NOT EXISTS projects (
|
|
7
8
|
id TEXT PRIMARY KEY,
|
|
@@ -128,7 +129,7 @@ CREATE TABLE IF NOT EXISTS webhooks (
|
|
|
128
129
|
id TEXT PRIMARY KEY,
|
|
129
130
|
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
130
131
|
url TEXT NOT NULL,
|
|
131
|
-
|
|
132
|
+
secret_encrypted TEXT NOT NULL,
|
|
132
133
|
events TEXT,
|
|
133
134
|
created_at TEXT NOT NULL,
|
|
134
135
|
updated_at TEXT NOT NULL
|
package/dist/ddl.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ddl.mjs","names":[],"sources":["../src/ddl.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"ddl.mjs","names":[],"sources":["../src/ddl.ts"],"sourcesContent":["/** Canonical SQLite DDL for all StoryShelf tables and indexes. */\nexport const DDL = `\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n git_repository TEXT,\n git_default_branch TEXT NOT NULL DEFAULT 'main',\n pixel_threshold REAL NOT NULL DEFAULT 0.1,\n max_diff_ratio REAL NOT NULL DEFAULT 0.01,\n public_branch_regex TEXT,\n storybook_meta TEXT,\n execute_play INTEGER NOT NULL DEFAULT 0,\n play_timeout_ms INTEGER NOT NULL DEFAULT 10000,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_status_configs (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n config TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS builds (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n git_sha TEXT NOT NULL,\n git_branch TEXT NOT NULL,\n is_default INTEGER NOT NULL DEFAULT 0,\n author_email TEXT,\n author_name TEXT,\n message TEXT,\n public INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'pending',\n snapshot_count INTEGER NOT NULL DEFAULT 0,\n changed_count INTEGER NOT NULL DEFAULT 0,\n approved_count INTEGER NOT NULL DEFAULT 0,\n rejected_count INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha);\nCREATE INDEX IF NOT EXISTS builds_git_branch_idx ON builds (git_branch);\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n story_name TEXT NOT NULL,\n story_title TEXT NOT NULL,\n story_import_path TEXT,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n viewport_width INTEGER NOT NULL DEFAULT 1280,\n viewport_height INTEGER NOT NULL DEFAULT 720,\n screenshot_path TEXT NOT NULL,\n diff_path TEXT,\n diff_pixels INTEGER,\n diff_ratio REAL,\n diff_passed INTEGER,\n status TEXT NOT NULL DEFAULT 'pending',\n reviewed_by TEXT,\n reviewed_at TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS snapshots_build_story_viewport_idx ON snapshots (build_id, story_id, viewport_name);\nCREATE INDEX IF NOT EXISTS snapshots_build_id_idx ON snapshots (build_id);\nCREATE TABLE IF NOT EXISTS baselines (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n branch TEXT NOT NULL,\n snapshot_id TEXT,\n screenshot_path TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS baselines_project_story_viewport_branch_idx ON baselines (project_id, story_id, viewport_name, branch);\nCREATE INDEX IF NOT EXISTS baselines_project_story_idx ON baselines (project_id, story_id);\nCREATE TABLE IF NOT EXISTS comments (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n snapshot_id TEXT REFERENCES snapshots(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n body TEXT NOT NULL,\n parent_id TEXT,\n resolved INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS comments_build_id_idx ON comments (build_id);\nCREATE TABLE IF NOT EXISTS label_types (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n name TEXT NOT NULL,\n link_template TEXT,\n color TEXT,\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS label_types_project_key_idx ON label_types (project_id, key);\nCREATE TABLE IF NOT EXISTS build_labels (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n type_key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS build_labels_build_type_value_idx ON build_labels (build_id, type_key, value);\nCREATE TABLE IF NOT EXISTS tokens (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n hash TEXT NOT NULL UNIQUE,\n last_used_at TEXT,\n created_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS webhooks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n url TEXT NOT NULL,\n secret_encrypted TEXT NOT NULL,\n events TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n avatar_url TEXT,\n role TEXT NOT NULL DEFAULT 'member',\n last_login_at TEXT,\n created_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_members (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_members_project_user_idx ON project_members (project_id, user_id);\n`;\n"],"mappings":";;;;;AACA,MAAa,MAAM"}
|
package/dist/diff/engine.d.mts
CHANGED
|
@@ -2,6 +2,14 @@ import __tsdown_shims_path from 'node:path';
|
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
import { DiffOptions, DiffResult } from "./options.mjs";
|
|
4
4
|
//#region src/diff/engine.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Compare baseline and current screenshots, returning pass/fail and a diff image.
|
|
7
|
+
*
|
|
8
|
+
* @param baseline - Baseline PNG buffer.
|
|
9
|
+
* @param current - Current capture PNG buffer.
|
|
10
|
+
* @param options - Pixel threshold and ratio limits.
|
|
11
|
+
* @returns The diff result with pixel counts and an optional overlay image.
|
|
12
|
+
*/
|
|
5
13
|
declare function diffImages(baseline: Buffer, current: Buffer, options: DiffOptions): DiffResult;
|
|
6
14
|
//#endregion
|
|
7
15
|
export { diffImages };
|
package/dist/diff/engine.mjs
CHANGED
|
@@ -4,6 +4,14 @@ import.meta.url;
|
|
|
4
4
|
import pixelmatch from "pixelmatch";
|
|
5
5
|
import { PNG } from "pngjs";
|
|
6
6
|
//#region src/diff/engine.ts
|
|
7
|
+
/**
|
|
8
|
+
* Compare baseline and current screenshots, returning pass/fail and a diff image.
|
|
9
|
+
*
|
|
10
|
+
* @param baseline - Baseline PNG buffer.
|
|
11
|
+
* @param current - Current capture PNG buffer.
|
|
12
|
+
* @param options - Pixel threshold and ratio limits.
|
|
13
|
+
* @returns The diff result with pixel counts and an optional overlay image.
|
|
14
|
+
*/
|
|
7
15
|
function diffImages(baseline, current, options) {
|
|
8
16
|
const baselinePng = PNG.sync.read(baseline);
|
|
9
17
|
const currentPng = PNG.sync.read(current);
|
package/dist/diff/engine.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.mjs","names":[],"sources":["../../src/diff/engine.ts"],"sourcesContent":["import pixelmatch from \"pixelmatch\";\nimport { PNG } from \"pngjs\";\
|
|
1
|
+
{"version":3,"file":"engine.mjs","names":[],"sources":["../../src/diff/engine.ts"],"sourcesContent":["import pixelmatch from \"pixelmatch\";\nimport { PNG } from \"pngjs\";\nimport type { DiffOptions, DiffResult } from \"./options.ts\";\n\n/**\n * Compare baseline and current screenshots, returning pass/fail and a diff image.\n *\n * @param baseline - Baseline PNG buffer.\n * @param current - Current capture PNG buffer.\n * @param options - Pixel threshold and ratio limits.\n * @returns The diff result with pixel counts and an optional overlay image.\n */\nexport function diffImages(baseline: Buffer, current: Buffer, options: DiffOptions): DiffResult {\n const baselinePng = PNG.sync.read(baseline);\n const currentPng = PNG.sync.read(current);\n\n const baselineDimensions = { width: baselinePng.width, height: baselinePng.height };\n const currentDimensions = { width: currentPng.width, height: currentPng.height };\n const sizeChanged =\n baselineDimensions.width !== currentDimensions.width ||\n baselineDimensions.height !== currentDimensions.height;\n\n if (sizeChanged) {\n if (options.failOnSizeChange) {\n return {\n passed: false,\n diffPixels: 0,\n diffRatio: 1,\n diffImage: null,\n baselineDimensions,\n currentDimensions,\n sizeChanged: true,\n };\n }\n\n // With `failOnSizeChange: false` a size mismatch is not a failure: diff only\n // The top-left overlapping region, normalised by its area. Pixelmatch needs\n // Equal-size inputs, so the larger image is cropped first.\n const width = Math.min(baselineDimensions.width, currentDimensions.width);\n const height = Math.min(baselineDimensions.height, currentDimensions.height);\n const overlap = compareRegions(\n cropRgba(baselinePng.data, baselineDimensions.width, width, height),\n cropRgba(currentPng.data, currentDimensions.width, width, height),\n width,\n height,\n options,\n );\n const diffRatio = overlap.diffPixels / (width * height);\n return {\n passed: diffRatio <= options.maxDiffRatio,\n diffPixels: overlap.diffPixels,\n diffRatio,\n diffImage: overlap.diffImage,\n baselineDimensions,\n currentDimensions,\n sizeChanged: true,\n };\n }\n\n const { width } = baselineDimensions;\n const { height } = baselineDimensions;\n const overlap = compareRegions(baselinePng.data, currentPng.data, width, height, options);\n const diffRatio = overlap.diffPixels / (width * height);\n return {\n passed: diffRatio <= options.maxDiffRatio,\n diffPixels: overlap.diffPixels,\n diffRatio,\n diffImage: overlap.diffImage,\n baselineDimensions,\n currentDimensions,\n sizeChanged: false,\n };\n}\n\nfunction cropRgba(source: Buffer, sourceWidth: number, width: number, height: number): Buffer {\n const cropped = Buffer.alloc(width * height * 4);\n const rowBytes = width * 4;\n const sourceRowBytes = sourceWidth * 4;\n for (let y = 0; y < height; y += 1) {\n source.copy(cropped, y * rowBytes, y * sourceRowBytes, y * sourceRowBytes + rowBytes);\n }\n return cropped;\n}\n\nfunction compareRegions(\n baselineData: Buffer,\n currentData: Buffer,\n width: number,\n height: number,\n options: DiffOptions,\n): { diffPixels: number; diffImage: Buffer } {\n const diffPng = new PNG({ width, height });\n const diffPixels = pixelmatch(baselineData, currentData, diffPng.data, width, height, {\n threshold: options.pixelThreshold,\n includeAA: options.includeAntialiasing,\n });\n return { diffPixels, diffImage: PNG.sync.write(diffPng) };\n}\n"],"mappings":";;;;;;;;;;;;;;AAYA,SAAgB,WAAW,UAAkB,SAAiB,SAAkC;CAC9F,MAAM,cAAc,IAAI,KAAK,KAAK,QAAQ;CAC1C,MAAM,aAAa,IAAI,KAAK,KAAK,OAAO;CAExC,MAAM,qBAAqB;EAAE,OAAO,YAAY;EAAO,QAAQ,YAAY;CAAO;CAClF,MAAM,oBAAoB;EAAE,OAAO,WAAW;EAAO,QAAQ,WAAW;CAAO;CAK/E,IAHE,mBAAmB,UAAU,kBAAkB,SAC/C,mBAAmB,WAAW,kBAAkB,QAEjC;EACf,IAAI,QAAQ,kBACV,OAAO;GACL,QAAQ;GACR,YAAY;GACZ,WAAW;GACX,WAAW;GACX;GACA;GACA,aAAa;EACf;EAMF,MAAM,QAAQ,KAAK,IAAI,mBAAmB,OAAO,kBAAkB,KAAK;EACxE,MAAM,SAAS,KAAK,IAAI,mBAAmB,QAAQ,kBAAkB,MAAM;EAC3E,MAAM,UAAU,eACd,SAAS,YAAY,MAAM,mBAAmB,OAAO,OAAO,MAAM,GAClE,SAAS,WAAW,MAAM,kBAAkB,OAAO,OAAO,MAAM,GAChE,OACA,QACA,OACF;EACA,MAAM,YAAY,QAAQ,cAAc,QAAQ;EAChD,OAAO;GACL,QAAQ,aAAa,QAAQ;GAC7B,YAAY,QAAQ;GACpB;GACA,WAAW,QAAQ;GACnB;GACA;GACA,aAAa;EACf;CACF;CAEA,MAAM,EAAE,UAAU;CAClB,MAAM,EAAE,WAAW;CACnB,MAAM,UAAU,eAAe,YAAY,MAAM,WAAW,MAAM,OAAO,QAAQ,OAAO;CACxF,MAAM,YAAY,QAAQ,cAAc,QAAQ;CAChD,OAAO;EACL,QAAQ,aAAa,QAAQ;EAC7B,YAAY,QAAQ;EACpB;EACA,WAAW,QAAQ;EACnB;EACA;EACA,aAAa;CACf;AACF;AAEA,SAAS,SAAS,QAAgB,aAAqB,OAAe,QAAwB;CAC5F,MAAM,UAAU,OAAO,MAAM,QAAQ,SAAS,CAAC;CAC/C,MAAM,WAAW,QAAQ;CACzB,MAAM,iBAAiB,cAAc;CACrC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,GAC/B,OAAO,KAAK,SAAS,IAAI,UAAU,IAAI,gBAAgB,IAAI,iBAAiB,QAAQ;CAEtF,OAAO;AACT;AAEA,SAAS,eACP,cACA,aACA,OACA,QACA,SAC2C;CAC3C,MAAM,UAAU,IAAI,IAAI;EAAE;EAAO;CAAO,CAAC;CAKzC,OAAO;EAAE,YAJU,WAAW,cAAc,aAAa,QAAQ,MAAM,OAAO,QAAQ;GACpF,WAAW,QAAQ;GACnB,WAAW,QAAQ;EACrB,CACkB;EAAG,WAAW,IAAI,KAAK,MAAM,OAAO;CAAE;AAC1D"}
|
package/dist/diff/options.d.mts
CHANGED
|
@@ -35,6 +35,8 @@ interface DiffResult {
|
|
|
35
35
|
/** Whether the two images have different dimensions. */
|
|
36
36
|
sizeChanged: boolean;
|
|
37
37
|
}
|
|
38
|
+
/** Default diff settings used when no project overrides are present. */
|
|
39
|
+
declare const DEFAULT_DIFF_OPTIONS: DiffOptions;
|
|
38
40
|
//#endregion
|
|
39
|
-
export { DiffOptions, DiffResult };
|
|
41
|
+
export { DEFAULT_DIFF_OPTIONS, DiffOptions, DiffResult };
|
|
40
42
|
//# sourceMappingURL=options.d.mts.map
|
package/dist/diff.d.mts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import __tsdown_shims_path from 'node:path';
|
|
2
|
+
import __tsdown_shims_url from 'node:url';
|
|
3
|
+
import { DEFAULT_DIFF_OPTIONS, DiffOptions, DiffResult } from "./diff/options.mjs";
|
|
4
|
+
import { diffImages } from "./diff/engine.mjs";
|
|
5
|
+
export { DEFAULT_DIFF_OPTIONS, type DiffOptions, type DiffResult, diffImages };
|
package/dist/diff.mjs
ADDED
package/dist/index.d.mts
CHANGED
|
@@ -1,31 +1,16 @@
|
|
|
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 { AuthAdapter, AuthCallback, AuthUser } from "./adapter/auth.mjs";
|
|
7
|
-
import { DEFAULT_VIEWPORTS, StoryEntry, StorySourceAdapter, Viewport } from "./capture/adapter.mjs";
|
|
8
|
-
import { CaptureJob, CaptureQueue, JobStatus, QueueEntry } from "./adapters/capture-queue.mjs";
|
|
9
|
-
import { CaptureRunner, RenderFailure, RenderResult, RenderedSnapshot } from "./adapter/capture-runner.mjs";
|
|
10
|
-
import { DatabaseAdapter, ListOptions } from "./adapter/database.mjs";
|
|
11
|
-
import { CheckStatus, GitHostAdapter, GitHostProvider } from "./adapter/git-host.mjs";
|
|
12
|
-
import { buildCommentMarkdown, commentMarker, describeStatus } from "./adapter/git-host/helpers.mjs";
|
|
3
|
+
import { CaptureQueue } from "./adapter/capture-queue.mjs";
|
|
4
|
+
import { DatabaseAdapter } from "./adapter/database.mjs";
|
|
5
|
+
import { GitHostProvider } from "./adapter/git-host.mjs";
|
|
13
6
|
import { StorageAdapter } from "./adapter/storage.mjs";
|
|
14
7
|
import { BrandTheme, ShelfConfig, ShelfOptions, UIConfig } from "./config.mjs";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { StorybookAdapter } from "./capture/storybook.mjs";
|
|
19
|
-
import { Baseline, Build, BuildLabel, Comment, LabelType, Project, ProjectMember, ProjectStatusConfig, Schema, Snapshot, StorybookMeta, Token, User, Webhook, baselines, buildLabels, builds, comments, labelTypes, projectMembers, projectStatusConfigs, projects, schema, snapshots, tokens, users, webhooks } from "./schema.mjs";
|
|
20
|
-
import { CaptureContext, persistCapture } from "./capture/pipeline.mjs";
|
|
21
|
-
import { CaptureJobOptions, executeCaptureJob } from "./capture/orchestrator.mjs";
|
|
22
|
-
import { InMemoryCaptureQueue, InMemoryCaptureQueueOptions } from "./capture/queue.mjs";
|
|
23
|
-
import { Retention } from "./retention/purge.mjs";
|
|
24
|
-
import { UrlBuilder, createUrlBuilder } from "./urls.mjs";
|
|
25
|
-
import { slugify, ulid } from "./utils/ulid.mjs";
|
|
26
|
-
import { baselinePath, diffPath, screenshotPath, storybookDir, storybookZipPath } from "./utils/paths.mjs";
|
|
8
|
+
import { createShelfLogger } from "./logger.mjs";
|
|
9
|
+
import { AuthUser } from "./adapter/auth.mjs";
|
|
10
|
+
import { AdapterInitResult } from "./adapter/init.mjs";
|
|
27
11
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
28
12
|
//#region src/index.d.ts
|
|
13
|
+
/** Per-request shelf context (adapters, config, user, capture queue). */
|
|
29
14
|
interface ShelfContext {
|
|
30
15
|
requestId?: string;
|
|
31
16
|
db: DatabaseAdapter;
|
|
@@ -39,10 +24,35 @@ interface ShelfContext {
|
|
|
39
24
|
captureQueue: CaptureQueue | null;
|
|
40
25
|
gitHosts: GitHostProvider[];
|
|
41
26
|
}
|
|
27
|
+
/** Hono application type carrying the shelf context variables. */
|
|
42
28
|
type ShelfApp = OpenAPIHono<{
|
|
43
29
|
Variables: ShelfContext;
|
|
44
30
|
}>;
|
|
45
|
-
|
|
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;
|
|
46
56
|
//#endregion
|
|
47
|
-
export { type
|
|
57
|
+
export { type BrandTheme, ShelfApp, type ShelfConfig, ShelfContext, ShelfLifecycle, type ShelfOptions, ShelfRouter, type UIConfig, createShelfRouter };
|
|
48
58
|
//# sourceMappingURL=index.d.mts.map
|