@storyshelf/core 0.1.0 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +9 -8
- package/dist/adapter/auth.mjs.map +1 -1
- package/dist/adapter/capture-runner.d.mts +4 -0
- package/dist/adapter/git-host/helpers.d.mts +1 -0
- package/dist/adapter/git-host/helpers.mjs +2 -1
- package/dist/adapter/git-host/helpers.mjs.map +1 -1
- package/dist/adapter/storage.d.mts +1 -0
- package/dist/adapters/capture-queue.d.mts +2 -0
- package/dist/adapters/webhook-events.mjs +8 -0
- package/dist/adapters/webhook-events.mjs.map +1 -1
- package/dist/capture/adapter.d.mts +11 -1
- package/dist/capture/adapter.mjs +19 -1
- package/dist/capture/adapter.mjs.map +1 -1
- package/dist/capture/orchestrator.d.mts +7 -0
- package/dist/capture/orchestrator.mjs +43 -10
- package/dist/capture/orchestrator.mjs.map +1 -1
- package/dist/capture/pipeline.d.mts +5 -3
- package/dist/capture/pipeline.mjs +18 -6
- package/dist/capture/pipeline.mjs.map +1 -1
- package/dist/capture/queue.d.mts +2 -0
- package/dist/capture/queue.mjs +2 -1
- package/dist/capture/queue.mjs.map +1 -1
- 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 +12 -3
- package/dist/capture/storybook.mjs.map +1 -1
- package/dist/config.d.mts +27 -20
- package/dist/config.mjs +16 -2
- package/dist/config.mjs.map +1 -1
- package/dist/ddl.d.mts +2 -1
- package/dist/ddl.mjs +3 -0
- package/dist/ddl.mjs.map +1 -1
- package/dist/diff/engine.d.mts +8 -0
- package/dist/diff/engine.mjs +10 -2
- package/dist/diff/engine.mjs.map +1 -1
- package/dist/index.d.mts +7 -4
- package/dist/index.mjs +10 -3
- package/dist/index.mjs.map +1 -1
- package/dist/logger.d.mts +3 -3
- package/dist/logger.mjs.map +1 -1
- package/dist/middleware/csrf.mjs +2 -1
- 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/models/baseline.d.mts +1 -0
- package/dist/models/baseline.mjs +3 -1
- package/dist/models/baseline.mjs.map +1 -1
- package/dist/models/build.d.mts +19 -1
- package/dist/models/build.mjs +22 -2
- package/dist/models/build.mjs.map +1 -1
- package/dist/models/comment.d.mts +2 -0
- package/dist/models/comment.mjs +3 -1
- package/dist/models/comment.mjs.map +1 -1
- package/dist/models/label.d.mts +6 -0
- package/dist/models/label.mjs +13 -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.d.mts +1 -0
- package/dist/models/project.mjs +3 -2
- package/dist/models/project.mjs.map +1 -1
- package/dist/models/snapshot.d.mts +1 -0
- 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.d.mts +1 -0
- package/dist/models/webhook.mjs +2 -1
- package/dist/models/webhook.mjs.map +1 -1
- package/dist/pages/build-detail.mjs +2 -1
- package/dist/pages/build-detail.mjs.map +1 -1
- package/dist/pages/build-diff.mjs +1 -0
- package/dist/pages/build-diff.mjs.map +1 -1
- package/dist/pages/compute-jobs.mjs +2 -0
- package/dist/pages/compute-jobs.mjs.map +1 -1
- package/dist/pages/label-detail.mjs +227 -0
- package/dist/pages/label-detail.mjs.map +1 -0
- package/dist/pages/login.mjs +1 -0
- package/dist/pages/login.mjs.map +1 -1
- package/dist/pages/project-builds.mjs +1 -0
- 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 +33 -42
- package/dist/pages/project-settings.mjs.map +1 -1
- package/dist/pages/projects.mjs +1 -0
- package/dist/pages/projects.mjs.map +1 -1
- package/dist/pages/root.mjs +1 -0
- 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 +1 -0
- package/dist/pages/settings-labels.mjs.map +1 -1
- package/dist/pages/settings-members.mjs +1 -0
- package/dist/pages/settings-members.mjs.map +1 -1
- package/dist/pages/settings-status.mjs +1 -0
- package/dist/pages/settings-status.mjs.map +1 -1
- package/dist/pages/settings-tests.mjs +149 -0
- package/dist/pages/settings-tests.mjs.map +1 -0
- 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 +59 -0
- package/dist/pages/storybook.mjs.map +1 -0
- package/dist/retention/purge.d.mts +3 -0
- package/dist/retention/purge.mjs +2 -1
- package/dist/retention/purge.mjs.map +1 -1
- package/dist/routers/admin.mjs +1 -0
- 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 +15 -3
- package/dist/routers/builds.handlers.mjs.map +1 -1
- package/dist/routers/builds.mjs +5 -2
- 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/helpers.mjs +7 -1
- 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 +34 -1
- package/dist/routers/labels.mjs.map +1 -1
- package/dist/routers/media.mjs +1 -0
- 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 +1 -0
- package/dist/routers/projects.mjs.map +1 -1
- package/dist/routers/schemas.mjs +40 -4
- package/dist/routers/schemas.mjs.map +1 -1
- package/dist/routers/settings.mjs +22 -0
- package/dist/routers/settings.mjs.map +1 -1
- package/dist/routers/snapshots.mjs +1 -0
- package/dist/routers/snapshots.mjs.map +1 -1
- package/dist/routers/status-configs.mjs +1 -0
- package/dist/routers/status-configs.mjs.map +1 -1
- package/dist/routers/storybook.mjs +113 -0
- package/dist/routers/storybook.mjs.map +1 -0
- package/dist/routers/tokens.mjs +1 -0
- package/dist/routers/tokens.mjs.map +1 -1
- package/dist/routers/ui.mjs +25 -2
- package/dist/routers/ui.mjs.map +1 -1
- package/dist/routers/webhooks.mjs +1 -0
- package/dist/routers/webhooks.mjs.map +1 -1
- package/dist/schema-tables.mjs +166 -0
- package/dist/schema-tables.mjs.map +1 -0
- package/dist/schema.d.mts +194 -4352
- package/dist/schema.mjs +26 -136
- 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 +14 -1
- package/dist/types.mjs +8 -0
- package/dist/types.mjs.map +1 -1
- package/dist/ui/components.mjs +5 -0
- package/dist/ui/components.mjs.map +1 -1
- package/dist/ui/document.d.mts +1 -0
- package/dist/ui/document.mjs +10 -0
- package/dist/ui/document.mjs.map +1 -1
- 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/paths.d.mts +5 -0
- package/dist/utils/paths.mjs +5 -0
- package/dist/utils/paths.mjs.map +1 -1
- package/dist/utils/ulid.d.mts +2 -0
- package/dist/utils/ulid.mjs +5 -3
- package/dist/utils/ulid.mjs.map +1 -1
- package/package.json +76 -67
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}"],"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) => `${root}/projects/${slug}/labels/${encodeURIComponent(key)}/${encodeURI(value)}`,\n storybook: (slug) => (publishedBaseDomain ? `https://${slug}.${publishedBaseDomain}` : `${root}/projects/${slug}/storybook`),\n storybookLabel: (slug, key, value) => `${root}/projects/${slug}/storybook/${encodeURIComponent(key)}/${encodeURI(value)}`,\n storybookBuild: (slug, buildId) =>\n publishedBaseDomain ? `https://${buildId}.${slug}.${publishedBaseDomain}` : `${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,UAAU,GAAG,KAAK,YAAY,KAAK,UAAU,mBAAmB,GAAG,EAAE,GAAG,UAAU,KAAK;EAC1G,YAAY,SAAU,sBAAsB,WAAW,KAAK,GAAG,wBAAwB,GAAG,KAAK,YAAY,KAAK;EAChH,iBAAiB,MAAM,KAAK,UAAU,GAAG,KAAK,YAAY,KAAK,aAAa,mBAAmB,GAAG,EAAE,GAAG,UAAU,KAAK;EACtH,iBAAiB,MAAM,YACrB,sBAAsB,WAAW,QAAQ,GAAG,KAAK,GAAG,wBAAwB,GAAG,KAAK,YAAY,KAAK,mBAAmB;EAC1H,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/paths.d.mts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
//#region src/utils/paths.d.ts
|
|
4
|
+
/** Storage path for a captured snapshot screenshot. */
|
|
4
5
|
declare function screenshotPath(projectId: string, buildId: string, storyId: string, viewport: string): string;
|
|
6
|
+
/** Storage path for a snapshot diff overlay image. */
|
|
5
7
|
declare function diffPath(projectId: string, buildId: string, storyId: string, viewport: string): string;
|
|
8
|
+
/** Storage path for a branch baseline screenshot. */
|
|
6
9
|
declare function baselinePath(projectId: string, branch: string, storyId: string, viewport: string): string;
|
|
10
|
+
/** Storage prefix for an extracted published Storybook. */
|
|
7
11
|
declare function storybookDir(projectId: string, buildId: string): string;
|
|
12
|
+
/** Storage path for an uploaded Storybook zip. */
|
|
8
13
|
declare function storybookZipPath(projectId: string, buildId: string): string;
|
|
9
14
|
//#endregion
|
|
10
15
|
export { baselinePath, diffPath, screenshotPath, storybookDir, storybookZipPath };
|
package/dist/utils/paths.mjs
CHANGED
|
@@ -2,18 +2,23 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
//#region src/utils/paths.ts
|
|
5
|
+
/** Storage path for a captured snapshot screenshot. */
|
|
5
6
|
function screenshotPath(projectId, buildId, storyId, viewport) {
|
|
6
7
|
return `${projectId}/builds/${buildId}/screenshots/${storyId}/${viewport}.png`;
|
|
7
8
|
}
|
|
9
|
+
/** Storage path for a snapshot diff overlay image. */
|
|
8
10
|
function diffPath(projectId, buildId, storyId, viewport) {
|
|
9
11
|
return `${projectId}/builds/${buildId}/diffs/${storyId}/${viewport}.png`;
|
|
10
12
|
}
|
|
13
|
+
/** Storage path for a branch baseline screenshot. */
|
|
11
14
|
function baselinePath(projectId, branch, storyId, viewport) {
|
|
12
15
|
return `${projectId}/baselines/${branch}/${storyId}/${viewport}.png`;
|
|
13
16
|
}
|
|
17
|
+
/** Storage prefix for an extracted published Storybook. */
|
|
14
18
|
function storybookDir(projectId, buildId) {
|
|
15
19
|
return `${projectId}/builds/${buildId}/storybook`;
|
|
16
20
|
}
|
|
21
|
+
/** Storage path for an uploaded Storybook zip. */
|
|
17
22
|
function storybookZipPath(projectId, buildId) {
|
|
18
23
|
return `${projectId}/builds/${buildId}/storybook.zip`;
|
|
19
24
|
}
|
package/dist/utils/paths.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.mjs","names":[],"sources":["../../src/utils/paths.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"paths.mjs","names":[],"sources":["../../src/utils/paths.ts"],"sourcesContent":["/** Storage path for a captured snapshot screenshot. */\nexport function screenshotPath(projectId: string, buildId: string, storyId: string, viewport: string): string {\n return `${projectId}/builds/${buildId}/screenshots/${storyId}/${viewport}.png`;\n}\n\n/** Storage path for a snapshot diff overlay image. */\nexport function diffPath(projectId: string, buildId: string, storyId: string, viewport: string): string {\n return `${projectId}/builds/${buildId}/diffs/${storyId}/${viewport}.png`;\n}\n\n/** Storage path for a branch baseline screenshot. */\nexport function baselinePath(projectId: string, branch: string, storyId: string, viewport: string): string {\n return `${projectId}/baselines/${branch}/${storyId}/${viewport}.png`;\n}\n\n/** Storage prefix for an extracted published Storybook. */\nexport function storybookDir(projectId: string, buildId: string): string {\n return `${projectId}/builds/${buildId}/storybook`;\n}\n\n/** Storage path for an uploaded Storybook zip. */\nexport function storybookZipPath(projectId: string, buildId: string): string {\n return `${projectId}/builds/${buildId}/storybook.zip`;\n}\n"],"mappings":";;;;;AACA,SAAgB,eAAe,WAAmB,SAAiB,SAAiB,UAA0B;CAC5G,OAAO,GAAG,UAAU,UAAU,QAAQ,eAAe,QAAQ,GAAG,SAAS;AAC3E;;AAGA,SAAgB,SAAS,WAAmB,SAAiB,SAAiB,UAA0B;CACtG,OAAO,GAAG,UAAU,UAAU,QAAQ,SAAS,QAAQ,GAAG,SAAS;AACrE;;AAGA,SAAgB,aAAa,WAAmB,QAAgB,SAAiB,UAA0B;CACzG,OAAO,GAAG,UAAU,aAAa,OAAO,GAAG,QAAQ,GAAG,SAAS;AACjE;;AAGA,SAAgB,aAAa,WAAmB,SAAyB;CACvE,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC;;AAGA,SAAgB,iBAAiB,WAAmB,SAAyB;CAC3E,OAAO,GAAG,UAAU,UAAU,QAAQ;AACxC"}
|
package/dist/utils/ulid.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
//#region src/utils/ulid.d.ts
|
|
4
|
+
/** Generate a sortable, collision-resistant ULID. */
|
|
4
5
|
declare function ulid(): string;
|
|
6
|
+
/** Convert a name to a URL-safe slug of at most 63 characters. */
|
|
5
7
|
declare function slugify(value: string): string;
|
|
6
8
|
//#endregion
|
|
7
9
|
export { slugify, ulid };
|
package/dist/utils/ulid.mjs
CHANGED
|
@@ -9,7 +9,7 @@ function encodeTime(time) {
|
|
|
9
9
|
let remaining = time;
|
|
10
10
|
for (let i = 9; i >= 0; i -= 1) {
|
|
11
11
|
const mod = remaining % 32;
|
|
12
|
-
out = CROCKFORD
|
|
12
|
+
out = CROCKFORD.charAt(mod) + out;
|
|
13
13
|
remaining = (remaining - mod) / 32;
|
|
14
14
|
}
|
|
15
15
|
return out;
|
|
@@ -22,16 +22,18 @@ function encodeRandom(bytes) {
|
|
|
22
22
|
buffer = buffer << 8 | byte;
|
|
23
23
|
bits += 8;
|
|
24
24
|
while (bits >= 5) {
|
|
25
|
-
out += CROCKFORD
|
|
25
|
+
out += CROCKFORD.charAt(buffer >>> bits - 5 & 31);
|
|
26
26
|
bits -= 5;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
if (bits > 0) out += CROCKFORD
|
|
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
|
|
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,84 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyshelf/core",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
3
|
+
"version": "0.1.3",
|
|
5
4
|
"description": "StoryShelf core: Hono router, adapter interfaces, models, capture pipeline, diff, retention.",
|
|
5
|
+
"homepage": "https://github.com/GuptaSiddhant/StoryShelf#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/GuptaSiddhant/StoryShelf/issues"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
6
10
|
"author": {
|
|
7
11
|
"name": "Siddhant Gupta",
|
|
8
12
|
"url": "https://guptasiddhant.com"
|
|
9
13
|
},
|
|
10
|
-
"license": "MIT",
|
|
11
|
-
"sideEffects": false,
|
|
12
14
|
"repository": {
|
|
13
15
|
"type": "git",
|
|
14
|
-
"url": "git+https://github.com/GuptaSiddhant/
|
|
16
|
+
"url": "git+https://github.com/GuptaSiddhant/StoryShelf.git",
|
|
15
17
|
"directory": "packages/core"
|
|
16
18
|
},
|
|
17
|
-
"homepage": "https://github.com/GuptaSiddhant/storyshelf#readme",
|
|
18
|
-
"bugs": {
|
|
19
|
-
"url": "https://github.com/GuptaSiddhant/storyshelf/issues"
|
|
20
|
-
},
|
|
21
|
-
"publishConfig": {
|
|
22
|
-
"access": "public",
|
|
23
|
-
"exports": {
|
|
24
|
-
".": "./dist/index.mjs",
|
|
25
|
-
"./adapter/auth": "./dist/adapter/auth.mjs",
|
|
26
|
-
"./adapter/capture-runner": "./dist/adapter/capture-runner.mjs",
|
|
27
|
-
"./adapter/database": "./dist/adapter/database.mjs",
|
|
28
|
-
"./adapter/git-host": "./dist/adapter/git-host.mjs",
|
|
29
|
-
"./adapter/git-host/helpers": "./dist/adapter/git-host/helpers.mjs",
|
|
30
|
-
"./adapter/storage": "./dist/adapter/storage.mjs",
|
|
31
|
-
"./ddl": "./dist/ddl.mjs",
|
|
32
|
-
"./models/baseline": "./dist/models/baseline.mjs",
|
|
33
|
-
"./models/build": "./dist/models/build.mjs",
|
|
34
|
-
"./models/comment": "./dist/models/comment.mjs",
|
|
35
|
-
"./models/label": "./dist/models/label.mjs",
|
|
36
|
-
"./models/member": "./dist/models/member.mjs",
|
|
37
|
-
"./models/project": "./dist/models/project.mjs",
|
|
38
|
-
"./models/snapshot": "./dist/models/snapshot.mjs",
|
|
39
|
-
"./models/token": "./dist/models/token.mjs",
|
|
40
|
-
"./models/webhook": "./dist/models/webhook.mjs",
|
|
41
|
-
"./schema": "./dist/schema.mjs",
|
|
42
|
-
"./types": "./dist/types.mjs",
|
|
43
|
-
"./package.json": "./package.json"
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
19
|
"files": [
|
|
47
20
|
"dist"
|
|
48
21
|
],
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
"dev": "tsdown -w",
|
|
52
|
-
"fmt": "oxfmt -c ../../.oxfmtrc.json ./src",
|
|
53
|
-
"lint": "oxlint --type-aware --type-check ./src",
|
|
54
|
-
"lint:fix": "nub run lint -- --fix",
|
|
55
|
-
"prepublishOnly": "nub run build",
|
|
56
|
-
"test": "vitest run",
|
|
57
|
-
"test:coverage": "vitest run --coverage",
|
|
58
|
-
"test:watch": "vitest"
|
|
59
|
-
},
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"@hono/swagger-ui": "^0.6.1",
|
|
62
|
-
"@hono/zod-openapi": "^1.1.5",
|
|
63
|
-
"adm-zip": "^0.6.0",
|
|
64
|
-
"drizzle-orm": "^0.44.0",
|
|
65
|
-
"hono": "^4.11.0",
|
|
66
|
-
"pino": "^10.3.1",
|
|
67
|
-
"pixelmatch": "^7.1.0",
|
|
68
|
-
"pngjs": "^7.0.0",
|
|
69
|
-
"zod": "^4.2.0"
|
|
70
|
-
},
|
|
71
|
-
"devDependencies": {
|
|
72
|
-
"@types/node": "catalog:",
|
|
73
|
-
"@types/pngjs": "^6.0.5",
|
|
74
|
-
"@vitest/coverage-v8": "catalog:",
|
|
75
|
-
"oxfmt": "catalog:",
|
|
76
|
-
"oxlint": "catalog:",
|
|
77
|
-
"oxlint-tsgolint": "catalog:",
|
|
78
|
-
"tsdown": "catalog:",
|
|
79
|
-
"typescript": "catalog:",
|
|
80
|
-
"vitest": "catalog:"
|
|
81
|
-
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"sideEffects": false,
|
|
82
24
|
"types": "./dist/index.d.mts",
|
|
83
25
|
"exports": {
|
|
84
26
|
".": {
|
|
@@ -158,5 +100,72 @@
|
|
|
158
100
|
"default": "./dist/types.mjs"
|
|
159
101
|
},
|
|
160
102
|
"./package.json": "./package.json"
|
|
103
|
+
},
|
|
104
|
+
"publishConfig": {
|
|
105
|
+
"exports": {
|
|
106
|
+
".": "./dist/index.mjs",
|
|
107
|
+
"./adapter/auth": "./dist/adapter/auth.mjs",
|
|
108
|
+
"./adapter/capture-runner": "./dist/adapter/capture-runner.mjs",
|
|
109
|
+
"./adapter/database": "./dist/adapter/database.mjs",
|
|
110
|
+
"./adapter/git-host": "./dist/adapter/git-host.mjs",
|
|
111
|
+
"./adapter/git-host/helpers": "./dist/adapter/git-host/helpers.mjs",
|
|
112
|
+
"./adapter/storage": "./dist/adapter/storage.mjs",
|
|
113
|
+
"./ddl": "./dist/ddl.mjs",
|
|
114
|
+
"./models/baseline": "./dist/models/baseline.mjs",
|
|
115
|
+
"./models/build": "./dist/models/build.mjs",
|
|
116
|
+
"./models/comment": "./dist/models/comment.mjs",
|
|
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",
|
|
123
|
+
"./schema": "./dist/schema.mjs",
|
|
124
|
+
"./types": "./dist/types.mjs",
|
|
125
|
+
"./package.json": "./package.json"
|
|
126
|
+
},
|
|
127
|
+
"access": "public"
|
|
128
|
+
},
|
|
129
|
+
"scripts": {
|
|
130
|
+
"build": "tsdown",
|
|
131
|
+
"dev": "tsdown -w",
|
|
132
|
+
"fmt": "oxfmt ./src",
|
|
133
|
+
"lint": "oxlint --type-aware --type-check ./src",
|
|
134
|
+
"lint:fix": "nub run lint -- --fix",
|
|
135
|
+
"prepublishOnly": "nub run build",
|
|
136
|
+
"test": "vitest run",
|
|
137
|
+
"test:coverage": "vitest run --coverage",
|
|
138
|
+
"test:watch": "vitest"
|
|
139
|
+
},
|
|
140
|
+
"dependencies": {
|
|
141
|
+
"@hono/swagger-ui": "^0.6.1",
|
|
142
|
+
"@hono/zod-openapi": "^1.1.5",
|
|
143
|
+
"adm-zip": "^0.6.0",
|
|
144
|
+
"drizzle-orm": "^0.44.0",
|
|
145
|
+
"hono": "^4.11.0",
|
|
146
|
+
"pino": "^10.3.1",
|
|
147
|
+
"pixelmatch": "^7.1.0",
|
|
148
|
+
"pngjs": "^7.0.0",
|
|
149
|
+
"zod": "^4.2.0"
|
|
150
|
+
},
|
|
151
|
+
"devDependencies": {
|
|
152
|
+
"@types/node": "catalog:",
|
|
153
|
+
"@types/pngjs": "^6.0.5",
|
|
154
|
+
"@vitest/coverage-v8": "catalog:",
|
|
155
|
+
"oxfmt": "catalog:",
|
|
156
|
+
"oxlint": "catalog:",
|
|
157
|
+
"oxlint-tsgolint": "catalog:",
|
|
158
|
+
"tsdown": "catalog:",
|
|
159
|
+
"typescript": "catalog:",
|
|
160
|
+
"vitest": "catalog:"
|
|
161
|
+
},
|
|
162
|
+
"jsr": {
|
|
163
|
+
"runtimeCompat": {
|
|
164
|
+
"node": true,
|
|
165
|
+
"deno": true,
|
|
166
|
+
"bun": true,
|
|
167
|
+
"workerd": false,
|
|
168
|
+
"browser": false
|
|
169
|
+
}
|
|
161
170
|
}
|
|
162
171
|
}
|