@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/ui/styles.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.mjs","names":[],"sources":["../../src/ui/styles.ts"],"sourcesContent":["import type { BrandTheme } from \"./theme.ts\";\n\nexport function baseStyle(light: BrandTheme, dark: BrandTheme): string {\n return `\n :root {\n --accent: ${light.accent};\n --accent-contrast: #fff;\n --surface-base: ${light.surface.base};\n --surface-card: ${light.surface.card};\n --surface-muted: #f4f4f5;\n --text-primary: ${light.text.primary};\n --text-secondary: ${light.text.secondary};\n --border: ${light.border};\n --radius: 10px;\n --radius-sm: 6px;\n --shadow: 0 1px 2px rgba(0,0,0,.06), 0 4px 12px rgba(0,0,0,.04);\n --status-approved: ${light.status.approved};\n --status-new: ${light.status.new};\n --status-rejected: ${light.status.rejected};\n --topbar-bg: ${light.accent};\n --sidebar-bg: #ffffff;\n --sidebar-width: 240px;\n }\n [data-theme=\"dark\"] {\n --accent: ${dark.accent};\n --surface-base: ${dark.surface.base};\n --surface-card: ${dark.surface.card};\n --surface-muted: #1e1e22;\n --text-primary: ${dark.text.primary};\n --text-secondary: ${dark.text.secondary};\n --border: ${dark.border};\n --status-approved: ${dark.status.approved};\n --status-new: ${dark.status.new};\n --status-rejected: ${dark.status.rejected};\n --topbar-bg: #0f172a;\n --sidebar-bg: #111113;\n }\n @media (prefers-color-scheme: dark) {\n [data-theme=\"system\"] {\n --accent: ${dark.accent};\n --surface-base: ${dark.surface.base};\n --surface-card: ${dark.surface.card};\n --surface-muted: #1e1e22;\n --text-primary: ${dark.text.primary};\n --text-secondary: ${dark.text.secondary};\n --border: ${dark.border};\n --status-approved: ${dark.status.approved};\n --status-new: ${dark.status.new};\n --status-rejected: ${dark.status.rejected};\n --topbar-bg: #0f172a;\n --sidebar-bg: #111113;\n }\n }\n * { box-sizing: border-box; }\n html { scroll-behavior: smooth; }\n body { margin: 0; font-family: ui-sans-system, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; background: var(--surface-base); color: var(--text-primary); line-height: 1.5; }\n a { color: var(--accent); text-decoration: none; }\n a:hover { text-decoration: underline; }\n a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n .skip-link { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }\n .skip-link:focus { left: 1rem; top: 1rem; width: auto; height: auto; background: var(--surface-card); color: var(--text-primary); padding: .5rem .75rem; border-radius: var(--radius-sm); box-shadow: var(--shadow); z-index: 100; }\n .topbar { position: sticky; top: 0; z-index: 40; background: var(--topbar-bg); color: #fff; border-bottom: 1px solid rgba(255,255,255,.12); }\n .topbar__inner { max-width: 1440px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .6rem 1rem; }\n .topbar__left, .topbar__right { display: flex; align-items: center; gap: .75rem; min-width: 0; }\n .topbar__menu { display: none; background: transparent; border: 1px solid rgba(255,255,255,.3); color: #fff; border-radius: 6px; padding: .35rem .5rem; cursor: pointer; }\n .brand { display: inline-flex; align-items: center; gap: .5rem; color: #fff; font-weight: 650; text-decoration: none; }\n .brand__mark { width: 28px; height: 28px; display: inline-grid; place-items: center; background: rgba(255,255,255,.18); border-radius: 8px; }\n .logo { border-radius: 6px; display: block; }\n .project-crumb { display: inline-flex; align-items: center; gap: .35rem; color: rgba(255,255,255,.9); }\n .project-crumb a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }\n .project-crumb__sep { opacity: .7; }\n .topbar__theme { background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.22); color: #fff; border-radius: 999px; padding: .35rem .6rem; cursor: pointer; display: inline-flex; gap: .25rem; }\n .topbar__theme [data-theme-icon] { display: none; }\n [data-theme=\"light\"] [data-theme-icon=\"light\"], [data-theme=\"dark\"] [data-theme-icon=\"dark\"], [data-theme=\"system\"] [data-theme-icon=\"system\"] { display: inline; }\n .topbar__login { background: #fff; color: var(--accent); padding: .4rem .75rem; border-radius: 999px; font-weight: 600; text-decoration: none; }\n .user-menu { display: inline-flex; align-items: center; gap: .5rem; background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.2); padding: .25rem .5rem .25rem .35rem; border-radius: 999px; }\n .user-menu__avatar { width: 28px; height: 28px; border-radius: 999px; object-fit: cover; background: rgba(255,255,255,.2); }\n .user-menu__avatar--fallback { display: inline-grid; place-items: center; font-weight: 700; color: #fff; }\n .user-menu__name { color: #fff; font-weight: 600; max-width: 12ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .user-menu__role { font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; background: rgba(255,255,255,.2); color: #fff; padding: .15rem .4rem; border-radius: 999px; }\n .user-menu__logout { color: #fff; font-size: .85rem; text-decoration: underline; text-underline-offset: 2px; margin-left: .25rem; }\n .shell { max-width: 1440px; margin: 0 auto; display: grid; grid-template-columns: var(--sidebar-width) 1fr; min-height: calc(100vh - 56px); }\n .sidebar { background: var(--sidebar-bg); border-right: 1px solid var(--border); padding: 1rem .75rem; position: sticky; top: 56px; height: calc(100vh - 56px); overflow: auto; }\n .sidebar__nav { display: flex; flex-direction: column; gap: .25rem; }\n .sidebar__section { margin: 1rem 0 .35rem; font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-secondary); padding: 0 .5rem; }\n .sidebar__link { display: flex; align-items: center; gap: .5rem; padding: .5rem .6rem; border-radius: 8px; color: var(--text-primary); text-decoration: none; }\n .sidebar__link:hover { background: var(--surface-muted); text-decoration: none; }\n .sidebar__link--active { background: var(--surface-muted); font-weight: 600; }\n .content { padding: 1.25rem 1.5rem 2rem; min-width: 0; max-width: 1100px; }\n .page-header { margin-bottom: 1.25rem; }\n .page-header__row { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; }\n .page-header__title { margin: 0; font-size: 1.6rem; line-height: 1.2; letter-spacing: -0.02em; }\n .page-header__desc { margin: .35rem 0 0; color: var(--text-secondary); max-width: 60ch; }\n .page-header__actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }\n .breadcrumbs ol { list-style: none; padding: 0; margin: 0 0 .5rem; display: flex; gap: .4rem; flex-wrap: wrap; color: var(--text-secondary); font-size: .85rem; }\n .breadcrumbs li + li::before { content: \"/\"; margin-right: .4rem; color: var(--text-secondary); }\n .card { background: var(--surface-card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); }\n .card--padded { padding: 1rem; }\n .btn { appearance: none; border: 1px solid transparent; border-radius: 8px; padding: .55rem .85rem; font-weight: 600; font-size: .9rem; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: .4rem; line-height: 1; }\n .btn--primary { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }\n .btn--primary:hover { filter: brightness(1.05); text-decoration: none; }\n .btn--secondary { background: var(--surface-card); color: var(--text-primary); border-color: var(--border); }\n .btn--ghost { background: transparent; color: var(--text-primary); border-color: transparent; }\n .btn--danger { background: var(--status-rejected); color: #fff; border-color: var(--status-rejected); }\n .btn:disabled { opacity: .6; cursor: not-allowed; }\n .badge { display: inline-flex; align-items: center; padding: .15rem .5rem; border-radius: 999px; font-size: .75rem; font-weight: 650; letter-spacing: .02em; border: 1px solid var(--border); background: var(--surface-muted); color: var(--text-secondary); }\n .badge--success { background: color-mix(in srgb, var(--status-approved) 14%, var(--surface-card)); color: var(--status-approved); border-color: color-mix(in srgb, var(--status-approved) 30%, var(--border)); }\n .badge--warning { background: color-mix(in srgb, var(--status-new) 14%, var(--surface-card)); color: var(--status-new); border-color: color-mix(in srgb, var(--status-new) 30%, var(--border)); }\n .badge--danger { background: color-mix(in srgb, var(--status-rejected) 14%, var(--surface-card)); color: var(--status-rejected); border-color: color-mix(in srgb, var(--status-rejected) 30%, var(--border)); }\n .badge--info { background: color-mix(in srgb, var(--accent) 10%, var(--surface-card)); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 25%, var(--border)); }\n .badge--neutral { background: var(--surface-muted); color: var(--text-secondary); }\n .field { display: grid; gap: .35rem; margin-bottom: .9rem; }\n .field__label { font-weight: 600; font-size: .9rem; }\n .field__input { width: 100%; padding: .6rem .7rem; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-card); color: var(--text-primary); font: inherit; }\n .field__input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }\n .field__input--error { border-color: var(--status-rejected); }\n .field__input--textarea { resize: vertical; }\n .field__hint { margin: 0; color: var(--text-secondary); font-size: .85rem; }\n .field__error { margin: 0; color: var(--status-rejected); font-size: .85rem; }\n .alert { border-radius: 8px; padding: .75rem .85rem; border: 1px solid var(--border); background: var(--surface-card); }\n .alert--info { border-color: color-mix(in srgb, var(--accent) 22%, var(--border)); background: color-mix(in srgb, var(--accent) 7%, var(--surface-card)); }\n .alert--success { border-color: color-mix(in srgb, var(--status-approved) 22%, var(--border)); background: color-mix(in srgb, var(--status-approved) 7%, var(--surface-card)); }\n .alert--warning { border-color: color-mix(in srgb, var(--status-new) 22%, var(--border)); background: color-mix(in srgb, var(--status-new) 7%, var(--surface-card)); }\n .alert--danger { border-color: color-mix(in srgb, var(--status-rejected) 22%, var(--border)); background: color-mix(in srgb, var(--status-rejected) 7%, var(--surface-card)); }\n .alert__title { display: block; margin-bottom: .2rem; }\n .tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin-bottom: 1rem; overflow-x: auto; }\n .tabs__link { padding: .6rem .75rem; border-bottom: 2px solid transparent; color: var(--text-secondary); text-decoration: none; white-space: nowrap; font-weight: 600; }\n .tabs__link:hover { color: var(--text-primary); text-decoration: none; }\n .tabs__link--active { color: var(--text-primary); border-bottom-color: var(--accent); }\n .empty { text-align: center; padding: 2rem 1rem; border: 1px dashed var(--border); border-radius: var(--radius); background: var(--surface-card); }\n .empty__title { margin: 0 0 .3rem; font-size: 1.1rem; }\n .empty__desc { margin: 0 auto; color: var(--text-secondary); max-width: 50ch; }\n .empty__action { margin-top: 1rem; }\n .grid { display: grid; gap: 1rem; }\n .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n @media (max-width: 880px) { .grid--2, .grid--3 { grid-template-columns: 1fr; } }\n .table-wrap { overflow: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-card); }\n table { width: 100%; border-collapse: collapse; font-size: .9rem; }\n th, td { text-align: left; padding: .65rem .75rem; border-bottom: 1px solid var(--border); vertical-align: top; }\n th { background: var(--surface-muted); font-weight: 650; color: var(--text-secondary); font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; }\n tr:last-child td { border-bottom: 0; }\n .stat { text-align: center; padding: .5rem; }\n .stat__value { font-size: 1.4rem; font-weight: 750; line-height: 1; }\n .stat__label { color: var(--text-secondary); font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; }\n .snapshot-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }\n .snapshot-card { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface-card); display: flex; flex-direction: column; }\n .snapshot-card__head { padding: .6rem .75rem; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; gap: .5rem; align-items: center; }\n .snapshot-card__meta { font-size: .8rem; color: var(--text-secondary); }\n .snapshot-card__body { padding: .5rem; display: grid; gap: .5rem; }\n .diff-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; }\n @media (max-width: 900px) { .diff-grid { grid-template-columns: 1fr; } }\n .diff-pane { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface-card); }\n .diff-pane__label { padding: .4rem .6rem; font-weight: 650; font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-secondary); background: var(--surface-muted); border-bottom: 1px solid var(--border); }\n .diff-pane__img { display: block; width: 100%; height: auto; background: repeating-conic-gradient(#e5e7eb 0% 25%, #f9fafb 0% 50%) 0 0 / 16px 16px; }\n .comment { border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem; background: var(--surface-card); }\n .comment__head { display: flex; gap: .5rem; align-items: center; font-size: .85rem; color: var(--text-secondary); }\n .comment__body { margin: .5rem 0 0; white-space: pre-wrap; word-break: break-word; }\n @media (max-width: 880px) {\n .topbar__menu { display: inline-flex; }\n .shell { grid-template-columns: 1fr; }\n .sidebar { display: none; position: fixed; inset: 56px 0 0 0; z-index: 30; height: auto; }\n .sidebar--open { display: block; }\n .content { padding: 1rem; }\n }\n `;\n}"],"mappings":";;;;AAEA,SAAgB,UAAU,OAAmB,MAA0B;CACrE,OAAO;;kBAES,MAAM,OAAO;;wBAEP,MAAM,QAAQ,KAAK;wBACnB,MAAM,QAAQ,KAAK;;wBAEnB,MAAM,KAAK,QAAQ;0BACjB,MAAM,KAAK,UAAU;kBAC7B,MAAM,OAAO;;;;2BAIJ,MAAM,OAAO,SAAS;sBAC3B,MAAM,OAAO,IAAI;2BACZ,MAAM,OAAO,SAAS;qBAC5B,MAAM,OAAO;;;;;kBAKhB,KAAK,OAAO;wBACN,KAAK,QAAQ,KAAK;wBAClB,KAAK,QAAQ,KAAK;;wBAElB,KAAK,KAAK,QAAQ;0BAChB,KAAK,KAAK,UAAU;kBAC5B,KAAK,OAAO;2BACH,KAAK,OAAO,SAAS;sBAC1B,KAAK,OAAO,IAAI;2BACX,KAAK,OAAO,SAAS;;;;;;oBAM5B,KAAK,OAAO;0BACN,KAAK,QAAQ,KAAK;0BAClB,KAAK,QAAQ,KAAK;;0BAElB,KAAK,KAAK,QAAQ;4BAChB,KAAK,KAAK,UAAU;oBAC5B,KAAK,OAAO;6BACH,KAAK,OAAO,SAAS;wBAC1B,KAAK,OAAO,IAAI;6BACX,KAAK,OAAO,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsHlD"}
|
|
1
|
+
{"version":3,"file":"styles.mjs","names":[],"sources":["../../src/ui/styles.ts"],"sourcesContent":["import type { BrandTheme } from \"./theme.ts\";\n\n/** Build the global CSS stylesheet from the light and dark brand themes. */\nexport function baseStyle(light: BrandTheme, dark: BrandTheme): string {\n return `\n :root {\n --accent: ${light.accent};\n --accent-contrast: #fff;\n --surface-base: ${light.surface.base};\n --surface-card: ${light.surface.card};\n --surface-muted: #f4f4f5;\n --text-primary: ${light.text.primary};\n --text-secondary: ${light.text.secondary};\n --border: ${light.border};\n --radius: 10px;\n --radius-sm: 6px;\n --shadow: 0 1px 2px rgba(0,0,0,.06), 0 4px 12px rgba(0,0,0,.04);\n --status-approved: ${light.status.approved};\n --status-new: ${light.status.new};\n --status-rejected: ${light.status.rejected};\n --topbar-bg: ${light.accent};\n --sidebar-bg: #ffffff;\n --sidebar-width: 240px;\n }\n [data-theme=\"dark\"] {\n --accent: ${dark.accent};\n --surface-base: ${dark.surface.base};\n --surface-card: ${dark.surface.card};\n --surface-muted: #1e1e22;\n --text-primary: ${dark.text.primary};\n --text-secondary: ${dark.text.secondary};\n --border: ${dark.border};\n --status-approved: ${dark.status.approved};\n --status-new: ${dark.status.new};\n --status-rejected: ${dark.status.rejected};\n --topbar-bg: #0f172a;\n --sidebar-bg: #111113;\n }\n @media (prefers-color-scheme: dark) {\n [data-theme=\"system\"] {\n --accent: ${dark.accent};\n --surface-base: ${dark.surface.base};\n --surface-card: ${dark.surface.card};\n --surface-muted: #1e1e22;\n --text-primary: ${dark.text.primary};\n --text-secondary: ${dark.text.secondary};\n --border: ${dark.border};\n --status-approved: ${dark.status.approved};\n --status-new: ${dark.status.new};\n --status-rejected: ${dark.status.rejected};\n --topbar-bg: #0f172a;\n --sidebar-bg: #111113;\n }\n }\n * { box-sizing: border-box; }\n html { scroll-behavior: smooth; }\n body { margin: 0; font-family: ui-sans-system, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; background: var(--surface-base); color: var(--text-primary); line-height: 1.5; }\n a { color: var(--accent); text-decoration: none; }\n a:hover { text-decoration: underline; }\n a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n .skip-link { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }\n .skip-link:focus { left: 1rem; top: 1rem; width: auto; height: auto; background: var(--surface-card); color: var(--text-primary); padding: .5rem .75rem; border-radius: var(--radius-sm); box-shadow: var(--shadow); z-index: 100; }\n .topbar { position: sticky; top: 0; z-index: 40; background: var(--topbar-bg); color: #fff; border-bottom: 1px solid rgba(255,255,255,.12); }\n .topbar__inner { max-width: 1440px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .6rem 1rem; }\n .topbar__left, .topbar__right { display: flex; align-items: center; gap: .75rem; min-width: 0; }\n .topbar__menu { display: none; background: transparent; border: 1px solid rgba(255,255,255,.3); color: #fff; border-radius: 6px; padding: .35rem .5rem; cursor: pointer; }\n .brand { display: inline-flex; align-items: center; gap: .5rem; color: #fff; font-weight: 650; text-decoration: none; }\n .brand__mark { width: 28px; height: 28px; display: inline-grid; place-items: center; background: rgba(255,255,255,.18); border-radius: 8px; }\n .logo { border-radius: 6px; display: block; }\n .project-crumb { display: inline-flex; align-items: center; gap: .35rem; color: rgba(255,255,255,.9); }\n .project-crumb a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }\n .project-crumb__sep { opacity: .7; }\n .topbar__theme { background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.22); color: #fff; border-radius: 999px; padding: .35rem .6rem; cursor: pointer; display: inline-flex; gap: .25rem; }\n .topbar__theme [data-theme-icon] { display: none; }\n [data-theme=\"light\"] [data-theme-icon=\"light\"], [data-theme=\"dark\"] [data-theme-icon=\"dark\"], [data-theme=\"system\"] [data-theme-icon=\"system\"] { display: inline; }\n .topbar__login { background: #fff; color: var(--accent); padding: .4rem .75rem; border-radius: 999px; font-weight: 600; text-decoration: none; }\n .user-menu { display: inline-flex; align-items: center; gap: .5rem; background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.2); padding: .25rem .5rem .25rem .35rem; border-radius: 999px; }\n .user-menu__avatar { width: 28px; height: 28px; border-radius: 999px; object-fit: cover; background: rgba(255,255,255,.2); }\n .user-menu__avatar--fallback { display: inline-grid; place-items: center; font-weight: 700; color: #fff; }\n .user-menu__name { color: #fff; font-weight: 600; max-width: 12ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .user-menu__role { font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; background: rgba(255,255,255,.2); color: #fff; padding: .15rem .4rem; border-radius: 999px; }\n .user-menu__logout { color: #fff; font-size: .85rem; text-decoration: underline; text-underline-offset: 2px; margin-left: .25rem; }\n .shell { max-width: 1440px; margin: 0 auto; display: grid; grid-template-columns: var(--sidebar-width) 1fr; min-height: calc(100vh - 56px); }\n .sidebar { background: var(--sidebar-bg); border-right: 1px solid var(--border); padding: 1rem .75rem; position: sticky; top: 56px; height: calc(100vh - 56px); overflow: auto; }\n .sidebar__nav { display: flex; flex-direction: column; gap: .25rem; }\n .sidebar__section { margin: 1rem 0 .35rem; font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-secondary); padding: 0 .5rem; }\n .sidebar__link { display: flex; align-items: center; gap: .5rem; padding: .5rem .6rem; border-radius: 8px; color: var(--text-primary); text-decoration: none; }\n .sidebar__link:hover { background: var(--surface-muted); text-decoration: none; }\n .sidebar__link--active { background: var(--surface-muted); font-weight: 600; }\n .content { padding: 1.25rem 1.5rem 2rem; min-width: 0; max-width: 1100px; }\n .page-header { margin-bottom: 1.25rem; }\n .page-header__row { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; }\n .page-header__title { margin: 0; font-size: 1.6rem; line-height: 1.2; letter-spacing: -0.02em; }\n .page-header__desc { margin: .35rem 0 0; color: var(--text-secondary); max-width: 60ch; }\n .page-header__actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }\n .breadcrumbs ol { list-style: none; padding: 0; margin: 0 0 .5rem; display: flex; gap: .4rem; flex-wrap: wrap; color: var(--text-secondary); font-size: .85rem; }\n .breadcrumbs li + li::before { content: \"/\"; margin-right: .4rem; color: var(--text-secondary); }\n .card { background: var(--surface-card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); }\n .card--padded { padding: 1rem; }\n .btn { appearance: none; border: 1px solid transparent; border-radius: 8px; padding: .55rem .85rem; font-weight: 600; font-size: .9rem; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: .4rem; line-height: 1; }\n .btn--primary { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }\n .btn--primary:hover { filter: brightness(1.05); text-decoration: none; }\n .btn--secondary { background: var(--surface-card); color: var(--text-primary); border-color: var(--border); }\n .btn--ghost { background: transparent; color: var(--text-primary); border-color: transparent; }\n .btn--danger { background: var(--status-rejected); color: #fff; border-color: var(--status-rejected); }\n .btn:disabled { opacity: .6; cursor: not-allowed; }\n .badge { display: inline-flex; align-items: center; padding: .15rem .5rem; border-radius: 999px; font-size: .75rem; font-weight: 650; letter-spacing: .02em; border: 1px solid var(--border); background: var(--surface-muted); color: var(--text-secondary); }\n .badge--success { background: color-mix(in srgb, var(--status-approved) 14%, var(--surface-card)); color: var(--status-approved); border-color: color-mix(in srgb, var(--status-approved) 30%, var(--border)); }\n .badge--warning { background: color-mix(in srgb, var(--status-new) 14%, var(--surface-card)); color: var(--status-new); border-color: color-mix(in srgb, var(--status-new) 30%, var(--border)); }\n .badge--danger { background: color-mix(in srgb, var(--status-rejected) 14%, var(--surface-card)); color: var(--status-rejected); border-color: color-mix(in srgb, var(--status-rejected) 30%, var(--border)); }\n .badge--info { background: color-mix(in srgb, var(--accent) 10%, var(--surface-card)); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 25%, var(--border)); }\n .badge--neutral { background: var(--surface-muted); color: var(--text-secondary); }\n .field { display: grid; gap: .35rem; margin-bottom: .9rem; }\n .field__label { font-weight: 600; font-size: .9rem; }\n .field__input { width: 100%; padding: .6rem .7rem; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-card); color: var(--text-primary); font: inherit; }\n .field__input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }\n .field__input--error { border-color: var(--status-rejected); }\n .field__input--textarea { resize: vertical; }\n .field__hint { margin: 0; color: var(--text-secondary); font-size: .85rem; }\n .field__error { margin: 0; color: var(--status-rejected); font-size: .85rem; }\n .alert { border-radius: 8px; padding: .75rem .85rem; border: 1px solid var(--border); background: var(--surface-card); }\n .alert--info { border-color: color-mix(in srgb, var(--accent) 22%, var(--border)); background: color-mix(in srgb, var(--accent) 7%, var(--surface-card)); }\n .alert--success { border-color: color-mix(in srgb, var(--status-approved) 22%, var(--border)); background: color-mix(in srgb, var(--status-approved) 7%, var(--surface-card)); }\n .alert--warning { border-color: color-mix(in srgb, var(--status-new) 22%, var(--border)); background: color-mix(in srgb, var(--status-new) 7%, var(--surface-card)); }\n .alert--danger { border-color: color-mix(in srgb, var(--status-rejected) 22%, var(--border)); background: color-mix(in srgb, var(--status-rejected) 7%, var(--surface-card)); }\n .alert__title { display: block; margin-bottom: .2rem; }\n .tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin-bottom: 1rem; overflow-x: auto; }\n .tabs__link { padding: .6rem .75rem; border-bottom: 2px solid transparent; color: var(--text-secondary); text-decoration: none; white-space: nowrap; font-weight: 600; }\n .tabs__link:hover { color: var(--text-primary); text-decoration: none; }\n .tabs__link--active { color: var(--text-primary); border-bottom-color: var(--accent); }\n .empty { text-align: center; padding: 2rem 1rem; border: 1px dashed var(--border); border-radius: var(--radius); background: var(--surface-card); }\n .empty__title { margin: 0 0 .3rem; font-size: 1.1rem; }\n .empty__desc { margin: 0 auto; color: var(--text-secondary); max-width: 50ch; }\n .empty__action { margin-top: 1rem; }\n .grid { display: grid; gap: 1rem; }\n .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n @media (max-width: 880px) { .grid--2, .grid--3 { grid-template-columns: 1fr; } }\n .table-wrap { overflow: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-card); }\n table { width: 100%; border-collapse: collapse; font-size: .9rem; }\n th, td { text-align: left; padding: .65rem .75rem; border-bottom: 1px solid var(--border); vertical-align: top; }\n th { background: var(--surface-muted); font-weight: 650; color: var(--text-secondary); font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; }\n tr:last-child td { border-bottom: 0; }\n .stat { text-align: center; padding: .5rem; }\n .stat__value { font-size: 1.4rem; font-weight: 750; line-height: 1; }\n .stat__label { color: var(--text-secondary); font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; }\n .snapshot-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }\n .snapshot-card { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface-card); display: flex; flex-direction: column; }\n .snapshot-card__head { padding: .6rem .75rem; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; gap: .5rem; align-items: center; }\n .snapshot-card__meta { font-size: .8rem; color: var(--text-secondary); }\n .snapshot-card__body { padding: .5rem; display: grid; gap: .5rem; }\n .diff-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; }\n @media (max-width: 900px) { .diff-grid { grid-template-columns: 1fr; } }\n .diff-pane { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface-card); }\n .diff-pane__label { padding: .4rem .6rem; font-weight: 650; font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-secondary); background: var(--surface-muted); border-bottom: 1px solid var(--border); }\n .diff-pane__img { display: block; width: 100%; height: auto; background: repeating-conic-gradient(#e5e7eb 0% 25%, #f9fafb 0% 50%) 0 0 / 16px 16px; }\n .comment { border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem; background: var(--surface-card); }\n .comment__head { display: flex; gap: .5rem; align-items: center; font-size: .85rem; color: var(--text-secondary); }\n .comment__body { margin: .5rem 0 0; white-space: pre-wrap; word-break: break-word; }\n @media (max-width: 880px) {\n .topbar__menu { display: inline-flex; }\n .shell { grid-template-columns: 1fr; }\n .sidebar { display: none; position: fixed; inset: 56px 0 0 0; z-index: 30; height: auto; }\n .sidebar--open { display: block; }\n .content { padding: 1rem; }\n }\n `;\n}\n"],"mappings":";;;;;AAGA,SAAgB,UAAU,OAAmB,MAA0B;CACrE,OAAO;;kBAES,MAAM,OAAO;;wBAEP,MAAM,QAAQ,KAAK;wBACnB,MAAM,QAAQ,KAAK;;wBAEnB,MAAM,KAAK,QAAQ;0BACjB,MAAM,KAAK,UAAU;kBAC7B,MAAM,OAAO;;;;2BAIJ,MAAM,OAAO,SAAS;sBAC3B,MAAM,OAAO,IAAI;2BACZ,MAAM,OAAO,SAAS;qBAC5B,MAAM,OAAO;;;;;kBAKhB,KAAK,OAAO;wBACN,KAAK,QAAQ,KAAK;wBAClB,KAAK,QAAQ,KAAK;;wBAElB,KAAK,KAAK,QAAQ;0BAChB,KAAK,KAAK,UAAU;kBAC5B,KAAK,OAAO;2BACH,KAAK,OAAO,SAAS;sBAC1B,KAAK,OAAO,IAAI;2BACX,KAAK,OAAO,SAAS;;;;;;oBAM5B,KAAK,OAAO;0BACN,KAAK,QAAQ,KAAK;0BAClB,KAAK,QAAQ,KAAK;;0BAElB,KAAK,KAAK,QAAQ;4BAChB,KAAK,KAAK,UAAU;oBAC5B,KAAK,OAAO;6BACH,KAAK,OAAO,SAAS;wBAC1B,KAAK,OAAO,IAAI;6BACX,KAAK,OAAO,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsHlD"}
|
package/dist/ui/theme.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
//#region src/ui/theme.ts
|
|
5
|
+
/** Default light brand theme. */
|
|
5
6
|
const LIGHT_THEME = {
|
|
6
7
|
accent: "#2b7fff",
|
|
7
8
|
surface: {
|
|
@@ -19,6 +20,7 @@ const LIGHT_THEME = {
|
|
|
19
20
|
rejected: "#dc2626"
|
|
20
21
|
}
|
|
21
22
|
};
|
|
23
|
+
/** Default dark brand theme. */
|
|
22
24
|
const DARK_THEME = {
|
|
23
25
|
accent: "#4f8fff",
|
|
24
26
|
surface: {
|
package/dist/ui/theme.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.mjs","names":[],"sources":["../../src/ui/theme.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"theme.mjs","names":[],"sources":["../../src/ui/theme.ts"],"sourcesContent":["/** Brand theme tokens (accent, surfaces, text, borders, statuses). */\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/** Default light brand theme. */\nexport const LIGHT_THEME: BrandTheme = {\n accent: \"#2b7fff\",\n surface: { base: \"#f6f6f7\", card: \"#ffffff\" },\n text: { primary: \"#09090b\", secondary: \"#71717b\" },\n border: \"#e4e4e7\",\n status: { approved: \"#16a34a\", new: \"#d97706\", rejected: \"#dc2626\" },\n};\n\n/** Default dark brand theme. */\nexport const DARK_THEME: BrandTheme = {\n accent: \"#4f8fff\",\n surface: { base: \"#09090b\", card: \"#18181b\" },\n text: { primary: \"#fafafa\", secondary: \"#9f9fa9\" },\n border: \"#ffffff1a\",\n status: { approved: \"#22c55e\", new: \"#f59e0b\", rejected: \"#ef4444\" },\n};\n"],"mappings":";;;;;AAUA,MAAa,cAA0B;CACrC,QAAQ;CACR,SAAS;EAAE,MAAM;EAAW,MAAM;CAAU;CAC5C,MAAM;EAAE,SAAS;EAAW,WAAW;CAAU;CACjD,QAAQ;CACR,QAAQ;EAAE,UAAU;EAAW,KAAK;EAAW,UAAU;CAAU;AACrE;;AAGA,MAAa,aAAyB;CACpC,QAAQ;CACR,SAAS;EAAE,MAAM;EAAW,MAAM;CAAU;CAC5C,MAAM;EAAE,SAAS;EAAW,WAAW;CAAU;CACjD,QAAQ;CACR,QAAQ;EAAE,UAAU;EAAW,KAAK;EAAW,UAAU;CAAU;AACrE"}
|
package/dist/urls.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
//#region src/urls.d.ts
|
|
4
|
+
/** Type-safe URL builder for project pages and published Storybooks. */
|
|
4
5
|
interface UrlBuilder {
|
|
5
6
|
projectsList(): string;
|
|
6
7
|
project(slug: string): string;
|
|
@@ -13,6 +14,13 @@ interface UrlBuilder {
|
|
|
13
14
|
storybookBuild(slug: string, buildId: string): string;
|
|
14
15
|
settings(slug: string): string;
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a URL builder rooted at the given base URL.
|
|
19
|
+
*
|
|
20
|
+
* @param baseUrl - Public root URL of the shelf server.
|
|
21
|
+
* @param publishedBaseDomain - Optional wildcard domain for published Storybooks.
|
|
22
|
+
* @returns The URL builder.
|
|
23
|
+
*/
|
|
16
24
|
declare function createUrlBuilder(baseUrl: string, publishedBaseDomain?: string): UrlBuilder;
|
|
17
25
|
//#endregion
|
|
18
26
|
export { UrlBuilder, createUrlBuilder };
|
package/dist/urls.mjs
CHANGED
|
@@ -2,6 +2,13 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
//#region src/urls.ts
|
|
5
|
+
/**
|
|
6
|
+
* Create a URL builder rooted at the given base URL.
|
|
7
|
+
*
|
|
8
|
+
* @param baseUrl - Public root URL of the shelf server.
|
|
9
|
+
* @param publishedBaseDomain - Optional wildcard domain for published Storybooks.
|
|
10
|
+
* @returns The URL builder.
|
|
11
|
+
*/
|
|
5
12
|
function createUrlBuilder(baseUrl, publishedBaseDomain) {
|
|
6
13
|
const root = baseUrl.replace(/\/+$/u, "");
|
|
7
14
|
return {
|
package/dist/urls.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urls.mjs","names":[],"sources":["../src/urls.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"urls.mjs","names":[],"sources":["../src/urls.ts"],"sourcesContent":["/** Type-safe URL builder for project pages and published Storybooks. */\nexport interface UrlBuilder {\n projectsList(): string;\n project(slug: string): string;\n buildsList(slug: string): string;\n build(slug: string, buildId: string): string;\n labels(slug: string): string;\n label(slug: string, key: string, value: string): string;\n storybook(slug: string): string;\n storybookLabel(slug: string, key: string, value: string): string;\n storybookBuild(slug: string, buildId: string): string;\n settings(slug: string): string;\n}\n\n/**\n * Create a URL builder rooted at the given base URL.\n *\n * @param baseUrl - Public root URL of the shelf server.\n * @param publishedBaseDomain - Optional wildcard domain for published Storybooks.\n * @returns The URL builder.\n */\nexport function createUrlBuilder(baseUrl: string, publishedBaseDomain?: string): UrlBuilder {\n const root = baseUrl.replace(/\\/+$/u, \"\");\n\n return {\n projectsList: () => root,\n project: (slug) => `${root}/projects/${slug}`,\n buildsList: (slug) => `${root}/projects/${slug}/builds`,\n build: (slug, buildId) => `${root}/projects/${slug}/builds/${buildId}`,\n labels: (slug) => `${root}/projects/${slug}/labels`,\n label: (slug, key, value) =>\n `${root}/projects/${slug}/labels/${encodeURIComponent(key)}/${encodeURI(value)}`,\n storybook: (slug) =>\n publishedBaseDomain\n ? `https://${slug}.${publishedBaseDomain}`\n : `${root}/projects/${slug}/storybook`,\n storybookLabel: (slug, key, value) =>\n `${root}/projects/${slug}/storybook/${encodeURIComponent(key)}/${encodeURI(value)}`,\n storybookBuild: (slug, buildId) =>\n publishedBaseDomain\n ? `https://${buildId}.${slug}.${publishedBaseDomain}`\n : `${root}/projects/${slug}/storybook/build/${buildId}`,\n settings: (slug) => `${root}/projects/${slug}/settings`,\n };\n}\n"],"mappings":";;;;;;;;;;;AAqBA,SAAgB,iBAAiB,SAAiB,qBAA0C;CAC1F,MAAM,OAAO,QAAQ,QAAQ,SAAS,EAAE;CAExC,OAAO;EACL,oBAAoB;EACpB,UAAU,SAAS,GAAG,KAAK,YAAY;EACvC,aAAa,SAAS,GAAG,KAAK,YAAY,KAAK;EAC/C,QAAQ,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,UAAU;EAC7D,SAAS,SAAS,GAAG,KAAK,YAAY,KAAK;EAC3C,QAAQ,MAAM,KAAK,UACjB,GAAG,KAAK,YAAY,KAAK,UAAU,mBAAmB,GAAG,EAAE,GAAG,UAAU,KAAK;EAC/E,YAAY,SACV,sBACI,WAAW,KAAK,GAAG,wBACnB,GAAG,KAAK,YAAY,KAAK;EAC/B,iBAAiB,MAAM,KAAK,UAC1B,GAAG,KAAK,YAAY,KAAK,aAAa,mBAAmB,GAAG,EAAE,GAAG,UAAU,KAAK;EAClF,iBAAiB,MAAM,YACrB,sBACI,WAAW,QAAQ,GAAG,KAAK,GAAG,wBAC9B,GAAG,KAAK,YAAY,KAAK,mBAAmB;EAClD,WAAW,SAAS,GAAG,KAAK,YAAY,KAAK;CAC/C;AACF"}
|
package/dist/utils/hash.mjs
CHANGED
|
@@ -3,12 +3,15 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { createHash, createHmac, randomBytes } from "node:crypto";
|
|
5
5
|
//#region src/utils/hash.ts
|
|
6
|
+
/** Hash a value with SHA-256, returning lowercase hex. */
|
|
6
7
|
function sha256(value) {
|
|
7
8
|
return createHash("sha256").update(value).digest("hex");
|
|
8
9
|
}
|
|
10
|
+
/** Sign a value with HMAC-SHA-256, returning lowercase hex. */
|
|
9
11
|
function hmacSha256(secret, value) {
|
|
10
12
|
return createHmac("sha256", secret).update(value).digest("hex");
|
|
11
13
|
}
|
|
14
|
+
/** Generate a prefixed random token and its SHA-256 hash. */
|
|
12
15
|
function randomToken(prefix) {
|
|
13
16
|
const value = `${prefix}${randomBytes(24).toString("base64url")}`;
|
|
14
17
|
return {
|
package/dist/utils/hash.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.mjs","names":[],"sources":["../../src/utils/hash.ts"],"sourcesContent":["import { createHash, createHmac, randomBytes, timingSafeEqual } from \"node:crypto\";\n\nexport function sha256(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nexport function hmacSha256(secret: string, value: string): string {\n return createHmac(\"sha256\", secret).update(value).digest(\"hex\");\n}\n\nexport function randomToken(prefix: string): { value: string; hash: string } {\n const value = `${prefix}${randomBytes(24).toString(\"base64url\")}`;\n return { value, hash: sha256(value) };\n}\n\nexport function timingSafeEqualString(a: string, b: string): boolean {\n const ab = Buffer.from(a);\n const bb = Buffer.from(b);\n return ab.length === bb.length && timingSafeEqual(ab, bb);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"hash.mjs","names":[],"sources":["../../src/utils/hash.ts"],"sourcesContent":["import { createHash, createHmac, randomBytes, timingSafeEqual } from \"node:crypto\";\n\n/** Hash a value with SHA-256, returning lowercase hex. */\nexport function sha256(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\n/** Sign a value with HMAC-SHA-256, returning lowercase hex. */\nexport function hmacSha256(secret: string, value: string): string {\n return createHmac(\"sha256\", secret).update(value).digest(\"hex\");\n}\n\n/** Generate a prefixed random token and its SHA-256 hash. */\nexport function randomToken(prefix: string): { value: string; hash: string } {\n const value = `${prefix}${randomBytes(24).toString(\"base64url\")}`;\n return { value, hash: sha256(value) };\n}\n\n/** Compare two strings in constant time to avoid timing leaks. */\nexport function timingSafeEqualString(a: string, b: string): boolean {\n const ab = Buffer.from(a);\n const bb = Buffer.from(b);\n return ab.length === bb.length && timingSafeEqual(ab, bb);\n}\n"],"mappings":";;;;;;AAGA,SAAgB,OAAO,OAAuB;CAC5C,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AACxD;;AAGA,SAAgB,WAAW,QAAgB,OAAuB;CAChE,OAAO,WAAW,UAAU,MAAM,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AAChE;;AAGA,SAAgB,YAAY,QAAiD;CAC3E,MAAM,QAAQ,GAAG,SAAS,YAAY,EAAE,CAAC,CAAC,SAAS,WAAW;CAC9D,OAAO;EAAE;EAAO,MAAM,OAAO,KAAK;CAAE;AACtC"}
|
package/dist/utils/ulid.mjs
CHANGED
|
@@ -29,9 +29,11 @@ function encodeRandom(bytes) {
|
|
|
29
29
|
if (bits > 0) out += CROCKFORD.charAt(buffer << 5 - bits & 31);
|
|
30
30
|
return out;
|
|
31
31
|
}
|
|
32
|
+
/** Generate a sortable, collision-resistant ULID. */
|
|
32
33
|
function ulid() {
|
|
33
34
|
return encodeTime(Date.now()) + encodeRandom(randomBytes(10));
|
|
34
35
|
}
|
|
36
|
+
/** Convert a name to a URL-safe slug of at most 63 characters. */
|
|
35
37
|
function slugify(value) {
|
|
36
38
|
return value.toLowerCase().replaceAll(/[^a-z0-9]+/gu, "-").replaceAll(/^-+|-+$/gu, "").slice(0, 63);
|
|
37
39
|
}
|
package/dist/utils/ulid.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ulid.mjs","names":[],"sources":["../../src/utils/ulid.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\n\nconst CROCKFORD = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nfunction encodeTime(time: number): string {\n let out = \"\";\n let remaining = time;\n for (let i = 9; i >= 0; i -= 1) {\n const mod = remaining % 32;\n out = CROCKFORD.charAt(mod) + out;\n remaining = (remaining - mod) / 32;\n }\n return out;\n}\n\n/* eslint-disable no-bitwise, no-non-null-assertion -- ULID encoding is inherently bitwise. */\nfunction encodeRandom(bytes: Buffer): string {\n let out = \"\";\n let buffer = 0;\n let bits = 0;\n for (const byte of bytes) {\n buffer = (buffer << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n out += CROCKFORD.charAt((buffer >>> (bits - 5)) & 31);\n bits -= 5;\n }\n }\n if (bits > 0) {\n out += CROCKFORD.charAt((buffer << (5 - bits)) & 31);\n }\n return out;\n}\n/* eslint-enable no-bitwise, no-non-null-assertion */\n\nexport function ulid(): string {\n return encodeTime(Date.now()) + encodeRandom(randomBytes(10));\n}\n\nexport function slugify(value: string): string {\n return value\n .toLowerCase()\n .replaceAll(/[^a-z0-9]+/gu, \"-\")\n .replaceAll(/^-+|-+$/gu, \"\")\n .slice(0, 63);\n}\n"],"mappings":";;;;;AAEA,MAAM,YAAY;AAElB,SAAS,WAAW,MAAsB;CACxC,IAAI,MAAM;CACV,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG;EAC9B,MAAM,MAAM,YAAY;EACxB,MAAM,UAAU,OAAO,GAAG,IAAI;EAC9B,aAAa,YAAY,OAAO;CAClC;CACA,OAAO;AACT;AAGA,SAAS,aAAa,OAAuB;CAC3C,IAAI,MAAM;CACV,IAAI,SAAS;CACb,IAAI,OAAO;CACX,KAAK,MAAM,QAAQ,OAAO;EACxB,SAAU,UAAU,IAAK;EACzB,QAAQ;EACR,OAAO,QAAQ,GAAG;GAChB,OAAO,UAAU,OAAQ,WAAY,OAAO,IAAM,EAAE;GACpD,QAAQ;EACV;CACF;CACA,IAAI,OAAO,GACT,OAAO,UAAU,OAAQ,UAAW,IAAI,OAAS,EAAE;CAErD,OAAO;AACT
|
|
1
|
+
{"version":3,"file":"ulid.mjs","names":[],"sources":["../../src/utils/ulid.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\n\nconst CROCKFORD = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nfunction encodeTime(time: number): string {\n let out = \"\";\n let remaining = time;\n for (let i = 9; i >= 0; i -= 1) {\n const mod = remaining % 32;\n out = CROCKFORD.charAt(mod) + out;\n remaining = (remaining - mod) / 32;\n }\n return out;\n}\n\n/* eslint-disable no-bitwise, no-non-null-assertion -- ULID encoding is inherently bitwise. */\nfunction encodeRandom(bytes: Buffer): string {\n let out = \"\";\n let buffer = 0;\n let bits = 0;\n for (const byte of bytes) {\n buffer = (buffer << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n out += CROCKFORD.charAt((buffer >>> (bits - 5)) & 31);\n bits -= 5;\n }\n }\n if (bits > 0) {\n out += CROCKFORD.charAt((buffer << (5 - bits)) & 31);\n }\n return out;\n}\n/* eslint-enable no-bitwise, no-non-null-assertion */\n\n/** Generate a sortable, collision-resistant ULID. */\nexport function ulid(): string {\n return encodeTime(Date.now()) + encodeRandom(randomBytes(10));\n}\n\n/** Convert a name to a URL-safe slug of at most 63 characters. */\nexport function slugify(value: string): string {\n return value\n .toLowerCase()\n .replaceAll(/[^a-z0-9]+/gu, \"-\")\n .replaceAll(/^-+|-+$/gu, \"\")\n .slice(0, 63);\n}\n"],"mappings":";;;;;AAEA,MAAM,YAAY;AAElB,SAAS,WAAW,MAAsB;CACxC,IAAI,MAAM;CACV,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG;EAC9B,MAAM,MAAM,YAAY;EACxB,MAAM,UAAU,OAAO,GAAG,IAAI;EAC9B,aAAa,YAAY,OAAO;CAClC;CACA,OAAO;AACT;AAGA,SAAS,aAAa,OAAuB;CAC3C,IAAI,MAAM;CACV,IAAI,SAAS;CACb,IAAI,OAAO;CACX,KAAK,MAAM,QAAQ,OAAO;EACxB,SAAU,UAAU,IAAK;EACzB,QAAQ;EACR,OAAO,QAAQ,GAAG;GAChB,OAAO,UAAU,OAAQ,WAAY,OAAO,IAAM,EAAE;GACpD,QAAQ;EACV;CACF;CACA,IAAI,OAAO,GACT,OAAO,UAAU,OAAQ,UAAW,IAAI,OAAS,EAAE;CAErD,OAAO;AACT;;AAIA,SAAgB,OAAe;CAC7B,OAAO,WAAW,KAAK,IAAI,CAAC,IAAI,aAAa,YAAY,EAAE,CAAC;AAC9D;;AAGA,SAAgB,QAAQ,OAAuB;CAC7C,OAAO,MACJ,YAAY,CAAC,CACb,WAAW,gBAAgB,GAAG,CAAC,CAC/B,WAAW,aAAa,EAAE,CAAC,CAC3B,MAAM,GAAG,EAAE;AAChB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyshelf/core",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "StoryShelf core: Hono router, adapter interfaces, models, capture pipeline, diff, retention.",
|
|
5
5
|
"homepage": "https://github.com/GuptaSiddhant/StoryShelf#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
"source": "./src/adapters/auth.ts",
|
|
32
32
|
"default": "./dist/adapter/auth.mjs"
|
|
33
33
|
},
|
|
34
|
+
"./adapter/capture-queue": {
|
|
35
|
+
"source": "./src/adapters/capture-queue.ts",
|
|
36
|
+
"default": "./dist/adapter/capture-queue.mjs"
|
|
37
|
+
},
|
|
34
38
|
"./adapter/capture-runner": {
|
|
35
39
|
"source": "./src/adapters/capture-runner.ts",
|
|
36
40
|
"default": "./dist/adapter/capture-runner.mjs"
|
|
@@ -43,85 +47,81 @@
|
|
|
43
47
|
"source": "./src/adapters/git-host/index.ts",
|
|
44
48
|
"default": "./dist/adapter/git-host.mjs"
|
|
45
49
|
},
|
|
50
|
+
"./adapter/git-host/comments": {
|
|
51
|
+
"source": "./src/adapters/git-host/comments.ts",
|
|
52
|
+
"default": "./dist/adapter/git-host/comments.mjs"
|
|
53
|
+
},
|
|
46
54
|
"./adapter/git-host/helpers": {
|
|
47
55
|
"source": "./src/adapters/git-host/helpers.ts",
|
|
48
56
|
"default": "./dist/adapter/git-host/helpers.mjs"
|
|
49
57
|
},
|
|
58
|
+
"./adapter/init": {
|
|
59
|
+
"source": "./src/adapters/init.ts",
|
|
60
|
+
"default": "./dist/adapter/init.mjs"
|
|
61
|
+
},
|
|
62
|
+
"./adapter/metadata": {
|
|
63
|
+
"source": "./src/adapters/metadata.ts",
|
|
64
|
+
"default": "./dist/adapter/metadata.mjs"
|
|
65
|
+
},
|
|
50
66
|
"./adapter/storage": {
|
|
51
67
|
"source": "./src/adapters/storage.ts",
|
|
52
68
|
"default": "./dist/adapter/storage.mjs"
|
|
53
69
|
},
|
|
70
|
+
"./capture": {
|
|
71
|
+
"source": "./src/capture/index.ts",
|
|
72
|
+
"default": "./dist/capture.mjs"
|
|
73
|
+
},
|
|
54
74
|
"./ddl": {
|
|
55
75
|
"source": "./src/ddl.ts",
|
|
56
76
|
"default": "./dist/ddl.mjs"
|
|
57
77
|
},
|
|
58
|
-
"./
|
|
59
|
-
"source": "./src/
|
|
60
|
-
"default": "./dist/
|
|
61
|
-
},
|
|
62
|
-
"./models/build": {
|
|
63
|
-
"source": "./src/models/build.ts",
|
|
64
|
-
"default": "./dist/models/build.mjs"
|
|
78
|
+
"./diff": {
|
|
79
|
+
"source": "./src/diff/index.ts",
|
|
80
|
+
"default": "./dist/diff.mjs"
|
|
65
81
|
},
|
|
66
|
-
"./
|
|
67
|
-
"source": "./src/
|
|
68
|
-
"default": "./dist/
|
|
82
|
+
"./logger": {
|
|
83
|
+
"source": "./src/logger.ts",
|
|
84
|
+
"default": "./dist/logger.mjs"
|
|
69
85
|
},
|
|
70
|
-
"./
|
|
71
|
-
"source": "./src/
|
|
72
|
-
"default": "./dist/
|
|
73
|
-
},
|
|
74
|
-
"./models/member": {
|
|
75
|
-
"source": "./src/models/member.ts",
|
|
76
|
-
"default": "./dist/models/member.mjs"
|
|
77
|
-
},
|
|
78
|
-
"./models/project": {
|
|
79
|
-
"source": "./src/models/project.ts",
|
|
80
|
-
"default": "./dist/models/project.mjs"
|
|
81
|
-
},
|
|
82
|
-
"./models/snapshot": {
|
|
83
|
-
"source": "./src/models/snapshot.ts",
|
|
84
|
-
"default": "./dist/models/snapshot.mjs"
|
|
85
|
-
},
|
|
86
|
-
"./models/token": {
|
|
87
|
-
"source": "./src/models/token.ts",
|
|
88
|
-
"default": "./dist/models/token.mjs"
|
|
89
|
-
},
|
|
90
|
-
"./models/webhook": {
|
|
91
|
-
"source": "./src/models/webhook.ts",
|
|
92
|
-
"default": "./dist/models/webhook.mjs"
|
|
86
|
+
"./paths": {
|
|
87
|
+
"source": "./src/utils/paths.ts",
|
|
88
|
+
"default": "./dist/paths.mjs"
|
|
93
89
|
},
|
|
94
90
|
"./schema": {
|
|
95
|
-
"source": "./src/schema.ts",
|
|
91
|
+
"source": "./src/schema/index.ts",
|
|
96
92
|
"default": "./dist/schema.mjs"
|
|
97
93
|
},
|
|
98
94
|
"./types": {
|
|
99
95
|
"source": "./src/types.ts",
|
|
100
96
|
"default": "./dist/types.mjs"
|
|
101
97
|
},
|
|
98
|
+
"./urls": {
|
|
99
|
+
"source": "./src/urls.ts",
|
|
100
|
+
"default": "./dist/urls.mjs"
|
|
101
|
+
},
|
|
102
102
|
"./package.json": "./package.json"
|
|
103
103
|
},
|
|
104
104
|
"publishConfig": {
|
|
105
105
|
"exports": {
|
|
106
106
|
".": "./dist/index.mjs",
|
|
107
107
|
"./adapter/auth": "./dist/adapter/auth.mjs",
|
|
108
|
+
"./adapter/capture-queue": "./dist/adapter/capture-queue.mjs",
|
|
108
109
|
"./adapter/capture-runner": "./dist/adapter/capture-runner.mjs",
|
|
109
110
|
"./adapter/database": "./dist/adapter/database.mjs",
|
|
110
111
|
"./adapter/git-host": "./dist/adapter/git-host.mjs",
|
|
112
|
+
"./adapter/git-host/comments": "./dist/adapter/git-host/comments.mjs",
|
|
111
113
|
"./adapter/git-host/helpers": "./dist/adapter/git-host/helpers.mjs",
|
|
114
|
+
"./adapter/init": "./dist/adapter/init.mjs",
|
|
115
|
+
"./adapter/metadata": "./dist/adapter/metadata.mjs",
|
|
112
116
|
"./adapter/storage": "./dist/adapter/storage.mjs",
|
|
117
|
+
"./capture": "./dist/capture.mjs",
|
|
113
118
|
"./ddl": "./dist/ddl.mjs",
|
|
114
|
-
"./
|
|
115
|
-
"./
|
|
116
|
-
"./
|
|
117
|
-
"./models/label": "./dist/models/label.mjs",
|
|
118
|
-
"./models/member": "./dist/models/member.mjs",
|
|
119
|
-
"./models/project": "./dist/models/project.mjs",
|
|
120
|
-
"./models/snapshot": "./dist/models/snapshot.mjs",
|
|
121
|
-
"./models/token": "./dist/models/token.mjs",
|
|
122
|
-
"./models/webhook": "./dist/models/webhook.mjs",
|
|
119
|
+
"./diff": "./dist/diff.mjs",
|
|
120
|
+
"./logger": "./dist/logger.mjs",
|
|
121
|
+
"./paths": "./dist/paths.mjs",
|
|
123
122
|
"./schema": "./dist/schema.mjs",
|
|
124
123
|
"./types": "./dist/types.mjs",
|
|
124
|
+
"./urls": "./dist/urls.mjs",
|
|
125
125
|
"./package.json": "./package.json"
|
|
126
126
|
},
|
|
127
127
|
"access": "public"
|
|
@@ -140,18 +140,20 @@
|
|
|
140
140
|
"dependencies": {
|
|
141
141
|
"@hono/swagger-ui": "^0.6.1",
|
|
142
142
|
"@hono/zod-openapi": "^1.1.5",
|
|
143
|
-
"adm-zip": "^0.6.0",
|
|
144
143
|
"drizzle-orm": "^0.44.0",
|
|
145
144
|
"hono": "^4.11.0",
|
|
146
145
|
"pino": "^10.3.1",
|
|
147
146
|
"pixelmatch": "^7.1.0",
|
|
148
147
|
"pngjs": "^7.0.0",
|
|
148
|
+
"unzipper": "0.12.5",
|
|
149
149
|
"zod": "^4.2.0"
|
|
150
150
|
},
|
|
151
151
|
"devDependencies": {
|
|
152
152
|
"@types/node": "catalog:",
|
|
153
153
|
"@types/pngjs": "^6.0.5",
|
|
154
|
+
"@types/unzipper": "0.10.11",
|
|
154
155
|
"@vitest/coverage-v8": "catalog:",
|
|
156
|
+
"adm-zip": "0.6.0",
|
|
155
157
|
"oxfmt": "catalog:",
|
|
156
158
|
"oxlint": "catalog:",
|
|
157
159
|
"oxlint-tsgolint": "catalog:",
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import __tsdown_shims_path from 'node:path';
|
|
2
|
-
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
//#region src/adapters/metadata.d.ts
|
|
5
|
-
/** Common adapter identity — every adapter instance exposes this. */
|
|
6
|
-
interface AdapterMetadata {
|
|
7
|
-
/** Human label for UI/logs. */
|
|
8
|
-
readonly name: string;
|
|
9
|
-
/** Package version injected at build via __PKG_VERSION__. */
|
|
10
|
-
readonly version: string;
|
|
11
|
-
/** Optional short description. */
|
|
12
|
-
readonly description?: string;
|
|
13
|
-
/** Machine key (e.g. "github", "sqlite", "local", "s3", "password", "oauth", "playwright", "sqs", "memory"). */
|
|
14
|
-
readonly kind: string;
|
|
15
|
-
}
|
|
16
|
-
/** Git-specific metadata extension (adds logo + validation schema). */
|
|
17
|
-
interface GitAdapterMetadata extends AdapterMetadata {
|
|
18
|
-
readonly kind: string;
|
|
19
|
-
readonly logo?: string;
|
|
20
|
-
readonly schema: z.ZodType;
|
|
21
|
-
}
|
|
22
|
-
//#endregion
|
|
23
|
-
export { AdapterMetadata, GitAdapterMetadata };
|
|
24
|
-
//# sourceMappingURL=metadata.d.mts.map
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import __tsdown_shims_path from 'node:path';
|
|
2
|
-
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
|
-
import { StorageAdapter } from "../adapter/storage.mjs";
|
|
5
|
-
import { Baseline } from "../schema.mjs";
|
|
6
|
-
//#region src/models/baseline.d.ts
|
|
7
|
-
declare class BaselineModel {
|
|
8
|
-
private readonly db;
|
|
9
|
-
private readonly storage;
|
|
10
|
-
constructor(db: DatabaseAdapter, storage: StorageAdapter);
|
|
11
|
-
getFor(projectId: string, storyId: string, viewport: string, branch: string): Promise<Baseline | null>;
|
|
12
|
-
resolve(projectId: string, storyId: string, viewport: string, branch: string, defaultBranch: string): Promise<Baseline | null>;
|
|
13
|
-
read(baseline: Baseline): Promise<Buffer>;
|
|
14
|
-
upsert(projectId: string, storyId: string, viewport: string, branch: string, snapshotId: string, sourcePath: string): Promise<Baseline>;
|
|
15
|
-
list(projectId: string): Promise<Baseline[]>;
|
|
16
|
-
removeOrphans(projectId: string, validStoryIds: Set<string>): Promise<number>;
|
|
17
|
-
}
|
|
18
|
-
//#endregion
|
|
19
|
-
export { type Baseline, BaselineModel };
|
|
20
|
-
//# sourceMappingURL=baseline.d.mts.map
|
package/dist/models/build.d.mts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import __tsdown_shims_path from 'node:path';
|
|
2
|
-
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { BuildStatus } from "../types.mjs";
|
|
4
|
-
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
5
|
-
import { Build } from "../schema.mjs";
|
|
6
|
-
//#region src/models/build.d.ts
|
|
7
|
-
/**
|
|
8
|
-
* Return whether a build is publicly viewable without a session.
|
|
9
|
-
*
|
|
10
|
-
* A build is public iff `builds.public` is set or its branch matches the
|
|
11
|
-
* project's `public_branch_regex` (ADR 0011). Supplying an empty/nonexistent
|
|
12
|
-
* regex makes every build require auth.
|
|
13
|
-
*/
|
|
14
|
-
declare function isPublicBuild(project: {
|
|
15
|
-
publicBranchRegex: string | null;
|
|
16
|
-
}, build: Pick<Build, "public" | "gitBranch">): boolean;
|
|
17
|
-
interface BuildCreateInput {
|
|
18
|
-
gitSha: string;
|
|
19
|
-
gitBranch: string;
|
|
20
|
-
isDefault?: boolean;
|
|
21
|
-
authorEmail?: string;
|
|
22
|
-
authorName?: string;
|
|
23
|
-
message?: string;
|
|
24
|
-
public?: boolean;
|
|
25
|
-
}
|
|
26
|
-
interface BuildListFilter {
|
|
27
|
-
status?: BuildStatus;
|
|
28
|
-
branch?: string;
|
|
29
|
-
labelKey?: string;
|
|
30
|
-
labelValue?: string;
|
|
31
|
-
}
|
|
32
|
-
declare class BuildModel {
|
|
33
|
-
private readonly db;
|
|
34
|
-
constructor(db: DatabaseAdapter);
|
|
35
|
-
create(projectId: string, input: BuildCreateInput): Promise<Build>;
|
|
36
|
-
get(id: string): Promise<Build | null>;
|
|
37
|
-
list(projectId: string, filter?: BuildListFilter): Promise<Build[]>;
|
|
38
|
-
/** Return the most recent build intended for publishing, if any. */
|
|
39
|
-
latestPublished(project: {
|
|
40
|
-
id: string;
|
|
41
|
-
publicBranchRegex: string | null;
|
|
42
|
-
}): Promise<Build | null>;
|
|
43
|
-
update(id: string, patch: Partial<Pick<Build, "status" | "public" | "message" | "authorEmail" | "authorName">>): Promise<Build>;
|
|
44
|
-
setStatus(id: string, status: BuildStatus): Promise<Build>;
|
|
45
|
-
updateCounts(id: string): Promise<Build>;
|
|
46
|
-
remove(id: string): Promise<void>;
|
|
47
|
-
}
|
|
48
|
-
//#endregion
|
|
49
|
-
export { type Build, BuildCreateInput, BuildListFilter, BuildModel, isPublicBuild };
|
|
50
|
-
//# sourceMappingURL=build.d.mts.map
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import __tsdown_shims_path from 'node:path';
|
|
2
|
-
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
|
-
import { Comment } from "../schema.mjs";
|
|
5
|
-
//#region src/models/comment.d.ts
|
|
6
|
-
interface CommentCreateInput {
|
|
7
|
-
body: string;
|
|
8
|
-
snapshotId?: string;
|
|
9
|
-
parentId?: string;
|
|
10
|
-
}
|
|
11
|
-
declare class CommentModel {
|
|
12
|
-
private readonly db;
|
|
13
|
-
constructor(db: DatabaseAdapter);
|
|
14
|
-
listByBuild(buildId: string): Promise<Comment[]>;
|
|
15
|
-
create(projectId: string, buildId: string, userId: string, input: CommentCreateInput): Promise<Comment>;
|
|
16
|
-
resolve(id: string): Promise<Comment>;
|
|
17
|
-
}
|
|
18
|
-
//#endregion
|
|
19
|
-
export { type Comment, CommentCreateInput, CommentModel };
|
|
20
|
-
//# sourceMappingURL=comment.d.mts.map
|
package/dist/models/label.d.mts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import __tsdown_shims_path from 'node:path';
|
|
2
|
-
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
|
-
import { BuildLabel, LabelType } from "../schema.mjs";
|
|
5
|
-
//#region src/models/label.d.ts
|
|
6
|
-
/** Data operations for label types and build labels. */
|
|
7
|
-
declare class LabelModel {
|
|
8
|
-
private readonly db;
|
|
9
|
-
/**
|
|
10
|
-
* @param db - Database adapter.
|
|
11
|
-
*/
|
|
12
|
-
constructor(db: DatabaseAdapter);
|
|
13
|
-
/**
|
|
14
|
-
* Seed the default label types for a project if missing.
|
|
15
|
-
*
|
|
16
|
-
* @param projectId - Project ID.
|
|
17
|
-
*/
|
|
18
|
-
seedFor(projectId: string): Promise<void>;
|
|
19
|
-
/** List all label types for a project. */
|
|
20
|
-
listTypes(projectId: string): Promise<LabelType[]>;
|
|
21
|
-
/** Fetch a label type by key, or null if not found. */
|
|
22
|
-
getType(projectId: string, key: string): Promise<LabelType | null>;
|
|
23
|
-
/** Create a custom label type for a project. */
|
|
24
|
-
createType(projectId: string, input: {
|
|
25
|
-
key: string;
|
|
26
|
-
name: string;
|
|
27
|
-
linkTemplate?: string;
|
|
28
|
-
color?: string;
|
|
29
|
-
}): Promise<LabelType>;
|
|
30
|
-
/** Update a custom label type's name, template or color. */
|
|
31
|
-
updateType(projectId: string, key: string, input: {
|
|
32
|
-
name?: string;
|
|
33
|
-
linkTemplate?: string | null;
|
|
34
|
-
color?: string | null;
|
|
35
|
-
}): Promise<LabelType | null>;
|
|
36
|
-
/** Remove a custom label type, rejecting reserved or persistent types. */
|
|
37
|
-
removeType(projectId: string, key: string): Promise<void>;
|
|
38
|
-
/** Attach a label value to a build. */
|
|
39
|
-
attach(projectId: string, buildId: string, typeKey: string, value: string): Promise<BuildLabel>;
|
|
40
|
-
/** List all labels attached to a build. */
|
|
41
|
-
listForBuild(buildId: string): Promise<BuildLabel[]>;
|
|
42
|
-
/** Return the id of the latest build carrying a given label value, if any. */
|
|
43
|
-
latestBuildId(projectId: string, typeKey: string, value: string): Promise<string | null>;
|
|
44
|
-
/** Return whether a build is marked as persistent. */
|
|
45
|
-
hasPersistent(projectId: string, buildId: string): Promise<boolean>;
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { type BuildLabel, LabelModel, type LabelType };
|
|
49
|
-
//# sourceMappingURL=label.d.mts.map
|
package/dist/models/member.d.mts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import __tsdown_shims_path from 'node:path';
|
|
2
|
-
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { ProjectRole, SiteRole } from "../types.mjs";
|
|
4
|
-
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
5
|
-
import { ProjectMember } from "../schema.mjs";
|
|
6
|
-
//#region src/models/member.d.ts
|
|
7
|
-
/** Data operations for project membership and roles. */
|
|
8
|
-
declare class MemberModel {
|
|
9
|
-
private readonly db;
|
|
10
|
-
/**
|
|
11
|
-
* @param db - Database adapter.
|
|
12
|
-
*/
|
|
13
|
-
constructor(db: DatabaseAdapter);
|
|
14
|
-
/** List all members of a project. */
|
|
15
|
-
list(projectId: string): Promise<ProjectMember[]>;
|
|
16
|
-
/** Fetch a project member by project and user id, or null if not found. */
|
|
17
|
-
get(projectId: string, userId: string): Promise<ProjectMember | null>;
|
|
18
|
-
/** Set a user's role in a project, creating the membership if needed. */
|
|
19
|
-
set(projectId: string, userId: string, role: ProjectRole): Promise<ProjectMember>;
|
|
20
|
-
/** Remove a user from a project if they are a member. */
|
|
21
|
-
remove(projectId: string, userId: string): Promise<void>;
|
|
22
|
-
/** Resolve a user's effective project role, honoring site-wide admins. */
|
|
23
|
-
effectiveRole(siteRole: SiteRole, projectId: string, userId: string): Promise<ProjectRole | null>;
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
export { MemberModel, type ProjectMember };
|
|
27
|
-
//# sourceMappingURL=member.d.mts.map
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import __tsdown_shims_path from 'node:path';
|
|
2
|
-
import __tsdown_shims_url from 'node:url';
|
|
3
|
-
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
|
-
import { Project } from "../schema.mjs";
|
|
5
|
-
//#region src/models/project.d.ts
|
|
6
|
-
interface ProjectCreateInput {
|
|
7
|
-
name: string;
|
|
8
|
-
gitRepository?: string;
|
|
9
|
-
gitDefaultBranch?: string;
|
|
10
|
-
storybookMeta?: unknown;
|
|
11
|
-
}
|
|
12
|
-
/** Data operations for project records. */
|
|
13
|
-
declare class ProjectModel {
|
|
14
|
-
private readonly db;
|
|
15
|
-
/**
|
|
16
|
-
* @param db - Database adapter.
|
|
17
|
-
*/
|
|
18
|
-
constructor(db: DatabaseAdapter);
|
|
19
|
-
/**
|
|
20
|
-
* Create a project with a unique slug.
|
|
21
|
-
*
|
|
22
|
-
* @param input - Project creation input.
|
|
23
|
-
* @returns The created project.
|
|
24
|
-
*/
|
|
25
|
-
create(input: ProjectCreateInput): Promise<Project>;
|
|
26
|
-
/** Fetch a project by id, or null if not found. */
|
|
27
|
-
get(id: string): Promise<Project | null>;
|
|
28
|
-
/** Fetch a project by its slug, or null if not found. */
|
|
29
|
-
getBySlug(slug: string): Promise<Project | null>;
|
|
30
|
-
/** List all projects. */
|
|
31
|
-
list(): Promise<Project[]>;
|
|
32
|
-
/** Update mutable fields of a project. */
|
|
33
|
-
update(id: string, patch: Partial<Omit<Project, "storybookMeta">> & {
|
|
34
|
-
storybookMeta?: unknown;
|
|
35
|
-
}): Promise<Project>;
|
|
36
|
-
/** Delete a project by id. */
|
|
37
|
-
remove(id: string): Promise<void>;
|
|
38
|
-
private uniqueSlug;
|
|
39
|
-
}
|
|
40
|
-
//#endregion
|
|
41
|
-
export { type Project, ProjectCreateInput, ProjectModel };
|
|
42
|
-
//# sourceMappingURL=project.d.mts.map
|